@docusaurus/utils 2.0.0-beta.fc64c12e4 → 2.0.0
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/lib/constants.d.ts +73 -0
- package/lib/constants.d.ts.map +1 -0
- package/lib/constants.js +78 -0
- package/lib/constants.js.map +1 -0
- package/lib/dataFileUtils.d.ts +60 -0
- package/lib/dataFileUtils.d.ts.map +1 -0
- package/lib/dataFileUtils.js +91 -0
- package/lib/dataFileUtils.js.map +1 -0
- package/lib/emitUtils.d.ts +32 -0
- package/lib/emitUtils.d.ts.map +1 -0
- package/lib/emitUtils.js +80 -0
- package/lib/emitUtils.js.map +1 -0
- package/lib/gitUtils.d.ts +66 -0
- package/lib/gitUtils.d.ts.map +1 -0
- package/lib/gitUtils.js +63 -0
- package/lib/gitUtils.js.map +1 -0
- package/lib/globUtils.d.ts +29 -0
- package/lib/globUtils.d.ts.map +1 -0
- package/lib/globUtils.js +36 -12
- package/lib/globUtils.js.map +1 -0
- package/lib/hashUtils.d.ts +6 -4
- package/lib/hashUtils.d.ts.map +1 -0
- package/lib/hashUtils.js +13 -10
- package/lib/hashUtils.js.map +1 -0
- package/lib/i18nUtils.d.ts +53 -0
- package/lib/i18nUtils.d.ts.map +1 -0
- package/lib/i18nUtils.js +70 -0
- package/lib/i18nUtils.js.map +1 -0
- package/lib/index.d.ts +15 -75
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +86 -395
- package/lib/index.js.map +1 -0
- package/lib/jsUtils.d.ts +28 -0
- package/lib/jsUtils.d.ts.map +1 -0
- package/lib/jsUtils.js +57 -0
- package/lib/jsUtils.js.map +1 -0
- package/lib/markdownLinks.d.ts +49 -5
- package/lib/markdownLinks.d.ts.map +1 -0
- package/lib/markdownLinks.js +57 -13
- package/lib/markdownLinks.js.map +1 -0
- package/lib/markdownUtils.d.ts +112 -0
- package/lib/markdownUtils.d.ts.map +1 -0
- package/lib/markdownUtils.js +271 -0
- package/lib/markdownUtils.js.map +1 -0
- package/lib/pathUtils.d.ts +45 -1
- package/lib/pathUtils.d.ts.map +1 -0
- package/lib/pathUtils.js +92 -12
- package/lib/pathUtils.js.map +1 -0
- package/lib/shellUtils.d.ts +8 -0
- package/lib/shellUtils.d.ts.map +1 -0
- package/lib/shellUtils.js +21 -0
- package/lib/shellUtils.js.map +1 -0
- package/lib/slugger.d.ts +24 -0
- package/lib/slugger.d.ts.map +1 -0
- package/lib/slugger.js +23 -0
- package/lib/slugger.js.map +1 -0
- package/lib/tags.d.ts +59 -0
- package/lib/tags.d.ts.map +1 -0
- package/lib/tags.js +91 -0
- package/lib/tags.js.map +1 -0
- package/lib/urlUtils.d.ts +66 -0
- package/lib/urlUtils.d.ts.map +1 -0
- package/lib/urlUtils.js +207 -0
- package/lib/urlUtils.js.map +1 -0
- package/lib/webpackUtils.d.ts +35 -0
- package/lib/webpackUtils.d.ts.map +1 -0
- package/lib/webpackUtils.js +115 -0
- package/lib/webpackUtils.js.map +1 -0
- package/package.json +27 -12
- package/src/constants.ts +98 -0
- package/src/dataFileUtils.ts +122 -0
- package/src/deps.d.ts +10 -0
- package/src/emitUtils.ts +99 -0
- package/src/gitUtils.ts +146 -0
- package/src/globUtils.ts +37 -15
- package/src/hashUtils.ts +9 -8
- package/src/i18nUtils.ts +114 -0
- package/src/index.ts +91 -502
- package/src/jsUtils.ts +59 -0
- package/src/markdownLinks.ts +101 -30
- package/src/markdownUtils.ts +357 -0
- package/src/pathUtils.ts +93 -12
- package/src/shellUtils.ts +18 -0
- package/src/slugger.ts +36 -0
- package/src/tags.ts +130 -0
- package/src/urlUtils.ts +234 -0
- package/src/webpackUtils.ts +153 -0
- package/lib/.tsbuildinfo +0 -1
- package/lib/codeTranslationsUtils.d.ts +0 -11
- package/lib/codeTranslationsUtils.js +0 -50
- package/lib/escapePath.d.ts +0 -17
- package/lib/escapePath.js +0 -25
- package/lib/markdownParser.d.ts +0 -30
- package/lib/markdownParser.js +0 -140
- package/lib/posixPath.d.ts +0 -14
- package/lib/posixPath.js +0 -28
- package/src/__tests__/__fixtures__/defaultCodeTranslations/en.json +0 -4
- package/src/__tests__/__fixtures__/defaultCodeTranslations/fr-FR.json +0 -5
- package/src/__tests__/__fixtures__/defaultCodeTranslations/fr.json +0 -4
- package/src/__tests__/__snapshots__/index.test.ts.snap +0 -8
- package/src/__tests__/codeTranslationsUtils.test.ts +0 -112
- package/src/__tests__/escapePath.test.ts +0 -25
- package/src/__tests__/globUtils.test.ts +0 -109
- package/src/__tests__/hashUtils.test.ts +0 -51
- package/src/__tests__/index.test.ts +0 -631
- package/src/__tests__/markdownParser.test.ts +0 -817
- package/src/__tests__/pathUtils.test.ts +0 -63
- package/src/__tests__/posixPath.test.ts +0 -25
- package/src/codeTranslationsUtils.ts +0 -56
- package/src/escapePath.ts +0 -23
- package/src/markdownParser.ts +0 -182
- package/src/posixPath.ts +0 -27
- package/tsconfig.json +0 -9
package/lib/markdownLinks.d.ts
CHANGED
|
@@ -4,24 +4,68 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
+
/**
|
|
8
|
+
* Content plugins have a base path and a localized path to source content from.
|
|
9
|
+
* We will look into the localized path in priority.
|
|
10
|
+
*/
|
|
7
11
|
export declare type ContentPaths = {
|
|
12
|
+
/**
|
|
13
|
+
* The absolute path to the base content directory, like `"<siteDir>/docs"`.
|
|
14
|
+
*/
|
|
8
15
|
contentPath: string;
|
|
16
|
+
/**
|
|
17
|
+
* The absolute path to the localized content directory, like
|
|
18
|
+
* `"<siteDir>/i18n/zh-Hans/plugin-content-docs"`.
|
|
19
|
+
*/
|
|
9
20
|
contentPathLocalized: string;
|
|
10
21
|
};
|
|
22
|
+
/** Data structure representing each broken Markdown link to be reported. */
|
|
11
23
|
export declare type BrokenMarkdownLink<T extends ContentPaths> = {
|
|
24
|
+
/** Absolute path to the file containing this link. */
|
|
12
25
|
filePath: string;
|
|
26
|
+
/**
|
|
27
|
+
* This is generic because it may contain extra metadata like version name,
|
|
28
|
+
* which the reporter can provide for context.
|
|
29
|
+
*/
|
|
13
30
|
contentPaths: T;
|
|
31
|
+
/**
|
|
32
|
+
* The content of the link, like `"./brokenFile.md"`
|
|
33
|
+
*/
|
|
14
34
|
link: string;
|
|
15
35
|
};
|
|
16
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Takes a Markdown file and replaces relative file references with their URL
|
|
38
|
+
* counterparts, e.g. `[link](./intro.md)` => `[link](/docs/intro)`, preserving
|
|
39
|
+
* everything else.
|
|
40
|
+
*
|
|
41
|
+
* This method uses best effort to find a matching file. The file reference can
|
|
42
|
+
* be relative to the directory of the current file (most likely) or any of the
|
|
43
|
+
* content paths (so `/tutorials/intro.md` can be resolved as
|
|
44
|
+
* `<siteDir>/docs/tutorials/intro.md`). Links that contain the `http(s):` or
|
|
45
|
+
* `@site/` prefix will always be ignored.
|
|
46
|
+
*/
|
|
47
|
+
export declare function replaceMarkdownLinks<T extends ContentPaths>({ siteDir, fileString, filePath, contentPaths, sourceToPermalink, }: {
|
|
48
|
+
/** Absolute path to the site directory, used to resolve aliased paths. */
|
|
17
49
|
siteDir: string;
|
|
50
|
+
/** The Markdown file content to be processed. */
|
|
18
51
|
fileString: string;
|
|
52
|
+
/** Absolute path to the current file containing `fileString`. */
|
|
19
53
|
filePath: string;
|
|
54
|
+
/** The content paths which the file reference may live in. */
|
|
20
55
|
contentPaths: T;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
56
|
+
/**
|
|
57
|
+
* A map from source paths to their URLs. Source paths are `@site` aliased.
|
|
58
|
+
*/
|
|
59
|
+
sourceToPermalink: {
|
|
60
|
+
[aliasedPath: string]: string;
|
|
61
|
+
};
|
|
62
|
+
}): {
|
|
63
|
+
/**
|
|
64
|
+
* The content with all Markdown file references replaced with their URLs.
|
|
65
|
+
* Unresolved links are left as-is.
|
|
66
|
+
*/
|
|
24
67
|
newContent: string;
|
|
68
|
+
/** The list of broken links, */
|
|
25
69
|
brokenMarkdownLinks: BrokenMarkdownLink<T>[];
|
|
26
70
|
};
|
|
27
|
-
|
|
71
|
+
//# sourceMappingURL=markdownLinks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownLinks.d.ts","sourceRoot":"","sources":["../src/markdownLinks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;GAGG;AACH,oBAAY,YAAY,GAAG;IACzB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,4EAA4E;AAC5E,oBAAY,kBAAkB,CAAC,CAAC,SAAS,YAAY,IAAI;IACvD,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,EAAE,CAAC,CAAC;IAChB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,YAAY,EAAE,EAC3D,OAAO,EACP,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,iBAAiB,GAClB,EAAE;IACD,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,YAAY,EAAE,CAAC,CAAC;IAChB;;OAEG;IACH,iBAAiB,EAAE;QAAC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC;CACpD,GAAG;IACF;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;CAC9C,CAmFA"}
|
package/lib/markdownLinks.js
CHANGED
|
@@ -7,35 +7,78 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.replaceMarkdownLinks = void 0;
|
|
10
|
-
const
|
|
11
|
-
const
|
|
10
|
+
const tslib_1 = require("tslib");
|
|
11
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
|
+
const dataFileUtils_1 = require("./dataFileUtils");
|
|
13
|
+
const pathUtils_1 = require("./pathUtils");
|
|
14
|
+
/**
|
|
15
|
+
* Takes a Markdown file and replaces relative file references with their URL
|
|
16
|
+
* counterparts, e.g. `[link](./intro.md)` => `[link](/docs/intro)`, preserving
|
|
17
|
+
* everything else.
|
|
18
|
+
*
|
|
19
|
+
* This method uses best effort to find a matching file. The file reference can
|
|
20
|
+
* be relative to the directory of the current file (most likely) or any of the
|
|
21
|
+
* content paths (so `/tutorials/intro.md` can be resolved as
|
|
22
|
+
* `<siteDir>/docs/tutorials/intro.md`). Links that contain the `http(s):` or
|
|
23
|
+
* `@site/` prefix will always be ignored.
|
|
24
|
+
*/
|
|
12
25
|
function replaceMarkdownLinks({ siteDir, fileString, filePath, contentPaths, sourceToPermalink, }) {
|
|
13
|
-
const { contentPath, contentPathLocalized } = contentPaths;
|
|
14
26
|
const brokenMarkdownLinks = [];
|
|
15
27
|
// Replace internal markdown linking (except in fenced blocks).
|
|
16
28
|
let fencedBlock = false;
|
|
29
|
+
let lastCodeFence = '';
|
|
17
30
|
const lines = fileString.split('\n').map((line) => {
|
|
18
31
|
if (line.trim().startsWith('```')) {
|
|
19
|
-
|
|
32
|
+
const codeFence = line.trim().match(/^`+/)[0];
|
|
33
|
+
if (!fencedBlock) {
|
|
34
|
+
fencedBlock = true;
|
|
35
|
+
lastCodeFence = codeFence;
|
|
36
|
+
// If we are in a ````-fenced block, all ``` would be plain text instead
|
|
37
|
+
// of fences
|
|
38
|
+
}
|
|
39
|
+
else if (codeFence.length >= lastCodeFence.length) {
|
|
40
|
+
fencedBlock = false;
|
|
41
|
+
}
|
|
20
42
|
}
|
|
21
43
|
if (fencedBlock) {
|
|
22
44
|
return line;
|
|
23
45
|
}
|
|
24
46
|
let modifiedLine = line;
|
|
25
47
|
// Replace inline-style links or reference-style links e.g:
|
|
26
|
-
// This is [Document 1](doc1.md)
|
|
27
|
-
// [doc1]: doc1.md
|
|
28
|
-
const mdRegex = /(
|
|
48
|
+
// This is [Document 1](doc1.md)
|
|
49
|
+
// [doc1]: doc1.md
|
|
50
|
+
const mdRegex = /(?:\]\(|\]:\s*)(?!https?:\/\/|@site\/)(?<filename>[^'")\]\s>]+\.mdx?)/g;
|
|
29
51
|
let mdMatch = mdRegex.exec(modifiedLine);
|
|
30
52
|
while (mdMatch !== null) {
|
|
31
53
|
// Replace it to correct html link.
|
|
32
|
-
const mdLink = mdMatch
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
const mdLink = mdMatch.groups.filename;
|
|
55
|
+
const sourcesToTry = [];
|
|
56
|
+
// ./file.md and ../file.md are always relative to the current file
|
|
57
|
+
if (!mdLink.startsWith('./') && !mdLink.startsWith('../')) {
|
|
58
|
+
sourcesToTry.push(...(0, dataFileUtils_1.getContentPathList)(contentPaths), siteDir);
|
|
59
|
+
}
|
|
60
|
+
// /file.md is always relative to the content path
|
|
61
|
+
if (!mdLink.startsWith('/')) {
|
|
62
|
+
sourcesToTry.push(path_1.default.dirname(filePath));
|
|
63
|
+
}
|
|
64
|
+
const aliasedSourceMatch = sourcesToTry
|
|
65
|
+
.map((p) => path_1.default.join(p, decodeURIComponent(mdLink)))
|
|
66
|
+
.map((source) => (0, pathUtils_1.aliasedSitePath)(source, siteDir))
|
|
67
|
+
.find((source) => sourceToPermalink[source]);
|
|
68
|
+
const permalink = aliasedSourceMatch
|
|
69
|
+
? sourceToPermalink[aliasedSourceMatch]
|
|
70
|
+
: undefined;
|
|
37
71
|
if (permalink) {
|
|
38
|
-
|
|
72
|
+
// MDX won't be happy if the permalink contains a space, we need to
|
|
73
|
+
// convert it to %20
|
|
74
|
+
const encodedPermalink = permalink
|
|
75
|
+
.split('/')
|
|
76
|
+
.map((part) => part.replace(/\s/g, '%20'))
|
|
77
|
+
.join('/');
|
|
78
|
+
modifiedLine = modifiedLine.replace(mdMatch[0], mdMatch[0].replace(mdLink, encodedPermalink));
|
|
79
|
+
// Adjust the lastIndex to avoid passing over the next link if the
|
|
80
|
+
// newly replaced URL is shorter.
|
|
81
|
+
mdRegex.lastIndex += encodedPermalink.length - mdLink.length;
|
|
39
82
|
}
|
|
40
83
|
else {
|
|
41
84
|
const brokenMarkdownLink = {
|
|
@@ -53,3 +96,4 @@ function replaceMarkdownLinks({ siteDir, fileString, filePath, contentPaths, sou
|
|
|
53
96
|
return { newContent, brokenMarkdownLinks };
|
|
54
97
|
}
|
|
55
98
|
exports.replaceMarkdownLinks = replaceMarkdownLinks;
|
|
99
|
+
//# sourceMappingURL=markdownLinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownLinks.js","sourceRoot":"","sources":["../src/markdownLinks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { type SluggerOptions } from './slugger';
|
|
8
|
+
/**
|
|
9
|
+
* Parses custom ID from a heading. The ID can contain any characters except
|
|
10
|
+
* `{#` and `}`.
|
|
11
|
+
*
|
|
12
|
+
* @param heading e.g. `## Some heading {#some-heading}` where the last
|
|
13
|
+
* character must be `}` for the ID to be recognized
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseMarkdownHeadingId(heading: string): {
|
|
16
|
+
/**
|
|
17
|
+
* The heading content sans the ID part, right-trimmed. e.g. `## Some heading`
|
|
18
|
+
*/
|
|
19
|
+
text: string;
|
|
20
|
+
/** The heading ID. e.g. `some-heading` */
|
|
21
|
+
id: string | undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Creates an excerpt of a Markdown file. This function will:
|
|
25
|
+
*
|
|
26
|
+
* - Ignore h1 headings (setext or atx)
|
|
27
|
+
* - Ignore import/export
|
|
28
|
+
* - Ignore code blocks
|
|
29
|
+
*
|
|
30
|
+
* And for the first contentful line, it will strip away most Markdown
|
|
31
|
+
* syntax, including HTML tags, emphasis, links (keeping the text), etc.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createExcerpt(fileString: string): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Takes a raw Markdown file content, and parses the front matter using
|
|
36
|
+
* gray-matter. Worth noting that gray-matter accepts TOML and other markup
|
|
37
|
+
* languages as well.
|
|
38
|
+
*
|
|
39
|
+
* @throws Throws when gray-matter throws. e.g.:
|
|
40
|
+
* ```md
|
|
41
|
+
* ---
|
|
42
|
+
* foo: : bar
|
|
43
|
+
* ---
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseFrontMatter(markdownFileContent: string): {
|
|
47
|
+
/** Front matter as parsed by gray-matter. */
|
|
48
|
+
frontMatter: {
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
};
|
|
51
|
+
/** The remaining content, trimmed. */
|
|
52
|
+
content: string;
|
|
53
|
+
};
|
|
54
|
+
declare type ParseMarkdownContentTitleOptions = {
|
|
55
|
+
/**
|
|
56
|
+
* If `true`, the matching title will be removed from the returned content.
|
|
57
|
+
* We can promise that at least one empty line will be left between the
|
|
58
|
+
* content before and after, but you shouldn't make too much assumption
|
|
59
|
+
* about what's left.
|
|
60
|
+
*/
|
|
61
|
+
removeContentTitle?: boolean;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Takes the raw Markdown content, without front matter, and tries to find an h1
|
|
65
|
+
* title (setext or atx) to be used as metadata.
|
|
66
|
+
*
|
|
67
|
+
* It only searches until the first contentful paragraph, ignoring import/export
|
|
68
|
+
* declarations.
|
|
69
|
+
*
|
|
70
|
+
* It will try to convert markdown to reasonable text, but won't be best effort,
|
|
71
|
+
* since it's only used as a fallback when `frontMatter.title` is not provided.
|
|
72
|
+
* For now, we just unwrap inline code (``# `config.js` `` => `config.js`).
|
|
73
|
+
*/
|
|
74
|
+
export declare function parseMarkdownContentTitle(contentUntrimmed: string, options?: ParseMarkdownContentTitleOptions): {
|
|
75
|
+
/** The content, optionally without the content title. */
|
|
76
|
+
content: string;
|
|
77
|
+
/** The title, trimmed and without the `#`. */
|
|
78
|
+
contentTitle: string | undefined;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Makes a full-round parse.
|
|
82
|
+
*
|
|
83
|
+
* @throws Throws when `parseFrontMatter` throws, usually because of invalid
|
|
84
|
+
* syntax.
|
|
85
|
+
*/
|
|
86
|
+
export declare function parseMarkdownString(markdownFileContent: string, options?: ParseMarkdownContentTitleOptions): {
|
|
87
|
+
/** @see {@link parseFrontMatter} */
|
|
88
|
+
frontMatter: {
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
};
|
|
91
|
+
/** @see {@link parseMarkdownContentTitle} */
|
|
92
|
+
contentTitle: string | undefined;
|
|
93
|
+
/** @see {@link createExcerpt} */
|
|
94
|
+
excerpt: string | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Content without front matter and (optionally) without title, depending on
|
|
97
|
+
* the `removeContentTitle` option.
|
|
98
|
+
*/
|
|
99
|
+
content: string;
|
|
100
|
+
};
|
|
101
|
+
export declare type WriteHeadingIDOptions = SluggerOptions & {
|
|
102
|
+
/** Overwrite existing heading IDs. */
|
|
103
|
+
overwrite?: boolean;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Takes Markdown content, returns new content with heading IDs written.
|
|
107
|
+
* Respects existing IDs (unless `overwrite=true`) and never generates colliding
|
|
108
|
+
* IDs (through the slugger).
|
|
109
|
+
*/
|
|
110
|
+
export declare function writeMarkdownHeadingId(content: string, options?: WriteHeadingIDOptions): string;
|
|
111
|
+
export {};
|
|
112
|
+
//# sourceMappingURL=markdownUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownUtils.d.ts","sourceRoot":"","sources":["../src/markdownUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAA8B,KAAK,cAAc,EAAC,MAAM,WAAW,CAAC;AAM3E;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IACvD;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;CACxB,CAUA;AAID;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA4EpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,mBAAmB,EAAE,MAAM,GAAG;IAC7D,6CAA6C;IAC7C,WAAW,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC,CAAC;IACtC,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB,CAMA;AASD,aAAK,gCAAgC,GAAG;IACtC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,gBAAgB,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE,gCAAgC,GACzC;IACD,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAyCA;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,MAAM,EAC3B,OAAO,CAAC,EAAE,gCAAgC,GACzC;IACD,oCAAoC;IACpC,WAAW,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC,CAAC;IACtC,6CAA6C;IAC7C,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,iCAAiC;IACjC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB,CAuBA;AA4BD,oBAAY,qBAAqB,GAAG,cAAc,GAAG;IACnD,sCAAsC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,qBAA+D,GACvE,MAAM,CAoCR"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.writeMarkdownHeadingId = exports.parseMarkdownString = exports.parseMarkdownContentTitle = exports.parseFrontMatter = exports.createExcerpt = exports.parseMarkdownHeadingId = void 0;
|
|
10
|
+
const tslib_1 = require("tslib");
|
|
11
|
+
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
12
|
+
const gray_matter_1 = tslib_1.__importDefault(require("gray-matter"));
|
|
13
|
+
const slugger_1 = require("./slugger");
|
|
14
|
+
// Some utilities for parsing Markdown content. These things are only used on
|
|
15
|
+
// server-side when we infer metadata like `title` and `description` from the
|
|
16
|
+
// content. Most parsing is still done in MDX through the mdx-loader.
|
|
17
|
+
/**
|
|
18
|
+
* Parses custom ID from a heading. The ID can contain any characters except
|
|
19
|
+
* `{#` and `}`.
|
|
20
|
+
*
|
|
21
|
+
* @param heading e.g. `## Some heading {#some-heading}` where the last
|
|
22
|
+
* character must be `}` for the ID to be recognized
|
|
23
|
+
*/
|
|
24
|
+
function parseMarkdownHeadingId(heading) {
|
|
25
|
+
const customHeadingIdRegex = /\s*\{#(?<id>(?:.(?!\{#|\}))*.)\}$/;
|
|
26
|
+
const matches = customHeadingIdRegex.exec(heading);
|
|
27
|
+
if (matches) {
|
|
28
|
+
return {
|
|
29
|
+
text: heading.replace(matches[0], ''),
|
|
30
|
+
id: matches.groups.id,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return { text: heading, id: undefined };
|
|
34
|
+
}
|
|
35
|
+
exports.parseMarkdownHeadingId = parseMarkdownHeadingId;
|
|
36
|
+
// TODO: Find a better way to do so, possibly by compiling the Markdown content,
|
|
37
|
+
// stripping out HTML tags and obtaining the first line.
|
|
38
|
+
/**
|
|
39
|
+
* Creates an excerpt of a Markdown file. This function will:
|
|
40
|
+
*
|
|
41
|
+
* - Ignore h1 headings (setext or atx)
|
|
42
|
+
* - Ignore import/export
|
|
43
|
+
* - Ignore code blocks
|
|
44
|
+
*
|
|
45
|
+
* And for the first contentful line, it will strip away most Markdown
|
|
46
|
+
* syntax, including HTML tags, emphasis, links (keeping the text), etc.
|
|
47
|
+
*/
|
|
48
|
+
function createExcerpt(fileString) {
|
|
49
|
+
const fileLines = fileString
|
|
50
|
+
.trimStart()
|
|
51
|
+
// Remove Markdown alternate title
|
|
52
|
+
.replace(/^[^\n]*\n[=]+/g, '')
|
|
53
|
+
.split('\n');
|
|
54
|
+
let inCode = false;
|
|
55
|
+
let inImport = false;
|
|
56
|
+
let lastCodeFence = '';
|
|
57
|
+
for (const fileLine of fileLines) {
|
|
58
|
+
if (fileLine === '' && inImport) {
|
|
59
|
+
inImport = false;
|
|
60
|
+
}
|
|
61
|
+
// Skip empty line.
|
|
62
|
+
if (!fileLine.trim()) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Skip import/export declaration.
|
|
66
|
+
if ((/^(?:import|export)\s.*/.test(fileLine) || inImport) && !inCode) {
|
|
67
|
+
inImport = true;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// Skip code block line.
|
|
71
|
+
if (fileLine.trim().startsWith('```')) {
|
|
72
|
+
const codeFence = fileLine.trim().match(/^`+/)[0];
|
|
73
|
+
if (!inCode) {
|
|
74
|
+
inCode = true;
|
|
75
|
+
lastCodeFence = codeFence;
|
|
76
|
+
// If we are in a ````-fenced block, all ``` would be plain text instead
|
|
77
|
+
// of fences
|
|
78
|
+
}
|
|
79
|
+
else if (codeFence.length >= lastCodeFence.length) {
|
|
80
|
+
inCode = false;
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
else if (inCode) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const cleanedLine = fileLine
|
|
88
|
+
// Remove HTML tags.
|
|
89
|
+
.replace(/<[^>]*>/g, '')
|
|
90
|
+
// Remove Title headers
|
|
91
|
+
.replace(/^#[^#]+#?/gm, '')
|
|
92
|
+
// Remove Markdown + ATX-style headers
|
|
93
|
+
.replace(/^#{1,6}\s*(?<text>[^#]*)\s*#{0,6}/gm, '$1')
|
|
94
|
+
// Remove emphasis.
|
|
95
|
+
.replace(/(?<opening>[*_]{1,3})(?<text>.*?)\1/g, '$2')
|
|
96
|
+
// Remove strikethroughs.
|
|
97
|
+
.replace(/~~(?<text>\S.*\S)~~/g, '$1')
|
|
98
|
+
// Remove images.
|
|
99
|
+
.replace(/!\[(?<alt>.*?)\][[(].*?[\])]/g, '$1')
|
|
100
|
+
// Remove footnotes.
|
|
101
|
+
.replace(/\[\^.+?\](?:: .*$)?/g, '')
|
|
102
|
+
// Remove inline links.
|
|
103
|
+
.replace(/\[(?<alt>.*?)\][[(].*?[\])]/g, '$1')
|
|
104
|
+
// Remove inline code.
|
|
105
|
+
.replace(/`(?<text>.+?)`/g, '$1')
|
|
106
|
+
// Remove blockquotes.
|
|
107
|
+
.replace(/^\s{0,3}>\s?/g, '')
|
|
108
|
+
// Remove admonition definition.
|
|
109
|
+
.replace(/:::.*/, '')
|
|
110
|
+
// Remove Emoji names within colons include preceding whitespace.
|
|
111
|
+
.replace(/\s?:(?:::|[^:\n])+:/g, '')
|
|
112
|
+
// Remove custom Markdown heading id.
|
|
113
|
+
.replace(/\{#*[\w-]+\}/, '')
|
|
114
|
+
.trim();
|
|
115
|
+
if (cleanedLine) {
|
|
116
|
+
return cleanedLine;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
exports.createExcerpt = createExcerpt;
|
|
122
|
+
/**
|
|
123
|
+
* Takes a raw Markdown file content, and parses the front matter using
|
|
124
|
+
* gray-matter. Worth noting that gray-matter accepts TOML and other markup
|
|
125
|
+
* languages as well.
|
|
126
|
+
*
|
|
127
|
+
* @throws Throws when gray-matter throws. e.g.:
|
|
128
|
+
* ```md
|
|
129
|
+
* ---
|
|
130
|
+
* foo: : bar
|
|
131
|
+
* ---
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
function parseFrontMatter(markdownFileContent) {
|
|
135
|
+
const { data, content } = (0, gray_matter_1.default)(markdownFileContent);
|
|
136
|
+
return {
|
|
137
|
+
frontMatter: data,
|
|
138
|
+
content: content.trim(),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
exports.parseFrontMatter = parseFrontMatter;
|
|
142
|
+
function toTextContentTitle(contentTitle) {
|
|
143
|
+
if (contentTitle.startsWith('`') && contentTitle.endsWith('`')) {
|
|
144
|
+
return contentTitle.substring(1, contentTitle.length - 1);
|
|
145
|
+
}
|
|
146
|
+
return contentTitle;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Takes the raw Markdown content, without front matter, and tries to find an h1
|
|
150
|
+
* title (setext or atx) to be used as metadata.
|
|
151
|
+
*
|
|
152
|
+
* It only searches until the first contentful paragraph, ignoring import/export
|
|
153
|
+
* declarations.
|
|
154
|
+
*
|
|
155
|
+
* It will try to convert markdown to reasonable text, but won't be best effort,
|
|
156
|
+
* since it's only used as a fallback when `frontMatter.title` is not provided.
|
|
157
|
+
* For now, we just unwrap inline code (``# `config.js` `` => `config.js`).
|
|
158
|
+
*/
|
|
159
|
+
function parseMarkdownContentTitle(contentUntrimmed, options) {
|
|
160
|
+
const removeContentTitleOption = options?.removeContentTitle ?? false;
|
|
161
|
+
const content = contentUntrimmed.trim();
|
|
162
|
+
// We only need to detect import statements that will be parsed by MDX as
|
|
163
|
+
// `import` nodes, as broken syntax can't render anyways. That means any block
|
|
164
|
+
// that has `import` at the very beginning and surrounded by empty lines.
|
|
165
|
+
const contentWithoutImport = content
|
|
166
|
+
.replace(/^(?:import\s(?:.|\r?\n(?!\r?\n))*(?:\r?\n){2,})*/, '')
|
|
167
|
+
.trim();
|
|
168
|
+
const regularTitleMatch = /^#[ \t]+(?<title>[^ \t].*)(?:\r?\n|$)/.exec(contentWithoutImport);
|
|
169
|
+
const alternateTitleMatch = /^(?<title>.*)\r?\n=+(?:\r?\n|$)/.exec(contentWithoutImport);
|
|
170
|
+
const titleMatch = regularTitleMatch ?? alternateTitleMatch;
|
|
171
|
+
if (!titleMatch) {
|
|
172
|
+
return { content, contentTitle: undefined };
|
|
173
|
+
}
|
|
174
|
+
const newContent = removeContentTitleOption
|
|
175
|
+
? content.replace(titleMatch[0], '')
|
|
176
|
+
: content;
|
|
177
|
+
if (regularTitleMatch) {
|
|
178
|
+
return {
|
|
179
|
+
content: newContent.trim(),
|
|
180
|
+
contentTitle: toTextContentTitle(regularTitleMatch
|
|
181
|
+
.groups.title.trim()
|
|
182
|
+
.replace(/\s*(?:\{#*[\w-]+\}|#+)$/, '')).trim(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
content: newContent.trim(),
|
|
187
|
+
contentTitle: toTextContentTitle(alternateTitleMatch.groups.title.trim().replace(/\s*=+$/, '')).trim(),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
exports.parseMarkdownContentTitle = parseMarkdownContentTitle;
|
|
191
|
+
/**
|
|
192
|
+
* Makes a full-round parse.
|
|
193
|
+
*
|
|
194
|
+
* @throws Throws when `parseFrontMatter` throws, usually because of invalid
|
|
195
|
+
* syntax.
|
|
196
|
+
*/
|
|
197
|
+
function parseMarkdownString(markdownFileContent, options) {
|
|
198
|
+
try {
|
|
199
|
+
const { frontMatter, content: contentWithoutFrontMatter } = parseFrontMatter(markdownFileContent);
|
|
200
|
+
const { content, contentTitle } = parseMarkdownContentTitle(contentWithoutFrontMatter, options);
|
|
201
|
+
const excerpt = createExcerpt(content);
|
|
202
|
+
return {
|
|
203
|
+
frontMatter,
|
|
204
|
+
content,
|
|
205
|
+
contentTitle,
|
|
206
|
+
excerpt,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
logger_1.default.error(`Error while parsing Markdown front matter.
|
|
211
|
+
This can happen if you use special characters in front matter values (try using double quotes around that value).`);
|
|
212
|
+
throw err;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.parseMarkdownString = parseMarkdownString;
|
|
216
|
+
function unwrapMarkdownLinks(line) {
|
|
217
|
+
return line.replace(/\[(?<alt>[^\]]+)\]\([^)]+\)/g, (match, p1) => p1);
|
|
218
|
+
}
|
|
219
|
+
function addHeadingId(line, slugger, maintainCase) {
|
|
220
|
+
let headingLevel = 0;
|
|
221
|
+
while (line.charAt(headingLevel) === '#') {
|
|
222
|
+
headingLevel += 1;
|
|
223
|
+
}
|
|
224
|
+
const headingText = line.slice(headingLevel).trimEnd();
|
|
225
|
+
const headingHashes = line.slice(0, headingLevel);
|
|
226
|
+
const slug = slugger.slug(unwrapMarkdownLinks(headingText).trim(), {
|
|
227
|
+
maintainCase,
|
|
228
|
+
});
|
|
229
|
+
return `${headingHashes}${headingText} {#${slug}}`;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Takes Markdown content, returns new content with heading IDs written.
|
|
233
|
+
* Respects existing IDs (unless `overwrite=true`) and never generates colliding
|
|
234
|
+
* IDs (through the slugger).
|
|
235
|
+
*/
|
|
236
|
+
function writeMarkdownHeadingId(content, options = { maintainCase: false, overwrite: false }) {
|
|
237
|
+
const { maintainCase = false, overwrite = false } = options;
|
|
238
|
+
const lines = content.split('\n');
|
|
239
|
+
const slugger = (0, slugger_1.createSlugger)();
|
|
240
|
+
// If we can't overwrite existing slugs, make sure other headings don't
|
|
241
|
+
// generate colliding slugs by first marking these slugs as occupied
|
|
242
|
+
if (!overwrite) {
|
|
243
|
+
lines.forEach((line) => {
|
|
244
|
+
const parsedHeading = parseMarkdownHeadingId(line);
|
|
245
|
+
if (parsedHeading.id) {
|
|
246
|
+
slugger.slug(parsedHeading.id);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
let inCode = false;
|
|
251
|
+
return lines
|
|
252
|
+
.map((line) => {
|
|
253
|
+
if (line.startsWith('```')) {
|
|
254
|
+
inCode = !inCode;
|
|
255
|
+
return line;
|
|
256
|
+
}
|
|
257
|
+
// Ignore h1 headings, as we don't create anchor links for those
|
|
258
|
+
if (inCode || !line.startsWith('##')) {
|
|
259
|
+
return line;
|
|
260
|
+
}
|
|
261
|
+
const parsedHeading = parseMarkdownHeadingId(line);
|
|
262
|
+
// Do not process if id is already there
|
|
263
|
+
if (parsedHeading.id && !overwrite) {
|
|
264
|
+
return line;
|
|
265
|
+
}
|
|
266
|
+
return addHeadingId(parsedHeading.text, slugger, maintainCase);
|
|
267
|
+
})
|
|
268
|
+
.join('\n');
|
|
269
|
+
}
|
|
270
|
+
exports.writeMarkdownHeadingId = writeMarkdownHeadingId;
|
|
271
|
+
//# sourceMappingURL=markdownUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownUtils.js","sourceRoot":"","sources":["../src/markdownUtils.ts"],"names":[],"mappings":"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"}
|
package/lib/pathUtils.d.ts
CHANGED
|
@@ -5,4 +5,48 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
export declare const isNameTooLong: (str: string) => boolean;
|
|
8
|
-
export declare
|
|
8
|
+
export declare function shortName(str: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Convert Windows backslash paths to posix style paths.
|
|
11
|
+
* E.g: endi\lie -> endi/lie
|
|
12
|
+
*
|
|
13
|
+
* Returns original path if the posix counterpart is not valid Windows path.
|
|
14
|
+
* This makes the legacy code that uses posixPath safe; but also makes it less
|
|
15
|
+
* useful when you actually want a path with forward slashes (e.g. for URL)
|
|
16
|
+
*
|
|
17
|
+
* Adopted from https://github.com/sindresorhus/slash/blob/main/index.js
|
|
18
|
+
*/
|
|
19
|
+
export declare function posixPath(str: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* When you want to display a path in a message/warning/error, it's more
|
|
22
|
+
* convenient to:
|
|
23
|
+
*
|
|
24
|
+
* - make it relative to `cwd()`
|
|
25
|
+
* - convert to posix (ie not using windows \ path separator)
|
|
26
|
+
*
|
|
27
|
+
* This way, Jest tests can run more reliably on any computer/CI on both
|
|
28
|
+
* Unix/Windows
|
|
29
|
+
* For Windows users this is not perfect (as they see / instead of \) but it's
|
|
30
|
+
* probably good enough
|
|
31
|
+
*/
|
|
32
|
+
export declare function toMessageRelativeFilePath(filePath: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Alias filepath relative to site directory, very useful so that we
|
|
35
|
+
* don't expose user's site structure.
|
|
36
|
+
* Example: some/path/to/website/docs/foo.md -> @site/docs/foo.md
|
|
37
|
+
*/
|
|
38
|
+
export declare function aliasedSitePath(filePath: string, siteDir: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* When you have a path like C:\X\Y
|
|
41
|
+
* It is not safe to use directly when generating code
|
|
42
|
+
* For example, this would fail due to unescaped \:
|
|
43
|
+
* `<img src={require('${filePath}')} />`
|
|
44
|
+
* But this would work: `<img src={require('${escapePath(filePath)}')} />`
|
|
45
|
+
*
|
|
46
|
+
* posixPath can't be used in all cases, because forward slashes are only valid
|
|
47
|
+
* Windows paths when they don't contain non-ascii characters, and posixPath
|
|
48
|
+
* doesn't escape those that fail to be converted.
|
|
49
|
+
*/
|
|
50
|
+
export declare function escapePath(str: string): string;
|
|
51
|
+
export declare function addTrailingPathSeparator(str: string): string;
|
|
52
|
+
//# sourceMappingURL=pathUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathUtils.d.ts","sourceRoot":"","sources":["../src/pathUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,OAMgC,CAAC;AAE7E,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB7C;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK5D"}
|