simple-customize-markdown-converter 1.2.0 → 1.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/README.md +47 -0
- package/dist/renderers/default/handler.js +67 -22
- package/dist/renderers/default/index.js +4 -2
- package/dist/renderers/react/handler.js +38 -21
- package/dist/renderers/react/index.js +3 -2
- package/dist/types/options/renderOptions.d.ts +10 -3
- package/dist/utilities/renderer-utils.d.ts +4 -0
- package/dist/utilities/renderer-utils.js +20 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -126,6 +126,53 @@ const options: MarkdownReactOptions = {
|
|
|
126
126
|
};
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
+
#### 3. Customize className (v1.2.1+)
|
|
130
|
+
You can custom CSS class name for each elements
|
|
131
|
+
- For HTML
|
|
132
|
+
```ts
|
|
133
|
+
const renderOptions: RenderOption<string> = {
|
|
134
|
+
className: {
|
|
135
|
+
Header: "common-h",
|
|
136
|
+
Header1: "main-title",
|
|
137
|
+
Paragraph: "text-muted"
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const md = "# Title\nParagraph content";
|
|
142
|
+
const result = convertMarkdownToHTML(md, { renderOptions });
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Output:
|
|
146
|
+
```html
|
|
147
|
+
<h1 class="main-title" style="border-bottom: 1px solid #d1d9e0b3">Title</h1>
|
|
148
|
+
<p class="text-muted">Paragraph content</p>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- For ReactJS
|
|
152
|
+
```ts
|
|
153
|
+
import { MarkdownComponent } from 'simple-customize-markdown-converter/react';
|
|
154
|
+
|
|
155
|
+
const options: MarkdownOptions<React.ReactNode> = {
|
|
156
|
+
renderOptions: {
|
|
157
|
+
className: {
|
|
158
|
+
Header: "h-common",
|
|
159
|
+
Header2: "h2-special",
|
|
160
|
+
Bold: "font-heavy"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
function App() {
|
|
166
|
+
return (
|
|
167
|
+
<MarkdownComponent
|
|
168
|
+
content="# Hello React"
|
|
169
|
+
className="md-body"
|
|
170
|
+
options
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
```
|
|
129
176
|
## Security
|
|
130
177
|
By default, HTML tags in Markdown are escaped. To allow raw HTML, explicitly set `allowDangerousHtml: true` in `converterOptions`. Be sure only **enable** this for **trusted** content.
|
|
131
178
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
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
|
+
const renderer_utils_1 = require("../../utilities/renderer-utils");
|
|
4
5
|
//Base structural nodes
|
|
5
6
|
exports.DocumentHandler = {
|
|
6
7
|
type: "Document",
|
|
@@ -8,70 +9,113 @@ exports.DocumentHandler = {
|
|
|
8
9
|
};
|
|
9
10
|
exports.ParagraphHandler = {
|
|
10
11
|
type: "Paragraph",
|
|
11
|
-
render: (
|
|
12
|
+
render: (node, children, ctx) => {
|
|
13
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
14
|
+
return `<p${cls ? ` class="${cls}"` : ""}>${children.join("")}</p>`;
|
|
15
|
+
}
|
|
12
16
|
};
|
|
13
17
|
//Container nodes
|
|
14
18
|
exports.CodeBlockHandler = {
|
|
15
19
|
type: "CodeBlock",
|
|
16
|
-
render: (node) =>
|
|
20
|
+
render: (node, _children, ctx) => {
|
|
21
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node, `lang-${node.lang}`);
|
|
22
|
+
return `<pre><code${cls ? ` class="${cls}"` : ""}>${(0, renderer_utils_1.escapeHtml)(node.content || "")}</code></pre>`;
|
|
23
|
+
}
|
|
17
24
|
};
|
|
18
25
|
exports.HeaderHandler = {
|
|
19
26
|
type: "Header",
|
|
20
|
-
render: (node, children) => {
|
|
27
|
+
render: (node, children, ctx) => {
|
|
21
28
|
if (node.level) {
|
|
29
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
30
|
+
const classAttr = cls ? ` class="${cls}"` : "";
|
|
22
31
|
const style = node.level <= 2 ? ' style="border-bottom: 1px solid #d1d9e0b3"' : '';
|
|
23
|
-
return `<h${node.level}${style}>${children.join("")}</h${node.level}>`;
|
|
32
|
+
return `<h${node.level}${classAttr}${style}>${children.join("")}</h${node.level}>`;
|
|
24
33
|
}
|
|
25
34
|
return `<p>${children.join("")}</p>`;
|
|
26
35
|
}
|
|
27
36
|
};
|
|
28
37
|
exports.QuoteHandler = {
|
|
29
38
|
type: "Quote",
|
|
30
|
-
render: (
|
|
39
|
+
render: (node, children, ctx) => {
|
|
40
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
41
|
+
const classAttr = cls ? ` class="${cls}"` : "";
|
|
42
|
+
return `<blockquote${classAttr} style="margin:0; padding:0 1em; color:#59636e; border-left:.25em solid #d1d9e0;">${children.join("")}</blockquote>`;
|
|
43
|
+
}
|
|
31
44
|
};
|
|
32
45
|
//For list nodes
|
|
33
46
|
exports.ListHandler = {
|
|
34
47
|
type: "List",
|
|
35
|
-
render: (node, children) =>
|
|
48
|
+
render: (node, children, ctx) => {
|
|
49
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
50
|
+
const classAttr = cls ? ` class="${cls}"` : "";
|
|
51
|
+
return node.ordered ? `<ol${classAttr}>${children.join("")}</ol>` : `<ul${classAttr}>${children.join("")}</ul>`;
|
|
52
|
+
}
|
|
36
53
|
};
|
|
37
54
|
exports.ListItemHandler = {
|
|
38
55
|
type: "ListItem",
|
|
39
|
-
render: (
|
|
56
|
+
render: (node, children, ctx) => {
|
|
57
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
58
|
+
return `<li${cls ? ` class="${cls}"` : ""}>${children.join("")}</li>`;
|
|
59
|
+
}
|
|
40
60
|
};
|
|
41
61
|
exports.TaskItemHandler = {
|
|
42
62
|
type: "TaskItem",
|
|
43
|
-
render: (node, children) =>
|
|
63
|
+
render: (node, children, ctx) => {
|
|
64
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
65
|
+
return `<li${cls ? ` class="${cls}"` : ""} style="list-style-type: none"><input type="checkbox" disabled ${node.checked ? "checked" : ""}>${children.join("")}</li>`;
|
|
66
|
+
}
|
|
44
67
|
};
|
|
45
68
|
//Styling nodes
|
|
46
69
|
exports.BoldHandler = {
|
|
47
70
|
type: "Bold",
|
|
48
|
-
render: (
|
|
71
|
+
render: (node, children, ctx) => {
|
|
72
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
73
|
+
return `<strong${cls ? ` class="${cls}"` : ""}>${children.join("")}</strong>`;
|
|
74
|
+
}
|
|
49
75
|
};
|
|
50
76
|
exports.ItalicHandler = {
|
|
51
77
|
type: "Italic",
|
|
52
|
-
render: (
|
|
78
|
+
render: (node, children, ctx) => {
|
|
79
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
80
|
+
return `<em${cls ? ` class="${cls}"` : ""}>${children.join("")}</em>`;
|
|
81
|
+
}
|
|
53
82
|
};
|
|
54
83
|
exports.StrikethroughHandler = {
|
|
55
84
|
type: "Strikethrough",
|
|
56
|
-
render: (
|
|
85
|
+
render: (node, children, ctx) => {
|
|
86
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
87
|
+
return `<s${cls ? ` class="${cls}"` : ""}>${children.join("")}</s>`;
|
|
88
|
+
}
|
|
57
89
|
};
|
|
58
90
|
exports.InlineCodeHandler = {
|
|
59
91
|
type: "InlineCode",
|
|
60
|
-
render: (node, _children) =>
|
|
92
|
+
render: (node, _children, ctx) => {
|
|
93
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
94
|
+
return `<code${cls ? ` class="${cls}"` : ""}>${(0, renderer_utils_1.escapeHtml)(node.content || "")}</code>`;
|
|
95
|
+
}
|
|
61
96
|
};
|
|
62
97
|
//Media nodes
|
|
63
98
|
exports.LinkHandler = {
|
|
64
99
|
type: "Link",
|
|
65
|
-
render: (node) =>
|
|
100
|
+
render: (node, _children, ctx) => {
|
|
101
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
102
|
+
return `<a href="${node.href}"${cls ? ` class="${cls}"` : ""} target="_blank" rel="noopener">${node.text}</a>`;
|
|
103
|
+
}
|
|
66
104
|
};
|
|
67
105
|
exports.ImageHandler = {
|
|
68
106
|
type: "Image",
|
|
69
|
-
render: (node) =>
|
|
107
|
+
render: (node, _children, ctx) => {
|
|
108
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
109
|
+
return `<img src="${node.src || ""}" alt="${node.alt || ""}"${cls ? ` class="${cls}"` : ""}/>`;
|
|
110
|
+
}
|
|
70
111
|
};
|
|
71
112
|
//Leaf nodes
|
|
72
113
|
exports.HorizontalLineHandler = {
|
|
73
114
|
type: "HorizontalLine",
|
|
74
|
-
render: () =>
|
|
115
|
+
render: (node, _children, ctx) => {
|
|
116
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
117
|
+
return `<hr${cls ? ` class="${cls}"` : ""}>`;
|
|
118
|
+
}
|
|
75
119
|
};
|
|
76
120
|
exports.TextHandler = {
|
|
77
121
|
type: "Text",
|
|
@@ -87,14 +131,18 @@ exports.HTMLBlockHandler = {
|
|
|
87
131
|
type: "HTMLBlock",
|
|
88
132
|
render: (node, _children, ctx) => {
|
|
89
133
|
const val = node.value || "";
|
|
90
|
-
|
|
134
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
135
|
+
const content = ctx.options.converterOptions?.allowDangerousHtml ? val : (0, renderer_utils_1.escapeHtml)(val);
|
|
136
|
+
return cls ? `<div${cls ? ` class="${cls}"` : ""}>${content}</div>` : content;
|
|
91
137
|
}
|
|
92
138
|
};
|
|
93
139
|
exports.HTMLInlineHandler = {
|
|
94
140
|
type: "HTMLInline",
|
|
95
141
|
render: (node, _children, ctx) => {
|
|
96
142
|
const val = node.value || "";
|
|
97
|
-
|
|
143
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node);
|
|
144
|
+
const content = ctx.options.converterOptions?.allowDangerousHtml ? val : (0, renderer_utils_1.escapeHtml)(val);
|
|
145
|
+
return cls ? `<span${cls ? ` class="${cls}"` : ""}>${content}</span>` : content;
|
|
98
146
|
}
|
|
99
147
|
};
|
|
100
148
|
//For footnote
|
|
@@ -103,12 +151,9 @@ exports.FootnoteRefHandler = {
|
|
|
103
151
|
render: (node, _children, ctx) => {
|
|
104
152
|
if (node.id) {
|
|
105
153
|
const idx = ctx.footnoteResolver.getUsedRefById(node.id);
|
|
106
|
-
|
|
154
|
+
const cls = (0, renderer_utils_1.getClassName)(ctx, node, "footnote-ref");
|
|
155
|
+
return `<sup id="fnref:${idx}"><a href="#fn:${idx}"${cls ? ` class="${cls}"` : ""}>[${idx}]</a></sup>`;
|
|
107
156
|
}
|
|
108
157
|
return "";
|
|
109
158
|
}
|
|
110
159
|
};
|
|
111
|
-
//Utilities
|
|
112
|
-
function escapeHtml(str) {
|
|
113
|
-
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
114
|
-
}
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.DefaultRenderer = void 0;
|
|
37
37
|
const Handlers = __importStar(require("./handler"));
|
|
38
|
+
const renderer_utils_1 = require("../../utilities/renderer-utils");
|
|
38
39
|
class DefaultRenderer {
|
|
39
40
|
constructor(footnoteResolver, options = {}) {
|
|
40
41
|
this.strategies = new Map();
|
|
@@ -95,6 +96,7 @@ class DefaultRenderer {
|
|
|
95
96
|
return "";
|
|
96
97
|
}
|
|
97
98
|
renderTable(node, children) {
|
|
99
|
+
const cls = (0, renderer_utils_1.getClassName)(this, node);
|
|
98
100
|
if (node.type === "Table" && node.rows) {
|
|
99
101
|
const header = node.rows.filter(row => row.isHeader);
|
|
100
102
|
const body = node.rows.filter(row => !row.isHeader);
|
|
@@ -108,10 +110,10 @@ class DefaultRenderer {
|
|
|
108
110
|
};
|
|
109
111
|
const tHead = header.length ? `<thead>${header.map(renderRows).join("")}</thead>` : "";
|
|
110
112
|
const tBody = body.length ? `<tbody>${body.map(renderRows).join("")}</tbody>` : "";
|
|
111
|
-
return `<table>${tHead}${tBody}</table>`;
|
|
113
|
+
return `<table${cls ? ` class="${cls}"` : ""}>${tHead}${tBody}</table>`;
|
|
112
114
|
}
|
|
113
115
|
else
|
|
114
|
-
return `<p>${children.join("\n")}</p>`;
|
|
116
|
+
return `<p${cls ? ` class="${cls}"` : ""}>${children.join("\n")}</p>`;
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
exports.DefaultRenderer = DefaultRenderer;
|
|
@@ -5,44 +5,54 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
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
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const renderer_utils_1 = require("../../utilities/renderer-utils");
|
|
8
9
|
//Base structural nodes
|
|
9
10
|
exports.DocumentHandler = {
|
|
10
11
|
type: "Document",
|
|
11
|
-
render: (
|
|
12
|
+
render: (node, children, ctx) => react_1.default.createElement(react_1.default.Fragment, null, ...children, ctx.renderFootnotes())
|
|
12
13
|
};
|
|
13
14
|
exports.ParagraphHandler = {
|
|
14
15
|
type: "Paragraph",
|
|
15
|
-
render: (
|
|
16
|
+
render: (node, children, ctx) => react_1.default.createElement("p", { className: (0, renderer_utils_1.getClassName)(ctx, node) }, ...children)
|
|
16
17
|
};
|
|
17
18
|
//Container nodes
|
|
18
19
|
exports.CodeBlockHandler = {
|
|
19
20
|
type: "CodeBlock",
|
|
20
|
-
render: (node) => react_1.default.createElement("pre", null, react_1.default.createElement("code", { className: `lang-${node.lang}` }, node.content || ""))
|
|
21
|
+
render: (node, _children, ctx) => react_1.default.createElement("pre", null, react_1.default.createElement("code", { className: (0, renderer_utils_1.getClassName)(ctx, node, `lang-${node.lang}`) }, node.content || ""))
|
|
21
22
|
};
|
|
22
23
|
exports.HeaderHandler = {
|
|
23
24
|
type: "Header",
|
|
24
|
-
render: (node, children) => {
|
|
25
|
+
render: (node, children, ctx) => {
|
|
25
26
|
if (!node.level)
|
|
26
27
|
return react_1.default.createElement("p", null, ...children);
|
|
27
|
-
return react_1.default.createElement(`h${node.level}`, {
|
|
28
|
+
return react_1.default.createElement(`h${node.level}`, {
|
|
29
|
+
className: (0, renderer_utils_1.getClassName)(ctx, node),
|
|
30
|
+
style: { borderBottom: node.level <= 2 ? "1px solid #d1d9e0b3" : undefined }
|
|
31
|
+
}, ...children);
|
|
28
32
|
}
|
|
29
33
|
};
|
|
30
34
|
exports.QuoteHandler = {
|
|
31
35
|
type: "Quote",
|
|
32
|
-
render: (
|
|
36
|
+
render: (node, children, ctx) => react_1.default.createElement("blockquote", {
|
|
37
|
+
className: (0, renderer_utils_1.getClassName)(ctx, node),
|
|
38
|
+
style: { margin: "0", padding: "0 1em", color: "#59636e", borderLeft: ".25em solid #d1d9e0" }
|
|
39
|
+
}, ...children)
|
|
33
40
|
};
|
|
34
41
|
//For list nodes
|
|
35
42
|
exports.ListHandler = {
|
|
36
43
|
type: "List",
|
|
37
|
-
render: (node, children) => react_1.default.createElement(node.ordered ? "ol" : "ul",
|
|
44
|
+
render: (node, children, ctx) => react_1.default.createElement(node.ordered ? "ol" : "ul", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, ...children)
|
|
38
45
|
};
|
|
39
46
|
exports.ListItemHandler = {
|
|
40
47
|
type: "ListItem",
|
|
41
|
-
render: (
|
|
48
|
+
render: (node, children, ctx) => react_1.default.createElement("li", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, ...children)
|
|
42
49
|
};
|
|
43
50
|
exports.TaskItemHandler = {
|
|
44
51
|
type: "TaskItem",
|
|
45
|
-
render: (node, children) => react_1.default.createElement("li", {
|
|
52
|
+
render: (node, children, ctx) => react_1.default.createElement("li", {
|
|
53
|
+
className: (0, renderer_utils_1.getClassName)(ctx, node),
|
|
54
|
+
style: { listStyleType: "none" }
|
|
55
|
+
}, react_1.default.createElement("input", {
|
|
46
56
|
type: "checkbox",
|
|
47
57
|
disabled: true,
|
|
48
58
|
checked: !!node.checked,
|
|
@@ -52,28 +62,32 @@ exports.TaskItemHandler = {
|
|
|
52
62
|
//Styling nodes
|
|
53
63
|
exports.BoldHandler = {
|
|
54
64
|
type: "Bold",
|
|
55
|
-
render: (
|
|
65
|
+
render: (node, children, ctx) => react_1.default.createElement("strong", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, ...children)
|
|
56
66
|
};
|
|
57
67
|
exports.ItalicHandler = {
|
|
58
68
|
type: "Italic",
|
|
59
|
-
render: (
|
|
69
|
+
render: (node, children, ctx) => react_1.default.createElement("em", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, ...children)
|
|
60
70
|
};
|
|
61
71
|
exports.StrikethroughHandler = {
|
|
62
72
|
type: "Strikethrough",
|
|
63
|
-
render: (
|
|
73
|
+
render: (node, children, ctx) => react_1.default.createElement("s", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, ...children)
|
|
64
74
|
};
|
|
65
75
|
exports.InlineCodeHandler = {
|
|
66
76
|
type: "InlineCode",
|
|
67
|
-
render: (node) => react_1.default.createElement("code",
|
|
77
|
+
render: (node, _children, ctx) => react_1.default.createElement("code", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, node.content || "")
|
|
68
78
|
};
|
|
69
79
|
//Media nodes
|
|
70
80
|
exports.LinkHandler = {
|
|
71
81
|
type: "Link",
|
|
72
|
-
render: (node) => react_1.default.createElement("a", {
|
|
82
|
+
render: (node, _children, ctx) => react_1.default.createElement("a", {
|
|
83
|
+
className: (0, renderer_utils_1.getClassName)(ctx, node),
|
|
84
|
+
href: node.href, target: "_blank", rel: "noopener"
|
|
85
|
+
}, node.text)
|
|
73
86
|
};
|
|
74
87
|
exports.ImageHandler = {
|
|
75
88
|
type: "Image",
|
|
76
|
-
render: (node) => react_1.default.createElement("img", {
|
|
89
|
+
render: (node, _children, ctx) => react_1.default.createElement("img", {
|
|
90
|
+
className: (0, renderer_utils_1.getClassName)(ctx, node),
|
|
77
91
|
src: node.src || "",
|
|
78
92
|
alt: node.alt || ""
|
|
79
93
|
})
|
|
@@ -81,7 +95,7 @@ exports.ImageHandler = {
|
|
|
81
95
|
//Leaf nodes
|
|
82
96
|
exports.HorizontalLineHandler = {
|
|
83
97
|
type: "HorizontalLine",
|
|
84
|
-
render: () => react_1.default.createElement("hr")
|
|
98
|
+
render: (node, _children, ctx) => react_1.default.createElement("hr", { className: (0, renderer_utils_1.getClassName)(ctx, node), })
|
|
85
99
|
};
|
|
86
100
|
exports.TextHandler = {
|
|
87
101
|
type: "Text",
|
|
@@ -98,8 +112,8 @@ exports.HTMLBlockHandler = {
|
|
|
98
112
|
render: (node, _children, ctx) => {
|
|
99
113
|
const val = node.value || "";
|
|
100
114
|
return ctx.options.converterOptions?.allowDangerousHtml
|
|
101
|
-
? react_1.default.createElement("div", { dangerouslySetInnerHTML: { __html: val } })
|
|
102
|
-
: react_1.default.createElement("code",
|
|
115
|
+
? react_1.default.createElement("div", { className: (0, renderer_utils_1.getClassName)(ctx, node), dangerouslySetInnerHTML: { __html: val } })
|
|
116
|
+
: react_1.default.createElement("code", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, val);
|
|
103
117
|
}
|
|
104
118
|
};
|
|
105
119
|
exports.HTMLInlineHandler = {
|
|
@@ -107,8 +121,8 @@ exports.HTMLInlineHandler = {
|
|
|
107
121
|
render: (node, _children, ctx) => {
|
|
108
122
|
const val = node.value || "";
|
|
109
123
|
return ctx.options.converterOptions?.allowDangerousHtml
|
|
110
|
-
? react_1.default.createElement("span", { dangerouslySetInnerHTML: { __html: val } })
|
|
111
|
-
: react_1.default.createElement("code",
|
|
124
|
+
? react_1.default.createElement("span", { className: (0, renderer_utils_1.getClassName)(ctx, node), dangerouslySetInnerHTML: { __html: val } })
|
|
125
|
+
: react_1.default.createElement("code", { className: (0, renderer_utils_1.getClassName)(ctx, node), }, val);
|
|
112
126
|
}
|
|
113
127
|
};
|
|
114
128
|
//For footnote
|
|
@@ -118,6 +132,9 @@ exports.FootnoteRefHandler = {
|
|
|
118
132
|
if (!node.id)
|
|
119
133
|
return null;
|
|
120
134
|
const idx = ctx.footnoteResolver.getUsedRefById(node.id);
|
|
121
|
-
return react_1.default.createElement("sup", { id: `fnref:${idx}` }, react_1.default.createElement("a", {
|
|
135
|
+
return react_1.default.createElement("sup", { id: `fnref:${idx}` }, react_1.default.createElement("a", {
|
|
136
|
+
className: (0, renderer_utils_1.getClassName)(ctx, node, "footnote-ref"),
|
|
137
|
+
href: `#fn:${idx}`,
|
|
138
|
+
}, `[${idx}]`));
|
|
122
139
|
}
|
|
123
140
|
};
|
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.ReactRenderer = void 0;
|
|
40
40
|
const react_1 = __importDefault(require("react"));
|
|
41
41
|
const Handlers = __importStar(require("./handler"));
|
|
42
|
+
const renderer_utils_1 = require("../../utilities/renderer-utils");
|
|
42
43
|
class ReactRenderer {
|
|
43
44
|
constructor(footnoteResolver, options = {}) {
|
|
44
45
|
this.strategies = new Map();
|
|
@@ -114,10 +115,10 @@ class ReactRenderer {
|
|
|
114
115
|
const tBody = body.length
|
|
115
116
|
? react_1.default.createElement("tbody", null, body.map((row, i) => renderRows(row, i)))
|
|
116
117
|
: null;
|
|
117
|
-
return react_1.default.createElement("table",
|
|
118
|
+
return react_1.default.createElement("table", { className: (0, renderer_utils_1.getClassName)(this, node), }, tHead, tBody);
|
|
118
119
|
}
|
|
119
120
|
else
|
|
120
|
-
return react_1.default.createElement("p",
|
|
121
|
+
return react_1.default.createElement("p", { className: (0, renderer_utils_1.getClassName)(this, node), }, ...children);
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
exports.ReactRenderer = ReactRenderer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ASTNode } from '../parser';
|
|
1
|
+
import { ASTNode, NodeType } from '../parser';
|
|
2
2
|
/**
|
|
3
3
|
* A strategy function type for rendering a specific AST node.
|
|
4
4
|
* @template TOutput - The resulting type after rendered.
|
|
@@ -23,8 +23,15 @@ export type GenericRenderElements<TOutput> = {
|
|
|
23
23
|
/**
|
|
24
24
|
* Options for customizing the rendering process for a specific output type.
|
|
25
25
|
* @template TOutput - The output type.
|
|
26
|
+
* @property className - Customize classname for one or more ASTNode types.
|
|
27
|
+
* @property elements - Optional custom rendered for one or more ASTNode types
|
|
26
28
|
*/
|
|
27
29
|
export interface RenderOption<TOutput> {
|
|
30
|
+
/**
|
|
31
|
+
* Use "Header" for all levels
|
|
32
|
+
* Use additional "Header1", "Header2"... "Header6" for specific header level
|
|
33
|
+
*/
|
|
34
|
+
className?: Partial<Record<NodeType | "Header1" | "Header2" | "Header3" | "Header4" | "Header5" | "Header6", string>>;
|
|
28
35
|
elements?: GenericRenderElements<TOutput>;
|
|
29
36
|
}
|
|
30
37
|
/**
|
|
@@ -41,7 +48,7 @@ export type DefaultRenderElements = GenericRenderElements<string>;
|
|
|
41
48
|
export type ReactRenderElements = GenericRenderElements<React.ReactNode>;
|
|
42
49
|
/**
|
|
43
50
|
* Options to customize how AST nodes are renderes into HTML
|
|
44
|
-
* @deprecated Use {@link RenderOption<string>}
|
|
51
|
+
* @deprecated Use {@link RenderOption<string>} instead to use newer options.
|
|
45
52
|
*
|
|
46
53
|
* @property elements - Optional custom rendered for one or more node types
|
|
47
54
|
* @example
|
|
@@ -60,7 +67,7 @@ export type DefaultRenderOption = {
|
|
|
60
67
|
};
|
|
61
68
|
/**
|
|
62
69
|
* Options to customize how AST nodes are renderes into ReactNode elements
|
|
63
|
-
* @deprecated Use {@link RenderOption<React.ReactNode>}
|
|
70
|
+
* @deprecated Use {@link RenderOption<React.ReactNode>} instead to use newer options.
|
|
64
71
|
*
|
|
65
72
|
* @property elements - Optional custom rendered for one or more node types
|
|
66
73
|
* @example
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { IRenderer } from "../renderers";
|
|
2
|
+
import { ASTNode } from "../types/parser";
|
|
3
|
+
export declare function escapeHtml(str: string): string;
|
|
4
|
+
export declare function getClassName<TOutput>(renderer: IRenderer<TOutput>, node: ASTNode, defaultClass?: string): string | undefined;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeHtml = escapeHtml;
|
|
4
|
+
exports.getClassName = getClassName;
|
|
5
|
+
function escapeHtml(str) {
|
|
6
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
7
|
+
}
|
|
8
|
+
function getClassName(renderer, node, defaultClass = "") {
|
|
9
|
+
const { type, level } = node;
|
|
10
|
+
const classNames = renderer.options.renderOptions?.className;
|
|
11
|
+
if (!classNames)
|
|
12
|
+
return defaultClass || undefined;
|
|
13
|
+
if (type === "Header" && level) {
|
|
14
|
+
const levelClass = classNames[`Header${level}`];
|
|
15
|
+
if (levelClass)
|
|
16
|
+
return `${defaultClass} ${levelClass}`.trim();
|
|
17
|
+
}
|
|
18
|
+
const typeClass = classNames[type];
|
|
19
|
+
return [defaultClass, typeClass].filter(Boolean).join(" ") || undefined;
|
|
20
|
+
}
|