simple-customize-markdown-converter 1.1.0 → 1.2.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/dist/core/lexer/handler.d.ts +23 -0
- package/dist/core/lexer/handler.js +272 -0
- package/dist/core/lexer/index.d.ts +42 -0
- package/dist/core/lexer/index.js +177 -0
- package/dist/core/parser/handler.d.ts +19 -0
- package/dist/core/parser/handler.js +254 -0
- package/dist/core/parser/index.d.ts +33 -0
- package/dist/core/parser/index.js +149 -0
- package/dist/core/resolver/footnote-resolver.d.ts +15 -0
- package/dist/core/resolver/footnote-resolver.js +36 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +4 -4
- package/dist/react.d.ts +3 -6
- package/dist/react.js +5 -5
- package/dist/renderers/default/handler.d.ts +21 -0
- package/dist/renderers/default/handler.js +114 -0
- package/dist/renderers/default/index.d.ts +14 -0
- package/dist/renderers/default/index.js +117 -0
- package/dist/renderers/index.d.ts +10 -0
- package/dist/renderers/index.js +2 -0
- package/dist/renderers/react/handler.d.ts +22 -0
- package/dist/renderers/react/handler.js +123 -0
- package/dist/renderers/react/index.d.ts +15 -0
- package/dist/renderers/react/index.js +123 -0
- package/dist/types/options/converterOptions.d.ts +1 -1
- package/dist/types/options/index.d.ts +5 -12
- package/dist/types/options/renderOptions.d.ts +63 -21
- package/dist/types/parser.d.ts +132 -0
- package/dist/types/parser.js +2 -0
- package/dist/types/renderer.d.ts +12 -0
- package/dist/types/renderer.js +2 -0
- package/dist/types/token.d.ts +94 -74
- package/dist/utilities/parser-utils.d.ts +5 -0
- package/dist/utilities/parser-utils.js +65 -0
- package/dist/utilities/tokenizer-utils.d.ts +11 -0
- package/dist/utilities/tokenizer-utils.js +159 -0
- package/package.json +5 -3
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FootnoteRefHandler = exports.HTMLInlineHandler = exports.HTMLBlockHandler = exports.TableHandler = exports.TextHandler = exports.HorizontalLineHandler = exports.ImageHandler = exports.LinkHandler = exports.InlineCodeHandler = exports.StrikethroughHandler = exports.ItalicHandler = exports.BoldHandler = exports.TaskItemHandler = exports.ListItemHandler = exports.ListHandler = exports.QuoteHandler = exports.HeaderHandler = exports.CodeBlockHandler = exports.ParagraphHandler = exports.DocumentHandler = void 0;
|
|
4
|
+
//Base structural nodes
|
|
5
|
+
exports.DocumentHandler = {
|
|
6
|
+
type: "Document",
|
|
7
|
+
render: (_node, children, ctx) => children.join("") + ctx.renderFootnotes()
|
|
8
|
+
};
|
|
9
|
+
exports.ParagraphHandler = {
|
|
10
|
+
type: "Paragraph",
|
|
11
|
+
render: (_node, children) => `<p>${children.join("")}</p>`
|
|
12
|
+
};
|
|
13
|
+
//Container nodes
|
|
14
|
+
exports.CodeBlockHandler = {
|
|
15
|
+
type: "CodeBlock",
|
|
16
|
+
render: (node) => `<pre><code class="lang-${node.lang}">${escapeHtml(node.content || "")}</code></pre>`,
|
|
17
|
+
};
|
|
18
|
+
exports.HeaderHandler = {
|
|
19
|
+
type: "Header",
|
|
20
|
+
render: (node, children) => {
|
|
21
|
+
if (node.level) {
|
|
22
|
+
const style = node.level <= 2 ? ' style="border-bottom: 1px solid #d1d9e0b3"' : '';
|
|
23
|
+
return `<h${node.level}${style}>${children.join("")}</h${node.level}>`;
|
|
24
|
+
}
|
|
25
|
+
return `<p>${children.join("")}</p>`;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.QuoteHandler = {
|
|
29
|
+
type: "Quote",
|
|
30
|
+
render: (_node, children) => `<blockquote style="margin:0; padding:0 1em; color:#59636e; border-left:.25em solid #d1d9e0;">${children.join("")}</blockquote>`
|
|
31
|
+
};
|
|
32
|
+
//For list nodes
|
|
33
|
+
exports.ListHandler = {
|
|
34
|
+
type: "List",
|
|
35
|
+
render: (node, children) => node.ordered ? `<ol>${children.join("")}</ol>` : `<ul>${children.join("")}</ul>`
|
|
36
|
+
};
|
|
37
|
+
exports.ListItemHandler = {
|
|
38
|
+
type: "ListItem",
|
|
39
|
+
render: (_node, children) => `<li>${children.join("")}</li>`
|
|
40
|
+
};
|
|
41
|
+
exports.TaskItemHandler = {
|
|
42
|
+
type: "TaskItem",
|
|
43
|
+
render: (node, children) => `<li><input type="checkbox" disabled ${node.checked ? "checked" : ""}>${children.join("")}</li>`
|
|
44
|
+
};
|
|
45
|
+
//Styling nodes
|
|
46
|
+
exports.BoldHandler = {
|
|
47
|
+
type: "Bold",
|
|
48
|
+
render: (_node, children) => `<strong>${children.join("")}</strong>`
|
|
49
|
+
};
|
|
50
|
+
exports.ItalicHandler = {
|
|
51
|
+
type: "Italic",
|
|
52
|
+
render: (_node, children) => `<em>${children.join("")}</em>`
|
|
53
|
+
};
|
|
54
|
+
exports.StrikethroughHandler = {
|
|
55
|
+
type: "Strikethrough",
|
|
56
|
+
render: (_node, children) => `<s>${children.join("")}</s>`
|
|
57
|
+
};
|
|
58
|
+
exports.InlineCodeHandler = {
|
|
59
|
+
type: "InlineCode",
|
|
60
|
+
render: (node, _children) => `<code>${escapeHtml(node.content || "")}</code>`
|
|
61
|
+
};
|
|
62
|
+
//Media nodes
|
|
63
|
+
exports.LinkHandler = {
|
|
64
|
+
type: "Link",
|
|
65
|
+
render: (node) => `<a href="${node.href}">${node.text}</a>`
|
|
66
|
+
};
|
|
67
|
+
exports.ImageHandler = {
|
|
68
|
+
type: "Image",
|
|
69
|
+
render: (node) => `<img src="${node.src || ""}" alt="${node.alt || ""}"/>`
|
|
70
|
+
};
|
|
71
|
+
//Leaf nodes
|
|
72
|
+
exports.HorizontalLineHandler = {
|
|
73
|
+
type: "HorizontalLine",
|
|
74
|
+
render: () => `<hr>`
|
|
75
|
+
};
|
|
76
|
+
exports.TextHandler = {
|
|
77
|
+
type: "Text",
|
|
78
|
+
render: (node) => node.value || ""
|
|
79
|
+
};
|
|
80
|
+
//Table nodes
|
|
81
|
+
exports.TableHandler = {
|
|
82
|
+
type: "Table",
|
|
83
|
+
render: (node, children, ctx) => ctx.renderTable(node, children)
|
|
84
|
+
};
|
|
85
|
+
//For HTML
|
|
86
|
+
exports.HTMLBlockHandler = {
|
|
87
|
+
type: "HTMLBlock",
|
|
88
|
+
render: (node, _children, ctx) => {
|
|
89
|
+
const val = node.value || "";
|
|
90
|
+
return ctx.options.converterOptions?.allowDangerousHtml ? val : escapeHtml(val);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
exports.HTMLInlineHandler = {
|
|
94
|
+
type: "HTMLInline",
|
|
95
|
+
render: (node, _children, ctx) => {
|
|
96
|
+
const val = node.value || "";
|
|
97
|
+
return ctx.options.converterOptions?.allowDangerousHtml ? val : escapeHtml(val);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
//For footnote
|
|
101
|
+
exports.FootnoteRefHandler = {
|
|
102
|
+
type: "FootnoteRef",
|
|
103
|
+
render: (node, _children, ctx) => {
|
|
104
|
+
if (node.id) {
|
|
105
|
+
const idx = ctx.footnoteResolver.getUsedRefById(node.id);
|
|
106
|
+
return `<sup id="fnref:${idx}"><a href="#fn:${idx}" class="footnote-ref">[${idx}]</a></sup>`;
|
|
107
|
+
}
|
|
108
|
+
return "";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
//Utilities
|
|
112
|
+
function escapeHtml(str) {
|
|
113
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
114
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IRenderer } from "..";
|
|
2
|
+
import { MarkdownOptions } from "../../types/options";
|
|
3
|
+
import { ASTNode } from "../../types/parser";
|
|
4
|
+
import { FootnoteResolver } from "../../core/resolver/footnote-resolver";
|
|
5
|
+
export declare class DefaultRenderer implements IRenderer<string> {
|
|
6
|
+
options: MarkdownOptions<string>;
|
|
7
|
+
footnoteResolver: FootnoteResolver;
|
|
8
|
+
private strategies;
|
|
9
|
+
constructor(footnoteResolver: FootnoteResolver, options?: MarkdownOptions<string>);
|
|
10
|
+
private registerDefaultStrategies;
|
|
11
|
+
render(node: ASTNode): string;
|
|
12
|
+
renderFootnotes(): string;
|
|
13
|
+
renderTable(node: ASTNode, children: string[]): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DefaultRenderer = void 0;
|
|
37
|
+
const Handlers = __importStar(require("./handler"));
|
|
38
|
+
class DefaultRenderer {
|
|
39
|
+
constructor(footnoteResolver, options = {}) {
|
|
40
|
+
this.strategies = new Map();
|
|
41
|
+
this.footnoteResolver = footnoteResolver;
|
|
42
|
+
this.options = options;
|
|
43
|
+
this.registerDefaultStrategies();
|
|
44
|
+
}
|
|
45
|
+
registerDefaultStrategies() {
|
|
46
|
+
const listDefaultStrategy = [
|
|
47
|
+
Handlers.DocumentHandler,
|
|
48
|
+
Handlers.ParagraphHandler,
|
|
49
|
+
Handlers.HeaderHandler,
|
|
50
|
+
Handlers.CodeBlockHandler,
|
|
51
|
+
Handlers.QuoteHandler,
|
|
52
|
+
Handlers.BoldHandler,
|
|
53
|
+
Handlers.ItalicHandler,
|
|
54
|
+
Handlers.StrikethroughHandler,
|
|
55
|
+
Handlers.InlineCodeHandler,
|
|
56
|
+
Handlers.LinkHandler,
|
|
57
|
+
Handlers.ImageHandler,
|
|
58
|
+
Handlers.ListHandler,
|
|
59
|
+
Handlers.ListItemHandler,
|
|
60
|
+
Handlers.TaskItemHandler,
|
|
61
|
+
Handlers.TableHandler,
|
|
62
|
+
Handlers.TextHandler,
|
|
63
|
+
Handlers.HorizontalLineHandler,
|
|
64
|
+
Handlers.HTMLBlockHandler,
|
|
65
|
+
Handlers.HTMLInlineHandler,
|
|
66
|
+
Handlers.FootnoteRefHandler
|
|
67
|
+
];
|
|
68
|
+
listDefaultStrategy.forEach(s => this.strategies.set(s.type, s));
|
|
69
|
+
}
|
|
70
|
+
render(node) {
|
|
71
|
+
const userRenderer = this.options.renderOptions?.elements?.[node.type];
|
|
72
|
+
const children = (node.children || []).map(child => this.render(child));
|
|
73
|
+
if (userRenderer) {
|
|
74
|
+
return userRenderer(node, children);
|
|
75
|
+
}
|
|
76
|
+
const strategy = this.strategies.get(node.type);
|
|
77
|
+
if (strategy) {
|
|
78
|
+
return strategy.render(node, children, this);
|
|
79
|
+
}
|
|
80
|
+
return children.join("");
|
|
81
|
+
}
|
|
82
|
+
renderFootnotes() {
|
|
83
|
+
if (this.footnoteResolver.isResolverValid()) {
|
|
84
|
+
const used = this.footnoteResolver.getUsedRef();
|
|
85
|
+
if (used.length === 0)
|
|
86
|
+
return "";
|
|
87
|
+
const items = used.map((id, i) => {
|
|
88
|
+
const def = this.footnoteResolver.getDef(id) ?? "";
|
|
89
|
+
const idx = i + 1;
|
|
90
|
+
return `<li id="fn:${idx}"><p>${def} <a href="#fnref:${idx}" class="footnote-backref">↩</a></p></li>`;
|
|
91
|
+
});
|
|
92
|
+
return `<section class="footnotes"><ol>${items.join("")}</ol></section>`;
|
|
93
|
+
}
|
|
94
|
+
else
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
renderTable(node, children) {
|
|
98
|
+
if (node.type === "Table" && node.rows) {
|
|
99
|
+
const header = node.rows.filter(row => row.isHeader);
|
|
100
|
+
const body = node.rows.filter(row => !row.isHeader);
|
|
101
|
+
const renderRows = (row) => {
|
|
102
|
+
const tag = row.isHeader ? "th" : "td";
|
|
103
|
+
const cells = row.cells.map(cell => {
|
|
104
|
+
const align = `style="text-align:${cell.align}"`;
|
|
105
|
+
return `<${tag} ${align}>${cell.children.map(c => this.render(c)).join("")}</${tag}>`;
|
|
106
|
+
}).join("");
|
|
107
|
+
return `<tr>${cells}</tr>`;
|
|
108
|
+
};
|
|
109
|
+
const tHead = header.length ? `<thead>${header.map(renderRows).join("")}</thead>` : "";
|
|
110
|
+
const tBody = body.length ? `<tbody>${body.map(renderRows).join("")}</tbody>` : "";
|
|
111
|
+
return `<table>${tHead}${tBody}</table>`;
|
|
112
|
+
}
|
|
113
|
+
else
|
|
114
|
+
return `<p>${children.join("\n")}</p>`;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.DefaultRenderer = DefaultRenderer;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ASTNode } from "../types/parser";
|
|
2
|
+
import { MarkdownOptions } from '../types/options/index';
|
|
3
|
+
import { FootnoteResolver } from "../core/resolver/footnote-resolver";
|
|
4
|
+
export interface IRenderer<TOutput> {
|
|
5
|
+
options: MarkdownOptions<TOutput>;
|
|
6
|
+
footnoteResolver: FootnoteResolver;
|
|
7
|
+
render(node: ASTNode): TOutput;
|
|
8
|
+
renderTable(node: ASTNode, children: TOutput[]): TOutput;
|
|
9
|
+
renderFootnotes(): TOutput;
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { RenderStrategy } from "../../types/renderer";
|
|
3
|
+
export declare const DocumentHandler: RenderStrategy<ReactNode>;
|
|
4
|
+
export declare const ParagraphHandler: RenderStrategy<ReactNode>;
|
|
5
|
+
export declare const CodeBlockHandler: RenderStrategy<ReactNode>;
|
|
6
|
+
export declare const HeaderHandler: RenderStrategy<ReactNode>;
|
|
7
|
+
export declare const QuoteHandler: RenderStrategy<ReactNode>;
|
|
8
|
+
export declare const ListHandler: RenderStrategy<ReactNode>;
|
|
9
|
+
export declare const ListItemHandler: RenderStrategy<ReactNode>;
|
|
10
|
+
export declare const TaskItemHandler: RenderStrategy<ReactNode>;
|
|
11
|
+
export declare const BoldHandler: RenderStrategy<ReactNode>;
|
|
12
|
+
export declare const ItalicHandler: RenderStrategy<ReactNode>;
|
|
13
|
+
export declare const StrikethroughHandler: RenderStrategy<ReactNode>;
|
|
14
|
+
export declare const InlineCodeHandler: RenderStrategy<ReactNode>;
|
|
15
|
+
export declare const LinkHandler: RenderStrategy<ReactNode>;
|
|
16
|
+
export declare const ImageHandler: RenderStrategy<ReactNode>;
|
|
17
|
+
export declare const HorizontalLineHandler: RenderStrategy<ReactNode>;
|
|
18
|
+
export declare const TextHandler: RenderStrategy<ReactNode>;
|
|
19
|
+
export declare const TableHandler: RenderStrategy<ReactNode>;
|
|
20
|
+
export declare const HTMLBlockHandler: RenderStrategy<ReactNode>;
|
|
21
|
+
export declare const HTMLInlineHandler: RenderStrategy<ReactNode>;
|
|
22
|
+
export declare const FootnoteRefHandler: RenderStrategy<ReactNode>;
|
|
@@ -0,0 +1,123 @@
|
|
|
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.FootnoteRefHandler = exports.HTMLInlineHandler = exports.HTMLBlockHandler = exports.TableHandler = exports.TextHandler = exports.HorizontalLineHandler = exports.ImageHandler = exports.LinkHandler = exports.InlineCodeHandler = exports.StrikethroughHandler = exports.ItalicHandler = exports.BoldHandler = exports.TaskItemHandler = exports.ListItemHandler = exports.ListHandler = exports.QuoteHandler = exports.HeaderHandler = exports.CodeBlockHandler = exports.ParagraphHandler = exports.DocumentHandler = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
//Base structural nodes
|
|
9
|
+
exports.DocumentHandler = {
|
|
10
|
+
type: "Document",
|
|
11
|
+
render: (_node, children, ctx) => react_1.default.createElement(react_1.default.Fragment, null, ...children, ctx.renderFootnotes())
|
|
12
|
+
};
|
|
13
|
+
exports.ParagraphHandler = {
|
|
14
|
+
type: "Paragraph",
|
|
15
|
+
render: (_node, children) => react_1.default.createElement("p", null, ...children)
|
|
16
|
+
};
|
|
17
|
+
//Container nodes
|
|
18
|
+
exports.CodeBlockHandler = {
|
|
19
|
+
type: "CodeBlock",
|
|
20
|
+
render: (node) => react_1.default.createElement("pre", null, react_1.default.createElement("code", { className: `lang-${node.lang}` }, node.content || ""))
|
|
21
|
+
};
|
|
22
|
+
exports.HeaderHandler = {
|
|
23
|
+
type: "Header",
|
|
24
|
+
render: (node, children) => {
|
|
25
|
+
if (!node.level)
|
|
26
|
+
return react_1.default.createElement("p", null, ...children);
|
|
27
|
+
return react_1.default.createElement(`h${node.level}`, { style: { borderBottom: node.level <= 2 ? "1px solid #d1d9e0b3" : undefined } }, ...children);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.QuoteHandler = {
|
|
31
|
+
type: "Quote",
|
|
32
|
+
render: (_node, children) => react_1.default.createElement("blockquote", { style: { margin: "0", padding: "0 1em", color: "#59636e", borderLeft: ".25em solid #d1d9e0" } }, ...children)
|
|
33
|
+
};
|
|
34
|
+
//For list nodes
|
|
35
|
+
exports.ListHandler = {
|
|
36
|
+
type: "List",
|
|
37
|
+
render: (node, children) => react_1.default.createElement(node.ordered ? "ol" : "ul", null, ...children)
|
|
38
|
+
};
|
|
39
|
+
exports.ListItemHandler = {
|
|
40
|
+
type: "ListItem",
|
|
41
|
+
render: (_node, children) => react_1.default.createElement("li", null, ...children)
|
|
42
|
+
};
|
|
43
|
+
exports.TaskItemHandler = {
|
|
44
|
+
type: "TaskItem",
|
|
45
|
+
render: (node, children) => react_1.default.createElement("li", { style: { listStyleType: "none" } }, react_1.default.createElement("input", {
|
|
46
|
+
type: "checkbox",
|
|
47
|
+
disabled: true,
|
|
48
|
+
checked: !!node.checked,
|
|
49
|
+
readOnly: true
|
|
50
|
+
}), ...children)
|
|
51
|
+
};
|
|
52
|
+
//Styling nodes
|
|
53
|
+
exports.BoldHandler = {
|
|
54
|
+
type: "Bold",
|
|
55
|
+
render: (_node, children) => react_1.default.createElement("strong", null, ...children)
|
|
56
|
+
};
|
|
57
|
+
exports.ItalicHandler = {
|
|
58
|
+
type: "Italic",
|
|
59
|
+
render: (_node, children) => react_1.default.createElement("em", null, ...children)
|
|
60
|
+
};
|
|
61
|
+
exports.StrikethroughHandler = {
|
|
62
|
+
type: "Strikethrough",
|
|
63
|
+
render: (_node, children) => react_1.default.createElement("s", null, ...children)
|
|
64
|
+
};
|
|
65
|
+
exports.InlineCodeHandler = {
|
|
66
|
+
type: "InlineCode",
|
|
67
|
+
render: (node) => react_1.default.createElement("code", null, node.content || "")
|
|
68
|
+
};
|
|
69
|
+
//Media nodes
|
|
70
|
+
exports.LinkHandler = {
|
|
71
|
+
type: "Link",
|
|
72
|
+
render: (node) => react_1.default.createElement("a", { href: node.href, target: "_blank", rel: "noopener" }, node.text)
|
|
73
|
+
};
|
|
74
|
+
exports.ImageHandler = {
|
|
75
|
+
type: "Image",
|
|
76
|
+
render: (node) => react_1.default.createElement("img", {
|
|
77
|
+
src: node.src || "",
|
|
78
|
+
alt: node.alt || ""
|
|
79
|
+
})
|
|
80
|
+
};
|
|
81
|
+
//Leaf nodes
|
|
82
|
+
exports.HorizontalLineHandler = {
|
|
83
|
+
type: "HorizontalLine",
|
|
84
|
+
render: () => react_1.default.createElement("hr")
|
|
85
|
+
};
|
|
86
|
+
exports.TextHandler = {
|
|
87
|
+
type: "Text",
|
|
88
|
+
render: (node) => node.value || ""
|
|
89
|
+
};
|
|
90
|
+
//Table nodes
|
|
91
|
+
exports.TableHandler = {
|
|
92
|
+
type: "Table",
|
|
93
|
+
render: (node, children, ctx) => ctx.renderTable(node, children)
|
|
94
|
+
};
|
|
95
|
+
//For HTML
|
|
96
|
+
exports.HTMLBlockHandler = {
|
|
97
|
+
type: "HTMLBlock",
|
|
98
|
+
render: (node, _children, ctx) => {
|
|
99
|
+
const val = node.value || "";
|
|
100
|
+
return ctx.options.converterOptions?.allowDangerousHtml
|
|
101
|
+
? react_1.default.createElement("div", { dangerouslySetInnerHTML: { __html: val } })
|
|
102
|
+
: react_1.default.createElement("code", null, val);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
exports.HTMLInlineHandler = {
|
|
106
|
+
type: "HTMLInline",
|
|
107
|
+
render: (node, _children, ctx) => {
|
|
108
|
+
const val = node.value || "";
|
|
109
|
+
return ctx.options.converterOptions?.allowDangerousHtml
|
|
110
|
+
? react_1.default.createElement("span", { dangerouslySetInnerHTML: { __html: val } })
|
|
111
|
+
: react_1.default.createElement("code", null, val);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
//For footnote
|
|
115
|
+
exports.FootnoteRefHandler = {
|
|
116
|
+
type: "FootnoteRef",
|
|
117
|
+
render: (node, _children, ctx) => {
|
|
118
|
+
if (!node.id)
|
|
119
|
+
return null;
|
|
120
|
+
const idx = ctx.footnoteResolver.getUsedRefById(node.id);
|
|
121
|
+
return react_1.default.createElement("sup", { id: `fnref:${idx}` }, react_1.default.createElement("a", { href: `#fn:${idx}`, className: "footnote-ref" }, `[${idx}]`));
|
|
122
|
+
}
|
|
123
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { IRenderer } from "..";
|
|
3
|
+
import { MarkdownOptions } from "../../types/options";
|
|
4
|
+
import { ASTNode } from "../../types/parser";
|
|
5
|
+
import { FootnoteResolver } from "../../core/resolver/footnote-resolver";
|
|
6
|
+
export declare class ReactRenderer implements IRenderer<React.ReactNode> {
|
|
7
|
+
options: MarkdownOptions<React.ReactNode>;
|
|
8
|
+
footnoteResolver: FootnoteResolver;
|
|
9
|
+
private strategies;
|
|
10
|
+
constructor(footnoteResolver: FootnoteResolver, options?: MarkdownOptions<React.ReactNode>);
|
|
11
|
+
private registerDefaultStrategies;
|
|
12
|
+
render(node: ASTNode): React.ReactNode;
|
|
13
|
+
renderFootnotes(): React.ReactNode;
|
|
14
|
+
renderTable(node: ASTNode, children: React.ReactNode[]): React.ReactNode;
|
|
15
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ReactRenderer = void 0;
|
|
40
|
+
const react_1 = __importDefault(require("react"));
|
|
41
|
+
const Handlers = __importStar(require("./handler"));
|
|
42
|
+
class ReactRenderer {
|
|
43
|
+
constructor(footnoteResolver, options = {}) {
|
|
44
|
+
this.strategies = new Map();
|
|
45
|
+
this.footnoteResolver = footnoteResolver;
|
|
46
|
+
this.options = options;
|
|
47
|
+
this.registerDefaultStrategies();
|
|
48
|
+
}
|
|
49
|
+
registerDefaultStrategies() {
|
|
50
|
+
const listDefaultStrategy = [
|
|
51
|
+
Handlers.DocumentHandler,
|
|
52
|
+
Handlers.ParagraphHandler,
|
|
53
|
+
Handlers.HeaderHandler,
|
|
54
|
+
Handlers.CodeBlockHandler,
|
|
55
|
+
Handlers.QuoteHandler,
|
|
56
|
+
Handlers.BoldHandler,
|
|
57
|
+
Handlers.ItalicHandler,
|
|
58
|
+
Handlers.StrikethroughHandler,
|
|
59
|
+
Handlers.InlineCodeHandler,
|
|
60
|
+
Handlers.LinkHandler,
|
|
61
|
+
Handlers.ImageHandler,
|
|
62
|
+
Handlers.ListHandler,
|
|
63
|
+
Handlers.ListItemHandler,
|
|
64
|
+
Handlers.TaskItemHandler,
|
|
65
|
+
Handlers.TableHandler,
|
|
66
|
+
Handlers.TextHandler,
|
|
67
|
+
Handlers.HorizontalLineHandler,
|
|
68
|
+
Handlers.HTMLBlockHandler,
|
|
69
|
+
Handlers.HTMLInlineHandler,
|
|
70
|
+
Handlers.FootnoteRefHandler
|
|
71
|
+
];
|
|
72
|
+
listDefaultStrategy.forEach(s => this.strategies.set(s.type, s));
|
|
73
|
+
}
|
|
74
|
+
render(node) {
|
|
75
|
+
const userRenderer = this.options.renderOptions?.elements?.[node.type];
|
|
76
|
+
const children = (node.children || []).map(child => this.render(child));
|
|
77
|
+
if (userRenderer) {
|
|
78
|
+
return userRenderer(node, children);
|
|
79
|
+
}
|
|
80
|
+
const strategy = this.strategies.get(node.type);
|
|
81
|
+
if (strategy) {
|
|
82
|
+
return strategy.render(node, children, this);
|
|
83
|
+
}
|
|
84
|
+
return children.join("");
|
|
85
|
+
}
|
|
86
|
+
renderFootnotes() {
|
|
87
|
+
if (this.footnoteResolver.isResolverValid()) {
|
|
88
|
+
const used = this.footnoteResolver.getUsedRef();
|
|
89
|
+
if (used.length === 0)
|
|
90
|
+
return null;
|
|
91
|
+
const items = used.map((id, i) => {
|
|
92
|
+
const def = this.footnoteResolver.getDef(id) ?? "";
|
|
93
|
+
const idx = i + 1;
|
|
94
|
+
return react_1.default.createElement("li", { id: `fn:${idx}` }, react_1.default.createElement("p", null, def + " ", react_1.default.createElement("a", { href: `#fnref:${idx}`, className: "footnote-backref" }, "↩")));
|
|
95
|
+
});
|
|
96
|
+
return react_1.default.createElement("section", { className: "footnotes" }, react_1.default.createElement("ol", null, ...items));
|
|
97
|
+
}
|
|
98
|
+
else
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
renderTable(node, children) {
|
|
102
|
+
if (node.type === "Table" && node.rows) {
|
|
103
|
+
const header = node.rows.filter(row => row.isHeader);
|
|
104
|
+
const body = node.rows.filter(row => !row.isHeader);
|
|
105
|
+
const renderRows = (row, rowIndex) => {
|
|
106
|
+
return react_1.default.createElement("tr", { key: rowIndex }, row.cells.map((cell, cellIndex) => {
|
|
107
|
+
const tag = row.isHeader ? "th" : "td";
|
|
108
|
+
return react_1.default.createElement(tag, { key: cellIndex, style: { textAlign: cell.align } }, ...cell.children.map(c => this.render(c)));
|
|
109
|
+
}));
|
|
110
|
+
};
|
|
111
|
+
const tHead = header.length
|
|
112
|
+
? react_1.default.createElement("thead", null, header.map((row, i) => renderRows(row, i)))
|
|
113
|
+
: null;
|
|
114
|
+
const tBody = body.length
|
|
115
|
+
? react_1.default.createElement("tbody", null, body.map((row, i) => renderRows(row, i)))
|
|
116
|
+
: null;
|
|
117
|
+
return react_1.default.createElement("table", null, tHead, tBody);
|
|
118
|
+
}
|
|
119
|
+
else
|
|
120
|
+
return react_1.default.createElement("p", null, ...children);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.ReactRenderer = ReactRenderer;
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { ConvertOption } from "./converterOptions";
|
|
2
|
-
import {
|
|
3
|
-
import { RenderOption } from "./renderOptions";
|
|
2
|
+
import { RenderOption } from './renderOptions';
|
|
4
3
|
/**
|
|
5
4
|
* General option for rendering Markdown into HTML strings
|
|
5
|
+
* @template TOutput - Output type after rendered
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
8
|
-
renderOptions?: RenderOption
|
|
7
|
+
export interface MarkdownOptions<TOutput> {
|
|
8
|
+
renderOptions?: RenderOption<TOutput>;
|
|
9
9
|
converterOptions?: ConvertOption;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* General option for rendering Markdown into `React.ReactNode` elements
|
|
13
|
-
*/
|
|
14
|
-
export type MarkdownReactOptions = {
|
|
15
|
-
renderOptions?: ReactRenderOption;
|
|
16
|
-
converterOptions?: ConvertOption;
|
|
17
|
-
};
|
|
10
|
+
}
|