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 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: (_node, children) => `<p>${children.join("")}</p>`
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) => `<pre><code class="lang-${node.lang}">${escapeHtml(node.content || "")}</code></pre>`,
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: (_node, children) => `<blockquote style="margin:0; padding:0 1em; color:#59636e; border-left:.25em solid #d1d9e0;">${children.join("")}</blockquote>`
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) => node.ordered ? `<ol>${children.join("")}</ol>` : `<ul>${children.join("")}</ul>`
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: (_node, children) => `<li>${children.join("")}</li>`
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) => `<li><input type="checkbox" disabled ${node.checked ? "checked" : ""}>${children.join("")}</li>`
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: (_node, children) => `<strong>${children.join("")}</strong>`
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: (_node, children) => `<em>${children.join("")}</em>`
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: (_node, children) => `<s>${children.join("")}</s>`
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) => `<code>${escapeHtml(node.content || "")}</code>`
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) => `<a href="${node.href}">${node.text}</a>`
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) => `<img src="${node.src || ""}" alt="${node.alt || ""}"/>`
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: () => `<hr>`
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
- return ctx.options.converterOptions?.allowDangerousHtml ? val : escapeHtml(val);
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
- return ctx.options.converterOptions?.allowDangerousHtml ? val : escapeHtml(val);
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
- return `<sup id="fnref:${idx}"><a href="#fn:${idx}" class="footnote-ref">[${idx}]</a></sup>`;
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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: (_node, children, ctx) => react_1.default.createElement(react_1.default.Fragment, null, ...children, ctx.renderFootnotes())
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: (_node, children) => react_1.default.createElement("p", null, ...children)
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}`, { style: { borderBottom: node.level <= 2 ? "1px solid #d1d9e0b3" : undefined } }, ...children);
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: (_node, children) => react_1.default.createElement("blockquote", { style: { margin: "0", padding: "0 1em", color: "#59636e", borderLeft: ".25em solid #d1d9e0" } }, ...children)
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", null, ...children)
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: (_node, children) => react_1.default.createElement("li", null, ...children)
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", { style: { listStyleType: "none" } }, react_1.default.createElement("input", {
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: (_node, children) => react_1.default.createElement("strong", null, ...children)
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: (_node, children) => react_1.default.createElement("em", null, ...children)
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: (_node, children) => react_1.default.createElement("s", null, ...children)
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", null, node.content || "")
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", { href: node.href, target: "_blank", rel: "noopener" }, node.text)
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", null, val);
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", null, val);
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", { href: `#fn:${idx}`, className: "footnote-ref" }, `[${idx}]`));
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", null, tHead, tBody);
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", null, ...children);
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>} for generic support.
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>} for generic support.
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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-customize-markdown-converter",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Transform Markdown into fully customizable HTML or React components.",
5
5
  "keywords": [
6
6
  "markdown",