simple-customize-markdown-converter 1.0.7 → 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.
Files changed (55) hide show
  1. package/README.md +74 -17
  2. package/dist/core/lexer/handler.d.ts +23 -0
  3. package/dist/core/lexer/handler.js +272 -0
  4. package/dist/core/lexer/index.d.ts +42 -0
  5. package/dist/core/lexer/index.js +177 -0
  6. package/dist/core/lexer.d.ts +46 -0
  7. package/dist/core/lexer.js +433 -0
  8. package/dist/core/parser/handler.d.ts +19 -0
  9. package/dist/core/parser/handler.js +254 -0
  10. package/dist/core/parser/index.d.ts +33 -0
  11. package/dist/core/parser/index.js +149 -0
  12. package/dist/core/parser.d.ts +37 -0
  13. package/dist/core/parser.js +346 -0
  14. package/dist/core/renderer.d.ts +3 -0
  15. package/dist/core/renderer.js +99 -0
  16. package/dist/core/resolver/footnote-resolver.d.ts +15 -0
  17. package/dist/core/resolver/footnote-resolver.js +36 -0
  18. package/dist/core/resolver.d.ts +15 -0
  19. package/dist/core/resolver.js +36 -0
  20. package/dist/index.d.ts +6 -3
  21. package/dist/index.js +10 -7
  22. package/dist/react.d.ts +36 -0
  23. package/dist/react.js +56 -0
  24. package/dist/renderers/default/handler.d.ts +21 -0
  25. package/dist/renderers/default/handler.js +114 -0
  26. package/dist/renderers/default/index.d.ts +14 -0
  27. package/dist/renderers/default/index.js +117 -0
  28. package/dist/renderers/default.d.ts +26 -0
  29. package/dist/renderers/default.js +105 -0
  30. package/dist/renderers/index.d.ts +10 -0
  31. package/dist/renderers/index.js +2 -0
  32. package/dist/renderers/react/handler.d.ts +22 -0
  33. package/dist/renderers/react/handler.js +123 -0
  34. package/dist/renderers/react/index.d.ts +15 -0
  35. package/dist/renderers/react/index.js +123 -0
  36. package/dist/renderers/react.d.ts +26 -0
  37. package/dist/renderers/react.js +123 -0
  38. package/dist/types/options/converterOptions.d.ts +11 -0
  39. package/dist/types/options/converterOptions.js +2 -0
  40. package/dist/types/options/index.d.ts +10 -0
  41. package/dist/types/options/index.js +2 -0
  42. package/dist/types/options/reactRenderOptions.d.ts +50 -0
  43. package/dist/types/options/reactRenderOptions.js +2 -0
  44. package/dist/types/options/renderOptions.d.ts +86 -0
  45. package/dist/types/options/renderOptions.js +2 -0
  46. package/dist/types/parser.d.ts +132 -0
  47. package/dist/types/parser.js +2 -0
  48. package/dist/types/renderer.d.ts +12 -0
  49. package/dist/types/renderer.js +2 -0
  50. package/dist/types/token.d.ts +94 -74
  51. package/dist/utilities/parser-utils.d.ts +5 -0
  52. package/dist/utilities/parser-utils.js +65 -0
  53. package/dist/utilities/tokenizer-utils.d.ts +11 -0
  54. package/dist/utilities/tokenizer-utils.js +159 -0
  55. package/package.json +24 -3
@@ -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;
@@ -0,0 +1,26 @@
1
+ import { ReactNode } from "react";
2
+ import { FootnoteResolver } from "../core/resolver";
3
+ import { Node } from "../types/node";
4
+ import { MarkdownReactOptions } from "../types/options";
5
+ export default class ReactRenderer {
6
+ options: MarkdownReactOptions;
7
+ footNoteResolver: FootnoteResolver;
8
+ constructor(footNoteResolver: FootnoteResolver, options: MarkdownReactOptions);
9
+ /**
10
+ * Render a Node (AST) to a ReactNode according renderer options
11
+ *
12
+ * @param node - The abstract syntax tree (AST) from the Parser
13
+ * @returns The ReactNode representing the rendered Markdown element.
14
+ */
15
+ render<K extends Node["type"]>(node: Extract<Node, {
16
+ type: K;
17
+ }>): ReactNode;
18
+ /**
19
+ * Select the appropriate rendering handler for a specific node type
20
+ * @param type - The type of AST Note
21
+ * @returns A function take a node and its children to procude a ReactNode.
22
+ */
23
+ private handleRender;
24
+ private renderTable;
25
+ private renderFootnotes;
26
+ }
@@ -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
+ const react_1 = __importDefault(require("react"));
7
+ class ReactRenderer {
8
+ constructor(footNoteResolver, options) {
9
+ this.footNoteResolver = footNoteResolver;
10
+ this.options = options;
11
+ }
12
+ /**
13
+ * Render a Node (AST) to a ReactNode according renderer options
14
+ *
15
+ * @param node - The abstract syntax tree (AST) from the Parser
16
+ * @returns The ReactNode representing the rendered Markdown element.
17
+ */
18
+ render(node) {
19
+ //Get proper handler type
20
+ const handler = this.handleRender(node.type);
21
+ //If node have children, recursive to handle all node's children
22
+ const children = "children" in node ? node.children.map((ele) => this.render(ele)) : [];
23
+ return handler(node, children);
24
+ }
25
+ /**
26
+ * Select the appropriate rendering handler for a specific node type
27
+ * @param type - The type of AST Note
28
+ * @returns A function take a node and its children to procude a ReactNode.
29
+ */
30
+ handleRender(type) {
31
+ const defaultRender = {
32
+ //Base structural nodes
33
+ Document: (_node, children) => react_1.default.createElement(react_1.default.Fragment, null, ...children, this.renderFootnotes()),
34
+ Paragraph: (_node, children) => react_1.default.createElement("p", null, ...children),
35
+ //Container nodes
36
+ CodeBlock: (node) => react_1.default.createElement("pre", null, react_1.default.createElement("code", { className: `lang-${node.lang}` }, node.content)),
37
+ Header: (node, children) => react_1.default.createElement(`h${node.level}`, { style: { borderBottom: node.level <= 2 ? "1px solid #d1d9e0b3" : undefined } }, ...children),
38
+ Quote: (_node, children) => react_1.default.createElement("blockquote", { style: { margin: "0", padding: "0 1em", color: "#59636e", borderLeft: ".25em solid #d1d9e0" } }, ...children),
39
+ //For list nodes
40
+ List: (node, children) => node.ordered ?
41
+ react_1.default.createElement("ol", null, ...children) :
42
+ react_1.default.createElement("ul", null, ...children),
43
+ ListItem: (_node, children) => react_1.default.createElement("li", null, ...children),
44
+ TaskItem: (node, children) => react_1.default.createElement("li", null, react_1.default.createElement("input", {
45
+ type: "checkbox",
46
+ disabled: true,
47
+ checked: !!node.checked,
48
+ readOnly: true
49
+ }), ...children),
50
+ //Styling nodes
51
+ Bold: (_node, children) => react_1.default.createElement("strong", null, ...children),
52
+ Italic: (_node, children) => react_1.default.createElement("em", null, ...children),
53
+ Strikethrough: (_node, children) => react_1.default.createElement("s", null, ...children),
54
+ InlineCode: (node) => react_1.default.createElement("code", null, node.content),
55
+ //Media nodes
56
+ Link: (node) => react_1.default.createElement("a", {
57
+ href: node.href,
58
+ //Security reason
59
+ target: "_blank",
60
+ rel: "noopener"
61
+ }, node.text),
62
+ Image: (node) => react_1.default.createElement("img", {
63
+ src: node.src,
64
+ alt: node.alt,
65
+ }, null),
66
+ //Leaf nodes
67
+ HorizontalLine: (_node) => react_1.default.createElement("hr"),
68
+ Text: (node) => node.value || "",
69
+ //For table nodes
70
+ Table: (node, children) => this.renderTable(node, children),
71
+ //For HTML
72
+ HTMLBlock: (node) => this.options.converterOptions?.allowDangerousHtml
73
+ ? react_1.default.createElement("div", { dangerouslySetInnerHTML: { __html: node.value } })
74
+ : react_1.default.createElement("code", null, node.value),
75
+ HTMLInline: (node) => this.options.converterOptions?.allowDangerousHtml
76
+ ? react_1.default.createElement("span", { dangerouslySetInnerHTML: { __html: node.value } })
77
+ : react_1.default.createElement("code", null, node.value),
78
+ //For footnote
79
+ FootnoteRef: (node) => {
80
+ const idx = this.footNoteResolver.getUsedRefById(node.id);
81
+ return react_1.default.createElement("sup", { id: `fnref:${idx}` }, react_1.default.createElement("a", { href: `#fn:${idx}`, className: "footnote-ref" }, `[${idx}]`));
82
+ }
83
+ };
84
+ return (this.options.renderOptions?.elements?.[type] ?? defaultRender[type]);
85
+ }
86
+ renderTable(node, children) {
87
+ if (node.type === "Table") {
88
+ const header = node.rows.filter(row => row.isHeader);
89
+ const body = node.rows.filter(row => !row.isHeader);
90
+ const renderRows = (row, rowIndex) => {
91
+ return react_1.default.createElement("tr", { key: rowIndex }, row.cells.map((cell, cellIndex) => {
92
+ const tag = row.isHeader ? "th" : "td";
93
+ return react_1.default.createElement(tag, { key: cellIndex, style: { textAlign: cell.align } }, ...cell.children.map(c => this.render(c)));
94
+ }));
95
+ };
96
+ const tHead = header.length
97
+ ? react_1.default.createElement("thead", null, header.map((row, i) => renderRows(row, i)))
98
+ : null;
99
+ const tBody = body.length
100
+ ? react_1.default.createElement("tbody", null, body.map((row, i) => renderRows(row, i)))
101
+ : null;
102
+ return react_1.default.createElement("table", null, tHead, tBody);
103
+ }
104
+ else
105
+ return react_1.default.createElement("p", null, ...children);
106
+ }
107
+ renderFootnotes() {
108
+ if (this.footNoteResolver.isResolverValid()) {
109
+ const used = this.footNoteResolver.getUsedRef();
110
+ if (used.length === 0)
111
+ return null;
112
+ const items = used.map((id, i) => {
113
+ const def = this.footNoteResolver.getDef(id) ?? "";
114
+ const idx = i + 1;
115
+ 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" }, "↩")));
116
+ });
117
+ return react_1.default.createElement("section", { className: "footnotes" }, react_1.default.createElement("ol", null, ...items));
118
+ }
119
+ else
120
+ return null;
121
+ }
122
+ }
123
+ exports.default = ReactRenderer;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * General option for the render process.
3
+ * These rules define high-level behavior for render process.
4
+ */
5
+ export type ConvertOption = {
6
+ /**
7
+ * Allow raw HTML rendered in the Markdown input.
8
+ * When false (default), HTML tags are escaped for security
9
+ */
10
+ allowDangerousHtml: boolean;
11
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ import { ConvertOption } from "./converterOptions";
2
+ import { RenderOption } from './renderOptions';
3
+ /**
4
+ * General option for rendering Markdown into HTML strings
5
+ * @template TOutput - Output type after rendered
6
+ */
7
+ export interface MarkdownOptions<TOutput> {
8
+ renderOptions?: RenderOption<TOutput>;
9
+ converterOptions?: ConvertOption;
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,50 @@
1
+ import { Node } from "../node";
2
+ /**
3
+ * Function type for rendering an AST node to a ReactNode.
4
+ *
5
+ * @template T - A subtype of `Node` corresponding to the render node
6
+ * @param node - The AST node to render
7
+ * @param children - An array of rendered `ReactNode` from the node's children
8
+ * @returns A `React.ReactNode` representation of the node
9
+ */
10
+ type ReactNodeRenderer<T extends Node = Node> = (node: T, children: React.ReactNode[]) => React.ReactNode;
11
+ /**
12
+ * A mapping of AST node types to custom render functions.
13
+ *
14
+ * - The key is a `Node["type"]` string literal (e.g. `"Header"`, `"Paragraph"`)
15
+ * - The value is a function `ReactNodeRenderer` function:
16
+ * - `node` is a `Node` with its attribute depending on its `type`.
17
+ * (e.g. `"Header"` nodes include `level`, `"CodeBlock"` nodes include `lang` and `content`, etc)
18
+ * - `children` is the array of rendered `ReactNode` of its children.
19
+ */
20
+ export type ReactRenderElements = {
21
+ [K in Node["type"]]?: ReactNodeRenderer<Extract<Node, {
22
+ type: K;
23
+ }>>;
24
+ };
25
+ /**
26
+ * Options to customize how AST nodes are renderes into ReactNode elements
27
+ *
28
+ * @property elements - Optional custom rendered for one or more node types
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * // Using JSX (Recommended for most users)
33
+ * const renderOptions: ReactRenderOption = {
34
+ * elements: {
35
+ * Paragraph: (_node, children) => <p className="paragraph">{children}</p>,
36
+ * Bold: (_node, children) => <strong className="bold-text">{children}</strong>,
37
+ * }
38
+ * }
39
+ * // Or using React.createElement (Common in library core or without JSX)
40
+ * const renderOptions: ReactRenderOption = {
41
+ * elements: {
42
+ * Bold: (_node, children) => React.createElement("b", { className: "bold" }, ...children),
43
+ * }
44
+ * }
45
+ * ```
46
+ */
47
+ export type ReactRenderOption = {
48
+ elements?: ReactRenderElements;
49
+ };
50
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,86 @@
1
+ import { ASTNode } from '../parser';
2
+ /**
3
+ * A strategy function type for rendering a specific AST node.
4
+ * @template TOutput - The resulting type after rendered.
5
+ * @template TNode - The specific `ASTNode` processed.
6
+ *
7
+ * @param node - The `ASTNode` object containing its properties.
8
+ * @param children - An array of already rendered `TOutput` of this node's childrens.
9
+ * @returns The rendered result for the given node.
10
+ *
11
+ * @since v.1.2.0 - Introduced `GenericNodeRenderer` for defining `RenderElement`
12
+ */
13
+ type GenericNodeRenderer<TOutput, TNode extends ASTNode = ASTNode> = (node: TNode, children: TOutput[]) => TOutput;
14
+ /**
15
+ * A mapping of `ASTNode` types to their coressponding rendering functions.
16
+ * @template TOutput - The target output type of the renderer.
17
+ */
18
+ export type GenericRenderElements<TOutput> = {
19
+ [K in ASTNode["type"]]?: GenericNodeRenderer<TOutput, ASTNode>;
20
+ } & {
21
+ [key: string]: GenericNodeRenderer<TOutput, any> | undefined;
22
+ };
23
+ /**
24
+ * Options for customizing the rendering process for a specific output type.
25
+ * @template TOutput - The output type.
26
+ */
27
+ export interface RenderOption<TOutput> {
28
+ elements?: GenericRenderElements<TOutput>;
29
+ }
30
+ /**
31
+ * An utilities type alias for render `ASTNode` to `HTML string`
32
+ * Equivalent to `GenericRenderElements<string>`.
33
+ * @alias DefaultRenderElements
34
+ */
35
+ export type DefaultRenderElements = GenericRenderElements<string>;
36
+ /**
37
+ * An utilities type alias for render `ASTNode` to `React.ReactNode`
38
+ * Equivalent to `GenericRenderElements<React.ReactNode>`.
39
+ * @alias ReactRenderElements
40
+ */
41
+ export type ReactRenderElements = GenericRenderElements<React.ReactNode>;
42
+ /**
43
+ * Options to customize how AST nodes are renderes into HTML
44
+ * @deprecated Use {@link RenderOption<string>} for generic support.
45
+ *
46
+ * @property elements - Optional custom rendered for one or more node types
47
+ * @example
48
+ * ```ts
49
+ * const renderOptions: RenderOption = {
50
+ * elements: {
51
+ * Paragraph: (_node, children) => `<div class="paragraph">${children.join("")}</div>`,
52
+ * Bold: (_node, children) => `<b class="bold-text">${children.join("")}</b>`,
53
+ * }
54
+ * }
55
+ * ```
56
+ *
57
+ */
58
+ export type DefaultRenderOption = {
59
+ elements?: DefaultRenderElements;
60
+ };
61
+ /**
62
+ * Options to customize how AST nodes are renderes into ReactNode elements
63
+ * @deprecated Use {@link RenderOption<React.ReactNode>} for generic support.
64
+ *
65
+ * @property elements - Optional custom rendered for one or more node types
66
+ * @example
67
+ * ```tsx
68
+ * // Using JSX (Recommended for most users)
69
+ * const renderOptions: ReactRenderOption = {
70
+ * elements: {
71
+ * Paragraph: (_node, children) => <p className="paragraph">{children}</p>,
72
+ * Bold: (_node, children) => <strong className="bold-text">{children}</strong>,
73
+ * }
74
+ * }
75
+ * // Or using React.createElement (Common in library core or without JSX)
76
+ * const renderOptions: ReactRenderOption = {
77
+ * elements: {
78
+ * Bold: (_node, children) => React.createElement("b", { className: "bold" }, ...children),
79
+ * }
80
+ * }
81
+ * ```
82
+ */
83
+ export type ReactRenderOption = {
84
+ elements?: ReactRenderElements;
85
+ };
86
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,132 @@
1
+ import { IParser } from '../core/parser/index';
2
+ import { Token } from './token';
3
+ /**
4
+ * AST (Abstract Syntax Tree) node definition.
5
+ *
6
+ * Each node represents a Markdown construct and some special nodes (Document, Paragraph).
7
+ * Some nodes are containers (have `children`), while others are leaf nodes (contain text).
8
+ *
9
+ * Variants:
10
+ * - Document: Root node, contains all other nodes.
11
+ * - Paragraph: A block of text, contain inline nodes.
12
+ * - Header: A header with given `level` (1-6)
13
+ * - Bold: Bold text
14
+ * - Italic: Italic text
15
+ * - Strikethrough: Strilethrough text
16
+ * - InlineCode: Inline code snippet, with it's `content`
17
+ * - Quote: A quote block
18
+ * - CodeBlock: A code block, with it's `lang` and `content`
19
+ * - List: A list, with it's level and children
20
+ * - ListItem: An item of a list, with it's children
21
+ * - TaskItem: An item for tasklist, with it's checked state
22
+ * - Link: A link, with it's `text` and `href`
23
+ * - Image: An image, with it's `src` and `alt`
24
+ * - HorizontalLine: A horizontal line
25
+ * - Text: Raw text content.
26
+ * - Table: A table, with it's rows
27
+ * - HTMLBlock: A HTML block element, with it's `value`
28
+ * - HTMLInline: An inline HTML element, with it's `value`
29
+ * - FootnoteRef: A refernce with it's `id`
30
+ *
31
+ * {@link ASTNode} for each variant's attribute listed detail
32
+ */
33
+ export type DefaultNodeType = "Document" | "Paragraph" | "Header" | "Bold" | "Italic" | "Strikethrough" | "InlineCode" | "CodeBlock" | "Quote" | "List" | "ListItem" | "TaskItem" | "Link" | "Image" | "HorizontalLine" | "Text" | "Table" | "HTMLBlock" | "HTMLInline" | "FootnoteRef";
34
+ export type NodeType = DefaultNodeType | (string & {});
35
+ export interface TableCell {
36
+ align: "left" | "center" | "right";
37
+ children: ASTNode[];
38
+ }
39
+ export interface TableRow {
40
+ isHeader: boolean;
41
+ cells: TableCell[];
42
+ }
43
+ /**
44
+ * AST (Abstract Syntax Tree) node definition. It representing all possible Markdown constructs and its possible properties.
45
+ *
46
+ * Use the `type` property to determine which other properties are available.
47
+ */
48
+ export interface ASTNode {
49
+ /**
50
+ * The type of the node, determining its structure and purpose.
51
+ * @see {@link DefaultNodeType} for standard types.
52
+ */
53
+ type: NodeType;
54
+ /**
55
+ * Nested nodes within this container.
56
+ * Applicable for: `Document`, `Paragraph`, `Header`, `Bold`, `Italic`, `Strikethrough`, `Quote`, `List`, `ListItem`, `TaskItem`.
57
+ */
58
+ children?: ASTNode[];
59
+ /**
60
+ * Raw string content.
61
+ * Applicable for: `Text` (the plain text), `HTMLBlock` & `HTMLInline` (the raw HTML code).
62
+ */
63
+ value?: string;
64
+ /**
65
+ * The internal content of a code element.
66
+ * Applicable for: `InlineCode`, `CodeBlock`.
67
+ */
68
+ content?: string;
69
+ /**
70
+ * The level of importance/depth.
71
+ * Applicable for: `Header` (1-6).
72
+ */
73
+ level?: number;
74
+ /**
75
+ * Programming language identifier for syntax highlighting.
76
+ * Applicable for: `CodeBlock` (e.g., "javascript", "python").
77
+ */
78
+ lang?: string;
79
+ /**
80
+ * URL or path for external resources.
81
+ * Applicable for: `Link` (destination), `Image` (source).
82
+ */
83
+ href?: string;
84
+ /**
85
+ * The clickable text label for a link.
86
+ * Applicable for: `Link`.
87
+ */
88
+ text?: string;
89
+ /**
90
+ * Source URL of an image.
91
+ * Applicable for: `Image`.
92
+ */
93
+ src?: string;
94
+ /**
95
+ * Alternative text for accessibility.
96
+ * Applicable for: `Image`.
97
+ */
98
+ alt?: string;
99
+ /**
100
+ * Indicates if a list is numbered (true) or bulleted (false).
101
+ * Applicable for: `List`.
102
+ */
103
+ ordered?: boolean;
104
+ /**
105
+ * The completion status of a task.
106
+ * Applicable for: `TaskItem`.
107
+ */
108
+ checked?: boolean;
109
+ /**
110
+ * Array of rows defining the table structure.
111
+ * Applicable for: `Table`.
112
+ */
113
+ rows?: TableRow[];
114
+ /**
115
+ * Unique identifier for referencing.
116
+ * Applicable for: `FootnoteRef`.
117
+ */
118
+ id?: string;
119
+ /**
120
+ * Allows custom properties for extensions or plugin-specific data.
121
+ */
122
+ [key: string]: any;
123
+ }
124
+ /**
125
+ * A Strategy pattern for handle parsing process for each Token.
126
+ * @property type - Strategy's type
127
+ * @property execute - A function handle parsing a `Token` to `ASTNode`
128
+ */
129
+ export interface ParsingStrategy {
130
+ type: string;
131
+ execute: (parser: IParser, token: Token) => ASTNode | ASTNode[] | void;
132
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,12 @@
1
+ import { IRenderer } from "../renderers";
2
+ import { ASTNode } from "./parser";
3
+ /**
4
+ * A Strategy pattern for handle parsing process for each ASTNode.
5
+ * @template TOutput - Output result after rendered by `render` property.
6
+ * @property type - Strategy's type
7
+ * @property execute - A function handle rendering a `ASTNode` to `TOutput`
8
+ */
9
+ export interface RenderStrategy<TOutput> {
10
+ type: string;
11
+ render: (node: ASTNode, children: TOutput[], context: IRenderer<TOutput>) => TOutput;
12
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });