@xyd-js/content 0.1.0-xyd.13 → 0.1.0-xyd.16
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 +34 -0
- package/ISSUES.md +1 -0
- package/TODO.md +2 -0
- package/dist/index.d.ts +24 -5
- package/dist/index.js +1411 -21776
- package/dist/index.js.map +1 -1
- package/dist/md.d.ts +62 -7
- package/dist/md.js +18071 -15085
- package/dist/md.js.map +1 -1
- package/dist/{mdToc-CYxzibVZ.d.ts → mdToc-NBBxMJ4l.d.ts} +1 -0
- package/dist/vite.d.ts +81 -2
- package/dist/vite.js +9716 -10090
- package/dist/vite.js.map +1 -1
- package/example.txt +0 -0
- package/package.json +24 -6
- 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 -11
- package/packages/md/plugins/mdCode.ts +52 -4
- package/packages/md/plugins/mdHeadingId.ts +47 -0
- package/packages/md/plugins/mdPage.ts +3 -0
- package/packages/md/plugins/mdThemeSettings.ts +4 -0
- package/packages/md/plugins/mdToc.ts +108 -17
- 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/vitest.config.ts +17 -0
- package/packages/md/plugins/mdCodeGroup.ts +0 -40
- package/packages/md/plugins/mdComponentDirective.ts +0 -141
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/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,40 +0,0 @@
|
|
|
1
|
-
import {visit} from 'unist-util-visit';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This plugin transforms a custom container directive into a JSX node
|
|
5
|
-
* https://github.com/remarkjs/remark-directive is needed to parse the container directive
|
|
6
|
-
*/
|
|
7
|
-
export function mdCodeGroup() {
|
|
8
|
-
return (tree: any) => {
|
|
9
|
-
visit(tree, 'containerDirective', (node) => {
|
|
10
|
-
// TODO: is `code-group` ok name? -> rename to CodeSample? or use `mdComponentDirective` instead
|
|
11
|
-
if (node.name !== 'code-group') {
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const description = node.attributes?.title || '';
|
|
16
|
-
const codeblocks = [];
|
|
17
|
-
|
|
18
|
-
for (const child of node.children) {
|
|
19
|
-
if (child.type === 'code') {
|
|
20
|
-
const meta = child.meta || '';
|
|
21
|
-
const value = child.value || '';
|
|
22
|
-
const lang = child.lang || '';
|
|
23
|
-
|
|
24
|
-
codeblocks.push({value, lang, meta});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Add metadata to the node
|
|
29
|
-
node.data = {
|
|
30
|
-
hName: 'DirectiveCodeSample',
|
|
31
|
-
hProperties: {
|
|
32
|
-
description,
|
|
33
|
-
codeblocks: JSON.stringify(codeblocks),
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
node.children = [];
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import {Plugin, unified} from "unified";
|
|
2
|
-
import remarkParse from "remark-parse";
|
|
3
|
-
import remarkMdx from "remark-mdx";
|
|
4
|
-
import {visit} from "unist-util-visit";
|
|
5
|
-
import {Node as UnistNode} from "unist";
|
|
6
|
-
|
|
7
|
-
function toPascalCase(str: string) {
|
|
8
|
-
return str
|
|
9
|
-
.replace(/([a-z])([A-Z])/g, "$1 $2") // Add space before capital letters
|
|
10
|
-
.replace(/[^a-zA-Z0-9]/g, " ") // Replace special characters with space
|
|
11
|
-
.split(" ") // Split by space
|
|
12
|
-
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize first letter
|
|
13
|
-
.join("");
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const supportedDirectives: { [key: string]: boolean } = {
|
|
18
|
-
Details: true,
|
|
19
|
-
details: true,
|
|
20
|
-
|
|
21
|
-
Table: true,
|
|
22
|
-
table: true,
|
|
23
|
-
|
|
24
|
-
Subtitle: true,
|
|
25
|
-
subtitle: true,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const tableComponents: { [key: string]: boolean } = {
|
|
29
|
-
Table: true,
|
|
30
|
-
table: true
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const parseMarkdown = (content: string) => {
|
|
34
|
-
const ast = unified()
|
|
35
|
-
.use(remarkParse)
|
|
36
|
-
.use(remarkMdx)
|
|
37
|
-
.parse(content);
|
|
38
|
-
return ast.children;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export const remarkDirectiveWithMarkdown: Plugin = () => {
|
|
42
|
-
return (tree: UnistNode) => {
|
|
43
|
-
visit(tree, 'containerDirective', (node: any) => {
|
|
44
|
-
if (!supportedDirectives[node.name]) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const isTable = tableComponents[node.name];
|
|
49
|
-
const attributes = [];
|
|
50
|
-
|
|
51
|
-
// TODO: MORE GENERIC CUZ IT HAS IMPL DETAILS OF TABLE
|
|
52
|
-
if (isTable) {
|
|
53
|
-
// TODO: support tsx tables like: [<>`Promise<Reference[]>`</>] ?
|
|
54
|
-
const tableData = JSON.parse(node.children[0].value);
|
|
55
|
-
const [header, ...rows] = tableData;
|
|
56
|
-
|
|
57
|
-
const jsxNode = {
|
|
58
|
-
type: 'mdxJsxFlowElement',
|
|
59
|
-
name: 'Table',
|
|
60
|
-
attributes: [],
|
|
61
|
-
children: [
|
|
62
|
-
{
|
|
63
|
-
type: 'mdxJsxFlowElement',
|
|
64
|
-
name: 'Table.Head',
|
|
65
|
-
attributes: [],
|
|
66
|
-
children: [
|
|
67
|
-
{
|
|
68
|
-
type: 'mdxJsxFlowElement',
|
|
69
|
-
name: 'Table.Tr',
|
|
70
|
-
attributes: [],
|
|
71
|
-
children: header.map((cell: string) => ({
|
|
72
|
-
type: 'mdxJsxFlowElement',
|
|
73
|
-
name: 'Table.Th',
|
|
74
|
-
attributes: [],
|
|
75
|
-
children: parseMarkdown(cell)
|
|
76
|
-
}))
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
},
|
|
80
|
-
// TODO: Table.Cell ?
|
|
81
|
-
...rows.map((row: string[]) => ({
|
|
82
|
-
type: 'mdxJsxFlowElement',
|
|
83
|
-
name: 'Table.Tr',
|
|
84
|
-
attributes: [],
|
|
85
|
-
children: row.map((cell: string) => ({
|
|
86
|
-
type: 'mdxJsxFlowElement',
|
|
87
|
-
name: 'Table.Td',
|
|
88
|
-
attributes: [],
|
|
89
|
-
children: parseMarkdown(cell)
|
|
90
|
-
}))
|
|
91
|
-
}))
|
|
92
|
-
]
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
Object.assign(node, jsxNode);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (node.attributes) {
|
|
100
|
-
const jsxProps = []
|
|
101
|
-
|
|
102
|
-
for (let [key, value] of Object.entries(node.attributes)) {
|
|
103
|
-
if (typeof value === "string" && !value.startsWith("<")) {
|
|
104
|
-
attributes.push({
|
|
105
|
-
type: 'mdxJsxAttribute',
|
|
106
|
-
name: key,
|
|
107
|
-
value: value
|
|
108
|
-
});
|
|
109
|
-
} else {
|
|
110
|
-
jsxProps.push(`${key}={${value}}`)
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const mdxString = `<Fragment ${jsxProps.join(" ")}></Fragment>`
|
|
116
|
-
|
|
117
|
-
const ast = unified()
|
|
118
|
-
.use(remarkParse)
|
|
119
|
-
.use(remarkMdx)
|
|
120
|
-
.parse(mdxString);
|
|
121
|
-
|
|
122
|
-
if (ast && ast.children[0] && ast.children[0].attributes) {
|
|
123
|
-
for (const attr of ast.children[0].attributes) {
|
|
124
|
-
// TODO: support markdown also e.g Hello `World` - currently it mus be: Hello <code>World</code>
|
|
125
|
-
attributes.push(attr);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const jsxNode = {
|
|
131
|
-
type: 'mdxJsxFlowElement',
|
|
132
|
-
name: toPascalCase(node.name),
|
|
133
|
-
attributes: attributes,
|
|
134
|
-
children: node.children
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
Object.assign(node, jsxNode);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|