@xyd-js/content 0.1.0-xyd.8 → 0.1.0-xyd.97
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/CHANGELOG.md +1157 -0
- package/ISSUES.md +1 -0
- package/LICENSE +21 -0
- package/TODO.md +2 -0
- package/dist/index.d.ts +24 -5
- package/dist/index.js +212 -566
- package/dist/index.js.map +1 -1
- package/dist/md.d.ts +69 -0
- package/dist/md.js +23396 -0
- package/dist/md.js.map +1 -0
- package/dist/mdToc-NBBxMJ4l.d.ts +12 -0
- package/dist/vite.d.ts +103 -9
- package/dist/vite.js +19992 -170
- package/dist/vite.js.map +1 -1
- package/package.json +26 -7
- package/packages/md/index.ts +17 -8
- package/packages/md/plugins/component-directives/index.ts +3 -0
- package/packages/md/plugins/component-directives/mdComponentDirective.ts +524 -0
- package/packages/md/plugins/component-directives/types.ts +1 -0
- package/packages/md/plugins/component-directives/utils.ts +27 -0
- package/packages/md/plugins/composer/__fixtures__/1.single-example/input.md +7 -0
- package/packages/md/plugins/composer/__fixtures__/1.single-example/output.json +63 -0
- package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/input.md +7 -0
- package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/output.json +63 -0
- package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/input.md +15 -0
- package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/output.json +122 -0
- package/packages/md/plugins/composer/__fixtures__/4.example-groups/input.md +23 -0
- package/packages/md/plugins/composer/__fixtures__/4.example-groups/output.json +184 -0
- package/packages/md/plugins/composer/__tests__/mdComposer.test.ts +41 -0
- package/packages/md/plugins/composer/__tests__/testHelpers.ts +48 -0
- package/packages/md/plugins/composer/index.ts +1 -0
- package/packages/md/plugins/composer/mdComposer.ts +146 -0
- package/packages/md/plugins/developer-writing/index.ts +3 -0
- package/packages/md/plugins/developer-writing/mdCodeRehype.ts +78 -0
- package/packages/md/plugins/functions/__fixtures__/external.ts +4 -0
- package/packages/md/plugins/functions/__fixtures__/test.js +11 -0
- package/packages/md/plugins/functions/__fixtures__/test.py +9 -0
- package/packages/md/plugins/functions/__fixtures__/test.ts +18 -0
- package/packages/md/plugins/functions/__tests__/mdFunctionImportCode.test.ts +295 -0
- package/packages/md/plugins/functions/__tests__/parseFunctionCall.test.ts +47 -0
- package/packages/md/plugins/functions/__tests__/testHelpers.ts +71 -0
- package/packages/md/plugins/functions/index.ts +11 -0
- package/packages/md/plugins/functions/mdFunctionChangelog.ts +124 -0
- package/packages/md/plugins/functions/mdFunctionImportCode.ts +83 -0
- package/packages/md/plugins/functions/mdFunctionUniform.ts +79 -0
- package/packages/md/plugins/functions/types.ts +6 -0
- package/packages/md/plugins/functions/uniformProcessor.ts +349 -0
- package/packages/md/plugins/functions/utils.ts +423 -0
- package/packages/md/plugins/index.ts +56 -9
- package/packages/md/plugins/mdCode.ts +67 -0
- package/packages/md/plugins/mdHeadingId.ts +47 -0
- package/packages/md/plugins/mdPage.ts +35 -0
- package/packages/md/plugins/{md-themeSettings.ts → mdThemeSettings.ts} +8 -0
- package/packages/md/plugins/mdToc.ts +224 -0
- package/packages/md/plugins/meta/index.ts +1 -0
- package/packages/md/plugins/meta/mdMeta.ts +189 -0
- package/packages/md/plugins/output-variables/__fixtures__/1.simple/input.md +22 -0
- package/packages/md/plugins/output-variables/__fixtures__/1.simple/output.json +191 -0
- package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/input.md +21 -0
- package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/output.json +127 -0
- package/packages/md/plugins/output-variables/__tests__/index.test.ts +28 -0
- package/packages/md/plugins/output-variables/__tests__/testHelpers.ts +36 -0
- package/packages/md/plugins/output-variables/index.ts +1 -0
- package/packages/md/plugins/output-variables/lib/const.ts +4 -0
- package/packages/md/plugins/output-variables/lib/factoryAttributes.ts +350 -0
- package/packages/md/plugins/output-variables/lib/factoryLabel.ts +135 -0
- package/packages/md/plugins/output-variables/lib/factoryName.ts +59 -0
- package/packages/md/plugins/output-variables/lib/index.ts +21 -0
- package/packages/md/plugins/output-variables/lib/outputVarsContainer.ts +328 -0
- package/packages/md/plugins/output-variables/lib/util.ts +494 -0
- package/packages/md/plugins/output-variables/remarkOutputVars.ts +22 -0
- package/packages/md/plugins/rehypeHeading.ts +50 -0
- package/packages/md/plugins/types.ts +15 -0
- package/packages/md/plugins/utils/componentLike.ts +72 -0
- package/packages/md/plugins/utils/index.ts +2 -0
- package/packages/md/plugins/utils/mdParameters.test.ts +114 -0
- package/packages/md/plugins/utils/mdParameters.ts +249 -0
- package/packages/md/plugins/utils/mdastTypes.ts +42 -0
- package/packages/md/search/index.ts +251 -0
- package/packages/md/search/types.ts +36 -0
- package/packages/vite/index.ts +8 -2
- package/src/fs.ts +51 -36
- package/src/index.ts +4 -4
- package/src/navigation.ts +50 -38
- package/src/types.ts +8 -0
- package/tsconfig.json +31 -8
- package/tsup.config.ts +2 -0
- package/vitest.config.ts +17 -0
- package/packages/md/plugins/md-code.ts +0 -15
- package/packages/md/plugins/md-codegroup.ts +0 -36
- package/packages/md/plugins/md-page.ts +0 -22
- package/packages/md/plugins/md-toc.ts +0 -133
package/packages/vite/index.ts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import type {Plugin} from 'rollup';
|
|
2
2
|
import mdx from '@mdx-js/rollup';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {Settings} from "@xyd-js/core";
|
|
5
|
+
|
|
6
|
+
import {RemarkMdxTocOptions, markdownPlugins} from "../md";
|
|
5
7
|
|
|
6
8
|
export interface VitePluginInterface {
|
|
7
9
|
toc: RemarkMdxTocOptions
|
|
10
|
+
settings: Settings
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export function vitePlugins(options: VitePluginInterface): Plugin[] {
|
|
11
14
|
return [
|
|
12
|
-
mdx(
|
|
15
|
+
mdx(markdownPlugins(
|
|
16
|
+
options.toc,
|
|
17
|
+
options.settings
|
|
18
|
+
)),
|
|
13
19
|
];
|
|
14
20
|
}
|
package/src/fs.ts
CHANGED
|
@@ -1,43 +1,58 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path from "path";
|
|
1
|
+
import fs from "fs/promises"
|
|
3
2
|
|
|
4
|
-
import {VFile} from "vfile"
|
|
5
|
-
import {
|
|
3
|
+
import { VFile } from "vfile"
|
|
4
|
+
import { PluggableList } from "unified";
|
|
5
|
+
import { compile as mdxCompile } from "@mdx-js/mdx";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Settings } from "@xyd-js/core"
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// TODO: cwd ?
|
|
14
|
-
const filePath = path.join(process.cwd(), `${slug}.${mdx ? "mdx" : "md"}`)
|
|
9
|
+
export {
|
|
10
|
+
pageFrontMatters,
|
|
11
|
+
filterNavigationByLevels
|
|
12
|
+
} from "./navigation"
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
export type { VarCode } from "./types"
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
export class ContentFS {
|
|
17
|
+
constructor(
|
|
18
|
+
private readonly settings: Settings,
|
|
19
|
+
private readonly remarkPlugins: PluggableList,
|
|
20
|
+
private readonly rehypePlugins: PluggableList,
|
|
21
|
+
) { }
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
public async compile(filePath: string): Promise<string> {
|
|
24
|
+
await fs.access(filePath)
|
|
25
|
+
|
|
26
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
27
|
+
|
|
28
|
+
return await this.compileContent(content, filePath)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
public async compileContent(content: string, filePath?: string): Promise<string> {
|
|
33
|
+
const vfile = new VFile({
|
|
34
|
+
path: filePath,
|
|
35
|
+
value: content,
|
|
36
|
+
contents: content
|
|
37
|
+
});
|
|
22
38
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
39
|
+
const compiled = await mdxCompile(vfile, {
|
|
40
|
+
remarkPlugins: this.remarkPlugins,
|
|
41
|
+
rehypePlugins: this.rehypePlugins,
|
|
42
|
+
recmaPlugins: [],
|
|
43
|
+
outputFormat: 'function-body',
|
|
44
|
+
development: false,
|
|
45
|
+
jsx: false
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return String(compiled)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public async readRaw(filePath: string) {
|
|
52
|
+
await fs.access(filePath)
|
|
53
|
+
|
|
54
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
55
|
+
|
|
56
|
+
return content
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/index.ts
CHANGED
package/src/navigation.ts
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
import {promises as fs} from 'fs';
|
|
2
|
-
import fs2, {open} from 'fs';
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
|
|
5
4
|
import React from "react";
|
|
6
5
|
import remarkFrontmatter from "remark-frontmatter";
|
|
7
6
|
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {compile as mdxCompile} from "@mdx-js/mdx";
|
|
7
|
+
import { VFile } from "vfile";
|
|
8
|
+
import { compile as mdxCompile } from "@mdx-js/mdx";
|
|
11
9
|
|
|
12
|
-
import {
|
|
10
|
+
import { Metadata, Sidebar, MetadataMap, Header, PageURL, VirtualPage } from "@xyd-js/core";
|
|
13
11
|
|
|
14
12
|
// TODO: better algorithm + data structures - since it's on build time it's not a big deal nevertheless it should be changed in the future
|
|
15
13
|
|
|
16
14
|
// pageFrontMatters gets frontmatters for given navigation
|
|
17
|
-
export async function pageFrontMatters(navigation: Sidebar[]): Promise<
|
|
18
|
-
const frontmatters:
|
|
15
|
+
export async function pageFrontMatters(navigation: Sidebar[], pagePathMapping: { [key: string]: string }): Promise<MetadataMap> {
|
|
16
|
+
const frontmatters: MetadataMap = {}
|
|
19
17
|
|
|
20
18
|
const promises: Promise<any>[] = []
|
|
21
19
|
|
|
22
|
-
function mapPages(page:
|
|
20
|
+
function mapPages(page: PageURL) {
|
|
23
21
|
if (typeof page !== "string") {
|
|
24
|
-
page
|
|
22
|
+
if ("virtual" in page) {
|
|
23
|
+
promises.push(job(page, frontmatters, pagePathMapping))
|
|
24
|
+
} else if ("pages" in page) {
|
|
25
|
+
page.pages?.forEach(mapPages)
|
|
26
|
+
}
|
|
25
27
|
return
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
promises.push(job(page, frontmatters))
|
|
30
|
+
promises.push(job(page, frontmatters, pagePathMapping))
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
navigation.map(async (nav: Sidebar) => {
|
|
@@ -43,7 +45,7 @@ export function filterNavigationByLevels(
|
|
|
43
45
|
slug: string
|
|
44
46
|
) {
|
|
45
47
|
const topLevelTabMatcher = headers?.reduce((acc: any, header) => {
|
|
46
|
-
const tabLevel = header?.
|
|
48
|
+
const tabLevel = header?.page?.split("/")?.length
|
|
47
49
|
|
|
48
50
|
if (!tabLevel) {
|
|
49
51
|
return {
|
|
@@ -54,13 +56,13 @@ export function filterNavigationByLevels(
|
|
|
54
56
|
if (!acc[tabLevel]) {
|
|
55
57
|
return {
|
|
56
58
|
...acc,
|
|
57
|
-
[tabLevel]: new Set().add(header?.
|
|
59
|
+
[tabLevel]: new Set().add(header?.page)
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
return {
|
|
62
64
|
...acc,
|
|
63
|
-
[tabLevel]: acc[tabLevel].add(header?.
|
|
65
|
+
[tabLevel]: acc[tabLevel].add(header?.page)
|
|
64
66
|
}
|
|
65
67
|
}, {}) as { [level: number]: Set<string> }
|
|
66
68
|
|
|
@@ -74,11 +76,20 @@ export function filterNavigationByLevels(
|
|
|
74
76
|
const level = parseInt(levelStr)
|
|
75
77
|
const findThisSlug = slug.split("/").filter(s => !!s).slice(0, level).join("/")
|
|
76
78
|
|
|
77
|
-
function findMatchedPage(page:
|
|
79
|
+
function findMatchedPage(page: PageURL) {
|
|
78
80
|
if (typeof page !== "string") {
|
|
79
|
-
page.
|
|
81
|
+
if ("virtual" in page && page.virtual) {
|
|
82
|
+
return matchPage(page.virtual)
|
|
83
|
+
} else if ("pages" in page) {
|
|
84
|
+
page.pages?.forEach(findMatchedPage)
|
|
85
|
+
}
|
|
80
86
|
return
|
|
81
87
|
}
|
|
88
|
+
|
|
89
|
+
return matchPage(page)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function matchPage(page: string) {
|
|
82
93
|
const findThisPage = page.split("/").filter(p => !!p).slice(0, level).join("/")
|
|
83
94
|
|
|
84
95
|
const set = topLevelTabMatcher[level]
|
|
@@ -107,7 +118,7 @@ function mdxExport(code: string) {
|
|
|
107
118
|
return fn(scope)
|
|
108
119
|
}
|
|
109
120
|
|
|
110
|
-
async function getFrontmatter(filePath: string): Promise<
|
|
121
|
+
async function getFrontmatter(filePath: string): Promise<Metadata> {
|
|
111
122
|
const body = await fs.readFile(filePath, "utf-8");
|
|
112
123
|
|
|
113
124
|
const vfile = new VFile({
|
|
@@ -134,39 +145,40 @@ async function getFrontmatter(filePath: string): Promise<FrontMatter> {
|
|
|
134
145
|
frontmatter
|
|
135
146
|
} = mdxExport(code)
|
|
136
147
|
|
|
137
|
-
const matter:
|
|
148
|
+
const matter: Metadata = frontmatter
|
|
149
|
+
|
|
150
|
+
if (!matter) {
|
|
151
|
+
throw new Error(`Frontmatter not found in ${filePath}`)
|
|
152
|
+
}
|
|
138
153
|
|
|
139
154
|
let title = ""
|
|
140
|
-
if (typeof matter.title === "string"
|
|
155
|
+
if (typeof matter.title === "string") {
|
|
141
156
|
title = matter.title
|
|
142
157
|
}
|
|
143
158
|
if (reactFrontmatter) {
|
|
144
|
-
|
|
145
|
-
matter.title = {
|
|
146
|
-
title,
|
|
147
|
-
code: reactFrontmatter.title.toString()
|
|
148
|
-
}
|
|
149
|
-
}
|
|
159
|
+
console.error("currently react frontmatter is not supported")
|
|
150
160
|
}
|
|
151
161
|
|
|
152
162
|
return matter
|
|
153
163
|
}
|
|
154
164
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
165
|
+
// TODO: indices map to not do like this - search for mdx if not then md
|
|
166
|
+
async function job(page: string | VirtualPage, frontmatters: MetadataMap, pagePathMapping: { [key: string]: string }) {
|
|
167
|
+
let pageName = ""
|
|
168
|
+
if (typeof page === "string") {
|
|
169
|
+
pageName = page
|
|
170
|
+
} else if (page.page) {
|
|
171
|
+
pageName = page.page
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!pageName || !pagePathMapping[pageName]) {
|
|
175
|
+
console.log(`⚠️ "${pageName}" is defined in the docs.json navigation but the file does not exist.`)
|
|
176
|
+
return
|
|
167
177
|
}
|
|
168
178
|
|
|
179
|
+
const filePath = path.join(process.cwd(), pagePathMapping[pageName])
|
|
180
|
+
|
|
169
181
|
const matter = await getFrontmatter(filePath)
|
|
170
182
|
|
|
171
|
-
frontmatters[
|
|
183
|
+
frontmatters[pageName] = matter
|
|
172
184
|
}
|
package/src/types.ts
ADDED
package/tsconfig.json
CHANGED
|
@@ -2,10 +2,24 @@
|
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"baseUrl": ".",
|
|
4
4
|
"paths": {
|
|
5
|
-
"@/mdx/*": [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"@/
|
|
5
|
+
"@/mdx/*": [
|
|
6
|
+
"src/mdx/*"
|
|
7
|
+
],
|
|
8
|
+
"@/navigation/*": [
|
|
9
|
+
"src/navigation/*"
|
|
10
|
+
],
|
|
11
|
+
"@/utils/*": [
|
|
12
|
+
"src/utils/*"
|
|
13
|
+
],
|
|
14
|
+
"@/vite-plugins/*": [
|
|
15
|
+
"src/vite-plugins/*"
|
|
16
|
+
],
|
|
17
|
+
"@xyd-js/core": [
|
|
18
|
+
"../xyd-core"
|
|
19
|
+
],
|
|
20
|
+
"@xyd-js/context": [
|
|
21
|
+
"../xyd-context/src/index.ts"
|
|
22
|
+
]
|
|
9
23
|
},
|
|
10
24
|
"target": "ES2020",
|
|
11
25
|
"module": "ESNext",
|
|
@@ -15,12 +29,21 @@
|
|
|
15
29
|
"skipLibCheck": true,
|
|
16
30
|
"forceConsistentCasingInFileNames": true,
|
|
17
31
|
"outDir": "./dist",
|
|
18
|
-
"types": [
|
|
32
|
+
"types": [
|
|
33
|
+
"node",
|
|
34
|
+
"estree",
|
|
35
|
+
"vite"
|
|
36
|
+
],
|
|
19
37
|
"declaration": true,
|
|
20
38
|
"declarationMap": true,
|
|
21
39
|
"incremental": true,
|
|
22
|
-
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
|
|
40
|
+
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo",
|
|
23
41
|
},
|
|
24
|
-
"include": [
|
|
25
|
-
|
|
42
|
+
"include": [
|
|
43
|
+
"src/**/*.ts"
|
|
44
|
+
],
|
|
45
|
+
"exclude": [
|
|
46
|
+
"node_modules",
|
|
47
|
+
"dist"
|
|
48
|
+
]
|
|
26
49
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -4,11 +4,13 @@ const config: Options = {
|
|
|
4
4
|
entry: {
|
|
5
5
|
index: 'src/index.ts',
|
|
6
6
|
vite: 'packages/vite/index.ts',
|
|
7
|
+
md: 'packages/md/index.ts',
|
|
7
8
|
},
|
|
8
9
|
dts: {
|
|
9
10
|
entry: {
|
|
10
11
|
index: 'src/index.ts',
|
|
11
12
|
vite: 'packages/vite/index.ts',
|
|
13
|
+
md: 'packages/md/index.ts'
|
|
12
14
|
},
|
|
13
15
|
resolve: true, // Resolve external types
|
|
14
16
|
},
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {defineConfig} from 'vitest/config'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: [
|
|
8
|
+
'src/**/*.test.ts',
|
|
9
|
+
'packages/**/*.test.ts',
|
|
10
|
+
'**/__tests__/**/*.test.ts'
|
|
11
|
+
],
|
|
12
|
+
coverage: {
|
|
13
|
+
provider: 'v8',
|
|
14
|
+
reporter: ['text', 'json', 'html'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
})
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {visit} from "unist-util-visit";
|
|
2
|
-
|
|
3
|
-
export function remarkInjectCodeMeta() {
|
|
4
|
-
return (tree: any) => {
|
|
5
|
-
visit(tree, 'code', (node) => {
|
|
6
|
-
if (node.meta) {
|
|
7
|
-
node.data = node.data || {};
|
|
8
|
-
node.data.hProperties = {
|
|
9
|
-
...(node.data.hProperties || {}),
|
|
10
|
-
meta: node.meta,
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {visit} from 'unist-util-visit';
|
|
2
|
-
|
|
3
|
-
// This plugin transforms a custom container directive into a JSX node
|
|
4
|
-
// https://github.com/remarkjs/remark-directive is needed to parse the container directive
|
|
5
|
-
|
|
6
|
-
export function mdCodeGroup() {
|
|
7
|
-
return (tree: any) => {
|
|
8
|
-
visit(tree, 'containerDirective', (node) => {
|
|
9
|
-
if (node.name !== 'code-group') return;
|
|
10
|
-
|
|
11
|
-
const description = node.attributes?.title || '';
|
|
12
|
-
const codeblocks = [];
|
|
13
|
-
|
|
14
|
-
for (const child of node.children) {
|
|
15
|
-
if (child.type === 'code') {
|
|
16
|
-
const meta = child.meta || '';
|
|
17
|
-
const value = child.value || '';
|
|
18
|
-
const lang = child.lang || '';
|
|
19
|
-
|
|
20
|
-
codeblocks.push({value, lang, meta});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Add metadata to the node
|
|
25
|
-
node.data = {
|
|
26
|
-
hName: 'DirectiveCodeSample',
|
|
27
|
-
hProperties: {
|
|
28
|
-
description,
|
|
29
|
-
codeblocks: JSON.stringify(codeblocks),
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
node.children = [];
|
|
34
|
-
});
|
|
35
|
-
};
|
|
36
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import {Plugin} from 'unified';
|
|
2
|
-
import {Node as UnistNode} from 'unist';
|
|
3
|
-
import {visit} from 'unist-util-visit';
|
|
4
|
-
|
|
5
|
-
declare global {
|
|
6
|
-
var page: boolean | null | undefined
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const extractPage: Plugin = () => {
|
|
10
|
-
return (tree: UnistNode) => {
|
|
11
|
-
visit(tree, 'exportNamedDeclaration', (node: any) => {
|
|
12
|
-
const declaration = node.declaration;
|
|
13
|
-
if (declaration && declaration.declarations) {
|
|
14
|
-
declaration.declarations.forEach((decl: any) => {
|
|
15
|
-
if (decl.id.name === 'page') {
|
|
16
|
-
global.page = decl.init as boolean;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
};
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {Root, Heading} from "mdast";
|
|
2
|
-
import {MdxjsEsm} from "mdast-util-mdx";
|
|
3
|
-
import {Plugin} from "unified"; // TODO: use Plugin type
|
|
4
|
-
import {MdxJsxFlowElement, MdxJsxAttribute} from "mdast-util-mdx-jsx";
|
|
5
|
-
|
|
6
|
-
export type TocEntry = {
|
|
7
|
-
depth: number,
|
|
8
|
-
value: string,
|
|
9
|
-
attributes: { [key: string]: string },
|
|
10
|
-
children: TocEntry[]
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type CustomTag = {
|
|
14
|
-
name: RegExp,
|
|
15
|
-
depth: (name: string) => number
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export interface RemarkMdxTocOptions {
|
|
19
|
-
name?: string,
|
|
20
|
-
customTags?: CustomTag[],
|
|
21
|
-
minDepth?: number
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// TODO: fix any
|
|
25
|
-
export const remarkMdxToc = (options: RemarkMdxTocOptions): Plugin => () => async (ast: any) => {
|
|
26
|
-
const {visit} = await import("unist-util-visit");
|
|
27
|
-
const {toString} = await import("mdast-util-to-string");
|
|
28
|
-
const {valueToEstree} = await import('estree-util-value-to-estree')
|
|
29
|
-
const {name: isIdentifierName} = await import('estree-util-is-identifier-name');
|
|
30
|
-
|
|
31
|
-
const mdast = ast as Root;
|
|
32
|
-
const name = options.name ?? "toc";
|
|
33
|
-
if (!isIdentifierName(name)) {
|
|
34
|
-
throw new Error(`Invalid name for an identifier: ${name}`);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const toc: TocEntry[] = [];
|
|
38
|
-
const flatToc: TocEntry[] = [];
|
|
39
|
-
const createEntry = (node: Heading | MdxJsxFlowElement, depth: number): TocEntry => {
|
|
40
|
-
let attributes = (node.data || {}) as TocEntry['attributes'];
|
|
41
|
-
if (node.type === "mdxJsxFlowElement") {
|
|
42
|
-
attributes = Object.fromEntries(
|
|
43
|
-
node.attributes
|
|
44
|
-
.filter(attribute => attribute.type === 'mdxJsxAttribute' && typeof attribute.value === 'string')
|
|
45
|
-
.map(attribute => [(attribute as MdxJsxAttribute).name, attribute.value])
|
|
46
|
-
) as TocEntry['attributes'];
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
depth,
|
|
50
|
-
value: toString(node, {includeImageAlt: false}),
|
|
51
|
-
attributes,
|
|
52
|
-
children: []
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
visit(mdast, ["heading", "mdxJsxFlowElement"], node => {
|
|
57
|
-
let depth = 0;
|
|
58
|
-
if (node.type === "mdxJsxFlowElement") {
|
|
59
|
-
let valid = false;
|
|
60
|
-
if (/^h[1-6]$/.test(node.name || "")) {
|
|
61
|
-
valid = true;
|
|
62
|
-
depth = parseInt(node.name!.substring(1));
|
|
63
|
-
} else if (options.customTags) {
|
|
64
|
-
for (const tag of options.customTags) {
|
|
65
|
-
if (tag.name.test(node.name || "")) {
|
|
66
|
-
valid = true;
|
|
67
|
-
depth = tag.depth(node.name || "");
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (!valid) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
} else if (node.type === "heading") {
|
|
77
|
-
depth = node.depth;
|
|
78
|
-
} else {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (depth && (options?.minDepth && options.minDepth > depth)) {
|
|
83
|
-
return
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const entry = createEntry(node, depth);
|
|
87
|
-
flatToc.push(entry);
|
|
88
|
-
|
|
89
|
-
let parent: TocEntry[] = toc;
|
|
90
|
-
for (let i = flatToc.length - 1; i >= 0; --i) {
|
|
91
|
-
const current = flatToc[i];
|
|
92
|
-
if (current.depth < entry.depth) {
|
|
93
|
-
parent = current.children;
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
parent.push(entry);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const tocExport: MdxjsEsm = {
|
|
101
|
-
type: "mdxjsEsm",
|
|
102
|
-
value: "",
|
|
103
|
-
data: {
|
|
104
|
-
estree: {
|
|
105
|
-
type: "Program",
|
|
106
|
-
sourceType: "module",
|
|
107
|
-
body: [
|
|
108
|
-
{
|
|
109
|
-
type: "ExportNamedDeclaration",
|
|
110
|
-
specifiers: [],
|
|
111
|
-
attributes: [],
|
|
112
|
-
source: null,
|
|
113
|
-
declaration: {
|
|
114
|
-
type: "VariableDeclaration",
|
|
115
|
-
kind: "const",
|
|
116
|
-
declarations: [
|
|
117
|
-
{
|
|
118
|
-
type: "VariableDeclarator",
|
|
119
|
-
id: {
|
|
120
|
-
type: "Identifier",
|
|
121
|
-
name
|
|
122
|
-
},
|
|
123
|
-
init: valueToEstree(toc)
|
|
124
|
-
}
|
|
125
|
-
]
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
]
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
mdast.children.unshift(tocExport);
|
|
133
|
-
};
|