@brillout/docpress 0.15.10-commit-f89d08f → 0.15.10-commit-05c2883
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 +1 -2
- package/components/CodeSnippets.css +66 -49
- package/components/CodeSnippets.tsx +26 -83
- package/components/Pre.css +51 -0
- package/components/Pre.tsx +79 -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/dist/components/CodeSnippets/useSelectCodeLang.js +1 -2
- package/dist/components/CodeSnippets.d.ts +0 -6
- package/dist/components/CodeSnippets.js +17 -55
- 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/resolvePageContext.js +18 -13
- package/dist/vite.config.js +9 -6
- package/index.ts +14 -7
- package/package.json +5 -3
- package/rehypeMetaToProps.ts +69 -0
- package/remarkDetype.ts +172 -0
- package/resolvePageContext.ts +19 -15
- package/vite.config.ts +9 -6
- package/detypePlugin.ts +0 -159
- package/dist/detypePlugin.d.ts +0 -3
- package/dist/detypePlugin.js +0 -139
- package/dist/utils/getMagicString.d.ts +0 -9
- package/dist/utils/getMagicString.js +0 -13
- package/utils/getMagicString.ts +0 -17
package/detypePlugin.ts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
export { detypePlugin }
|
|
2
|
-
|
|
3
|
-
import type { PluginOption } from 'vite'
|
|
4
|
-
import module from 'node:module'
|
|
5
|
-
import { assertUsage } from './utils/assert.js'
|
|
6
|
-
import pc from '@brillout/picocolors'
|
|
7
|
-
import { getMagicString } from './utils/getMagicString.js'
|
|
8
|
-
// Cannot use `import { transform } from 'detype'` as it results in errors,
|
|
9
|
-
// and the package has no default export. Using `module.createRequire` instead.
|
|
10
|
-
const { transform: detype } = module.createRequire(import.meta.url)('detype') as typeof import('detype')
|
|
11
|
-
|
|
12
|
-
const prettierOptions: NonNullable<Parameters<typeof detype>[2]>['prettierOptions'] = {
|
|
13
|
-
semi: false,
|
|
14
|
-
singleQuote: true,
|
|
15
|
-
printWidth: 100,
|
|
16
|
-
trailingComma: 'none',
|
|
17
|
-
}
|
|
18
|
-
// RegExp to find TypeScript code blocks.
|
|
19
|
-
//
|
|
20
|
-
// For example:
|
|
21
|
-
// ~~~mdx
|
|
22
|
-
// ```ts
|
|
23
|
-
// const hello: string = 'world'
|
|
24
|
-
// ```
|
|
25
|
-
// ~~~
|
|
26
|
-
//
|
|
27
|
-
// But also indented code blocks:
|
|
28
|
-
// ~~~mdx
|
|
29
|
-
// > Also works:
|
|
30
|
-
// > - In blockquotes
|
|
31
|
-
// > - In bullet points
|
|
32
|
-
// > ```ts
|
|
33
|
-
// > const hello: string = 'world'
|
|
34
|
-
// > ```
|
|
35
|
-
// ~~~
|
|
36
|
-
const codeBlockRE = /^(.*)```(tsx?|vue|yaml)[^\n]*\n([\s\S]*?)```/gm
|
|
37
|
-
|
|
38
|
-
function detypePlugin(): PluginOption {
|
|
39
|
-
return {
|
|
40
|
-
name: '@brillout/docpress:detypePlugin',
|
|
41
|
-
enforce: 'pre',
|
|
42
|
-
transform: async (code: string, moduleId: string) => {
|
|
43
|
-
if (!moduleId.endsWith('.mdx')) return
|
|
44
|
-
return await transformCode(code, moduleId)
|
|
45
|
-
},
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function transformCode(code: string, moduleId: string) {
|
|
50
|
-
const matches = Array.from(code.matchAll(codeBlockRE))
|
|
51
|
-
if (matches.length === 0) return
|
|
52
|
-
|
|
53
|
-
const { magicString, getMagicStringResult } = getMagicString(code, moduleId)
|
|
54
|
-
|
|
55
|
-
magicString.prepend(`import { CodeSnippets, CodeSnippet } from '@brillout/docpress';\n\n`)
|
|
56
|
-
|
|
57
|
-
// [Claude AI] Process matches in reverse order to avoid offset issues
|
|
58
|
-
for (let i = matches.length - 1; i >= 0; i--) {
|
|
59
|
-
const match = matches[i]
|
|
60
|
-
const [codeBlockOuterStr, codeBlockIndent, codeBlockLang, codeBlockContentWithIndent] = match
|
|
61
|
-
const isYaml = codeBlockLang === 'yaml'
|
|
62
|
-
|
|
63
|
-
// Remove indentation
|
|
64
|
-
const codeBlockOpen = codeBlockOuterStr.split('\n')[0].slice(codeBlockIndent.length)
|
|
65
|
-
const codeBlockContent = removeCodeBlockIndent(codeBlockContentWithIndent, codeBlockIndent, moduleId)
|
|
66
|
-
|
|
67
|
-
let replacement: string
|
|
68
|
-
if (codeBlockOpen.includes('ts-only') && !isYaml) {
|
|
69
|
-
replacement = `${codeBlockIndent}<CodeSnippet codeLang="ts" tsOnly>\n${codeBlockOuterStr}\n${codeBlockIndent}</CodeSnippet>`
|
|
70
|
-
} else {
|
|
71
|
-
// someFileName.ts => someFileName.js
|
|
72
|
-
let codeBlockContentJs = codeBlockContent.replaceAll('.ts', '.js')
|
|
73
|
-
const codeBlockClose = '```'
|
|
74
|
-
if (isYaml && codeBlockContentJs === codeBlockContent) {
|
|
75
|
-
continue
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Remove TypeScript
|
|
79
|
-
if (!isYaml) {
|
|
80
|
-
codeBlockContentJs = await detype(codeBlockContentJs, `some-dummy-filename.${codeBlockLang}`, {
|
|
81
|
-
removeTsComments: true,
|
|
82
|
-
prettierOptions,
|
|
83
|
-
})
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Update code block open delimiter
|
|
87
|
-
const codeBlockLangJs =
|
|
88
|
-
codeBlockLang === 'vue'
|
|
89
|
-
? 'vue'
|
|
90
|
-
: // ts => js | tsx => jsx
|
|
91
|
-
codeBlockLang.replace('t', 'j')
|
|
92
|
-
const codeBlockOpenJs = codeBlockOpen.replace(codeBlockLang, codeBlockLangJs)
|
|
93
|
-
|
|
94
|
-
// Wrap each with <CodeSnippet>
|
|
95
|
-
let codeSnippets = [
|
|
96
|
-
wrapCodeSnippet('ts', `${codeBlockOpen}\n${codeBlockContent}${codeBlockClose}`),
|
|
97
|
-
wrapCodeSnippet('js', `${codeBlockOpenJs}\n${codeBlockContentJs}${codeBlockClose}`),
|
|
98
|
-
].join('\n')
|
|
99
|
-
|
|
100
|
-
// Wrap with <CodeSnippets> (if not YAML)
|
|
101
|
-
codeSnippets = isYaml
|
|
102
|
-
? codeSnippets
|
|
103
|
-
: // Rename/Replace Words via Custom Magic Comments
|
|
104
|
-
processMagicComments(`<CodeSnippets>\n${codeSnippets}\n</CodeSnippets>`)
|
|
105
|
-
|
|
106
|
-
// Restore indentation
|
|
107
|
-
codeSnippets = restoreCodeBlockIndent(codeSnippets, codeBlockIndent)
|
|
108
|
-
|
|
109
|
-
// Done
|
|
110
|
-
replacement = codeSnippets
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const blockStartIndex = match.index!
|
|
114
|
-
const blockEndIndex = blockStartIndex + codeBlockOuterStr.length
|
|
115
|
-
magicString.overwrite(blockStartIndex, blockEndIndex, replacement)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return getMagicStringResult()
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function wrapCodeSnippet(lang: string, content: string) {
|
|
122
|
-
return `<CodeSnippet codeLang="${lang}">\n${content}\n</CodeSnippet>`
|
|
123
|
-
}
|
|
124
|
-
function removeCodeBlockIndent(code: string, codeBlockIndent: string, moduleId: string) {
|
|
125
|
-
if (!codeBlockIndent.length) return code
|
|
126
|
-
return code
|
|
127
|
-
.split('\n')
|
|
128
|
-
.map((line) => {
|
|
129
|
-
const lineStart = codeBlockIndent.trimEnd()
|
|
130
|
-
assertUsage(
|
|
131
|
-
line.startsWith(lineStart),
|
|
132
|
-
`In ${pc.bold(pc.blue(moduleId))} the line '${pc.bold(line)}' must start with '${pc.bold(lineStart)}'`,
|
|
133
|
-
)
|
|
134
|
-
return line.slice(codeBlockIndent.length)
|
|
135
|
-
})
|
|
136
|
-
.join('\n')
|
|
137
|
-
}
|
|
138
|
-
function restoreCodeBlockIndent(code: string, codeBlockIndent: string) {
|
|
139
|
-
if (!codeBlockIndent.length) return code
|
|
140
|
-
return code
|
|
141
|
-
.split('\n')
|
|
142
|
-
.map((line) => `${codeBlockIndent}${line}`)
|
|
143
|
-
.join('\n')
|
|
144
|
-
}
|
|
145
|
-
function processMagicComments(code: string) {
|
|
146
|
-
// @detype-rename DummyLayout>Layout
|
|
147
|
-
const renameCommentRE = /^\/\/\s@detype-rename\s(\w+)>(\w+)\n/gm
|
|
148
|
-
const matches = Array.from(code.matchAll(renameCommentRE))
|
|
149
|
-
|
|
150
|
-
if (matches.length) {
|
|
151
|
-
for (let i = 0; i < matches.length / 2; i++) {
|
|
152
|
-
const match = matches[i]
|
|
153
|
-
const [fullMatch, renameFrom, renameTo] = match
|
|
154
|
-
code = code.split(fullMatch).join('').replaceAll(renameFrom, renameTo)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return code.replaceAll('//~', '')
|
|
159
|
-
}
|
package/dist/detypePlugin.d.ts
DELETED
package/dist/detypePlugin.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
export { detypePlugin };
|
|
2
|
-
import module from 'node:module';
|
|
3
|
-
import { assertUsage } from './utils/assert.js';
|
|
4
|
-
import pc from '@brillout/picocolors';
|
|
5
|
-
import { getMagicString } from './utils/getMagicString.js';
|
|
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
|
-
// RegExp to find TypeScript code blocks.
|
|
16
|
-
//
|
|
17
|
-
// For example:
|
|
18
|
-
// ~~~mdx
|
|
19
|
-
// ```ts
|
|
20
|
-
// const hello: string = 'world'
|
|
21
|
-
// ```
|
|
22
|
-
// ~~~
|
|
23
|
-
//
|
|
24
|
-
// But also indented code blocks:
|
|
25
|
-
// ~~~mdx
|
|
26
|
-
// > Also works:
|
|
27
|
-
// > - In blockquotes
|
|
28
|
-
// > - In bullet points
|
|
29
|
-
// > ```ts
|
|
30
|
-
// > const hello: string = 'world'
|
|
31
|
-
// > ```
|
|
32
|
-
// ~~~
|
|
33
|
-
const codeBlockRE = /^(.*)```(tsx?|vue|yaml)[^\n]*\n([\s\S]*?)```/gm;
|
|
34
|
-
function detypePlugin() {
|
|
35
|
-
return {
|
|
36
|
-
name: '@brillout/docpress:detypePlugin',
|
|
37
|
-
enforce: 'pre',
|
|
38
|
-
transform: async (code, moduleId) => {
|
|
39
|
-
if (!moduleId.endsWith('.mdx'))
|
|
40
|
-
return;
|
|
41
|
-
return await transformCode(code, moduleId);
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
async function transformCode(code, moduleId) {
|
|
46
|
-
const matches = Array.from(code.matchAll(codeBlockRE));
|
|
47
|
-
if (matches.length === 0)
|
|
48
|
-
return;
|
|
49
|
-
const { magicString, getMagicStringResult } = getMagicString(code, moduleId);
|
|
50
|
-
magicString.prepend(`import { CodeSnippets, CodeSnippet } from '@brillout/docpress';\n\n`);
|
|
51
|
-
// [Claude AI] Process matches in reverse order to avoid offset issues
|
|
52
|
-
for (let i = matches.length - 1; i >= 0; i--) {
|
|
53
|
-
const match = matches[i];
|
|
54
|
-
const [codeBlockOuterStr, codeBlockIndent, codeBlockLang, codeBlockContentWithIndent] = match;
|
|
55
|
-
const isYaml = codeBlockLang === 'yaml';
|
|
56
|
-
// Remove indentation
|
|
57
|
-
const codeBlockOpen = codeBlockOuterStr.split('\n')[0].slice(codeBlockIndent.length);
|
|
58
|
-
const codeBlockContent = removeCodeBlockIndent(codeBlockContentWithIndent, codeBlockIndent, moduleId);
|
|
59
|
-
let replacement;
|
|
60
|
-
if (codeBlockOpen.includes('ts-only') && !isYaml) {
|
|
61
|
-
replacement = `${codeBlockIndent}<CodeSnippet codeLang="ts" tsOnly>\n${codeBlockOuterStr}\n${codeBlockIndent}</CodeSnippet>`;
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
// someFileName.ts => someFileName.js
|
|
65
|
-
let codeBlockContentJs = codeBlockContent.replaceAll('.ts', '.js');
|
|
66
|
-
const codeBlockClose = '```';
|
|
67
|
-
if (isYaml && codeBlockContentJs === codeBlockContent) {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
// Remove TypeScript
|
|
71
|
-
if (!isYaml) {
|
|
72
|
-
codeBlockContentJs = await detype(codeBlockContentJs, `some-dummy-filename.${codeBlockLang}`, {
|
|
73
|
-
removeTsComments: true,
|
|
74
|
-
prettierOptions,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
// Update code block open delimiter
|
|
78
|
-
const codeBlockLangJs = codeBlockLang === 'vue'
|
|
79
|
-
? 'vue'
|
|
80
|
-
: // ts => js | tsx => jsx
|
|
81
|
-
codeBlockLang.replace('t', 'j');
|
|
82
|
-
const codeBlockOpenJs = codeBlockOpen.replace(codeBlockLang, codeBlockLangJs);
|
|
83
|
-
// Wrap each with <CodeSnippet>
|
|
84
|
-
let codeSnippets = [
|
|
85
|
-
wrapCodeSnippet('ts', `${codeBlockOpen}\n${codeBlockContent}${codeBlockClose}`),
|
|
86
|
-
wrapCodeSnippet('js', `${codeBlockOpenJs}\n${codeBlockContentJs}${codeBlockClose}`),
|
|
87
|
-
].join('\n');
|
|
88
|
-
// Wrap with <CodeSnippets> (if not YAML)
|
|
89
|
-
codeSnippets = isYaml
|
|
90
|
-
? codeSnippets
|
|
91
|
-
: // Rename/Replace Words via Custom Magic Comments
|
|
92
|
-
processMagicComments(`<CodeSnippets>\n${codeSnippets}\n</CodeSnippets>`);
|
|
93
|
-
// Restore indentation
|
|
94
|
-
codeSnippets = restoreCodeBlockIndent(codeSnippets, codeBlockIndent);
|
|
95
|
-
// Done
|
|
96
|
-
replacement = codeSnippets;
|
|
97
|
-
}
|
|
98
|
-
const blockStartIndex = match.index;
|
|
99
|
-
const blockEndIndex = blockStartIndex + codeBlockOuterStr.length;
|
|
100
|
-
magicString.overwrite(blockStartIndex, blockEndIndex, replacement);
|
|
101
|
-
}
|
|
102
|
-
return getMagicStringResult();
|
|
103
|
-
}
|
|
104
|
-
function wrapCodeSnippet(lang, content) {
|
|
105
|
-
return `<CodeSnippet codeLang="${lang}">\n${content}\n</CodeSnippet>`;
|
|
106
|
-
}
|
|
107
|
-
function removeCodeBlockIndent(code, codeBlockIndent, moduleId) {
|
|
108
|
-
if (!codeBlockIndent.length)
|
|
109
|
-
return code;
|
|
110
|
-
return code
|
|
111
|
-
.split('\n')
|
|
112
|
-
.map((line) => {
|
|
113
|
-
const lineStart = codeBlockIndent.trimEnd();
|
|
114
|
-
assertUsage(line.startsWith(lineStart), `In ${pc.bold(pc.blue(moduleId))} the line '${pc.bold(line)}' must start with '${pc.bold(lineStart)}'`);
|
|
115
|
-
return line.slice(codeBlockIndent.length);
|
|
116
|
-
})
|
|
117
|
-
.join('\n');
|
|
118
|
-
}
|
|
119
|
-
function restoreCodeBlockIndent(code, codeBlockIndent) {
|
|
120
|
-
if (!codeBlockIndent.length)
|
|
121
|
-
return code;
|
|
122
|
-
return code
|
|
123
|
-
.split('\n')
|
|
124
|
-
.map((line) => `${codeBlockIndent}${line}`)
|
|
125
|
-
.join('\n');
|
|
126
|
-
}
|
|
127
|
-
function processMagicComments(code) {
|
|
128
|
-
// @detype-rename DummyLayout>Layout
|
|
129
|
-
const renameCommentRE = /^\/\/\s@detype-rename\s(\w+)>(\w+)\n/gm;
|
|
130
|
-
const matches = Array.from(code.matchAll(renameCommentRE));
|
|
131
|
-
if (matches.length) {
|
|
132
|
-
for (let i = 0; i < matches.length / 2; i++) {
|
|
133
|
-
const match = matches[i];
|
|
134
|
-
const [fullMatch, renameFrom, renameTo] = match;
|
|
135
|
-
code = code.split(fullMatch).join('').replaceAll(renameFrom, renameTo);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return code.replaceAll('//~', '');
|
|
139
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export { getMagicString };
|
|
2
|
-
import MagicString from 'magic-string';
|
|
3
|
-
// Used everywhere instead of `new MagicString()` for consistent source map generation
|
|
4
|
-
function getMagicString(code, id) {
|
|
5
|
-
const magicString = new MagicString(code);
|
|
6
|
-
const getMagicStringResult = () => {
|
|
7
|
-
return {
|
|
8
|
-
code: magicString.toString(),
|
|
9
|
-
map: magicString.generateMap({ hires: true, source: id }),
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
return { magicString, getMagicStringResult };
|
|
13
|
-
}
|
package/utils/getMagicString.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export { getMagicString }
|
|
2
|
-
|
|
3
|
-
import MagicString from 'magic-string'
|
|
4
|
-
|
|
5
|
-
// Used everywhere instead of `new MagicString()` for consistent source map generation
|
|
6
|
-
function getMagicString(code: string, id: string) {
|
|
7
|
-
const magicString = new MagicString(code)
|
|
8
|
-
|
|
9
|
-
const getMagicStringResult = () => {
|
|
10
|
-
return {
|
|
11
|
-
code: magicString.toString(),
|
|
12
|
-
map: magicString.generateMap({ hires: true, source: id }),
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return { magicString, getMagicStringResult }
|
|
17
|
-
}
|