comark 0.2.0 → 0.2.1
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/dist/internal/stringify/handlers/hr.d.ts +1 -1
- package/dist/internal/stringify/handlers/hr.js +4 -1
- package/dist/internal/stringify/handlers/html.js +1 -1
- package/dist/internal/stringify/handlers/mdc.js +2 -1
- package/dist/plugins/highlight.d.ts +2 -2
- package/dist/plugins/highlight.js +2 -2
- package/dist/plugins/json-render.d.ts +53 -0
- package/dist/plugins/json-render.js +99 -0
- package/package.json +5 -4
|
@@ -37,7 +37,7 @@ export async function html(node, state, parent) {
|
|
|
37
37
|
for (let i = 0; i < children.length; i++) {
|
|
38
38
|
const childContent = childrenContent[i];
|
|
39
39
|
const child = children[i];
|
|
40
|
-
const isBlock = blockTags.has(String(child?.[0])) || (!inlineTags.has(String(child?.[0])) && !hasTextSibling);
|
|
40
|
+
const isBlock = typeof child !== 'string' && (blockTags.has(String(child?.[0])) || (!inlineTags.has(String(child?.[0])) && !hasTextSibling));
|
|
41
41
|
if (i > 0 && !isPrevBlock && isBlock) {
|
|
42
42
|
content += state.context.blockSeparator;
|
|
43
43
|
}
|
|
@@ -28,7 +28,8 @@ export async function mdc(node, state, parent) {
|
|
|
28
28
|
content = content.trimEnd();
|
|
29
29
|
const attrs = attributeEntries.length > 0 ? comarkAttributes(attributes) : '';
|
|
30
30
|
if (tag === 'span') {
|
|
31
|
-
return `[${content}]${attrs}
|
|
31
|
+
return `[${content}]${attrs}`
|
|
32
|
+
+ (inline ? '' : state.context.blockSeparator);
|
|
32
33
|
}
|
|
33
34
|
const fence = ':'.repeat((state.nodeDepthInTree || 0) + 2);
|
|
34
35
|
let result = `:${tag}${content && `[${content}]`}${attrs}` + (!parent ? state.context.blockSeparator : '');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LanguageRegistration, ShikiTransformer,
|
|
1
|
+
import type { LanguageRegistration, ShikiTransformer, ShikiPrimitive, ThemeRegistration } from 'shiki';
|
|
2
2
|
import type { ComarkNode, ComarkTree } from 'comark';
|
|
3
3
|
export interface HighlightOptions {
|
|
4
4
|
/**
|
|
@@ -45,7 +45,7 @@ export interface CodeBlockAttributes {
|
|
|
45
45
|
* Get or create the Shiki highlighter instance
|
|
46
46
|
* Uses a singleton pattern to avoid creating multiple highlighters
|
|
47
47
|
*/
|
|
48
|
-
export declare function getHighlighter(options?: HighlightOptions): Promise<
|
|
48
|
+
export declare function getHighlighter(options?: HighlightOptions): Promise<ShikiPrimitive>;
|
|
49
49
|
/**
|
|
50
50
|
* Highlight code using Shiki with codeToTokens
|
|
51
51
|
* Returns comark nodes built from hast
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComarkPlugin } from "../utils/helpers.js";
|
|
2
|
-
import {
|
|
2
|
+
import { createShikiPrimitive } from 'shiki';
|
|
3
3
|
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
|
|
4
4
|
import { codeToHast } from 'shiki/core';
|
|
5
5
|
let highlighter = null;
|
|
@@ -24,7 +24,7 @@ export async function getHighlighter(options = {}) {
|
|
|
24
24
|
try {
|
|
25
25
|
highlighterPromise = (async () => {
|
|
26
26
|
const { themes, languages } = await registerDefaults(options);
|
|
27
|
-
const hl = await
|
|
27
|
+
const hl = await createShikiPrimitive({
|
|
28
28
|
themes: themes,
|
|
29
29
|
langs: languages,
|
|
30
30
|
langAlias: {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
interface JsonRenderConfig {
|
|
2
|
+
}
|
|
3
|
+
/**
|
|
4
|
+
* Plugin for rendering [JSON Render](https://json-render.dev/) specs as UI components.
|
|
5
|
+
*
|
|
6
|
+
* Transforms `json-render` fenced code blocks into Comark AST nodes at parse time.
|
|
7
|
+
* Supports both full specs (with `root` and `elements`) and single-element shorthand.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Plugin configuration options
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { parse } from 'comark'
|
|
14
|
+
* import jsonRender from 'comark/plugins/json-render'
|
|
15
|
+
*
|
|
16
|
+
* const result = await parse(`
|
|
17
|
+
* \`\`\`json-render
|
|
18
|
+
* {
|
|
19
|
+
* "root": "card",
|
|
20
|
+
* "elements": {
|
|
21
|
+
* "card": {
|
|
22
|
+
* "type": "Card",
|
|
23
|
+
* "props": { "title": "Hello" },
|
|
24
|
+
* "children": ["text"]
|
|
25
|
+
* },
|
|
26
|
+
* "text": {
|
|
27
|
+
* "type": "Text",
|
|
28
|
+
* "props": { "content": "World" }
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* \`\`\`
|
|
33
|
+
* `, {
|
|
34
|
+
* plugins: [jsonRender()]
|
|
35
|
+
* })
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```vue
|
|
40
|
+
* <script setup>
|
|
41
|
+
* import { Comark } from '@comark/vue'
|
|
42
|
+
* import jsonRender from '@comark/vue/plugins/json-render'
|
|
43
|
+
* </script>
|
|
44
|
+
*
|
|
45
|
+
* <template>
|
|
46
|
+
* <Suspense>
|
|
47
|
+
* <Comark :plugins="[jsonRender()]">{{ content }}</Comark>
|
|
48
|
+
* </Suspense>
|
|
49
|
+
* </template>
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare const _default: import("..").ComarkPluginFactory<JsonRenderConfig>;
|
|
53
|
+
export default _default;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { defineComarkPlugin } from '../parse';
|
|
2
|
+
import { textContent, visit } from '../utils';
|
|
3
|
+
import { parseYaml } from '../internal/yaml';
|
|
4
|
+
function jsonRenderToAst(jrt) {
|
|
5
|
+
if (!jrt.root) {
|
|
6
|
+
jrt = {
|
|
7
|
+
root: 'template',
|
|
8
|
+
elements: { template: jrt },
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const tree = jrt;
|
|
12
|
+
const root = tree.elements[tree.root];
|
|
13
|
+
return jsonRenderElementToAst(root, tree.elements);
|
|
14
|
+
}
|
|
15
|
+
function jsonRenderElementToAst(element, elements) {
|
|
16
|
+
if (element.type === 'Text') {
|
|
17
|
+
return String(element.props.content);
|
|
18
|
+
}
|
|
19
|
+
const children = element.children?.map(childName => elements[childName])
|
|
20
|
+
.filter(Boolean) || [];
|
|
21
|
+
return [
|
|
22
|
+
element.type,
|
|
23
|
+
element.props,
|
|
24
|
+
...children.map(child => jsonRenderElementToAst(child, elements)),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Plugin for rendering [JSON Render](https://json-render.dev/) specs as UI components.
|
|
29
|
+
*
|
|
30
|
+
* Transforms `json-render` fenced code blocks into Comark AST nodes at parse time.
|
|
31
|
+
* Supports both full specs (with `root` and `elements`) and single-element shorthand.
|
|
32
|
+
*
|
|
33
|
+
* @param config - Plugin configuration options
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { parse } from 'comark'
|
|
38
|
+
* import jsonRender from 'comark/plugins/json-render'
|
|
39
|
+
*
|
|
40
|
+
* const result = await parse(`
|
|
41
|
+
* \`\`\`json-render
|
|
42
|
+
* {
|
|
43
|
+
* "root": "card",
|
|
44
|
+
* "elements": {
|
|
45
|
+
* "card": {
|
|
46
|
+
* "type": "Card",
|
|
47
|
+
* "props": { "title": "Hello" },
|
|
48
|
+
* "children": ["text"]
|
|
49
|
+
* },
|
|
50
|
+
* "text": {
|
|
51
|
+
* "type": "Text",
|
|
52
|
+
* "props": { "content": "World" }
|
|
53
|
+
* }
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* \`\`\`
|
|
57
|
+
* `, {
|
|
58
|
+
* plugins: [jsonRender()]
|
|
59
|
+
* })
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```vue
|
|
64
|
+
* <script setup>
|
|
65
|
+
* import { Comark } from '@comark/vue'
|
|
66
|
+
* import jsonRender from '@comark/vue/plugins/json-render'
|
|
67
|
+
* </script>
|
|
68
|
+
*
|
|
69
|
+
* <template>
|
|
70
|
+
* <Suspense>
|
|
71
|
+
* <Comark :plugins="[jsonRender()]">{{ content }}</Comark>
|
|
72
|
+
* </Suspense>
|
|
73
|
+
* </template>
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export default defineComarkPlugin((_config = {}) => ({
|
|
77
|
+
name: 'json-render',
|
|
78
|
+
post: async (state) => {
|
|
79
|
+
visit(state.tree, node => node[0] === 'pre' && (node[1].language === 'json-render'
|
|
80
|
+
|| node[1].language === 'yaml-render'), (preNode) => {
|
|
81
|
+
const language = preNode[1].language;
|
|
82
|
+
try {
|
|
83
|
+
let spec = undefined;
|
|
84
|
+
if (language === 'json-render') {
|
|
85
|
+
spec = JSON.parse(textContent(preNode));
|
|
86
|
+
}
|
|
87
|
+
else if (language === 'yaml-render') {
|
|
88
|
+
spec = parseYaml(textContent(preNode));
|
|
89
|
+
}
|
|
90
|
+
if (spec) {
|
|
91
|
+
return jsonRenderToAst(spec);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// nothing to do
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "comark",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"description": "Components in Markdown (Comark) parser with streaming support for Vue, React, Svelte and HTML",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"beautiful-mermaid": "^1.1.3",
|
|
44
44
|
"katex": "^0.16.33",
|
|
45
|
-
"shiki": "^
|
|
45
|
+
"shiki": "^4.0.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"shiki": {
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
+
"@json-render/core": "^0.16.0",
|
|
59
60
|
"@nuxt/kit": "^4.4.2",
|
|
60
61
|
"@shikijs/primitive": "^4.0.2",
|
|
61
62
|
"@shikijs/twoslash": "^4.0.2",
|
|
@@ -67,10 +68,10 @@
|
|
|
67
68
|
"mitata": "^1.0.34",
|
|
68
69
|
"tsx": "^4.21.0",
|
|
69
70
|
"twoslash": "^0.3.6",
|
|
70
|
-
"vitest": "^4.1.
|
|
71
|
+
"vitest": "^4.1.4"
|
|
71
72
|
},
|
|
72
73
|
"dependencies": {
|
|
73
|
-
"@comark/markdown-it": "^0.3.
|
|
74
|
+
"@comark/markdown-it": "^0.3.3",
|
|
74
75
|
"entities": "^8.0.0",
|
|
75
76
|
"htmlparser2": "^12.0.0",
|
|
76
77
|
"js-yaml": "^4.1.1",
|