@@ -10,28 +10,28 @@ import { highlightToHast } from './index.mjs';
10
10
// to attribute the current language of the <pre> element
11
11
const languagePrefix = 'language-' ;
12
12
13
+ // The regex to match metadata
14
+ const rMeta = / ( \w + ) (?: = (?: " ( [ ^ " ] + ) " | ( \S + ) ) ) ? / g;
15
+
13
16
/**
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.
23
20
*/
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 ;
27
26
}
28
27
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
+ }
31
33
32
- return parameter !== undefined && parameter . length > 0
33
- ? parameter
34
- : undefined ;
34
+ return obj ;
35
35
}
36
36
37
37
/**
@@ -65,11 +65,7 @@ export default function rehypeShikiji() {
65
65
66
66
while ( isCodeBlock ( parent ?. children [ currentIndex ] ) ) {
67
67
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 ) ;
73
69
74
70
// We should get the language name from the class name
75
71
if ( codeElement . properties . className ?. length ) {
@@ -80,18 +76,13 @@ export default function rehypeShikiji() {
80
76
}
81
77
82
78
// Map the display names of each variant for the CodeTab
83
- displayNames . push ( displayName ?. replaceAll ( '|' , '' ) ?? '' ) ;
79
+ displayNames . push ( meta . displayName ?. replaceAll ( '|' , '' ) ?? '' ) ;
84
80
85
81
codeTabsChildren . push ( parent ?. children [ currentIndex ] ) ;
86
82
87
83
// If `active="true"` is provided in a CodeBox
88
84
// 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' ) {
95
86
defaultTab = String ( codeTabsChildren . length - 1 ) ;
96
87
}
97
88
@@ -162,30 +153,35 @@ export default function rehypeShikiji() {
162
153
return ;
163
154
}
164
155
156
+ // Get the metadata
157
+ const meta = parseMeta ( preElement . data ?. meta ) ;
158
+
165
159
// Retrieve the whole <pre> contents as a parsed DOM string
166
160
const preElementContents = toString ( preElement ) ;
167
161
168
162
// Grabs the relevant alias/name of the language
169
163
const languageId = codeLanguage . slice ( languagePrefix . length ) ;
170
164
171
165
// 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
+ ) ;
173
171
174
172
// Adds the original language back to the <pre> element
175
173
children [ 0 ] . properties . class = classNames (
176
174
children [ 0 ] . properties . class ,
177
175
codeLanguage
178
176
) ;
179
177
180
- const showCopyButton = getMetaParameter (
181
- preElement . data ?. meta ,
182
- 'showCopyButton'
183
- ) ;
184
-
185
178
// Adds a Copy Button to the CodeBox if requested as an additional parameter
186
179
// 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 ;
189
185
}
190
186
191
187
// Replaces the <pre> element with the updated one
0 commit comments