@@ -10,28 +10,28 @@ import { highlightToHast } from './index.mjs';
1010// to attribute the current language of the <pre> element
1111const languagePrefix = 'language-' ;
1212
13+ // The regex to match metadata
14+ const rMeta = / ( \w + ) (?: = (?: " ( [ ^ " ] + ) " | ( \S + ) ) ) ? / g;
15+
1316/**
14- * Retrieve the value for the given meta key.
15- *
16- * @example - Returns "CommonJS"
17- * getMetaParameter('displayName="CommonJS"', 'displayName');
18- *
19- * @param {any } meta - The meta parameter.
20- * @param {string } key - The key to retrieve the value.
21- *
22- * @return {string | undefined } - The value related to the given key.
17+ * Parses a fenced code block metadata string into a JavaScript object.
18+ * @param {string } meta - The metadata string from a Markdown code fence.
19+ * @returns {Record<string, string|boolean> } An object representing the metadata.
2320 */
24- function getMetaParameter ( meta , key ) {
25- if ( typeof meta !== 'string' ) {
26- return ;
21+ function parseMeta ( meta ) {
22+ const obj = { __raw : meta } ;
23+
24+ if ( ! meta ) {
25+ return obj ;
2726 }
2827
29- const matches = meta . match ( new RegExp ( `${ key } ="(?<parameter>[^"]*)"` ) ) ;
30- const parameter = matches ?. groups . parameter ;
28+ let match ;
29+
30+ while ( ( match = rMeta . exec ( meta ) ) !== null ) {
31+ obj [ match [ 1 ] ] = match [ 2 ] ?? match [ 3 ] ?? true ;
32+ }
3133
32- return parameter !== undefined && parameter . length > 0
33- ? parameter
34- : undefined ;
34+ return obj ;
3535}
3636
3737/**
@@ -65,11 +65,7 @@ export default function rehypeShikiji() {
6565
6666 while ( isCodeBlock ( parent ?. children [ currentIndex ] ) ) {
6767 const codeElement = parent ?. children [ currentIndex ] . children [ 0 ] ;
68-
69- const displayName = getMetaParameter (
70- codeElement . data ?. meta ,
71- 'displayName'
72- ) ;
68+ const meta = parseMeta ( codeElement . data ?. meta ) ;
7369
7470 // We should get the language name from the class name
7571 if ( codeElement . properties . className ?. length ) {
@@ -80,18 +76,13 @@ export default function rehypeShikiji() {
8076 }
8177
8278 // Map the display names of each variant for the CodeTab
83- displayNames . push ( displayName ?. replaceAll ( '|' , '' ) ?? '' ) ;
79+ displayNames . push ( meta . displayName ?. replaceAll ( '|' , '' ) ?? '' ) ;
8480
8581 codeTabsChildren . push ( parent ?. children [ currentIndex ] ) ;
8682
8783 // If `active="true"` is provided in a CodeBox
8884 // then the default selected entry of the CodeTabs will be the desired entry
89- const specificActive = getMetaParameter (
90- codeElement . data ?. meta ,
91- 'active'
92- ) ;
93-
94- if ( specificActive === 'true' ) {
85+ if ( meta . active === 'true' ) {
9586 defaultTab = String ( codeTabsChildren . length - 1 ) ;
9687 }
9788
@@ -162,30 +153,35 @@ export default function rehypeShikiji() {
162153 return ;
163154 }
164155
156+ // Get the metadata
157+ const meta = parseMeta ( preElement . data ?. meta ) ;
158+
165159 // Retrieve the whole <pre> contents as a parsed DOM string
166160 const preElementContents = toString ( preElement ) ;
167161
168162 // Grabs the relevant alias/name of the language
169163 const languageId = codeLanguage . slice ( languagePrefix . length ) ;
170164
171165 // Parses the <pre> contents and returns a HAST tree with the highlighted code
172- const { children } = highlightToHast ( preElementContents , languageId ) ;
166+ const { children } = highlightToHast (
167+ preElementContents ,
168+ languageId ,
169+ meta
170+ ) ;
173171
174172 // Adds the original language back to the <pre> element
175173 children [ 0 ] . properties . class = classNames (
176174 children [ 0 ] . properties . class ,
177175 codeLanguage
178176 ) ;
179177
180- const showCopyButton = getMetaParameter (
181- preElement . data ?. meta ,
182- 'showCopyButton'
183- ) ;
184-
185178 // Adds a Copy Button to the CodeBox if requested as an additional parameter
186179 // And avoids setting the property (overriding) if undefined or invalid value
187- if ( showCopyButton && [ 'true' , 'false' ] . includes ( showCopyButton ) ) {
188- children [ 0 ] . properties . showCopyButton = showCopyButton ;
180+ if (
181+ meta . showCopyButton &&
182+ [ 'true' , 'false' ] . includes ( meta . showCopyButton )
183+ ) {
184+ children [ 0 ] . properties . showCopyButton = meta . showCopyButton ;
189185 }
190186
191187 // Replaces the <pre> element with the updated one
0 commit comments