@brillout/docpress 0.15.10 → 0.15.11
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/components/CodeSnippets/useSelectCodeLang.ts +60 -0
- package/components/CodeSnippets.css +78 -0
- package/components/CodeSnippets.tsx +50 -0
- package/components/Pre.css +51 -0
- package/components/Pre.tsx +72 -0
- package/components/index.ts +1 -0
- package/components/useMDXComponents.tsx +13 -0
- package/css/button.css +23 -0
- package/css/code.css +3 -21
- package/css/index.css +1 -0
- package/css/tooltip.css +10 -2
- package/dist/+config.js +1 -1
- package/dist/NavItemComponent.js +38 -46
- package/dist/components/CodeBlockTransformer.js +2 -3
- package/dist/components/CodeSnippets/useSelectCodeLang.d.ts +7 -0
- package/dist/components/CodeSnippets/useSelectCodeLang.js +50 -0
- package/dist/components/CodeSnippets.d.ts +11 -0
- package/dist/components/CodeSnippets.js +35 -0
- package/dist/components/Comment.js +1 -2
- package/dist/components/FileRemoved.js +4 -6
- package/dist/components/HorizontalLine.js +1 -2
- package/dist/components/ImportMeta.js +2 -3
- package/dist/components/Link.js +34 -50
- package/dist/components/Note.js +17 -29
- package/dist/components/P.js +1 -12
- package/dist/components/RepoLink.js +7 -9
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/determineNavItemsColumnLayout.js +48 -63
- package/dist/parseMarkdownMini.js +5 -17
- package/dist/parsePageSections.js +41 -82
- package/dist/rehypeMetaToProps.d.ts +19 -0
- package/dist/rehypeMetaToProps.js +62 -0
- package/dist/remarkDetype.d.ts +4 -0
- package/dist/remarkDetype.js +146 -0
- package/dist/renderer/usePageContext.js +6 -7
- package/dist/resolvePageContext.js +103 -110
- package/dist/utils/Emoji/Emoji.js +13 -21
- package/dist/utils/assert.js +14 -16
- package/dist/utils/cls.js +1 -1
- package/dist/utils/determineSectionUrlHash.js +5 -5
- package/dist/utils/filter.js +2 -2
- package/dist/utils/getGlobalObject.js +3 -3
- package/dist/vite.config.js +12 -7
- package/index.ts +15 -5
- package/package.json +5 -1
- package/rehypeMetaToProps.ts +69 -0
- package/remarkDetype.ts +172 -0
- package/resolvePageContext.ts +19 -15
- package/tsconfig.json +2 -1
- package/vite.config.ts +9 -4
|
@@ -1,66 +1,26 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
-
function step(op) {
|
|
15
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
-
switch (op[0]) {
|
|
20
|
-
case 0: case 1: t = op; break;
|
|
21
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
-
default:
|
|
25
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
-
if (t[2]) _.ops.pop();
|
|
30
|
-
_.trys.pop(); continue;
|
|
31
|
-
}
|
|
32
|
-
op = body.call(thisArg, _);
|
|
33
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
1
|
export { parsePageSections };
|
|
38
2
|
import { assert } from './utils/assert.js';
|
|
39
3
|
import { determineSectionUrlHash } from './utils/determineSectionUrlHash.js';
|
|
40
4
|
import os from 'os';
|
|
41
5
|
function parsePageSections() {
|
|
42
|
-
var _this = this;
|
|
43
6
|
return {
|
|
44
7
|
name: '@brillout/docpress:parsePageSections',
|
|
45
8
|
enforce: 'pre',
|
|
46
|
-
transform:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return [2 /*return*/, codeNew];
|
|
54
|
-
});
|
|
55
|
-
}); },
|
|
9
|
+
transform: async (code, id) => {
|
|
10
|
+
if (!id.endsWith('+Page.mdx')) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const codeNew = transform(code);
|
|
14
|
+
return codeNew;
|
|
15
|
+
},
|
|
56
16
|
};
|
|
57
17
|
}
|
|
58
18
|
function transform(code) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
19
|
+
const pageSections = [];
|
|
20
|
+
let isCodeBlock = false;
|
|
21
|
+
let codeNew = code
|
|
62
22
|
.split('\n')
|
|
63
|
-
.map(
|
|
23
|
+
.map((line) => {
|
|
64
24
|
// Skip code blocks, e.g.
|
|
65
25
|
// ~~~md
|
|
66
26
|
// # Markdown Example
|
|
@@ -78,51 +38,50 @@ function transform(code) {
|
|
|
78
38
|
|| line.startsWith('<h2')
|
|
79
39
|
*/
|
|
80
40
|
) {
|
|
81
|
-
|
|
82
|
-
pageSections.push({ pageSectionId
|
|
41
|
+
const { pageSectionId, pageSectionLevel, pageSectionTitle, headingHtml } = parsePageSection(line);
|
|
42
|
+
pageSections.push({ pageSectionId, pageSectionLevel, pageSectionTitle });
|
|
83
43
|
return headingHtml;
|
|
84
44
|
}
|
|
85
45
|
return line;
|
|
86
46
|
})
|
|
87
47
|
.join('\n');
|
|
88
|
-
|
|
89
|
-
.map(
|
|
90
|
-
.join(', ')
|
|
91
|
-
codeNew +=
|
|
48
|
+
const exportCode = `export const pageSectionsExport = [${pageSections
|
|
49
|
+
.map((pageSection) => JSON.stringify(pageSection))
|
|
50
|
+
.join(', ')}];`;
|
|
51
|
+
codeNew += `\n\n${exportCode}\n`;
|
|
92
52
|
return codeNew;
|
|
93
53
|
}
|
|
94
54
|
function parsePageSection(line) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
assert(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
var anchor = titleMdx;
|
|
55
|
+
const [lineBegin, ...lineWords] = line.split(' ');
|
|
56
|
+
assert(lineBegin.split('#').join('') === '', { line, lineWords });
|
|
57
|
+
const pageSectionLevel = lineBegin.length;
|
|
58
|
+
const titleMdx = lineWords.join(' ');
|
|
59
|
+
assert(!titleMdx.startsWith(' '), { line, lineWords });
|
|
60
|
+
assert(titleMdx, { line, lineWords });
|
|
61
|
+
let pageSectionTitle = titleMdx;
|
|
62
|
+
let anchor = titleMdx;
|
|
104
63
|
{
|
|
105
64
|
// Support custom anchor: `## Some Title{#custom-anchor}`
|
|
106
|
-
|
|
65
|
+
const customAnchor = /(?<={#).*(?=})/g.exec(titleMdx)?.[0];
|
|
107
66
|
if (customAnchor) {
|
|
108
67
|
anchor = customAnchor;
|
|
109
68
|
pageSectionTitle = titleMdx.replace(/{#.*}/g, '');
|
|
110
69
|
}
|
|
111
70
|
}
|
|
112
|
-
|
|
113
|
-
|
|
71
|
+
const pageSectionId = determineSectionUrlHash(anchor);
|
|
72
|
+
const titleParsed = parseMarkdownMini(pageSectionTitle);
|
|
114
73
|
assert(pageSectionId === null || pageSectionId.length > 0);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
74
|
+
const headingId = pageSectionId === null ? '' : ` id="${pageSectionId}"`;
|
|
75
|
+
const headingHtml = `<h${pageSectionLevel}${headingId}>${titleParsed}</h${pageSectionLevel}>`;
|
|
76
|
+
const pageSection = { pageSectionLevel, pageSectionTitle, pageSectionId, headingHtml };
|
|
118
77
|
return pageSection;
|
|
119
78
|
}
|
|
120
79
|
function parseMarkdownMini(titleMarkdown) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
titleMarkdown.split('').forEach(
|
|
80
|
+
const parts = [];
|
|
81
|
+
let current;
|
|
82
|
+
titleMarkdown.split('').forEach((letter) => {
|
|
124
83
|
if (letter === '`') {
|
|
125
|
-
if (
|
|
84
|
+
if (current?.nodeType === 'code') {
|
|
126
85
|
// </code>
|
|
127
86
|
parts.push(current);
|
|
128
87
|
current = undefined;
|
|
@@ -145,25 +104,25 @@ function parseMarkdownMini(titleMarkdown) {
|
|
|
145
104
|
if (current) {
|
|
146
105
|
parts.push(current);
|
|
147
106
|
}
|
|
148
|
-
|
|
149
|
-
.map(
|
|
107
|
+
const titleHtml = parts
|
|
108
|
+
.map((part) => {
|
|
150
109
|
if (part.nodeType === 'code') {
|
|
151
|
-
return
|
|
110
|
+
return `<code>${serializeText(part.content)}</code>`;
|
|
152
111
|
}
|
|
153
112
|
else {
|
|
154
|
-
assert(part.nodeType === 'text', { parts
|
|
113
|
+
assert(part.nodeType === 'text', { parts });
|
|
155
114
|
return serializeText(part.content);
|
|
156
115
|
}
|
|
157
116
|
})
|
|
158
117
|
.join('');
|
|
159
118
|
return titleHtml;
|
|
160
119
|
function serializeText(text) {
|
|
161
|
-
|
|
120
|
+
let textEscaped = text.split("'").join("\\'");
|
|
162
121
|
// https://github.com/brillout/docpress/pull/2
|
|
163
122
|
if (isWindows()) {
|
|
164
123
|
textEscaped = textEscaped.replace(/\r/, '');
|
|
165
124
|
}
|
|
166
|
-
return
|
|
125
|
+
return `{'${textEscaped}'}`;
|
|
167
126
|
}
|
|
168
127
|
}
|
|
169
128
|
function isWindows() {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { rehypeMetaToProps };
|
|
2
|
+
import type { Root } from 'hast';
|
|
3
|
+
/**
|
|
4
|
+
* Rehype plugin to extract metadata from `<code>` blocks in markdown
|
|
5
|
+
* and attach them as props to the parent `<pre>` element.
|
|
6
|
+
*
|
|
7
|
+
* This allows using those props inside a custom `<Pre>` component.
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
* ~~~mdx
|
|
11
|
+
* ```js foo="bar" hide_copy='true'
|
|
12
|
+
* export function add(a, b) {
|
|
13
|
+
* return a + b
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
* ~~~
|
|
17
|
+
* These props are then added to the `<pre>` element
|
|
18
|
+
*/
|
|
19
|
+
declare function rehypeMetaToProps(): (tree: Root) => void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export { rehypeMetaToProps };
|
|
2
|
+
import { visit } from 'unist-util-visit';
|
|
3
|
+
/**
|
|
4
|
+
* Rehype plugin to extract metadata from `<code>` blocks in markdown
|
|
5
|
+
* and attach them as props to the parent `<pre>` element.
|
|
6
|
+
*
|
|
7
|
+
* This allows using those props inside a custom `<Pre>` component.
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
* ~~~mdx
|
|
11
|
+
* ```js foo="bar" hide_copy='true'
|
|
12
|
+
* export function add(a, b) {
|
|
13
|
+
* return a + b
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
* ~~~
|
|
17
|
+
* These props are then added to the `<pre>` element
|
|
18
|
+
*/
|
|
19
|
+
function rehypeMetaToProps() {
|
|
20
|
+
return (tree) => {
|
|
21
|
+
visit(tree, 'element', (node, _index, parent) => {
|
|
22
|
+
if (node.tagName === 'code' && parent?.type === 'element' && parent.tagName === 'pre') {
|
|
23
|
+
const props = parseMetaString(node.data?.meta);
|
|
24
|
+
parent.properties ??= {};
|
|
25
|
+
parent.properties = { ...parent.properties, ...props };
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Minimal parser for a metadata string into key-value pairs.
|
|
32
|
+
*
|
|
33
|
+
* Supports simple patterns: key or key="value".
|
|
34
|
+
*
|
|
35
|
+
* Keys must contain only letters, dashes, or underscores (no digits).
|
|
36
|
+
* Keys are converted to kebab-case. Values default to "true" if missing.
|
|
37
|
+
*
|
|
38
|
+
* Example:
|
|
39
|
+
* parseMetaString('foo fooBar="value"')
|
|
40
|
+
* => { foo: 'true', foo_bar: 'value' }
|
|
41
|
+
*
|
|
42
|
+
* @param metaString - The input metadata string.
|
|
43
|
+
* @returns A plain object of parsed key-value pairs.
|
|
44
|
+
*/
|
|
45
|
+
function parseMetaString(metaString) {
|
|
46
|
+
if (!metaString)
|
|
47
|
+
return {};
|
|
48
|
+
const props = {};
|
|
49
|
+
const keyValuePairRE = /([a-zA-Z_-]+)(?:="([^"]*)")?(?=\s|$)/g;
|
|
50
|
+
for (const match of metaString.matchAll(keyValuePairRE)) {
|
|
51
|
+
let [_, key, value] = match;
|
|
52
|
+
props[kebabCase(key)] = value || 'true';
|
|
53
|
+
}
|
|
54
|
+
return props;
|
|
55
|
+
}
|
|
56
|
+
// Simple function to convert a camelCase or PascalCase string to kebab-case.
|
|
57
|
+
function kebabCase(str) {
|
|
58
|
+
return str
|
|
59
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
60
|
+
.replace('_', '-')
|
|
61
|
+
.toLowerCase();
|
|
62
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
export { remarkDetype };
|
|
2
|
+
import { visit } from 'unist-util-visit';
|
|
3
|
+
import { assertUsage } from './utils/assert.js';
|
|
4
|
+
import pc from '@brillout/picocolors';
|
|
5
|
+
import module from 'node:module';
|
|
6
|
+
// Cannot use `import { transform } from 'detype'` as it results in errors,
|
|
7
|
+
// and the package has no default export. Using `module.createRequire` instead.
|
|
8
|
+
const { transform: detype } = module.createRequire(import.meta.url)('detype');
|
|
9
|
+
const prettierOptions = {
|
|
10
|
+
semi: false,
|
|
11
|
+
singleQuote: true,
|
|
12
|
+
printWidth: 100,
|
|
13
|
+
trailingComma: 'none',
|
|
14
|
+
};
|
|
15
|
+
function remarkDetype() {
|
|
16
|
+
return async function transformer(tree, file) {
|
|
17
|
+
const code_nodes = [];
|
|
18
|
+
visit(tree, 'code', (node, index, parent) => {
|
|
19
|
+
if (!parent || typeof index === 'undefined')
|
|
20
|
+
return;
|
|
21
|
+
// Skip if `node.lang` is not ts, tsx, vue, or yaml
|
|
22
|
+
if (!['ts', 'tsx', 'vue', 'yaml'].includes(node.lang || ''))
|
|
23
|
+
return;
|
|
24
|
+
// Skip if 'ts-only' meta is present
|
|
25
|
+
if (node.meta?.includes('ts-only'))
|
|
26
|
+
return;
|
|
27
|
+
// Collect this node for post-processing
|
|
28
|
+
code_nodes.push({ codeBlock: node, index, parent });
|
|
29
|
+
});
|
|
30
|
+
for (const node of code_nodes.reverse()) {
|
|
31
|
+
if (node.codeBlock.lang === 'yaml') {
|
|
32
|
+
transformYaml(node);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
await transformTsToJs(node, file);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function transformYaml(node) {
|
|
41
|
+
const { codeBlock, index, parent } = node;
|
|
42
|
+
const codeBlockContentJs = replaceFileNameSuffixes(codeBlock.value);
|
|
43
|
+
// Skip wrapping if the YAML code block hasn't changed
|
|
44
|
+
if (codeBlockContentJs === codeBlock.value)
|
|
45
|
+
return;
|
|
46
|
+
const { position, ...rest } = codeBlock;
|
|
47
|
+
// Create a new code node for the JS version based on the modified YAML
|
|
48
|
+
const yamlJsCode = {
|
|
49
|
+
...rest,
|
|
50
|
+
value: codeBlockContentJs,
|
|
51
|
+
};
|
|
52
|
+
// Wrap both the original YAML and `yamlJsCode` with <CodeSnippets>
|
|
53
|
+
const yamlContainer = {
|
|
54
|
+
type: 'mdxJsxFlowElement',
|
|
55
|
+
name: 'CodeSnippets',
|
|
56
|
+
children: [yamlJsCode, codeBlock],
|
|
57
|
+
attributes: [],
|
|
58
|
+
};
|
|
59
|
+
parent.children.splice(index, 1, yamlContainer);
|
|
60
|
+
}
|
|
61
|
+
async function transformTsToJs(node, file) {
|
|
62
|
+
const { codeBlock, index, parent } = node;
|
|
63
|
+
let codeBlockContentJs = replaceFileNameSuffixes(codeBlock.value);
|
|
64
|
+
// Remove TypeScript from the TS/TSX/Vue code node
|
|
65
|
+
try {
|
|
66
|
+
codeBlockContentJs = await detype(codeBlockContentJs, `some-dummy-filename.${codeBlock.lang}`, {
|
|
67
|
+
customizeBabelConfig(config) {
|
|
68
|
+
// Add `onlyRemoveTypeImports: true` to the internal `@babel/preset-typescript` config
|
|
69
|
+
// https://github.com/cyco130/detype/blob/46ec867e9efd31d31a312a215ca169bd6bff4726/src/transform.ts#L206
|
|
70
|
+
assertUsage(config.presets && config.presets.length === 1, 'Unexpected Babel config presets');
|
|
71
|
+
config.presets = [[config.presets[0], { onlyRemoveTypeImports: true }]];
|
|
72
|
+
},
|
|
73
|
+
removeTsComments: true,
|
|
74
|
+
prettierOptions,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
// Log errors and return original content instead of throwing
|
|
79
|
+
console.error(pc.red(error.message));
|
|
80
|
+
console.error([
|
|
81
|
+
`Failed to transform the code block in: ${pc.bold(pc.blue(file.path))}.`,
|
|
82
|
+
"This likely happened due to invalid TypeScript syntax (see detype's error message above). You can either:",
|
|
83
|
+
'- Fix the code block syntax',
|
|
84
|
+
'- Set the code block language to js instead of ts',
|
|
85
|
+
'- Use custom meta or comments https://github.com/brillout/docpress#detype',
|
|
86
|
+
].join('\n') + '\n');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// Clean up both JS and TS code contents: correct diff comments (for js only) and apply custom magic comment replacements
|
|
90
|
+
codeBlockContentJs = cleanUpCode(codeBlockContentJs.trimEnd(), true);
|
|
91
|
+
codeBlock.value = cleanUpCode(codeBlock.value);
|
|
92
|
+
// No wrapping needed if JS and TS code are still identical
|
|
93
|
+
if (codeBlockContentJs === codeBlock.value)
|
|
94
|
+
return;
|
|
95
|
+
const { position, lang, ...rest } = codeBlock;
|
|
96
|
+
const jsCode = {
|
|
97
|
+
...rest,
|
|
98
|
+
// The jsCode lang should be js|jsx|vue
|
|
99
|
+
lang: lang.replace('t', 'j'),
|
|
100
|
+
value: codeBlockContentJs,
|
|
101
|
+
};
|
|
102
|
+
// Wrap both the original `codeBlock` and `jsCode` with <CodeSnippets>
|
|
103
|
+
const container = {
|
|
104
|
+
type: 'mdxJsxFlowElement',
|
|
105
|
+
name: 'CodeSnippets',
|
|
106
|
+
children: [jsCode, codeBlock],
|
|
107
|
+
attributes: [],
|
|
108
|
+
};
|
|
109
|
+
parent.children.splice(index, 1, container);
|
|
110
|
+
}
|
|
111
|
+
// Replace all '.ts' extensions with '.js'
|
|
112
|
+
function replaceFileNameSuffixes(codeBlockValue) {
|
|
113
|
+
return codeBlockValue.replaceAll('.ts', '.js');
|
|
114
|
+
}
|
|
115
|
+
function cleanUpCode(code, isJsCode = false) {
|
|
116
|
+
if (isJsCode) {
|
|
117
|
+
code = correctCodeDiffComments(code);
|
|
118
|
+
}
|
|
119
|
+
return processMagicComments(code);
|
|
120
|
+
}
|
|
121
|
+
function processMagicComments(code) {
|
|
122
|
+
// @detype-replace DummyLayout Layout
|
|
123
|
+
const renameCommentRE = /^\/\/\s@detype-replace\s([^ ]+) ([^ ]+)\n/gm;
|
|
124
|
+
const matches = Array.from(code.matchAll(renameCommentRE));
|
|
125
|
+
if (matches.length) {
|
|
126
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
127
|
+
const match = matches[i];
|
|
128
|
+
const [fullMatch, renameFrom, renameTo] = match;
|
|
129
|
+
code = code.split(fullMatch).join('').replaceAll(renameFrom, renameTo);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
code = code.replaceAll('// @detype-uncomment ', '');
|
|
133
|
+
return code;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Correct code diff comments that detype() unexpectedly reformatted (using Prettier and Babel internally)
|
|
137
|
+
* after removing TypeScript.
|
|
138
|
+
* See https://github.com/brillout/docpress/pull/47#issuecomment-3263953899
|
|
139
|
+
* @param code Transformed Javascript code.
|
|
140
|
+
* @returns The corrected code.
|
|
141
|
+
*/
|
|
142
|
+
function correctCodeDiffComments(code) {
|
|
143
|
+
// Expected to match the code diff comments: `// [!code ++]` and `// [!code --]` started with newline and optional spaces
|
|
144
|
+
const codeDiffRE = /\n\s*\/\/\s\[!code.+\]/g;
|
|
145
|
+
return code.replaceAll(codeDiffRE, (codeDiff) => codeDiff.trimStart());
|
|
146
|
+
}
|
|
@@ -3,20 +3,19 @@ export { usePageContext };
|
|
|
3
3
|
export { usePageContextLegacy };
|
|
4
4
|
import React, { useContext } from 'react';
|
|
5
5
|
import { getGlobalObject } from '../utils/getGlobalObject';
|
|
6
|
-
|
|
6
|
+
const globalObject = getGlobalObject('usePageContext.ts', {
|
|
7
7
|
Ctx: React.createContext(undefined),
|
|
8
8
|
});
|
|
9
9
|
function usePageContextLegacy() {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const { Ctx } = globalObject;
|
|
11
|
+
const pageContext = useContext(Ctx);
|
|
12
12
|
return pageContext.resolved;
|
|
13
13
|
}
|
|
14
14
|
function usePageContext() {
|
|
15
|
-
|
|
15
|
+
const pageContext = useContext(globalObject.Ctx);
|
|
16
16
|
return pageContext;
|
|
17
17
|
}
|
|
18
|
-
function PageContextProvider(
|
|
19
|
-
|
|
20
|
-
var Ctx = globalObject.Ctx;
|
|
18
|
+
function PageContextProvider({ pageContext, children, }) {
|
|
19
|
+
const { Ctx } = globalObject;
|
|
21
20
|
return React.createElement(Ctx.Provider, { value: pageContext }, children);
|
|
22
21
|
}
|