@mui/internal-markdown 1.0.2 → 1.0.4
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/index.d.ts +18 -1
- package/loader.js +128 -6
- package/package.json +3 -3
- package/parseMarkdown.js +3 -9
- package/parseMarkdown.test.js +3 -3
- package/prepareMarkdown.js +1 -1
package/index.d.ts
CHANGED
|
@@ -12,7 +12,24 @@ export function createRender(context: {
|
|
|
12
12
|
ignoreLanguagePages: (path: string) => boolean;
|
|
13
13
|
}): (markdown: string) => string;
|
|
14
14
|
|
|
15
|
-
export
|
|
15
|
+
export interface MarkdownHeaders {
|
|
16
|
+
packageName?: string;
|
|
17
|
+
productId: string;
|
|
18
|
+
githubLabel?: string;
|
|
19
|
+
waiAria?: string;
|
|
20
|
+
materialDesign?: string;
|
|
21
|
+
components: string[];
|
|
22
|
+
hooks?: string[];
|
|
23
|
+
slug?: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
image?: string;
|
|
27
|
+
tags?: string[];
|
|
28
|
+
authors?: string[];
|
|
29
|
+
date?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getHeaders(markdown: string): MarkdownHeaders;
|
|
16
33
|
|
|
17
34
|
export function getTitle(markdown: string): string;
|
|
18
35
|
|
package/loader.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { promises: fs, readdirSync } = require('fs');
|
|
1
|
+
const { promises: fs, readdirSync, statSync } = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const prepareMarkdown = require('./prepareMarkdown');
|
|
4
4
|
const extractImports = require('./extractImports');
|
|
@@ -19,7 +19,7 @@ function upperCaseFirst(string) {
|
|
|
19
19
|
* @example moduleIDToJSIdentifier('../Box-new.js') === '$$$BoxNewJs'
|
|
20
20
|
*/
|
|
21
21
|
function moduleIDToJSIdentifier(moduleID) {
|
|
22
|
-
const delimiter = /(
|
|
22
|
+
const delimiter = /(@|\.|-|\/|:)/;
|
|
23
23
|
return moduleID
|
|
24
24
|
.split(delimiter)
|
|
25
25
|
.filter((part) => !delimiter.test(part))
|
|
@@ -127,6 +127,7 @@ module.exports = async function demoLoader() {
|
|
|
127
127
|
const demoModuleIDs = new Set();
|
|
128
128
|
const componentModuleIDs = new Set();
|
|
129
129
|
const nonEditableDemos = new Set();
|
|
130
|
+
const relativeModules = new Map();
|
|
130
131
|
const demoNames = Array.from(
|
|
131
132
|
new Set(
|
|
132
133
|
docs.en.rendered
|
|
@@ -142,6 +143,63 @@ module.exports = async function demoLoader() {
|
|
|
142
143
|
),
|
|
143
144
|
);
|
|
144
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @param {*} demoName
|
|
148
|
+
* @param {*} moduleFilepath
|
|
149
|
+
* @param {*} variant
|
|
150
|
+
* @param {*} importModuleID
|
|
151
|
+
* @example detectRelativeImports('ComboBox.js', '', JS', './top100Films') => relativeModules.set('ComboBox.js', new Map([['./top100Films.js', ['JS']]]))
|
|
152
|
+
*/
|
|
153
|
+
function detectRelativeImports(demoName, moduleFilepath, variant, importModuleID) {
|
|
154
|
+
if (importModuleID.startsWith('.')) {
|
|
155
|
+
let relativeModuleFilename = importModuleID;
|
|
156
|
+
const demoMap = relativeModules.get(demoName);
|
|
157
|
+
// If the moduleID does not end with an extension, or ends with an unsupported extension (e.g. ".styling") we need to resolve it
|
|
158
|
+
// Fastest way to get a file extension, see: https://stackoverflow.com/a/12900504/
|
|
159
|
+
const importType = importModuleID.slice(
|
|
160
|
+
(Math.max(0, importModuleID.lastIndexOf('.')) || Infinity) + 1,
|
|
161
|
+
);
|
|
162
|
+
const supportedTypes = ['js', 'jsx', 'ts', 'tsx', 'css', 'json'];
|
|
163
|
+
if (!importType || !supportedTypes.includes(importType)) {
|
|
164
|
+
// If the demo is a JS demo, we can assume that the relative import is either
|
|
165
|
+
// a `.js` or a `.jsx` file, with `.js` taking precedence over `.jsx`
|
|
166
|
+
// likewise for TS demos, with `.ts` taking precedence over `.tsx`
|
|
167
|
+
const extensions =
|
|
168
|
+
variant === 'JS' ? ['.js', '.jsx', '.ts', '.tsx'] : ['.ts', '.tsx', '.js', '.jsx'];
|
|
169
|
+
const extension = extensions.find((ext) => {
|
|
170
|
+
try {
|
|
171
|
+
return statSync(path.join(moduleFilepath, '..', `${importModuleID}${ext}`));
|
|
172
|
+
} catch (error) {
|
|
173
|
+
// If the file does not exist, we return false and continue to the next extension
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
if (!extension) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
[
|
|
180
|
+
`You are trying to import a module "${importModuleID}" in the demo "${demoName}" that could not be resolved.`,
|
|
181
|
+
`Please make sure that one of the following file exists:`,
|
|
182
|
+
...extensions.map((ext) => `- ${importModuleID}${ext}`),
|
|
183
|
+
].join('\n'),
|
|
184
|
+
);
|
|
185
|
+
} else {
|
|
186
|
+
relativeModuleFilename = `${importModuleID}${extension}`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (!demoMap) {
|
|
191
|
+
relativeModules.set(demoName, new Map([[relativeModuleFilename, [variant]]]));
|
|
192
|
+
} else {
|
|
193
|
+
const variantArray = demoMap.get(relativeModuleFilename);
|
|
194
|
+
if (variantArray) {
|
|
195
|
+
variantArray.push(variant);
|
|
196
|
+
} else {
|
|
197
|
+
demoMap.set(relativeModuleFilename, [variant]);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
145
203
|
await Promise.all(
|
|
146
204
|
demoNames.map(async (demoName) => {
|
|
147
205
|
const multipleDemoVersionsUsed = !demoName.endsWith('.js');
|
|
@@ -168,11 +226,14 @@ module.exports = async function demoLoader() {
|
|
|
168
226
|
raw: await fs.readFile(moduleFilepath, { encoding: 'utf8' }),
|
|
169
227
|
};
|
|
170
228
|
demoModuleIDs.add(moduleID);
|
|
229
|
+
|
|
171
230
|
// Skip non-editable demos
|
|
172
231
|
if (!nonEditableDemos.has(demoName)) {
|
|
173
|
-
extractImports(demos[demoName].raw).forEach((importModuleID) =>
|
|
174
|
-
|
|
175
|
-
|
|
232
|
+
extractImports(demos[demoName].raw).forEach((importModuleID) => {
|
|
233
|
+
// detect relative import
|
|
234
|
+
detectRelativeImports(demoName, moduleFilepath, 'JS', importModuleID);
|
|
235
|
+
importedModuleIDs.add(importModuleID);
|
|
236
|
+
});
|
|
176
237
|
}
|
|
177
238
|
|
|
178
239
|
if (multipleDemoVersionsUsed) {
|
|
@@ -343,10 +404,69 @@ module.exports = async function demoLoader() {
|
|
|
343
404
|
// But this leads to building both demo version i.e. more build time.
|
|
344
405
|
demos[demoName].moduleTS = this.mode === 'production' ? moduleID : moduleTS;
|
|
345
406
|
demos[demoName].rawTS = rawTS;
|
|
407
|
+
|
|
408
|
+
// Extract relative imports from the TypeScript version
|
|
409
|
+
// of demos which have relative imports in the JS version
|
|
410
|
+
if (relativeModules.has(demoName)) {
|
|
411
|
+
extractImports(demos[demoName].rawTS).forEach((importModuleID) => {
|
|
412
|
+
detectRelativeImports(demoName, moduleTSFilepath, 'TS', importModuleID);
|
|
413
|
+
importedModuleIDs.add(importModuleID);
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
346
417
|
demoModuleIDs.add(demos[demoName].moduleTS);
|
|
347
418
|
} catch (error) {
|
|
348
419
|
// TS version of the demo doesn't exist. This is fine.
|
|
349
420
|
}
|
|
421
|
+
|
|
422
|
+
/* Map over relative import module IDs and resolve them
|
|
423
|
+
* while grouping by demo variant
|
|
424
|
+
* From:
|
|
425
|
+
* relativeModules: { 'ComboBox.js' =>
|
|
426
|
+
* { './top100Films.js' => ['JS', 'TS'] }
|
|
427
|
+
* }
|
|
428
|
+
* To:
|
|
429
|
+
* demos["ComboBox.js"].relativeModules = {
|
|
430
|
+
* JS: [{ module: './top100Films.js', raw: '...' }],
|
|
431
|
+
* TS: [{ module: './top100Films.js', raw: '...' }]
|
|
432
|
+
* }
|
|
433
|
+
* }
|
|
434
|
+
*/
|
|
435
|
+
|
|
436
|
+
if (relativeModules.has(demoName)) {
|
|
437
|
+
if (!demos[demoName].relativeModules) {
|
|
438
|
+
demos[demoName].relativeModules = {};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
await Promise.all(
|
|
442
|
+
Array.from(relativeModules.get(demoName)).map(async ([relativeModuleID, variants]) => {
|
|
443
|
+
let raw = '';
|
|
444
|
+
try {
|
|
445
|
+
raw = await fs.readFile(path.join(path.dirname(moduleFilepath), relativeModuleID), {
|
|
446
|
+
encoding: 'utf8',
|
|
447
|
+
});
|
|
448
|
+
} catch {
|
|
449
|
+
throw new Error(
|
|
450
|
+
`Could not find a module for the relative import "${relativeModuleID}" in the demo "${demoName}"`,
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const moduleData = { module: relativeModuleID, raw };
|
|
455
|
+
const modules = demos[demoName].relativeModules;
|
|
456
|
+
|
|
457
|
+
variants.forEach((variant) => {
|
|
458
|
+
if (modules[variant]) {
|
|
459
|
+
// Avoid duplicates
|
|
460
|
+
if (!modules[variant].some((elem) => elem.module === relativeModuleID)) {
|
|
461
|
+
modules[variant].push(moduleData);
|
|
462
|
+
}
|
|
463
|
+
} else {
|
|
464
|
+
modules[variant] = [moduleData];
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
}),
|
|
468
|
+
);
|
|
469
|
+
}
|
|
350
470
|
}),
|
|
351
471
|
);
|
|
352
472
|
|
|
@@ -365,7 +485,9 @@ module.exports = async function demoLoader() {
|
|
|
365
485
|
);
|
|
366
486
|
|
|
367
487
|
componentNames.forEach((componentName) => {
|
|
368
|
-
const moduleID =
|
|
488
|
+
const moduleID = componentName.startsWith('@mui/docs/')
|
|
489
|
+
? componentName
|
|
490
|
+
: path.join(this.rootContext, 'src', componentName).replace(/\\/g, '/');
|
|
369
491
|
|
|
370
492
|
components[moduleID] = componentName;
|
|
371
493
|
componentModuleIDs.add(moduleID);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/internal-markdown",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "MUI markdown parser. This is an internal package not meant for general use.",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
"directory": "packages/markdown"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@babel/runtime": "^7.24.
|
|
19
|
+
"@babel/runtime": "^7.24.5",
|
|
20
20
|
"lodash": "^4.17.21",
|
|
21
21
|
"marked": "^5.1.2",
|
|
22
22
|
"prismjs": "^1.29.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@types/chai": "^4.3.
|
|
25
|
+
"@types/chai": "^4.3.16",
|
|
26
26
|
"chai": "^4.4.1"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
package/parseMarkdown.js
CHANGED
|
@@ -364,11 +364,7 @@ function createRender(context) {
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
return [
|
|
367
|
-
`<h${level} id="${hash}">`,
|
|
368
|
-
headingHtml,
|
|
369
|
-
`<a aria-labelledby="${hash}" class="anchor-link" href="#${hash}" tabindex="-1">`,
|
|
370
|
-
'<svg><use xlink:href="#anchor-link-icon" /></svg>',
|
|
371
|
-
'</a>',
|
|
367
|
+
`<h${level} id="${hash}"><a href="#${hash}" class="title-link-to-anchor">${headingHtml}<span class="anchor-icon"><svg><use xlink:href="#anchor-link-icon" /></svg></span></a>`,
|
|
372
368
|
`<button title="Post a comment" class="comment-link" data-feedback-hash="${hash}">`,
|
|
373
369
|
'<svg><use xlink:href="#comment-link-icon" /></svg>',
|
|
374
370
|
`</button>`,
|
|
@@ -427,10 +423,8 @@ function createRender(context) {
|
|
|
427
423
|
escaped ? code : escape(code, true)
|
|
428
424
|
}</code></pre>${[
|
|
429
425
|
'<button data-ga-event-category="code" data-ga-event-action="copy-click" aria-label="Copy the code" class="MuiCode-copy">',
|
|
430
|
-
'<
|
|
431
|
-
'<
|
|
432
|
-
'<use class="MuiCode-copied-icon" xlink:href="#copied-icon" />',
|
|
433
|
-
'</svg>',
|
|
426
|
+
'<span class="MuiCode-copy-label">Copy</span>',
|
|
427
|
+
'<span class="MuiCode-copied-label">Copied</span>',
|
|
434
428
|
'<span class="MuiCode-copyKeypress"><span>(or</span> $keyC<span>)</span></span></button></div>',
|
|
435
429
|
].join('')}\n`;
|
|
436
430
|
};
|
package/parseMarkdown.test.js
CHANGED
|
@@ -295,9 +295,9 @@ authors:
|
|
|
295
295
|
).to.equal(
|
|
296
296
|
[
|
|
297
297
|
`<h1>Accordion</h1>`,
|
|
298
|
-
`<h2 id="basic-features"
|
|
299
|
-
`<h2 id="using-slots-and-slotprops"
|
|
300
|
-
`<h3 id="specific-example"
|
|
298
|
+
`<h2 id="basic-features"><a href="#basic-features" class="title-link-to-anchor">Basic features 🧪<span class="anchor-icon"><svg><use xlink:href="#anchor-link-icon" /></svg></span></a><button title="Post a comment" class="comment-link" data-feedback-hash="basic-features"><svg><use xlink:href="#comment-link-icon" /></svg></button></h2>`,
|
|
299
|
+
`<h2 id="using-slots-and-slotprops"><a href="#using-slots-and-slotprops" class="title-link-to-anchor">Using <code>slots</code> and <code>slotProps</code><span class="anchor-icon"><svg><use xlink:href="#anchor-link-icon" /></svg></span></a><button title="Post a comment" class="comment-link" data-feedback-hash="using-slots-and-slotprops"><svg><use xlink:href="#comment-link-icon" /></svg></button></h2>`,
|
|
300
|
+
`<h3 id="specific-example"><a href="#specific-example" class="title-link-to-anchor">Specific example<span class="anchor-icon"><svg><use xlink:href="#anchor-link-icon" /></svg></span></a><button title="Post a comment" class="comment-link" data-feedback-hash="specific-example"><svg><use xlink:href="#comment-link-icon" /></svg></button></h3>`,
|
|
301
301
|
].join(''),
|
|
302
302
|
);
|
|
303
303
|
|
package/prepareMarkdown.js
CHANGED