@mui/internal-docs-infra 0.3.1-canary.2 → 0.3.1-canary.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/CodeHighlighter/CodeHighlighter.js +8 -1
- package/esm/CodeHighlighter/types.d.ts +7 -1
- package/esm/pipeline/loadCodeVariant/loadCodeFallback.js +7 -2
- package/esm/pipeline/loadCodeVariant/loadCodeVariant.js +101 -50
- package/esm/pipeline/loaderUtils/getLanguageFromExtension.d.ts +24 -0
- package/esm/pipeline/loaderUtils/getLanguageFromExtension.js +63 -0
- package/esm/pipeline/loaderUtils/index.d.ts +2 -1
- package/esm/pipeline/loaderUtils/index.js +2 -1
- package/esm/pipeline/parseSource/grammars.d.ts +12 -1
- package/esm/pipeline/parseSource/grammars.js +34 -2
- package/esm/pipeline/parseSource/index.d.ts +2 -1
- package/esm/pipeline/parseSource/index.js +2 -1
- package/esm/pipeline/parseSource/parseSource.js +14 -5
- package/esm/pipeline/transformHtmlCodePrecomputed/transformHtmlCodePrecomputed.js +130 -86
- package/esm/pipeline/transformMarkdownCode/transformMarkdownCode.js +59 -83
- package/esm/useCode/Pre.d.ts +2 -0
- package/esm/useCode/Pre.js +2 -0
- package/esm/useCode/useFileNavigation.js +25 -1
- package/package.json +2 -2
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import _regenerator from "@babel/runtime/helpers/esm/regenerator";
|
|
2
2
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
3
|
import { createStarryNight } from '@wooorm/starry-night';
|
|
4
|
-
import { grammars, extensionMap } from "./grammars.js";
|
|
4
|
+
import { grammars, extensionMap, getGrammarFromLanguage } from "./grammars.js";
|
|
5
5
|
import { starryNightGutter } from "./addLineGutters.js";
|
|
6
6
|
var STARRY_NIGHT_KEY = '__docs_infra_starry_night_instance__';
|
|
7
|
-
export var parseSource = function parseSource(source, fileName) {
|
|
7
|
+
export var parseSource = function parseSource(source, fileName, language) {
|
|
8
8
|
var starryNight = globalThis[STARRY_NIGHT_KEY];
|
|
9
9
|
if (!starryNight) {
|
|
10
10
|
throw new Error('Starry Night not initialized. Use createParseSource to create an initialized parseSource function.');
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
// Determine the grammar scope: prefer explicit language, then fall back to file extension
|
|
14
|
+
var grammarScope;
|
|
15
|
+
if (language) {
|
|
16
|
+
grammarScope = getGrammarFromLanguage(language);
|
|
17
|
+
}
|
|
18
|
+
if (!grammarScope && fileName) {
|
|
19
|
+
var fileType = fileName.slice(fileName.lastIndexOf('.'));
|
|
20
|
+
grammarScope = extensionMap[fileType];
|
|
21
|
+
}
|
|
22
|
+
if (!grammarScope) {
|
|
14
23
|
// Return a basic HAST root node with the source text for unsupported file types
|
|
15
24
|
// TODO: should we split and add line gutters?
|
|
16
25
|
return {
|
|
@@ -21,7 +30,7 @@ export var parseSource = function parseSource(source, fileName) {
|
|
|
21
30
|
}]
|
|
22
31
|
};
|
|
23
32
|
}
|
|
24
|
-
var highlighted = starryNight.highlight(source,
|
|
33
|
+
var highlighted = starryNight.highlight(source, grammarScope);
|
|
25
34
|
var sourceLines = source.split(/\r?\n|\r/);
|
|
26
35
|
starryNightGutter(highlighted, sourceLines); // mutates the tree to add line gutters
|
|
27
36
|
|
|
@@ -1,85 +1,106 @@
|
|
|
1
1
|
import _regenerator from "@babel/runtime/helpers/esm/regenerator";
|
|
2
2
|
import _typeof from "@babel/runtime/helpers/esm/typeof";
|
|
3
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
3
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
5
4
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
5
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
6
6
|
import { visit } from 'unist-util-visit';
|
|
7
7
|
import { loadCodeVariant } from "../loadCodeVariant/loadCodeVariant.js";
|
|
8
8
|
import { createParseSource } from "../parseSource/index.js";
|
|
9
9
|
import { TypescriptToJavascriptTransformer } from "../transformTypescriptToJavascript/index.js";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* Reserved data properties that are handled internally and should not be passed to userProps.
|
|
12
|
+
* These are either processed by the transform pipeline or have special meaning.
|
|
13
13
|
*/
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// Markdown
|
|
29
|
-
markdown: 'md',
|
|
30
|
-
md: 'md',
|
|
31
|
-
// MDX
|
|
32
|
-
mdx: 'mdx',
|
|
33
|
-
// HTML
|
|
34
|
-
html: 'html',
|
|
35
|
-
// CSS
|
|
36
|
-
css: 'css',
|
|
37
|
-
// Shell
|
|
38
|
-
shell: 'sh',
|
|
39
|
-
bash: 'sh',
|
|
40
|
-
sh: 'sh',
|
|
41
|
-
// YAML
|
|
42
|
-
yaml: 'yaml',
|
|
43
|
-
yml: 'yaml'
|
|
44
|
-
};
|
|
14
|
+
var RESERVED_DATA_PROPS = new Set(['dataFilename',
|
|
15
|
+
// Used for fileName
|
|
16
|
+
'dataVariant',
|
|
17
|
+
// Used for variant name
|
|
18
|
+
'dataTransform',
|
|
19
|
+
// Used for skipTransforms
|
|
20
|
+
'dataPrecompute',
|
|
21
|
+
// The precomputed output itself
|
|
22
|
+
'dataContentProps',
|
|
23
|
+
// The serialized user props output
|
|
24
|
+
'dataName',
|
|
25
|
+
// Used for demo name
|
|
26
|
+
'dataSlug' // Used for demo slug/URL
|
|
27
|
+
]);
|
|
45
28
|
|
|
46
29
|
/**
|
|
47
|
-
* Extracts
|
|
30
|
+
* Extracts user-defined data properties from a code element.
|
|
31
|
+
* Filters out reserved properties and returns remaining data-* attributes.
|
|
32
|
+
* Converts from camelCase (dataTitle) to kebab-case keys (title).
|
|
48
33
|
*/
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
function extractUserProps(codeElement) {
|
|
35
|
+
var props = codeElement.properties;
|
|
36
|
+
if (!props) {
|
|
37
|
+
return undefined;
|
|
52
38
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
var userProps = {};
|
|
40
|
+
for (var _i = 0, _Object$entries = Object.entries(props); _i < _Object$entries.length; _i++) {
|
|
41
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
42
|
+
key = _Object$entries$_i[0],
|
|
43
|
+
value = _Object$entries$_i[1];
|
|
44
|
+
// Only process data-* attributes (in camelCase form: dataXxx)
|
|
45
|
+
if (key.startsWith('data') && key.length > 4 && !RESERVED_DATA_PROPS.has(key)) {
|
|
46
|
+
// Convert dataTitle -> title, dataHighlight -> highlight
|
|
47
|
+
var propName = key.charAt(4).toLowerCase() + key.slice(5);
|
|
48
|
+
// Convert value to string
|
|
49
|
+
userProps[propName] = String(value);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Object.keys(userProps).length > 0 ? userProps : undefined;
|
|
58
53
|
}
|
|
59
54
|
|
|
60
55
|
/**
|
|
61
|
-
* Gets the filename from data-filename attribute
|
|
62
|
-
* Returns undefined if no explicit filename
|
|
56
|
+
* Gets the filename from data-filename attribute only
|
|
57
|
+
* Returns undefined if no explicit filename is provided
|
|
63
58
|
*/
|
|
64
59
|
function getFileName(codeElement) {
|
|
65
|
-
var _codeElement$properti
|
|
60
|
+
var _codeElement$properti;
|
|
66
61
|
// Check for explicit data-filename attribute
|
|
67
62
|
var dataFilename = (_codeElement$properti = codeElement.properties) == null ? void 0 : _codeElement$properti.dataFilename;
|
|
68
63
|
if (dataFilename && typeof dataFilename === 'string') {
|
|
69
64
|
return dataFilename;
|
|
70
65
|
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Extracts language from a className like "language-typescript" or "language-js"
|
|
71
|
+
* Returns the language portion after "language-" prefix
|
|
72
|
+
*/
|
|
73
|
+
function extractLanguageFromClassName(className) {
|
|
74
|
+
if (!className) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
var classes = Array.isArray(className) ? className : [className];
|
|
78
|
+
var _iterator = _createForOfIteratorHelper(classes),
|
|
79
|
+
_step;
|
|
80
|
+
try {
|
|
81
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
82
|
+
var cls = _step.value;
|
|
83
|
+
if (typeof cls === 'string' && cls.startsWith('language-')) {
|
|
84
|
+
return cls.slice('language-'.length);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} catch (err) {
|
|
88
|
+
_iterator.e(err);
|
|
89
|
+
} finally {
|
|
90
|
+
_iterator.f();
|
|
77
91
|
}
|
|
78
|
-
|
|
79
|
-
// Return undefined instead of a fallback - let the system handle gracefully
|
|
80
92
|
return undefined;
|
|
81
93
|
}
|
|
82
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Gets the language from class="language-*" attribute
|
|
97
|
+
*/
|
|
98
|
+
function getLanguage(codeElement) {
|
|
99
|
+
var _codeElement$properti2;
|
|
100
|
+
var className = (_codeElement$properti2 = codeElement.properties) == null ? void 0 : _codeElement$properti2.className;
|
|
101
|
+
return extractLanguageFromClassName(className);
|
|
102
|
+
}
|
|
103
|
+
|
|
83
104
|
/**
|
|
84
105
|
* Extracts text content from HAST nodes
|
|
85
106
|
*/
|
|
@@ -106,11 +127,11 @@ function extractCodeFromSemanticStructure(element) {
|
|
|
106
127
|
var figures = element.children.filter(function (child) {
|
|
107
128
|
return child.type === 'element' && child.tagName === 'figure';
|
|
108
129
|
});
|
|
109
|
-
var
|
|
110
|
-
|
|
130
|
+
var _iterator2 = _createForOfIteratorHelper(figures),
|
|
131
|
+
_step2;
|
|
111
132
|
try {
|
|
112
|
-
for (
|
|
113
|
-
var figure =
|
|
133
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
134
|
+
var figure = _step2.value;
|
|
114
135
|
// Extract variant name from figcaption
|
|
115
136
|
var variantName = void 0;
|
|
116
137
|
var figcaption = figure.children.find(function (child) {
|
|
@@ -130,15 +151,16 @@ function extractCodeFromSemanticStructure(element) {
|
|
|
130
151
|
results.push({
|
|
131
152
|
codeElement: extracted.codeElement,
|
|
132
153
|
filename: extracted.filename,
|
|
154
|
+
language: extracted.language,
|
|
133
155
|
variantName: variantName || extracted.variantName
|
|
134
156
|
});
|
|
135
157
|
}
|
|
136
158
|
}
|
|
137
159
|
}
|
|
138
160
|
} catch (err) {
|
|
139
|
-
|
|
161
|
+
_iterator2.e(err);
|
|
140
162
|
} finally {
|
|
141
|
-
|
|
163
|
+
_iterator2.f();
|
|
142
164
|
}
|
|
143
165
|
} else if (element.tagName === 'dl') {
|
|
144
166
|
// Handle standalone dl
|
|
@@ -157,11 +179,11 @@ function extractFromDl(dl) {
|
|
|
157
179
|
// Find dt for filename and dd for code
|
|
158
180
|
var filename;
|
|
159
181
|
var codeElement;
|
|
160
|
-
var
|
|
161
|
-
|
|
182
|
+
var _iterator3 = _createForOfIteratorHelper(dl.children),
|
|
183
|
+
_step3;
|
|
162
184
|
try {
|
|
163
|
-
for (
|
|
164
|
-
var child =
|
|
185
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
186
|
+
var child = _step3.value;
|
|
165
187
|
if (child.type === 'element') {
|
|
166
188
|
if (child.tagName === 'dt') {
|
|
167
189
|
// Extract filename from dt > code
|
|
@@ -188,17 +210,20 @@ function extractFromDl(dl) {
|
|
|
188
210
|
}
|
|
189
211
|
}
|
|
190
212
|
} catch (err) {
|
|
191
|
-
|
|
213
|
+
_iterator3.e(err);
|
|
192
214
|
} finally {
|
|
193
|
-
|
|
215
|
+
_iterator3.f();
|
|
194
216
|
}
|
|
195
217
|
if (codeElement) {
|
|
196
218
|
var _codeElement$properti3;
|
|
197
219
|
// Extract variant name from data-variant if available
|
|
198
220
|
var variantName = (_codeElement$properti3 = codeElement.properties) == null ? void 0 : _codeElement$properti3.dataVariant;
|
|
221
|
+
// Extract language from className
|
|
222
|
+
var language = getLanguage(codeElement);
|
|
199
223
|
return {
|
|
200
224
|
codeElement: codeElement,
|
|
201
225
|
filename: filename,
|
|
226
|
+
language: language,
|
|
202
227
|
variantName: variantName
|
|
203
228
|
};
|
|
204
229
|
}
|
|
@@ -238,11 +263,14 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
238
263
|
return child.type === 'element' && child.tagName === 'code';
|
|
239
264
|
});
|
|
240
265
|
if (codeElement) {
|
|
241
|
-
// Extract filename from data-filename
|
|
266
|
+
// Extract filename from data-filename attribute (explicit only)
|
|
242
267
|
var filename = getFileName(codeElement);
|
|
268
|
+
// Extract language from className
|
|
269
|
+
var language = getLanguage(codeElement);
|
|
243
270
|
extractedElements = [{
|
|
244
271
|
codeElement: codeElement,
|
|
245
272
|
filename: filename,
|
|
273
|
+
language: language,
|
|
246
274
|
variantName: undefined // Basic pre > code doesn't have variants
|
|
247
275
|
}];
|
|
248
276
|
}
|
|
@@ -254,7 +282,7 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
254
282
|
}
|
|
255
283
|
if (extractedElements.length > 0) {
|
|
256
284
|
var transformPromise = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
257
|
-
var variants, _codeElement$properti4, _extractedElements$, _codeElement, _filename, sourceCode, variant,
|
|
285
|
+
var _firstCodeElement$pro, _firstCodeElement$pro2, variants, _codeElement$properti4, _extractedElements$, _codeElement, _filename, _language, sourceCode, variant, processedCode, variantPromises, variantResults, _iterator4, _step4, result, userProps, firstCodeElement, _t;
|
|
258
286
|
return _regenerator().w(function (_context2) {
|
|
259
287
|
while (1) switch (_context2.p = _context2.n) {
|
|
260
288
|
case 0:
|
|
@@ -263,19 +291,19 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
263
291
|
variants = {};
|
|
264
292
|
if (extractedElements.length === 1) {
|
|
265
293
|
// Single element - use "Default" as variant name
|
|
266
|
-
_extractedElements$ = extractedElements[0], _codeElement = _extractedElements$.codeElement, _filename = _extractedElements$.filename;
|
|
294
|
+
_extractedElements$ = extractedElements[0], _codeElement = _extractedElements$.codeElement, _filename = _extractedElements$.filename, _language = _extractedElements$.language;
|
|
267
295
|
sourceCode = extractTextContent(_codeElement);
|
|
268
296
|
variant = {
|
|
269
297
|
source: sourceCode,
|
|
270
298
|
skipTransforms: !((_codeElement$properti4 = _codeElement.properties) != null && _codeElement$properti4.dataTransform)
|
|
271
|
-
}; // Add filename if
|
|
299
|
+
}; // Add filename if explicitly provided
|
|
272
300
|
if (_filename) {
|
|
273
301
|
variant.fileName = _filename;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Add language if available (from className)
|
|
305
|
+
if (_language) {
|
|
306
|
+
variant.language = _language;
|
|
279
307
|
}
|
|
280
308
|
variants.Default = variant;
|
|
281
309
|
} else {
|
|
@@ -284,6 +312,7 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
284
312
|
var _codeElement$properti5;
|
|
285
313
|
var codeElement = _ref3.codeElement,
|
|
286
314
|
filename = _ref3.filename,
|
|
315
|
+
language = _ref3.language,
|
|
287
316
|
variantName = _ref3.variantName;
|
|
288
317
|
var sourceCode = extractTextContent(codeElement);
|
|
289
318
|
|
|
@@ -294,14 +323,14 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
294
323
|
skipTransforms: !((_codeElement$properti5 = codeElement.properties) != null && _codeElement$properti5.dataTransform)
|
|
295
324
|
};
|
|
296
325
|
|
|
297
|
-
// Add filename if
|
|
326
|
+
// Add filename if explicitly provided
|
|
298
327
|
if (filename) {
|
|
299
328
|
variant.fileName = filename;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Add language if available (from className)
|
|
332
|
+
if (language) {
|
|
333
|
+
variant.language = language;
|
|
305
334
|
}
|
|
306
335
|
variants[finalVariantName] = variant;
|
|
307
336
|
});
|
|
@@ -353,21 +382,22 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
353
382
|
return Promise.all(variantPromises);
|
|
354
383
|
case 1:
|
|
355
384
|
variantResults = _context2.v;
|
|
356
|
-
|
|
385
|
+
_iterator4 = _createForOfIteratorHelper(variantResults);
|
|
357
386
|
try {
|
|
358
|
-
for (
|
|
359
|
-
result =
|
|
387
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
388
|
+
result = _step4.value;
|
|
360
389
|
if (result) {
|
|
361
390
|
processedCode[result.variantName] = result.processedVariant;
|
|
362
391
|
}
|
|
363
392
|
}
|
|
364
393
|
|
|
365
|
-
//
|
|
394
|
+
// Extract user props from the first code element (they should be the same for all variants)
|
|
366
395
|
} catch (err) {
|
|
367
|
-
|
|
396
|
+
_iterator4.e(err);
|
|
368
397
|
} finally {
|
|
369
|
-
|
|
398
|
+
_iterator4.f();
|
|
370
399
|
}
|
|
400
|
+
userProps = extractUserProps(extractedElements[0].codeElement); // Clear all code element contents
|
|
371
401
|
extractedElements.forEach(function (_ref7) {
|
|
372
402
|
var codeElement = _ref7.codeElement;
|
|
373
403
|
codeElement.children = [];
|
|
@@ -385,6 +415,20 @@ export var transformHtmlCodePrecomputed = function transformHtmlCodePrecomputed(
|
|
|
385
415
|
node.properties = {};
|
|
386
416
|
}
|
|
387
417
|
node.properties.dataPrecompute = JSON.stringify(processedCode);
|
|
418
|
+
|
|
419
|
+
// Pass through name and slug if provided on the code element
|
|
420
|
+
firstCodeElement = extractedElements[0].codeElement;
|
|
421
|
+
if ((_firstCodeElement$pro = firstCodeElement.properties) != null && _firstCodeElement$pro.dataName) {
|
|
422
|
+
node.properties.dataName = firstCodeElement.properties.dataName;
|
|
423
|
+
}
|
|
424
|
+
if ((_firstCodeElement$pro2 = firstCodeElement.properties) != null && _firstCodeElement$pro2.dataSlug) {
|
|
425
|
+
node.properties.dataSlug = firstCodeElement.properties.dataSlug;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Set user props if any exist
|
|
429
|
+
if (userProps) {
|
|
430
|
+
node.properties.dataContentProps = JSON.stringify(userProps);
|
|
431
|
+
}
|
|
388
432
|
_context2.n = 3;
|
|
389
433
|
break;
|
|
390
434
|
case 2:
|
|
@@ -2,6 +2,8 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
|
2
2
|
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
3
3
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
4
|
import { visit } from 'unist-util-visit';
|
|
5
|
+
import { normalizeLanguage } from "../loaderUtils/getLanguageFromExtension.js";
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* Remark plugin that transforms code blocks with variants into semantic HTML structures.
|
|
7
9
|
*
|
|
@@ -54,67 +56,36 @@ import { visit } from 'unist-util-visit';
|
|
|
54
56
|
* <dl>
|
|
55
57
|
* <dt><code>index.js</code></dt>
|
|
56
58
|
* <dd>
|
|
57
|
-
* <pre><code class="language-
|
|
59
|
+
* <pre><code class="language-shell">pnpm install @mui/internal-docs-infra</code></pre>
|
|
58
60
|
* </dd>
|
|
59
61
|
* </dl>
|
|
60
62
|
* </figure>
|
|
61
63
|
* </section>
|
|
62
64
|
*
|
|
63
|
-
* Or for individual blocks (no
|
|
65
|
+
* Or for individual blocks without filename (no dl wrapper needed):
|
|
66
|
+
* <pre><code class="language-typescript" data-transform="true">console.log('test' as const)</code></pre>
|
|
67
|
+
*
|
|
68
|
+
* Or with explicit filename (uses dl/dt/dd structure):
|
|
64
69
|
* <dl>
|
|
65
|
-
* <dt><code>
|
|
70
|
+
* <dt><code>example.ts</code></dt>
|
|
66
71
|
* <dd>
|
|
67
|
-
* <pre><code class="language-
|
|
72
|
+
* <pre><code class="language-typescript">console.log('test' as const)</code></pre>
|
|
68
73
|
* </dd>
|
|
69
74
|
* </dl>
|
|
75
|
+
*
|
|
76
|
+
* Note: The `dl/dt/dd` structure is only used when an explicit `filename` prop is provided.
|
|
77
|
+
* Language information is passed via the `class="language-*"` attribute on the code element.
|
|
70
78
|
*/
|
|
71
79
|
|
|
72
80
|
/**
|
|
73
|
-
*
|
|
74
|
-
|
|
75
|
-
var LANGUAGE_TO_EXTENSION = {
|
|
76
|
-
// JavaScript
|
|
77
|
-
javascript: 'js',
|
|
78
|
-
js: 'js',
|
|
79
|
-
// TypeScript
|
|
80
|
-
typescript: 'ts',
|
|
81
|
-
ts: 'ts',
|
|
82
|
-
// TSX/JSX
|
|
83
|
-
tsx: 'tsx',
|
|
84
|
-
jsx: 'jsx',
|
|
85
|
-
// JSON
|
|
86
|
-
json: 'json',
|
|
87
|
-
// Markdown
|
|
88
|
-
markdown: 'md',
|
|
89
|
-
md: 'md',
|
|
90
|
-
// MDX
|
|
91
|
-
mdx: 'mdx',
|
|
92
|
-
// HTML
|
|
93
|
-
html: 'html',
|
|
94
|
-
// CSS
|
|
95
|
-
css: 'css',
|
|
96
|
-
// Shell
|
|
97
|
-
shell: 'sh',
|
|
98
|
-
bash: 'sh',
|
|
99
|
-
sh: 'sh',
|
|
100
|
-
// YAML
|
|
101
|
-
yaml: 'yaml',
|
|
102
|
-
yml: 'yaml'
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Gets filename from language or explicit filename prop
|
|
81
|
+
* Gets filename from explicit filename prop only.
|
|
82
|
+
* Does not derive filename from language - language is passed via className instead.
|
|
107
83
|
*/
|
|
108
|
-
function getFileName(
|
|
109
|
-
//
|
|
84
|
+
function getFileName(props) {
|
|
85
|
+
// Only return explicit filename
|
|
110
86
|
if (props.filename) {
|
|
111
87
|
return props.filename;
|
|
112
88
|
}
|
|
113
|
-
|
|
114
|
-
// Derive from language
|
|
115
|
-
if (language && LANGUAGE_TO_EXTENSION[language]) {
|
|
116
|
-
return "index.".concat(LANGUAGE_TO_EXTENSION[language]);
|
|
117
|
-
}
|
|
118
89
|
return null;
|
|
119
90
|
}
|
|
120
91
|
|
|
@@ -230,12 +201,11 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
230
201
|
|
|
231
202
|
// Handle individual code blocks with options (but no variants)
|
|
232
203
|
if (!metaData.variant && !metaData.variantType && Object.keys(allProps).length > 0) {
|
|
233
|
-
// Create a dl element for individual blocks with options
|
|
234
204
|
var codeHProperties = {};
|
|
235
205
|
|
|
236
|
-
// Add language class
|
|
206
|
+
// Add normalized language as class
|
|
237
207
|
if (langFromMeta) {
|
|
238
|
-
codeHProperties.className = "language-".concat(langFromMeta);
|
|
208
|
+
codeHProperties.className = "language-".concat(normalizeLanguage(langFromMeta));
|
|
239
209
|
}
|
|
240
210
|
|
|
241
211
|
// Add all props as data attributes (in camelCase)
|
|
@@ -249,15 +219,40 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
249
219
|
}).join('')) : "data".concat(key.charAt(0).toUpperCase() + key.slice(1));
|
|
250
220
|
codeHProperties[camelKey] = value;
|
|
251
221
|
});
|
|
252
|
-
var fileName = getFileName(
|
|
253
|
-
|
|
222
|
+
var fileName = getFileName(allProps);
|
|
223
|
+
|
|
224
|
+
// Create pre > code element
|
|
225
|
+
var preElement = {
|
|
226
|
+
type: 'element',
|
|
227
|
+
tagName: 'pre',
|
|
228
|
+
data: {
|
|
229
|
+
hName: 'pre',
|
|
230
|
+
hProperties: {}
|
|
231
|
+
},
|
|
232
|
+
children: [{
|
|
233
|
+
type: 'element',
|
|
234
|
+
tagName: 'code',
|
|
235
|
+
data: {
|
|
236
|
+
hName: 'code',
|
|
237
|
+
hProperties: codeHProperties
|
|
238
|
+
},
|
|
239
|
+
children: [{
|
|
240
|
+
type: 'text',
|
|
241
|
+
value: codeNode.value
|
|
242
|
+
}]
|
|
243
|
+
}]
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// If there's a filename, wrap in dl/dt/dd structure
|
|
247
|
+
// Otherwise, just use pre > code directly
|
|
248
|
+
var outputElement = fileName ? {
|
|
254
249
|
type: 'element',
|
|
255
250
|
tagName: 'dl',
|
|
256
251
|
data: {
|
|
257
252
|
hName: 'dl',
|
|
258
253
|
hProperties: {}
|
|
259
254
|
},
|
|
260
|
-
children: [
|
|
255
|
+
children: [{
|
|
261
256
|
type: 'element',
|
|
262
257
|
tagName: 'dt',
|
|
263
258
|
data: {
|
|
@@ -276,38 +271,19 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
276
271
|
value: fileName
|
|
277
272
|
}]
|
|
278
273
|
}]
|
|
279
|
-
}
|
|
274
|
+
}, {
|
|
280
275
|
type: 'element',
|
|
281
276
|
tagName: 'dd',
|
|
282
277
|
data: {
|
|
283
278
|
hName: 'dd',
|
|
284
279
|
hProperties: {}
|
|
285
280
|
},
|
|
286
|
-
children: [
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
data: {
|
|
290
|
-
hName: 'pre',
|
|
291
|
-
hProperties: {}
|
|
292
|
-
},
|
|
293
|
-
children: [{
|
|
294
|
-
type: 'element',
|
|
295
|
-
tagName: 'code',
|
|
296
|
-
data: {
|
|
297
|
-
hName: 'code',
|
|
298
|
-
hProperties: codeHProperties
|
|
299
|
-
},
|
|
300
|
-
children: [{
|
|
301
|
-
type: 'text',
|
|
302
|
-
value: codeNode.value
|
|
303
|
-
}]
|
|
304
|
-
}]
|
|
305
|
-
}]
|
|
306
|
-
}])
|
|
307
|
-
};
|
|
281
|
+
children: [preElement]
|
|
282
|
+
}]
|
|
283
|
+
} : preElement;
|
|
308
284
|
|
|
309
285
|
// Replace this individual code block immediately
|
|
310
|
-
parentNode.children[index] =
|
|
286
|
+
parentNode.children[index] = outputElement;
|
|
311
287
|
processedIndices.add(index);
|
|
312
288
|
return;
|
|
313
289
|
}
|
|
@@ -499,9 +475,9 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
499
475
|
// Build hProperties for HTML attributes
|
|
500
476
|
var codeHProperties = {};
|
|
501
477
|
|
|
502
|
-
// Add language class
|
|
478
|
+
// Add normalized language as class
|
|
503
479
|
if (block.actualLang) {
|
|
504
|
-
codeHProperties.className = "language-".concat(block.actualLang);
|
|
480
|
+
codeHProperties.className = "language-".concat(normalizeLanguage(block.actualLang));
|
|
505
481
|
}
|
|
506
482
|
|
|
507
483
|
// Add additional props as data attributes (in camelCase)
|
|
@@ -518,7 +494,7 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
518
494
|
|
|
519
495
|
// Add data-variant to track the variant
|
|
520
496
|
codeHProperties.dataVariant = block.variant;
|
|
521
|
-
var fileName = getFileName(block.
|
|
497
|
+
var fileName = getFileName(block.props);
|
|
522
498
|
return {
|
|
523
499
|
type: 'element',
|
|
524
500
|
tagName: 'figure',
|
|
@@ -679,9 +655,9 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
679
655
|
var block = codeBlocks[0];
|
|
680
656
|
var _codeHProperties = {};
|
|
681
657
|
|
|
682
|
-
// Add language class
|
|
658
|
+
// Add normalized language as class
|
|
683
659
|
if (block.actualLang) {
|
|
684
|
-
_codeHProperties.className = "language-".concat(block.actualLang);
|
|
660
|
+
_codeHProperties.className = "language-".concat(normalizeLanguage(block.actualLang));
|
|
685
661
|
}
|
|
686
662
|
|
|
687
663
|
// Add additional props as data attributes (in camelCase)
|
|
@@ -698,8 +674,8 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
698
674
|
|
|
699
675
|
// Add data-variant to track the variant
|
|
700
676
|
_codeHProperties.dataVariant = block.variant;
|
|
701
|
-
var _fileName = getFileName(block.
|
|
702
|
-
var
|
|
677
|
+
var _fileName = getFileName(block.props);
|
|
678
|
+
var dlElement = {
|
|
703
679
|
type: 'element',
|
|
704
680
|
tagName: 'dl',
|
|
705
681
|
data: {
|
|
@@ -762,7 +738,7 @@ export var transformMarkdownCode = function transformMarkdownCode() {
|
|
|
762
738
|
};
|
|
763
739
|
|
|
764
740
|
// Replace this single code block
|
|
765
|
-
parentNode.children[codeBlocks[0].index] =
|
|
741
|
+
parentNode.children[codeBlocks[0].index] = dlElement;
|
|
766
742
|
}
|
|
767
743
|
}
|
|
768
744
|
}
|
package/esm/useCode/Pre.d.ts
CHANGED
|
@@ -3,12 +3,14 @@ import type { VariantSource } from "../CodeHighlighter/types.js";
|
|
|
3
3
|
export declare function Pre({
|
|
4
4
|
children,
|
|
5
5
|
className,
|
|
6
|
+
language,
|
|
6
7
|
ref,
|
|
7
8
|
shouldHighlight,
|
|
8
9
|
hydrateMargin
|
|
9
10
|
}: {
|
|
10
11
|
children: VariantSource;
|
|
11
12
|
className?: string;
|
|
13
|
+
language?: string;
|
|
12
14
|
ref?: React.Ref<HTMLPreElement>;
|
|
13
15
|
shouldHighlight?: boolean;
|
|
14
16
|
hydrateMargin?: string;
|