@mdsnai/sdk 0.1.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/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/cli/args.d.ts +8 -0
- package/dist/cli/args.js +63 -0
- package/dist/cli/commands/build.d.ts +5 -0
- package/dist/cli/commands/build.js +19 -0
- package/dist/cli/commands/create.d.ts +2 -0
- package/dist/cli/commands/create.js +39 -0
- package/dist/cli/commands/dev.d.ts +10 -0
- package/dist/cli/commands/dev.js +13 -0
- package/dist/cli/commands/start.d.ts +9 -0
- package/dist/cli/commands/start.js +13 -0
- package/dist/cli/entry.d.ts +2 -0
- package/dist/cli/entry.js +8 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +58 -0
- package/dist/core/action/execution.d.ts +4 -0
- package/dist/core/action/execution.js +57 -0
- package/dist/core/action/index.d.ts +2 -0
- package/dist/core/action/index.js +7 -0
- package/dist/core/action/types.d.ts +19 -0
- package/dist/core/action/types.js +2 -0
- package/dist/core/document/frontmatter.d.ts +5 -0
- package/dist/core/document/frontmatter.js +41 -0
- package/dist/core/document/markdown.d.ts +5 -0
- package/dist/core/document/markdown.js +83 -0
- package/dist/core/document/page-definition.d.ts +2 -0
- package/dist/core/document/page-definition.js +24 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +5 -0
- package/dist/core/model/block.d.ts +30 -0
- package/dist/core/model/block.js +2 -0
- package/dist/core/model/document.d.ts +13 -0
- package/dist/core/model/document.js +2 -0
- package/dist/core/model/fragment.d.ts +4 -0
- package/dist/core/model/fragment.js +2 -0
- package/dist/core/model/index.d.ts +5 -0
- package/dist/core/model/index.js +2 -0
- package/dist/core/model/input.d.ts +11 -0
- package/dist/core/model/input.js +2 -0
- package/dist/core/model/schema.d.ts +4 -0
- package/dist/core/model/schema.js +2 -0
- package/dist/core/protocol/mdsn.d.ts +6 -0
- package/dist/core/protocol/mdsn.js +80 -0
- package/dist/core/protocol/statements.d.ts +12 -0
- package/dist/core/protocol/statements.js +140 -0
- package/dist/core/protocol/validation.d.ts +4 -0
- package/dist/core/protocol/validation.js +60 -0
- package/dist/framework/create-framework-app.d.ts +12 -0
- package/dist/framework/create-framework-app.js +11 -0
- package/dist/framework/hosted-app.d.ts +13 -0
- package/dist/framework/hosted-app.js +133 -0
- package/dist/framework/index.d.ts +4 -0
- package/dist/framework/index.js +7 -0
- package/dist/framework/site-app.d.ts +12 -0
- package/dist/framework/site-app.js +146 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +18 -0
- package/dist/server/action-host.d.ts +3 -0
- package/dist/server/action-host.js +8 -0
- package/dist/server/action-runtime.d.ts +8 -0
- package/dist/server/action-runtime.js +81 -0
- package/dist/server/action.d.ts +41 -0
- package/dist/server/action.js +97 -0
- package/dist/server/build.d.ts +10 -0
- package/dist/server/build.js +166 -0
- package/dist/server/config.d.ts +56 -0
- package/dist/server/config.js +42 -0
- package/dist/server/dev.d.ts +48 -0
- package/dist/server/dev.js +90 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.js +16 -0
- package/dist/server/init.d.ts +1 -0
- package/dist/server/init.js +176 -0
- package/dist/server/layout.d.ts +17 -0
- package/dist/server/layout.js +40 -0
- package/dist/server/markdown.d.ts +53 -0
- package/dist/server/markdown.js +76 -0
- package/dist/server/module-loader.d.ts +4 -0
- package/dist/server/module-loader.js +71 -0
- package/dist/server/negotiate.d.ts +3 -0
- package/dist/server/negotiate.js +55 -0
- package/dist/server/page-host.d.ts +21 -0
- package/dist/server/page-host.js +66 -0
- package/dist/server/page-links.d.ts +10 -0
- package/dist/server/page-links.js +80 -0
- package/dist/server/route-matcher.d.ts +6 -0
- package/dist/server/route-matcher.js +73 -0
- package/dist/server/routes.d.ts +6 -0
- package/dist/server/routes.js +73 -0
- package/dist/server/server.d.ts +27 -0
- package/dist/server/server.js +152 -0
- package/dist/server/site.d.ts +11 -0
- package/dist/server/site.js +59 -0
- package/dist/server/targets.d.ts +7 -0
- package/dist/server/targets.js +21 -0
- package/dist/web/block-runtime.d.ts +2 -0
- package/dist/web/block-runtime.js +27 -0
- package/dist/web/fragment-render.d.ts +10 -0
- package/dist/web/fragment-render.js +59 -0
- package/dist/web/headless.d.ts +95 -0
- package/dist/web/headless.js +370 -0
- package/dist/web/i18n.d.ts +31 -0
- package/dist/web/i18n.js +69 -0
- package/dist/web/index.d.ts +11 -0
- package/dist/web/index.js +22 -0
- package/dist/web/navigation.d.ts +3 -0
- package/dist/web/navigation.js +32 -0
- package/dist/web/page-bootstrap.d.ts +6 -0
- package/dist/web/page-bootstrap.js +29 -0
- package/dist/web/page-client-runtime.d.ts +15 -0
- package/dist/web/page-client-runtime.js +22 -0
- package/dist/web/page-client-script.d.ts +2 -0
- package/dist/web/page-client-script.js +567 -0
- package/dist/web/page-html.d.ts +8 -0
- package/dist/web/page-html.js +49 -0
- package/dist/web/page-render.d.ts +20 -0
- package/dist/web/page-render.js +92 -0
- package/dist/web/public-client-runtime.d.ts +1 -0
- package/dist/web/public-client-runtime.js +5 -0
- package/dist/web/public-render.d.ts +12 -0
- package/dist/web/public-render.js +18 -0
- package/dist/web/target-path.d.ts +1 -0
- package/dist/web/target-path.js +35 -0
- package/package.json +91 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseFrameworkTarget = parseFrameworkTarget;
|
|
4
|
+
exports.isActionTarget = isActionTarget;
|
|
5
|
+
function parseFrameworkTarget(target) {
|
|
6
|
+
if (!target || /\.md$/i.test(target) || /^https?:\/\//i.test(target)) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const actionPath = target.replace(/^\/+/, "");
|
|
10
|
+
if (!actionPath) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
kind: "action",
|
|
15
|
+
target,
|
|
16
|
+
actionPath,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function isActionTarget(target) {
|
|
20
|
+
return parseFrameworkTarget(target) !== null;
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBlockRegionMarkup = createBlockRegionMarkup;
|
|
4
|
+
exports.replaceBlockRegionMarkup = replaceBlockRegionMarkup;
|
|
5
|
+
function escapeHtml(value) {
|
|
6
|
+
return value
|
|
7
|
+
.replace(/&/g, "&")
|
|
8
|
+
.replace(/</g, "<")
|
|
9
|
+
.replace(/>/g, ">")
|
|
10
|
+
.replace(/"/g, """)
|
|
11
|
+
.replace(/'/g, "'");
|
|
12
|
+
}
|
|
13
|
+
function createRegionMarker(kind, blockName) {
|
|
14
|
+
return `<!--mdsn:block-region:${kind}:${escapeHtml(blockName)}-->`;
|
|
15
|
+
}
|
|
16
|
+
function createBlockRegionMarkup(blockName, innerHtml) {
|
|
17
|
+
return `${createRegionMarker("start", blockName)}<section class="mdsn-block-region" data-mdsn-block-region="${escapeHtml(blockName)}">${innerHtml}</section>${createRegionMarker("end", blockName)}`;
|
|
18
|
+
}
|
|
19
|
+
function replaceBlockRegionMarkup(html, blockName, replacementInnerHtml) {
|
|
20
|
+
const escapedName = escapeHtml(blockName).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
+
const pattern = new RegExp(`<!--mdsn:block-region:start:${escapedName}-->[\\s\\S]*?<!--mdsn:block-region:end:${escapedName}-->`, "g");
|
|
22
|
+
if (pattern.test(html)) {
|
|
23
|
+
return html.replace(pattern, createBlockRegionMarkup(blockName, replacementInnerHtml));
|
|
24
|
+
}
|
|
25
|
+
const legacyPattern = new RegExp(`<section class="mdsn-block-region" data-mdsn-block-region="${escapedName}">[\\s\\S]*?<\\/section>`, "g");
|
|
26
|
+
return html.replace(legacyPattern, createBlockRegionMarkup(blockName, replacementInnerHtml));
|
|
27
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BlockDefinition } from "../core/model/block";
|
|
2
|
+
import type { SchemaDefinition } from "../core/model/schema";
|
|
3
|
+
import { type CreatePageRenderOptions } from "./page-render";
|
|
4
|
+
export interface ParsedBlockFragment {
|
|
5
|
+
markdown: string;
|
|
6
|
+
schemas: SchemaDefinition[];
|
|
7
|
+
blocks: BlockDefinition[];
|
|
8
|
+
}
|
|
9
|
+
export declare function parseBlockFragment(raw: string): ParsedBlockFragment;
|
|
10
|
+
export declare function renderBlockFragmentHtml(raw: string, blockName?: string, options?: CreatePageRenderOptions): string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseBlockFragment = parseBlockFragment;
|
|
7
|
+
exports.renderBlockFragmentHtml = renderBlockFragmentHtml;
|
|
8
|
+
const markdown_it_1 = __importDefault(require("markdown-it"));
|
|
9
|
+
const headless_1 = require("./headless");
|
|
10
|
+
const page_render_1 = require("./page-render");
|
|
11
|
+
function escapeHtml(value) {
|
|
12
|
+
return value
|
|
13
|
+
.replace(/&/g, "&")
|
|
14
|
+
.replace(/</g, "<")
|
|
15
|
+
.replace(/>/g, ">")
|
|
16
|
+
.replace(/"/g, """)
|
|
17
|
+
.replace(/'/g, "'");
|
|
18
|
+
}
|
|
19
|
+
function unwrapBlockRegionMarkup(renderedHtml, blockName) {
|
|
20
|
+
const escapedName = escapeHtml(blockName).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
+
const pattern = new RegExp(`<!--mdsn:block-region:start:${escapedName}--><section class="mdsn-block-region" data-mdsn-block-region="${escapedName}">([\\s\\S]*?)<\\/section><!--mdsn:block-region:end:${escapedName}-->`, "gu");
|
|
22
|
+
return renderedHtml.replace(pattern, "$1");
|
|
23
|
+
}
|
|
24
|
+
function parseBlockFragment(raw) {
|
|
25
|
+
const parsed = (0, headless_1.parseFragment)(raw);
|
|
26
|
+
return {
|
|
27
|
+
markdown: parsed.containers.map((container) => container.markdown).join("\n\n").trim(),
|
|
28
|
+
schemas: [],
|
|
29
|
+
blocks: parsed.block ? [parsed.block] : [],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function createMarkdownRenderer(options) {
|
|
33
|
+
return new markdown_it_1.default({
|
|
34
|
+
html: true,
|
|
35
|
+
linkify: options?.linkify ?? true,
|
|
36
|
+
typographer: options?.typographer ?? false,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function renderBlockFragmentHtml(raw, blockName, options) {
|
|
40
|
+
const fragment = (0, headless_1.parseFragment)(raw);
|
|
41
|
+
const effectiveBlockName = blockName ?? fragment.block?.name;
|
|
42
|
+
const renderer = createMarkdownRenderer(options?.markdown);
|
|
43
|
+
const renderedHtml = fragment.segments.map((segment) => {
|
|
44
|
+
if (segment.type === "container") {
|
|
45
|
+
return renderer.render(segment.container.markdown).trimEnd();
|
|
46
|
+
}
|
|
47
|
+
if (!effectiveBlockName) {
|
|
48
|
+
throw new Error("Interactive block fragments require a block name");
|
|
49
|
+
}
|
|
50
|
+
const block = segment.block.name === effectiveBlockName
|
|
51
|
+
? segment.block
|
|
52
|
+
: { ...segment.block, name: effectiveBlockName };
|
|
53
|
+
return (0, page_render_1.renderBlockPanelHtml)(block, options, "plain");
|
|
54
|
+
}).join("");
|
|
55
|
+
if (!fragment.block || !effectiveBlockName) {
|
|
56
|
+
return renderedHtml.trimEnd();
|
|
57
|
+
}
|
|
58
|
+
return unwrapBlockRegionMarkup(renderedHtml, effectiveBlockName).trimEnd();
|
|
59
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { BlockAnchorDefinition, BlockDefinition, DocumentDefinition, FrontmatterData } from "../core";
|
|
2
|
+
export type MarkdownInlineNode = {
|
|
3
|
+
type: "text";
|
|
4
|
+
value: string;
|
|
5
|
+
} | {
|
|
6
|
+
type: "strong";
|
|
7
|
+
children: MarkdownInlineNode[];
|
|
8
|
+
} | {
|
|
9
|
+
type: "em";
|
|
10
|
+
children: MarkdownInlineNode[];
|
|
11
|
+
} | {
|
|
12
|
+
type: "inline_code";
|
|
13
|
+
value: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: "link";
|
|
16
|
+
href: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
children: MarkdownInlineNode[];
|
|
19
|
+
} | {
|
|
20
|
+
type: "image";
|
|
21
|
+
src: string;
|
|
22
|
+
alt: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: "softbreak";
|
|
26
|
+
} | {
|
|
27
|
+
type: "hardbreak";
|
|
28
|
+
} | {
|
|
29
|
+
type: "html_inline";
|
|
30
|
+
value: string;
|
|
31
|
+
};
|
|
32
|
+
export type MarkdownBlockNode = {
|
|
33
|
+
type: "heading";
|
|
34
|
+
depth: number;
|
|
35
|
+
children: MarkdownInlineNode[];
|
|
36
|
+
} | {
|
|
37
|
+
type: "paragraph";
|
|
38
|
+
children: MarkdownInlineNode[];
|
|
39
|
+
} | {
|
|
40
|
+
type: "list";
|
|
41
|
+
ordered: boolean;
|
|
42
|
+
start?: number;
|
|
43
|
+
items: MarkdownBlockNode[][];
|
|
44
|
+
} | {
|
|
45
|
+
type: "blockquote";
|
|
46
|
+
children: MarkdownBlockNode[];
|
|
47
|
+
} | {
|
|
48
|
+
type: "code";
|
|
49
|
+
language?: string;
|
|
50
|
+
value: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: "html";
|
|
53
|
+
value: string;
|
|
54
|
+
} | {
|
|
55
|
+
type: "thematic_break";
|
|
56
|
+
} | {
|
|
57
|
+
type: "table";
|
|
58
|
+
header: MarkdownInlineNode[][];
|
|
59
|
+
rows: MarkdownInlineNode[][][];
|
|
60
|
+
};
|
|
61
|
+
export interface MarkdownContainer {
|
|
62
|
+
id: string;
|
|
63
|
+
markdown: string;
|
|
64
|
+
nodes: MarkdownBlockNode[];
|
|
65
|
+
}
|
|
66
|
+
export type PageStructureSegment = {
|
|
67
|
+
type: "container";
|
|
68
|
+
container: MarkdownContainer;
|
|
69
|
+
} | {
|
|
70
|
+
type: "anchor";
|
|
71
|
+
anchor: BlockAnchorDefinition;
|
|
72
|
+
};
|
|
73
|
+
export type FragmentStructureSegment = {
|
|
74
|
+
type: "container";
|
|
75
|
+
container: MarkdownContainer;
|
|
76
|
+
} | {
|
|
77
|
+
type: "block";
|
|
78
|
+
block: BlockDefinition;
|
|
79
|
+
};
|
|
80
|
+
export interface ParsedPage {
|
|
81
|
+
frontmatter: FrontmatterData;
|
|
82
|
+
containers: MarkdownContainer[];
|
|
83
|
+
anchors: BlockAnchorDefinition[];
|
|
84
|
+
blocks: BlockDefinition[];
|
|
85
|
+
segments: PageStructureSegment[];
|
|
86
|
+
}
|
|
87
|
+
export interface ParsedFragment {
|
|
88
|
+
containers: MarkdownContainer[];
|
|
89
|
+
block?: BlockDefinition;
|
|
90
|
+
segments: FragmentStructureSegment[];
|
|
91
|
+
}
|
|
92
|
+
export declare function parseMarkdown(source: string): MarkdownBlockNode[];
|
|
93
|
+
export declare function parsePage(source: string): ParsedPage;
|
|
94
|
+
export declare function createParsedPage(document: DocumentDefinition): ParsedPage;
|
|
95
|
+
export declare function parseFragment(source: string): ParsedFragment;
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseMarkdown = parseMarkdown;
|
|
7
|
+
exports.parsePage = parsePage;
|
|
8
|
+
exports.createParsedPage = createParsedPage;
|
|
9
|
+
exports.parseFragment = parseFragment;
|
|
10
|
+
const markdown_it_1 = __importDefault(require("markdown-it"));
|
|
11
|
+
const core_1 = require("../core");
|
|
12
|
+
const frontmatter_1 = require("../core/document/frontmatter");
|
|
13
|
+
const mdsn_1 = require("../core/protocol/mdsn");
|
|
14
|
+
function createMarkdownParser() {
|
|
15
|
+
return new markdown_it_1.default({
|
|
16
|
+
html: true,
|
|
17
|
+
linkify: true,
|
|
18
|
+
typographer: false,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function parseInlineNodes(tokens, startIndex = 0, stopType) {
|
|
22
|
+
const nodes = [];
|
|
23
|
+
let index = startIndex;
|
|
24
|
+
while (index < tokens.length) {
|
|
25
|
+
const token = tokens[index];
|
|
26
|
+
if (stopType && token.type === stopType) {
|
|
27
|
+
return [nodes, index];
|
|
28
|
+
}
|
|
29
|
+
switch (token.type) {
|
|
30
|
+
case "text":
|
|
31
|
+
nodes.push({ type: "text", value: token.content });
|
|
32
|
+
index += 1;
|
|
33
|
+
continue;
|
|
34
|
+
case "strong_open": {
|
|
35
|
+
const [children, nextIndex] = parseInlineNodes(tokens, index + 1, "strong_close");
|
|
36
|
+
nodes.push({ type: "strong", children });
|
|
37
|
+
index = nextIndex + 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
case "em_open": {
|
|
41
|
+
const [children, nextIndex] = parseInlineNodes(tokens, index + 1, "em_close");
|
|
42
|
+
nodes.push({ type: "em", children });
|
|
43
|
+
index = nextIndex + 1;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
case "code_inline":
|
|
47
|
+
nodes.push({ type: "inline_code", value: token.content });
|
|
48
|
+
index += 1;
|
|
49
|
+
continue;
|
|
50
|
+
case "link_open": {
|
|
51
|
+
const [children, nextIndex] = parseInlineNodes(tokens, index + 1, "link_close");
|
|
52
|
+
nodes.push({
|
|
53
|
+
type: "link",
|
|
54
|
+
href: token.attrGet("href") ?? "",
|
|
55
|
+
title: token.attrGet("title") ?? undefined,
|
|
56
|
+
children,
|
|
57
|
+
});
|
|
58
|
+
index = nextIndex + 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
case "image":
|
|
62
|
+
nodes.push({
|
|
63
|
+
type: "image",
|
|
64
|
+
src: token.attrGet("src") ?? "",
|
|
65
|
+
alt: token.content,
|
|
66
|
+
title: token.attrGet("title") ?? undefined,
|
|
67
|
+
});
|
|
68
|
+
index += 1;
|
|
69
|
+
continue;
|
|
70
|
+
case "softbreak":
|
|
71
|
+
nodes.push({ type: "softbreak" });
|
|
72
|
+
index += 1;
|
|
73
|
+
continue;
|
|
74
|
+
case "hardbreak":
|
|
75
|
+
nodes.push({ type: "hardbreak" });
|
|
76
|
+
index += 1;
|
|
77
|
+
continue;
|
|
78
|
+
case "html_inline":
|
|
79
|
+
nodes.push({ type: "html_inline", value: token.content });
|
|
80
|
+
index += 1;
|
|
81
|
+
continue;
|
|
82
|
+
default:
|
|
83
|
+
index += 1;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return [nodes, index];
|
|
88
|
+
}
|
|
89
|
+
function parseTable(tokens, startIndex) {
|
|
90
|
+
const header = [];
|
|
91
|
+
const rows = [];
|
|
92
|
+
let index = startIndex + 1;
|
|
93
|
+
let currentRow = null;
|
|
94
|
+
while (index < tokens.length) {
|
|
95
|
+
const token = tokens[index];
|
|
96
|
+
if (token.type === "table_close") {
|
|
97
|
+
return [{ type: "table", header, rows }, index + 1];
|
|
98
|
+
}
|
|
99
|
+
if (token.type === "tr_open") {
|
|
100
|
+
currentRow = [];
|
|
101
|
+
index += 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (token.type === "tr_close") {
|
|
105
|
+
if (currentRow) {
|
|
106
|
+
if (header.length === 0) {
|
|
107
|
+
header.push(...currentRow);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
rows.push(currentRow);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
currentRow = null;
|
|
114
|
+
index += 1;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (token.type === "th_open" || token.type === "td_open") {
|
|
118
|
+
const inlineToken = tokens[index + 1];
|
|
119
|
+
const children = inlineToken?.type === "inline"
|
|
120
|
+
? parseInlineNodes(inlineToken.children ?? [])[0]
|
|
121
|
+
: [];
|
|
122
|
+
currentRow?.push(children);
|
|
123
|
+
index += 3;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
index += 1;
|
|
127
|
+
}
|
|
128
|
+
throw new Error("Unterminated markdown table");
|
|
129
|
+
}
|
|
130
|
+
function parseBlockNodes(tokens, startIndex = 0, stopType) {
|
|
131
|
+
const nodes = [];
|
|
132
|
+
let index = startIndex;
|
|
133
|
+
while (index < tokens.length) {
|
|
134
|
+
const token = tokens[index];
|
|
135
|
+
if (stopType && token.type === stopType) {
|
|
136
|
+
return [nodes, index];
|
|
137
|
+
}
|
|
138
|
+
switch (token.type) {
|
|
139
|
+
case "heading_open": {
|
|
140
|
+
const inlineToken = tokens[index + 1];
|
|
141
|
+
const children = inlineToken?.type === "inline"
|
|
142
|
+
? parseInlineNodes(inlineToken.children ?? [])[0]
|
|
143
|
+
: [];
|
|
144
|
+
nodes.push({
|
|
145
|
+
type: "heading",
|
|
146
|
+
depth: Number(token.tag.slice(1)),
|
|
147
|
+
children,
|
|
148
|
+
});
|
|
149
|
+
index += 3;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
case "paragraph_open": {
|
|
153
|
+
const inlineToken = tokens[index + 1];
|
|
154
|
+
const children = inlineToken?.type === "inline"
|
|
155
|
+
? parseInlineNodes(inlineToken.children ?? [])[0]
|
|
156
|
+
: [];
|
|
157
|
+
nodes.push({ type: "paragraph", children });
|
|
158
|
+
index += 3;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
case "bullet_list_open":
|
|
162
|
+
case "ordered_list_open": {
|
|
163
|
+
const ordered = token.type === "ordered_list_open";
|
|
164
|
+
const closeType = ordered ? "ordered_list_close" : "bullet_list_close";
|
|
165
|
+
const items = [];
|
|
166
|
+
const startValue = token.attrGet("start");
|
|
167
|
+
index += 1;
|
|
168
|
+
while (index < tokens.length && tokens[index]?.type !== closeType) {
|
|
169
|
+
if (tokens[index]?.type !== "list_item_open") {
|
|
170
|
+
index += 1;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const [itemNodes, nextIndex] = parseBlockNodes(tokens, index + 1, "list_item_close");
|
|
174
|
+
items.push(itemNodes);
|
|
175
|
+
index = nextIndex + 1;
|
|
176
|
+
}
|
|
177
|
+
nodes.push({
|
|
178
|
+
type: "list",
|
|
179
|
+
ordered,
|
|
180
|
+
start: ordered && startValue ? Number(startValue) : undefined,
|
|
181
|
+
items,
|
|
182
|
+
});
|
|
183
|
+
index += 1;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
case "blockquote_open": {
|
|
187
|
+
const [children, nextIndex] = parseBlockNodes(tokens, index + 1, "blockquote_close");
|
|
188
|
+
nodes.push({ type: "blockquote", children });
|
|
189
|
+
index = nextIndex + 1;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
case "fence":
|
|
193
|
+
case "code_block":
|
|
194
|
+
nodes.push({
|
|
195
|
+
type: "code",
|
|
196
|
+
language: token.info?.trim() || undefined,
|
|
197
|
+
value: token.content,
|
|
198
|
+
});
|
|
199
|
+
index += 1;
|
|
200
|
+
continue;
|
|
201
|
+
case "html_block":
|
|
202
|
+
nodes.push({ type: "html", value: token.content });
|
|
203
|
+
index += 1;
|
|
204
|
+
continue;
|
|
205
|
+
case "hr":
|
|
206
|
+
nodes.push({ type: "thematic_break" });
|
|
207
|
+
index += 1;
|
|
208
|
+
continue;
|
|
209
|
+
case "table_open": {
|
|
210
|
+
const [tableNode, nextIndex] = parseTable(tokens, index);
|
|
211
|
+
nodes.push(tableNode);
|
|
212
|
+
index = nextIndex;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
index += 1;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return [nodes, index];
|
|
221
|
+
}
|
|
222
|
+
function parseMarkdownContainer(markdown, id) {
|
|
223
|
+
return {
|
|
224
|
+
id,
|
|
225
|
+
markdown,
|
|
226
|
+
nodes: parseMarkdown(markdown),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function splitMarkdownByAnchors(markdown) {
|
|
230
|
+
const containers = [];
|
|
231
|
+
const anchors = [];
|
|
232
|
+
const segments = [];
|
|
233
|
+
const lines = markdown.split(/\r?\n/);
|
|
234
|
+
let activeFence = false;
|
|
235
|
+
let currentLines = [];
|
|
236
|
+
const pushContainer = () => {
|
|
237
|
+
const containerMarkdown = currentLines.join("\n").trim();
|
|
238
|
+
currentLines = [];
|
|
239
|
+
if (!containerMarkdown) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const container = parseMarkdownContainer(containerMarkdown, `container-${containers.length}`);
|
|
243
|
+
containers.push(container);
|
|
244
|
+
segments.push({ type: "container", container });
|
|
245
|
+
};
|
|
246
|
+
for (const line of lines) {
|
|
247
|
+
const trimmed = line.trim();
|
|
248
|
+
if (trimmed.startsWith("```") || trimmed.startsWith("~~~")) {
|
|
249
|
+
activeFence = !activeFence;
|
|
250
|
+
currentLines.push(line);
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (!activeFence) {
|
|
254
|
+
const anchorMatch = trimmed.match(/^<!--\s*mdsn:block\s+([a-zA-Z_][\w-]*)\s*-->$/);
|
|
255
|
+
if (anchorMatch) {
|
|
256
|
+
pushContainer();
|
|
257
|
+
const anchor = { name: anchorMatch[1] };
|
|
258
|
+
anchors.push(anchor);
|
|
259
|
+
segments.push({ type: "anchor", anchor });
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
currentLines.push(line);
|
|
264
|
+
}
|
|
265
|
+
pushContainer();
|
|
266
|
+
return { containers, anchors, segments };
|
|
267
|
+
}
|
|
268
|
+
function splitFragmentSource(markdown) {
|
|
269
|
+
const segments = [];
|
|
270
|
+
const lines = markdown.split(/\r?\n/);
|
|
271
|
+
let activeFence = null;
|
|
272
|
+
let currentMarkdownLines = [];
|
|
273
|
+
let index = 0;
|
|
274
|
+
const pushMarkdownSegment = () => {
|
|
275
|
+
const segmentMarkdown = currentMarkdownLines.join("\n").trim();
|
|
276
|
+
currentMarkdownLines = [];
|
|
277
|
+
if (!segmentMarkdown) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
segments.push({ type: "markdown", markdown: segmentMarkdown });
|
|
281
|
+
};
|
|
282
|
+
while (index < lines.length) {
|
|
283
|
+
const line = lines[index] ?? "";
|
|
284
|
+
const trimmed = line.trim();
|
|
285
|
+
const fenceMatch = trimmed.match(/^(`{3,}|~{3,})(.*)$/);
|
|
286
|
+
if (fenceMatch) {
|
|
287
|
+
const marker = fenceMatch[1];
|
|
288
|
+
const info = fenceMatch[2].trim();
|
|
289
|
+
if (activeFence) {
|
|
290
|
+
if (trimmed === activeFence) {
|
|
291
|
+
activeFence = null;
|
|
292
|
+
}
|
|
293
|
+
currentMarkdownLines.push(line);
|
|
294
|
+
index += 1;
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (marker === "```" && info === "mdsn") {
|
|
298
|
+
pushMarkdownSegment();
|
|
299
|
+
index += 1;
|
|
300
|
+
const blockLines = [];
|
|
301
|
+
while (index < lines.length && lines[index]?.trim() !== "```") {
|
|
302
|
+
blockLines.push(lines[index] ?? "");
|
|
303
|
+
index += 1;
|
|
304
|
+
}
|
|
305
|
+
if (index >= lines.length) {
|
|
306
|
+
throw new Error("Unterminated mdsn code block");
|
|
307
|
+
}
|
|
308
|
+
segments.push({ type: "mdsn", source: blockLines.join("\n") });
|
|
309
|
+
index += 1;
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
activeFence = marker;
|
|
313
|
+
currentMarkdownLines.push(line);
|
|
314
|
+
index += 1;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
currentMarkdownLines.push(line);
|
|
318
|
+
index += 1;
|
|
319
|
+
}
|
|
320
|
+
pushMarkdownSegment();
|
|
321
|
+
return segments;
|
|
322
|
+
}
|
|
323
|
+
function parseMarkdown(source) {
|
|
324
|
+
const parser = createMarkdownParser();
|
|
325
|
+
const tokens = parser.parse(source, {});
|
|
326
|
+
return parseBlockNodes(tokens)[0];
|
|
327
|
+
}
|
|
328
|
+
function parsePage(source) {
|
|
329
|
+
const document = (0, core_1.parsePageDefinition)(source);
|
|
330
|
+
return createParsedPage(document);
|
|
331
|
+
}
|
|
332
|
+
function createParsedPage(document) {
|
|
333
|
+
const structure = splitMarkdownByAnchors(document.markdown);
|
|
334
|
+
return {
|
|
335
|
+
frontmatter: document.frontmatter,
|
|
336
|
+
containers: structure.containers,
|
|
337
|
+
anchors: structure.anchors,
|
|
338
|
+
blocks: document.blocks,
|
|
339
|
+
segments: structure.segments,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
function parseFragment(source) {
|
|
343
|
+
const { body } = (0, frontmatter_1.parseFrontmatter)(source);
|
|
344
|
+
const sourceSegments = splitFragmentSource(body);
|
|
345
|
+
const mdsnSegments = sourceSegments.filter((segment) => segment.type === "mdsn");
|
|
346
|
+
if (mdsnSegments.length > 1) {
|
|
347
|
+
throw new Error("A block fragment may contain at most one mdsn code block");
|
|
348
|
+
}
|
|
349
|
+
const parsedBlock = mdsnSegments.length > 0
|
|
350
|
+
? (0, mdsn_1.parseMdsnBlocks)([mdsnSegments[0].source]).blocks[0]
|
|
351
|
+
: undefined;
|
|
352
|
+
const containers = [];
|
|
353
|
+
const segments = [];
|
|
354
|
+
for (const segment of sourceSegments) {
|
|
355
|
+
if (segment.type === "markdown") {
|
|
356
|
+
const container = parseMarkdownContainer(segment.markdown, `container-${containers.length}`);
|
|
357
|
+
containers.push(container);
|
|
358
|
+
segments.push({ type: "container", container });
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (parsedBlock) {
|
|
362
|
+
segments.push({ type: "block", block: parsedBlock });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
containers,
|
|
367
|
+
block: parsedBlock,
|
|
368
|
+
segments,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type WebRuntimeLocale = "en" | "zh";
|
|
2
|
+
export type WebRuntimeMessages = {
|
|
3
|
+
chooseOption: string;
|
|
4
|
+
inputSectionTitle: string;
|
|
5
|
+
readSectionTitle: string;
|
|
6
|
+
writeSectionTitle: string;
|
|
7
|
+
sourceLabel: string;
|
|
8
|
+
viewRawMarkdownLink: string;
|
|
9
|
+
pageReadyStatus: string;
|
|
10
|
+
emptyBlock: string;
|
|
11
|
+
emptyList: string;
|
|
12
|
+
emptyImage: string;
|
|
13
|
+
imageAltFallback: string;
|
|
14
|
+
listItemFallback: string;
|
|
15
|
+
jsonInputEmpty: string;
|
|
16
|
+
jsonInputInvalid: string;
|
|
17
|
+
missingInput: string;
|
|
18
|
+
fillRequired: string;
|
|
19
|
+
operationRunning: string;
|
|
20
|
+
operationFailed: string;
|
|
21
|
+
operationSuccess: string;
|
|
22
|
+
networkError: string;
|
|
23
|
+
dependencyChainInterrupted: string;
|
|
24
|
+
blockErrorState: string;
|
|
25
|
+
dependencyNotReady: string;
|
|
26
|
+
unknownError: string;
|
|
27
|
+
};
|
|
28
|
+
export declare const WEB_RUNTIME_MESSAGES: Record<WebRuntimeLocale, WebRuntimeMessages>;
|
|
29
|
+
export declare const DEFAULT_WEB_RUNTIME_LOCALE: WebRuntimeLocale;
|
|
30
|
+
export declare function resolveWebRuntimeLocale(input?: string | null): WebRuntimeLocale;
|
|
31
|
+
export declare function getWebRuntimeMessages(input?: string | null): WebRuntimeMessages;
|
package/dist/web/i18n.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_WEB_RUNTIME_LOCALE = exports.WEB_RUNTIME_MESSAGES = void 0;
|
|
4
|
+
exports.resolveWebRuntimeLocale = resolveWebRuntimeLocale;
|
|
5
|
+
exports.getWebRuntimeMessages = getWebRuntimeMessages;
|
|
6
|
+
exports.WEB_RUNTIME_MESSAGES = {
|
|
7
|
+
en: {
|
|
8
|
+
chooseOption: "Please choose",
|
|
9
|
+
inputSectionTitle: "Input",
|
|
10
|
+
readSectionTitle: "Read",
|
|
11
|
+
writeSectionTitle: "Write",
|
|
12
|
+
sourceLabel: "Source",
|
|
13
|
+
viewRawMarkdownLink: "View raw Markdown",
|
|
14
|
+
pageReadyStatus: "Page loaded. Ready for action.",
|
|
15
|
+
emptyBlock: "No content yet.",
|
|
16
|
+
emptyList: "No entries yet.",
|
|
17
|
+
emptyImage: "No image yet.",
|
|
18
|
+
imageAltFallback: "image",
|
|
19
|
+
listItemFallback: "item",
|
|
20
|
+
jsonInputEmpty: "JSON input cannot be empty.",
|
|
21
|
+
jsonInputInvalid: "Invalid JSON input.",
|
|
22
|
+
missingInput: "Missing input: ",
|
|
23
|
+
fillRequired: "Please fill: ",
|
|
24
|
+
operationRunning: "Running: ",
|
|
25
|
+
operationFailed: "Failed: ",
|
|
26
|
+
operationSuccess: "Succeeded: ",
|
|
27
|
+
networkError: "Network error: ",
|
|
28
|
+
dependencyChainInterrupted: "Execution failed, dependency chain interrupted.",
|
|
29
|
+
blockErrorState: "This block is in an error state.",
|
|
30
|
+
dependencyNotReady: "Dependencies not ready: ",
|
|
31
|
+
unknownError: "UNKNOWN_ERROR",
|
|
32
|
+
},
|
|
33
|
+
zh: {
|
|
34
|
+
chooseOption: "请选择",
|
|
35
|
+
inputSectionTitle: "输入",
|
|
36
|
+
readSectionTitle: "读取",
|
|
37
|
+
writeSectionTitle: "写入",
|
|
38
|
+
sourceLabel: "源文件",
|
|
39
|
+
viewRawMarkdownLink: "查看原始 Markdown",
|
|
40
|
+
pageReadyStatus: "页面已加载,等待操作。",
|
|
41
|
+
emptyBlock: "暂无内容。",
|
|
42
|
+
emptyList: "还没有内容。",
|
|
43
|
+
emptyImage: "暂无图片。",
|
|
44
|
+
imageAltFallback: "image",
|
|
45
|
+
listItemFallback: "item",
|
|
46
|
+
jsonInputEmpty: "JSON 输入不能为空。",
|
|
47
|
+
jsonInputInvalid: "JSON 输入格式错误。",
|
|
48
|
+
missingInput: "缺少输入:",
|
|
49
|
+
fillRequired: "请先填写:",
|
|
50
|
+
operationRunning: "执行中:",
|
|
51
|
+
operationFailed: "执行失败:",
|
|
52
|
+
operationSuccess: "执行成功:",
|
|
53
|
+
networkError: "网络错误:",
|
|
54
|
+
dependencyChainInterrupted: "执行失败,依赖链已中断。",
|
|
55
|
+
blockErrorState: "当前 block 已进入错误状态。",
|
|
56
|
+
dependencyNotReady: "依赖未就绪:",
|
|
57
|
+
unknownError: "UNKNOWN_ERROR",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
exports.DEFAULT_WEB_RUNTIME_LOCALE = "en";
|
|
61
|
+
function resolveWebRuntimeLocale(input) {
|
|
62
|
+
if (typeof input !== "string")
|
|
63
|
+
return exports.DEFAULT_WEB_RUNTIME_LOCALE;
|
|
64
|
+
const normalized = input.trim().toLowerCase();
|
|
65
|
+
return normalized.startsWith("zh") ? "zh" : "en";
|
|
66
|
+
}
|
|
67
|
+
function getWebRuntimeMessages(input) {
|
|
68
|
+
return exports.WEB_RUNTIME_MESSAGES[resolveWebRuntimeLocale(input)];
|
|
69
|
+
}
|