pd-markdown 1.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/package.json +26 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.d.ts +4 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.js +5 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.js.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.d.ts +4 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.js +4 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.js.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.d.ts +6 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.js +36 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.js.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.d.ts +14 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.js +18 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.js.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.d.ts +27 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.js +37 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.js.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.d.ts +22 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.js +95 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.js.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.d.ts +55 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.d.ts.map +1 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.js +2 -0
- package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.js.map +1 -0
- package/packages/parser/__tests__/frontmatter.test.ts +69 -0
- package/packages/parser/__tests__/gfm.test.ts +83 -0
- package/packages/parser/__tests__/processor.test.ts +136 -0
- package/packages/parser/__tests__/transform/heading.test.ts +56 -0
- package/packages/parser/__tests__/transform/list.test.ts +67 -0
- package/packages/parser/__tests__/transform/table.test.ts +85 -0
- package/packages/parser/dist/index.cjs +191 -0
- package/packages/parser/dist/index.cjs.map +1 -0
- package/packages/parser/dist/index.d.ts +4 -0
- package/packages/parser/dist/index.d.ts.map +1 -0
- package/packages/parser/dist/index.mjs +185 -0
- package/packages/parser/dist/index.mjs.map +1 -0
- package/packages/parser/dist/plugins/index.d.ts +4 -0
- package/packages/parser/dist/plugins/index.d.ts.map +1 -0
- package/packages/parser/dist/plugins/transform/heading.d.ts +6 -0
- package/packages/parser/dist/plugins/transform/heading.d.ts.map +1 -0
- package/packages/parser/dist/plugins/transform/list.d.ts +14 -0
- package/packages/parser/dist/plugins/transform/list.d.ts.map +1 -0
- package/packages/parser/dist/plugins/transform/table.d.ts +27 -0
- package/packages/parser/dist/plugins/transform/table.d.ts.map +1 -0
- package/packages/parser/dist/processor.d.ts +22 -0
- package/packages/parser/dist/processor.d.ts.map +1 -0
- package/packages/parser/dist/types/index.d.ts +55 -0
- package/packages/parser/dist/types/index.d.ts.map +1 -0
- package/packages/parser/node_modules/.bin/yaml +17 -0
- package/packages/parser/package.json +38 -0
- package/packages/parser/rollup.config.ts +38 -0
- package/packages/parser/src/index.ts +15 -0
- package/packages/parser/src/plugins/index.ts +3 -0
- package/packages/parser/src/plugins/transform/heading.ts +40 -0
- package/packages/parser/src/plugins/transform/list.ts +29 -0
- package/packages/parser/src/plugins/transform/table.ts +62 -0
- package/packages/parser/src/processor.ts +119 -0
- package/packages/parser/src/types/index.ts +60 -0
- package/packages/parser/tsconfig.json +9 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.d.ts +36 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.d.ts.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.js +99 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.js.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.d.ts +22 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.d.ts.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.js +46 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.js.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.d.ts +7 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.d.ts.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.js +8 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.js.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.d.ts +22 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.d.ts.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.js +140 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.js.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.d.ts +16 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.d.ts.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.js +39 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.js.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.d.ts +49 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.d.ts.map +1 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.js +19 -0
- package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.js.map +1 -0
- package/packages/utils/__tests__/query.test.ts +155 -0
- package/packages/utils/__tests__/sanitize.test.ts +96 -0
- package/packages/utils/__tests__/slugify.test.ts +71 -0
- package/packages/utils/__tests__/traverse.test.ts +131 -0
- package/packages/utils/dist/ast/query.d.ts +36 -0
- package/packages/utils/dist/ast/query.d.ts.map +1 -0
- package/packages/utils/dist/ast/traverse.d.ts +22 -0
- package/packages/utils/dist/ast/traverse.d.ts.map +1 -0
- package/packages/utils/dist/index.cjs +358 -0
- package/packages/utils/dist/index.cjs.map +1 -0
- package/packages/utils/dist/index.d.ts +7 -0
- package/packages/utils/dist/index.d.ts.map +1 -0
- package/packages/utils/dist/index.mjs +343 -0
- package/packages/utils/dist/index.mjs.map +1 -0
- package/packages/utils/dist/string/sanitize.d.ts +22 -0
- package/packages/utils/dist/string/sanitize.d.ts.map +1 -0
- package/packages/utils/dist/string/slugify.d.ts +16 -0
- package/packages/utils/dist/string/slugify.d.ts.map +1 -0
- package/packages/utils/dist/types/index.d.ts +49 -0
- package/packages/utils/dist/types/index.d.ts.map +1 -0
- package/packages/utils/package.json +27 -0
- package/packages/utils/rollup.config.ts +26 -0
- package/packages/utils/src/ast/query.ts +127 -0
- package/packages/utils/src/ast/traverse.ts +73 -0
- package/packages/utils/src/index.ts +20 -0
- package/packages/utils/src/string/sanitize.ts +155 -0
- package/packages/utils/src/string/slugify.ts +43 -0
- package/packages/utils/src/types/index.ts +72 -0
- package/packages/utils/tsconfig.json +8 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.d.ts +27 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.js +39 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.d.ts +10 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.js +130 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.d.ts +17 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.js +14 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.d.ts +8 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.js +5 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.d.ts +13 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.js +9 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.d.ts +8 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.js +7 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.d.ts +7 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.js +5 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.d.ts +8 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.js +7 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.d.ts +13 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.js +14 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.d.ts +8 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.js +5 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.d.ts +19 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.js +18 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.d.ts +34 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.js +28 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.d.ts +11 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.js +28 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.js.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.d.ts +6 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.d.ts.map +1 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.js +9 -0
- package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.js.map +1 -0
- package/packages/web/__tests__/MarkdownRenderer.test.tsx +89 -0
- package/packages/web/__tests__/NodeRenderer.test.tsx +97 -0
- package/packages/web/__tests__/components/Code.test.tsx +71 -0
- package/packages/web/__tests__/components/Heading.test.tsx +65 -0
- package/packages/web/__tests__/components/List.test.tsx +100 -0
- package/packages/web/__tests__/components/Table.test.tsx +105 -0
- package/packages/web/__tests__/useMarkdown.test.ts +63 -0
- package/packages/web/dist/components/MarkdownRenderer.d.ts +27 -0
- package/packages/web/dist/components/MarkdownRenderer.d.ts.map +1 -0
- package/packages/web/dist/components/NodeRenderer.d.ts +10 -0
- package/packages/web/dist/components/NodeRenderer.d.ts.map +1 -0
- package/packages/web/dist/components/context.d.ts +17 -0
- package/packages/web/dist/components/context.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Blockquote.d.ts +8 -0
- package/packages/web/dist/components/defaults/Blockquote.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Code.d.ts +13 -0
- package/packages/web/dist/components/defaults/Code.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Heading.d.ts +8 -0
- package/packages/web/dist/components/defaults/Heading.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Image.d.ts +7 -0
- package/packages/web/dist/components/defaults/Image.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Link.d.ts +8 -0
- package/packages/web/dist/components/defaults/Link.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/List.d.ts +13 -0
- package/packages/web/dist/components/defaults/List.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Paragraph.d.ts +8 -0
- package/packages/web/dist/components/defaults/Paragraph.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/Table.d.ts +19 -0
- package/packages/web/dist/components/defaults/Table.d.ts.map +1 -0
- package/packages/web/dist/components/defaults/index.d.ts +34 -0
- package/packages/web/dist/components/defaults/index.d.ts.map +1 -0
- package/packages/web/dist/hooks/useMarkdown.d.ts +11 -0
- package/packages/web/dist/hooks/useMarkdown.d.ts.map +1 -0
- package/packages/web/dist/index.cjs +306 -0
- package/packages/web/dist/index.cjs.map +1 -0
- package/packages/web/dist/index.d.ts +6 -0
- package/packages/web/dist/index.d.ts.map +1 -0
- package/packages/web/dist/index.mjs +287 -0
- package/packages/web/dist/index.mjs.map +1 -0
- package/packages/web/package.json +40 -0
- package/packages/web/rollup.config.ts +36 -0
- package/packages/web/src/components/MarkdownRenderer.tsx +70 -0
- package/packages/web/src/components/NodeRenderer.tsx +205 -0
- package/packages/web/src/components/context.ts +24 -0
- package/packages/web/src/components/defaults/Blockquote.tsx +11 -0
- package/packages/web/src/components/defaults/Code.tsx +26 -0
- package/packages/web/src/components/defaults/Heading.tsx +14 -0
- package/packages/web/src/components/defaults/Image.tsx +10 -0
- package/packages/web/src/components/defaults/Link.tsx +18 -0
- package/packages/web/src/components/defaults/List.tsx +33 -0
- package/packages/web/src/components/defaults/Paragraph.tsx +11 -0
- package/packages/web/src/components/defaults/Table.tsx +50 -0
- package/packages/web/src/components/defaults/index.tsx +80 -0
- package/packages/web/src/hooks/useMarkdown.ts +32 -0
- package/packages/web/src/index.ts +37 -0
- package/packages/web/tsconfig.json +11 -0
- package/packages/web/vitest.config.ts +9 -0
- package/pnpm-workspace.yaml +2 -0
- package/tsconfig.base.json +26 -0
- package/tsconfig.json +8 -0
- package/vitest.config.ts +28 -0
- package/vitest.setup.ts +1 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pd-markdown/web",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React components for rendering markdown",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.mjs",
|
|
9
|
+
"require": "./dist/index.cjs",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.cjs",
|
|
14
|
+
"module": "./dist/index.mjs",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": ["dist"],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "rollup -c rollup.config.ts --configPlugin typescript",
|
|
19
|
+
"clean": "rm -rf dist *.tsbuildinfo"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@pd-markdown/parser": "workspace:*",
|
|
23
|
+
"@pd-markdown/utils": "workspace:*"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
27
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@testing-library/react": "^16.2.0",
|
|
31
|
+
"@types/mdast": "^4.0.4",
|
|
32
|
+
"@types/react": "^19.0.8",
|
|
33
|
+
"@types/react-dom": "^19.0.3",
|
|
34
|
+
"jsdom": "^26.0.0",
|
|
35
|
+
"react": "^19.0.0",
|
|
36
|
+
"react-dom": "^19.0.0"
|
|
37
|
+
},
|
|
38
|
+
"sideEffects": false,
|
|
39
|
+
"license": "MIT"
|
|
40
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import typescript from '@rollup/plugin-typescript'
|
|
2
|
+
import resolve from '@rollup/plugin-node-resolve'
|
|
3
|
+
import commonjs from '@rollup/plugin-commonjs'
|
|
4
|
+
import { defineConfig } from 'rollup'
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
input: 'src/index.ts',
|
|
8
|
+
output: [
|
|
9
|
+
{
|
|
10
|
+
file: 'dist/index.mjs',
|
|
11
|
+
format: 'esm',
|
|
12
|
+
sourcemap: true,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
file: 'dist/index.cjs',
|
|
16
|
+
format: 'cjs',
|
|
17
|
+
sourcemap: true,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
plugins: [
|
|
21
|
+
resolve(),
|
|
22
|
+
commonjs(),
|
|
23
|
+
typescript({
|
|
24
|
+
tsconfig: './tsconfig.json',
|
|
25
|
+
declaration: true,
|
|
26
|
+
declarationDir: './dist',
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
29
|
+
external: [
|
|
30
|
+
'react',
|
|
31
|
+
'react-dom',
|
|
32
|
+
'react/jsx-runtime',
|
|
33
|
+
'@pd-markdown/utils',
|
|
34
|
+
'@pd-markdown/parser',
|
|
35
|
+
],
|
|
36
|
+
})
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { FC, CSSProperties } from 'react'
|
|
2
|
+
import type { Root } from 'mdast'
|
|
3
|
+
import { createParser, type ParserOptions } from '@pd-markdown/parser'
|
|
4
|
+
import { MarkdownContext } from './context'
|
|
5
|
+
import { NodeRenderer } from './NodeRenderer'
|
|
6
|
+
import type { ComponentMap } from './defaults'
|
|
7
|
+
|
|
8
|
+
export interface MarkdownRendererProps {
|
|
9
|
+
/** Markdown source string (will be parsed) */
|
|
10
|
+
source?: string
|
|
11
|
+
/** Pre-parsed AST (skip parsing, useful for SSR) */
|
|
12
|
+
ast?: Root
|
|
13
|
+
/** Custom component overrides */
|
|
14
|
+
components?: Partial<ComponentMap>
|
|
15
|
+
/** CSS class name for wrapper */
|
|
16
|
+
className?: string
|
|
17
|
+
/** Inline styles for wrapper */
|
|
18
|
+
style?: CSSProperties
|
|
19
|
+
/** Parser options (only used when source is provided) */
|
|
20
|
+
parserOptions?: ParserOptions
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Singleton parser for client-side use
|
|
24
|
+
let defaultParser: ReturnType<typeof createParser> | null = null
|
|
25
|
+
|
|
26
|
+
function getParser(options?: ParserOptions) {
|
|
27
|
+
if (options) {
|
|
28
|
+
return createParser(options)
|
|
29
|
+
}
|
|
30
|
+
if (!defaultParser) {
|
|
31
|
+
defaultParser = createParser()
|
|
32
|
+
}
|
|
33
|
+
return defaultParser
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Main markdown renderer component
|
|
38
|
+
*
|
|
39
|
+
* Supports both client-side and server-side rendering:
|
|
40
|
+
* - Pass `source` for automatic parsing
|
|
41
|
+
* - Pass `ast` for pre-parsed content (SSR optimization)
|
|
42
|
+
*/
|
|
43
|
+
export const MarkdownRenderer: FC<MarkdownRendererProps> = ({
|
|
44
|
+
source,
|
|
45
|
+
ast,
|
|
46
|
+
components = {},
|
|
47
|
+
className,
|
|
48
|
+
style,
|
|
49
|
+
parserOptions,
|
|
50
|
+
}) => {
|
|
51
|
+
// Use provided AST or parse source
|
|
52
|
+
let tree: Root
|
|
53
|
+
if (ast) {
|
|
54
|
+
tree = ast
|
|
55
|
+
} else if (source) {
|
|
56
|
+
const parser = getParser(parserOptions)
|
|
57
|
+
tree = parser.parse(source)
|
|
58
|
+
} else {
|
|
59
|
+
// No content provided
|
|
60
|
+
return null
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<MarkdownContext.Provider value={{ components }}>
|
|
65
|
+
<div className={className} style={style}>
|
|
66
|
+
<NodeRenderer node={tree} />
|
|
67
|
+
</div>
|
|
68
|
+
</MarkdownContext.Provider>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { Content, Root, PhrasingContent, Parent } from 'mdast'
|
|
3
|
+
import { useMarkdownContext } from './context'
|
|
4
|
+
import { defaultComponents } from './defaults'
|
|
5
|
+
|
|
6
|
+
export interface NodeRendererProps {
|
|
7
|
+
node: Content | Root
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Recursive node renderer that renders AST nodes to React elements
|
|
12
|
+
*/
|
|
13
|
+
export const NodeRenderer: FC<NodeRendererProps> = ({ node }) => {
|
|
14
|
+
const { components } = useMarkdownContext()
|
|
15
|
+
|
|
16
|
+
// Get the component for this node type
|
|
17
|
+
const getComponent = (type: string) => {
|
|
18
|
+
return components[type] || defaultComponents[type]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Render children nodes
|
|
22
|
+
const renderChildren = (children: Content[]): ReactNode => {
|
|
23
|
+
return children.map((child, index) => (
|
|
24
|
+
<NodeRenderer key={index} node={child} />
|
|
25
|
+
))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Render phrasing content (inline elements)
|
|
29
|
+
const renderPhrasingContent = (children: PhrasingContent[]): ReactNode => {
|
|
30
|
+
return children.map((child, index) => {
|
|
31
|
+
switch (child.type) {
|
|
32
|
+
case 'text':
|
|
33
|
+
return child.value
|
|
34
|
+
|
|
35
|
+
case 'strong':
|
|
36
|
+
return <strong key={index}>{renderPhrasingContent(child.children)}</strong>
|
|
37
|
+
|
|
38
|
+
case 'emphasis':
|
|
39
|
+
return <em key={index}>{renderPhrasingContent(child.children)}</em>
|
|
40
|
+
|
|
41
|
+
case 'delete':
|
|
42
|
+
return <del key={index}>{renderPhrasingContent(child.children)}</del>
|
|
43
|
+
|
|
44
|
+
case 'inlineCode': {
|
|
45
|
+
const InlineCode = getComponent('inlineCode')
|
|
46
|
+
return InlineCode ? <InlineCode key={index} node={child} /> : <code key={index}>{child.value}</code>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
case 'link': {
|
|
50
|
+
const Link = getComponent('link')
|
|
51
|
+
return Link ? (
|
|
52
|
+
<Link key={index} node={child}>
|
|
53
|
+
{renderPhrasingContent(child.children)}
|
|
54
|
+
</Link>
|
|
55
|
+
) : (
|
|
56
|
+
<a key={index} href={child.url}>
|
|
57
|
+
{renderPhrasingContent(child.children)}
|
|
58
|
+
</a>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
case 'image': {
|
|
63
|
+
const Image = getComponent('image')
|
|
64
|
+
return Image ? <Image key={index} node={child} /> : <img key={index} src={child.url} alt={child.alt || ''} />
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
case 'break':
|
|
68
|
+
return <br key={index} />
|
|
69
|
+
|
|
70
|
+
case 'html':
|
|
71
|
+
// For safety, render HTML as text in React
|
|
72
|
+
return child.value
|
|
73
|
+
|
|
74
|
+
default:
|
|
75
|
+
// For unknown inline types, try to render as text if possible
|
|
76
|
+
if ('value' in child && typeof child.value === 'string') {
|
|
77
|
+
return child.value
|
|
78
|
+
}
|
|
79
|
+
if ('children' in child) {
|
|
80
|
+
return renderPhrasingContent((child as any).children)
|
|
81
|
+
}
|
|
82
|
+
return null
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Handle different node types
|
|
88
|
+
switch (node.type) {
|
|
89
|
+
case 'root':
|
|
90
|
+
return <>{renderChildren(node.children)}</>
|
|
91
|
+
|
|
92
|
+
case 'heading': {
|
|
93
|
+
const Heading = getComponent('heading')
|
|
94
|
+
return Heading ? (
|
|
95
|
+
<Heading node={node}>{renderPhrasingContent(node.children)}</Heading>
|
|
96
|
+
) : null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
case 'paragraph': {
|
|
100
|
+
const Paragraph = getComponent('paragraph')
|
|
101
|
+
return Paragraph ? (
|
|
102
|
+
<Paragraph node={node}>{renderPhrasingContent(node.children)}</Paragraph>
|
|
103
|
+
) : null
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
case 'list': {
|
|
107
|
+
const List = getComponent('list')
|
|
108
|
+
return List ? (
|
|
109
|
+
<List node={node}>{renderChildren(node.children)}</List>
|
|
110
|
+
) : null
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
case 'listItem': {
|
|
114
|
+
const ListItem = getComponent('listItem')
|
|
115
|
+
const children = node.children.map((child, index) => {
|
|
116
|
+
// Unwrap single paragraph in list item
|
|
117
|
+
if (child.type === 'paragraph' && node.children.length === 1) {
|
|
118
|
+
return renderPhrasingContent(child.children)
|
|
119
|
+
}
|
|
120
|
+
return <NodeRenderer key={index} node={child} />
|
|
121
|
+
})
|
|
122
|
+
return ListItem ? <ListItem node={node}>{children}</ListItem> : null
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
case 'table': {
|
|
126
|
+
const Table = getComponent('table')
|
|
127
|
+
const TableRow = getComponent('tableRow')
|
|
128
|
+
|
|
129
|
+
if (!Table || !TableRow) return null
|
|
130
|
+
|
|
131
|
+
const [headerRow, ...bodyRows] = node.children
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<Table node={node}>
|
|
135
|
+
{headerRow && (
|
|
136
|
+
<TableRow node={headerRow} isHeader>
|
|
137
|
+
{headerRow.children.map((cell, index) => (
|
|
138
|
+
<NodeRenderer key={index} node={cell} />
|
|
139
|
+
))}
|
|
140
|
+
</TableRow>
|
|
141
|
+
)}
|
|
142
|
+
{bodyRows.length > 0 && (
|
|
143
|
+
<tbody>
|
|
144
|
+
{bodyRows.map((row, rowIndex) => (
|
|
145
|
+
<TableRow key={rowIndex} node={row}>
|
|
146
|
+
{row.children.map((cell, cellIndex) => (
|
|
147
|
+
<NodeRenderer key={cellIndex} node={cell} />
|
|
148
|
+
))}
|
|
149
|
+
</TableRow>
|
|
150
|
+
))}
|
|
151
|
+
</tbody>
|
|
152
|
+
)}
|
|
153
|
+
</Table>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
case 'tableCell': {
|
|
158
|
+
const TableCell = getComponent('tableCell')
|
|
159
|
+
return TableCell ? (
|
|
160
|
+
<TableCell node={node}>{renderPhrasingContent(node.children)}</TableCell>
|
|
161
|
+
) : null
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
case 'code': {
|
|
165
|
+
const Code = getComponent('code')
|
|
166
|
+
return Code ? <Code node={node} /> : null
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
case 'blockquote': {
|
|
170
|
+
const Blockquote = getComponent('blockquote')
|
|
171
|
+
return Blockquote ? (
|
|
172
|
+
<Blockquote node={node}>{renderChildren(node.children)}</Blockquote>
|
|
173
|
+
) : null
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
case 'thematicBreak':
|
|
177
|
+
return <hr />
|
|
178
|
+
|
|
179
|
+
case 'html':
|
|
180
|
+
// For safety, don't render raw HTML by default
|
|
181
|
+
return null
|
|
182
|
+
|
|
183
|
+
case 'yaml':
|
|
184
|
+
// Frontmatter shouldn't be rendered
|
|
185
|
+
return null
|
|
186
|
+
|
|
187
|
+
default: {
|
|
188
|
+
// Try to find a custom component for unknown types
|
|
189
|
+
const CustomComponent = getComponent(node.type)
|
|
190
|
+
if (CustomComponent) {
|
|
191
|
+
const children = 'children' in node
|
|
192
|
+
? renderChildren((node as Parent).children as Content[])
|
|
193
|
+
: undefined
|
|
194
|
+
return <CustomComponent node={node}>{children}</CustomComponent>
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Fallback: try to render children if available
|
|
198
|
+
if ('children' in node) {
|
|
199
|
+
return <>{renderChildren((node as Parent).children as Content[])}</>
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return null
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react'
|
|
2
|
+
import type { ComponentMap } from './defaults'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Context value for markdown renderer
|
|
6
|
+
*/
|
|
7
|
+
export interface MarkdownContextValue {
|
|
8
|
+
/** Custom component overrides */
|
|
9
|
+
components: Partial<ComponentMap>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Context for passing configuration down the component tree
|
|
14
|
+
*/
|
|
15
|
+
export const MarkdownContext = createContext<MarkdownContextValue>({
|
|
16
|
+
components: {},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hook to access markdown context
|
|
21
|
+
*/
|
|
22
|
+
export function useMarkdownContext(): MarkdownContextValue {
|
|
23
|
+
return useContext(MarkdownContext)
|
|
24
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { Blockquote as BlockquoteNode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface BlockquoteProps {
|
|
5
|
+
node: BlockquoteNode
|
|
6
|
+
children: ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Blockquote: FC<BlockquoteProps> = ({ children }) => {
|
|
10
|
+
return <blockquote>{children}</blockquote>
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { Code as CodeNode, InlineCode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface CodeProps {
|
|
5
|
+
node: CodeNode
|
|
6
|
+
children?: ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Code: FC<CodeProps> = ({ node }) => {
|
|
10
|
+
const className = node.lang ? `language-${node.lang}` : undefined
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<pre>
|
|
14
|
+
<code className={className}>{node.value}</code>
|
|
15
|
+
</pre>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface InlineCodeProps {
|
|
20
|
+
node: InlineCode
|
|
21
|
+
children?: ReactNode
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const InlineCodeComponent: FC<InlineCodeProps> = ({ node }) => {
|
|
25
|
+
return <code>{node.value}</code>
|
|
26
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { Heading as HeadingNode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface HeadingProps {
|
|
5
|
+
node: HeadingNode
|
|
6
|
+
children: ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Heading: FC<HeadingProps> = ({ node, children }) => {
|
|
10
|
+
const Tag = `h${node.depth}` as const
|
|
11
|
+
const id = node.data && 'id' in node.data ? (node.data.id as string) : undefined
|
|
12
|
+
|
|
13
|
+
return <Tag id={id}>{children}</Tag>
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FC } from 'react'
|
|
2
|
+
import type { Image as ImageNode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface ImageProps {
|
|
5
|
+
node: ImageNode
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const Image: FC<ImageProps> = ({ node }) => {
|
|
9
|
+
return <img src={node.url} alt={node.alt || ''} title={node.title || undefined} />
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { Link as LinkNode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface LinkProps {
|
|
5
|
+
node: LinkNode
|
|
6
|
+
children: ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Link: FC<LinkProps> = ({ node, children }) => {
|
|
10
|
+
// Basic security: prevent javascript: URLs
|
|
11
|
+
const href = node.url?.startsWith('javascript:') ? '#' : node.url
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<a href={href} title={node.title || undefined}>
|
|
15
|
+
{children}
|
|
16
|
+
</a>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { List as ListNode, ListItem as ListItemNode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface ListProps {
|
|
5
|
+
node: ListNode
|
|
6
|
+
children: ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const List: FC<ListProps> = ({ node, children }) => {
|
|
10
|
+
const Tag = node.ordered ? 'ol' : 'ul'
|
|
11
|
+
const start = node.ordered && node.start != null && node.start !== 1 ? node.start : undefined
|
|
12
|
+
|
|
13
|
+
return <Tag start={start}>{children}</Tag>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ListItemProps {
|
|
17
|
+
node: ListItemNode
|
|
18
|
+
children: ReactNode
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const ListItem: FC<ListItemProps> = ({ node, children }) => {
|
|
22
|
+
// Handle task list items
|
|
23
|
+
if (typeof node.checked === 'boolean') {
|
|
24
|
+
return (
|
|
25
|
+
<li className="task-list-item">
|
|
26
|
+
<input type="checkbox" checked={node.checked} readOnly />
|
|
27
|
+
<span>{children}</span>
|
|
28
|
+
</li>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return <li>{children}</li>
|
|
33
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type { Paragraph as ParagraphNode } from 'mdast'
|
|
3
|
+
|
|
4
|
+
export interface ParagraphProps {
|
|
5
|
+
node: ParagraphNode
|
|
6
|
+
children: ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Paragraph: FC<ParagraphProps> = ({ children }) => {
|
|
10
|
+
return <p>{children}</p>
|
|
11
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react'
|
|
2
|
+
import type {
|
|
3
|
+
Table as TableNode,
|
|
4
|
+
TableRow as TableRowNode,
|
|
5
|
+
TableCell as TableCellNode,
|
|
6
|
+
} from 'mdast'
|
|
7
|
+
|
|
8
|
+
export interface TableProps {
|
|
9
|
+
node: TableNode
|
|
10
|
+
children: ReactNode
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Table: FC<TableProps> = ({ children }) => {
|
|
14
|
+
return (
|
|
15
|
+
<table>
|
|
16
|
+
{children}
|
|
17
|
+
</table>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface TableRowProps {
|
|
22
|
+
node: TableRowNode
|
|
23
|
+
children: ReactNode
|
|
24
|
+
isHeader?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const TableRow: FC<TableRowProps> = ({ children, isHeader }) => {
|
|
28
|
+
if (isHeader) {
|
|
29
|
+
return (
|
|
30
|
+
<thead>
|
|
31
|
+
<tr>{children}</tr>
|
|
32
|
+
</thead>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
return <tr>{children}</tr>
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface TableCellProps {
|
|
39
|
+
node: TableCellNode
|
|
40
|
+
children: ReactNode
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const TableCell: FC<TableCellProps> = ({ node, children }) => {
|
|
44
|
+
const isHeader = node.data?.isHeader
|
|
45
|
+
const align = node.data?.align as 'left' | 'center' | 'right' | null
|
|
46
|
+
const Tag = isHeader ? 'th' : 'td'
|
|
47
|
+
const style = align ? { textAlign: align } : undefined
|
|
48
|
+
|
|
49
|
+
return <Tag style={style}>{children}</Tag>
|
|
50
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import { Heading, HeadingProps } from './Heading'
|
|
4
|
+
import { Paragraph, ParagraphProps } from './Paragraph'
|
|
5
|
+
import { List, ListItem, ListProps, ListItemProps } from './List'
|
|
6
|
+
import { Table, TableRow, TableCell, TableProps, TableRowProps, TableCellProps } from './Table'
|
|
7
|
+
import { Code, InlineCodeComponent, CodeProps, InlineCodeProps } from './Code'
|
|
8
|
+
import { Link, LinkProps } from './Link'
|
|
9
|
+
import { Image, ImageProps } from './Image'
|
|
10
|
+
import { Blockquote, BlockquoteProps } from './Blockquote'
|
|
11
|
+
|
|
12
|
+
// Re-export all components
|
|
13
|
+
export {
|
|
14
|
+
Heading,
|
|
15
|
+
Paragraph,
|
|
16
|
+
List,
|
|
17
|
+
ListItem,
|
|
18
|
+
Table,
|
|
19
|
+
TableRow,
|
|
20
|
+
TableCell,
|
|
21
|
+
Code,
|
|
22
|
+
InlineCodeComponent,
|
|
23
|
+
Link,
|
|
24
|
+
Image,
|
|
25
|
+
Blockquote,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Re-export prop types
|
|
29
|
+
export type {
|
|
30
|
+
HeadingProps,
|
|
31
|
+
ParagraphProps,
|
|
32
|
+
ListProps,
|
|
33
|
+
ListItemProps,
|
|
34
|
+
TableProps,
|
|
35
|
+
TableRowProps,
|
|
36
|
+
TableCellProps,
|
|
37
|
+
CodeProps,
|
|
38
|
+
InlineCodeProps,
|
|
39
|
+
LinkProps,
|
|
40
|
+
ImageProps,
|
|
41
|
+
BlockquoteProps,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Map of node types to their corresponding React components
|
|
46
|
+
*/
|
|
47
|
+
export interface ComponentMap {
|
|
48
|
+
heading: React.FC<HeadingProps>
|
|
49
|
+
paragraph: React.FC<ParagraphProps>
|
|
50
|
+
list: React.FC<ListProps>
|
|
51
|
+
listItem: React.FC<ListItemProps>
|
|
52
|
+
table: React.FC<TableProps>
|
|
53
|
+
tableRow: React.FC<TableRowProps>
|
|
54
|
+
tableCell: React.FC<TableCellProps>
|
|
55
|
+
code: React.FC<CodeProps>
|
|
56
|
+
inlineCode: React.FC<InlineCodeProps>
|
|
57
|
+
link: React.FC<LinkProps>
|
|
58
|
+
image: React.FC<ImageProps>
|
|
59
|
+
blockquote: React.FC<BlockquoteProps>
|
|
60
|
+
// Allow custom node types
|
|
61
|
+
[key: string]: React.FC<any>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Default component map
|
|
66
|
+
*/
|
|
67
|
+
export const defaultComponents: ComponentMap = {
|
|
68
|
+
heading: Heading,
|
|
69
|
+
paragraph: Paragraph,
|
|
70
|
+
list: List,
|
|
71
|
+
listItem: ListItem,
|
|
72
|
+
table: Table,
|
|
73
|
+
tableRow: TableRow,
|
|
74
|
+
tableCell: TableCell,
|
|
75
|
+
code: Code,
|
|
76
|
+
inlineCode: InlineCodeComponent,
|
|
77
|
+
link: Link,
|
|
78
|
+
image: Image,
|
|
79
|
+
blockquote: Blockquote,
|
|
80
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import type { Root } from 'mdast'
|
|
3
|
+
import { createParser, type ParserOptions } from '@pd-markdown/parser'
|
|
4
|
+
|
|
5
|
+
// Cached parser instance
|
|
6
|
+
let cachedParser: ReturnType<typeof createParser> | null = null
|
|
7
|
+
|
|
8
|
+
function getParser(options?: ParserOptions) {
|
|
9
|
+
if (options) {
|
|
10
|
+
return createParser(options)
|
|
11
|
+
}
|
|
12
|
+
if (!cachedParser) {
|
|
13
|
+
cachedParser = createParser()
|
|
14
|
+
}
|
|
15
|
+
return cachedParser
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Hook for parsing markdown on the client side
|
|
20
|
+
*
|
|
21
|
+
* @param source - Markdown source string
|
|
22
|
+
* @param options - Parser options
|
|
23
|
+
* @returns Parsed AST
|
|
24
|
+
*/
|
|
25
|
+
export function useMarkdown(source: string, options?: ParserOptions): Root {
|
|
26
|
+
const ast = useMemo(() => {
|
|
27
|
+
const parser = getParser(options)
|
|
28
|
+
return parser.parse(source)
|
|
29
|
+
}, [source, options])
|
|
30
|
+
|
|
31
|
+
return ast
|
|
32
|
+
}
|