MCPcopy Index your code
hub / github.com/nodejs/nodejs.org / rehypeShikiji

Function rehypeShikiji

packages/rehype-shiki/src/plugin.mjs:59–193  ·  view source on GitHub ↗
(options)

Source from the content-addressed store, hash-verified

57 * @param {import('#rs/index.mjs').HighlighterOptions & { highlighter: import('#rs/highlighter.mjs').SyntaxHighlighter }} options
58 */
59export default async function rehypeShikiji(options) {
60 const highlighter =
61 options?.highlighter ?? (await createHighlighter(options));
62
63 return function (tree) {
64 visit(tree, 'element', (_, index, parent) => {
65 const languages = [];
66 const displayNames = [];
67 const codeTabsChildren = [];
68
69 let defaultTab = '0';
70 let currentIndex = index;
71
72 while (isCodeBlock(parent?.children[currentIndex])) {
73 const codeElement = parent?.children[currentIndex].children[0];
74 const meta = parseMeta(codeElement.data?.meta);
75
76 // We should get the language name from the class name
77 if (codeElement.properties.className?.length) {
78 const className = codeElement.properties.className.join(' ');
79 const matches = className.match(/language-(?<language>.*)/);
80
81 languages.push(matches?.groups.language ?? 'text');
82 }
83
84 // Map the display names of each variant for the CodeTab
85 displayNames.push(meta.displayName?.replaceAll('|', '') ?? '');
86
87 codeTabsChildren.push(parent?.children[currentIndex]);
88
89 // If `active="true"` is provided in a CodeBox
90 // then the default selected entry of the CodeTabs will be the desired entry
91 if (meta.active === 'true') {
92 defaultTab = String(codeTabsChildren.length - 1);
93 }
94
95 const nextNode = parent?.children[currentIndex + 1];
96
97 // If the CodeBoxes are on the root tree the next Element will be
98 // an empty text element so we should skip it
99 currentIndex += nextNode && nextNode?.type === 'text' ? 2 : 1;
100 }
101
102 if (codeTabsChildren.length >= 2) {
103 const codeTabElement = {
104 type: 'element',
105 tagName: 'CodeTabs',
106 children: codeTabsChildren,
107 properties: {
108 languages: languages.join('|'),
109 displayNames: displayNames.join('|'),
110 defaultTab,
111 },
112 };
113
114 // This removes all the original Code Elements and adds a new CodeTab Element
115 // at the original start of the first Code Element
116 parent.children.splice(index, currentIndex - index, codeTabElement);

Callers 2

plugin.test.mjsFile · 0.85
plugins.mjsFile · 0.85

Calls 3

createHighlighterFunction · 0.85
isCodeBlockFunction · 0.85
parseMetaFunction · 0.85

Tested by

no test coverage detected