@gravity-ui/markdown-editor 14.4.0 → 14.5.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.
Files changed (82) hide show
  1. package/build/cjs/bundle/Editor.js +1 -0
  2. package/build/cjs/bundle/config/markup.d.ts +41 -17
  3. package/build/cjs/bundle/config/markup.js +413 -308
  4. package/build/cjs/bundle/config/wysiwyg.d.ts +29 -18
  5. package/build/cjs/bundle/config/wysiwyg.js +526 -310
  6. package/build/cjs/bundle/sticky/sticky.css +1 -1
  7. package/build/cjs/bundle/types.d.ts +2 -0
  8. package/build/cjs/extensions/behavior/Clipboard/utils.d.ts +1 -0
  9. package/build/cjs/extensions/behavior/Clipboard/utils.js +1 -0
  10. package/build/cjs/extensions/markdown/CodeBlock/handle-paste.js +5 -17
  11. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.d.ts +7 -0
  12. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/const.js +8 -1
  13. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.d.ts +1 -1
  14. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.js +2 -1
  15. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.d.ts +1 -1
  16. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/schema.js +7 -7
  17. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/serializer.d.ts +1 -1
  18. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js +2 -2
  19. package/build/cjs/extensions/yfm/Checkbox/const.d.ts +1 -1
  20. package/build/cjs/extensions/yfm/Checkbox/const.js +2 -1
  21. package/build/cjs/extensions/yfm/Checkbox/index.d.ts +2 -2
  22. package/build/cjs/extensions/yfm/Checkbox/index.js +4 -38
  23. package/build/cjs/extensions/yfm/Checkbox/nodeviews.d.ts +16 -0
  24. package/build/cjs/extensions/yfm/Checkbox/nodeviews.js +56 -0
  25. package/build/cjs/extensions/yfm/YfmFile/YfmFileSpecs/const.d.ts +12 -0
  26. package/build/cjs/extensions/yfm/YfmFile/YfmFileSpecs/const.js +21 -2
  27. package/build/cjs/extensions/yfm/YfmFile/YfmFileSpecs/index.d.ts +8 -1
  28. package/build/cjs/extensions/yfm/YfmFile/YfmFileSpecs/index.js +29 -5
  29. package/build/cjs/markup/codemirror/create.d.ts +1 -0
  30. package/build/cjs/markup/codemirror/create.js +41 -4
  31. package/build/cjs/markup/codemirror/html-to-markdown/converters.d.ts +111 -0
  32. package/build/cjs/markup/codemirror/html-to-markdown/converters.js +214 -0
  33. package/build/cjs/markup/codemirror/html-to-markdown/handlers.d.ts +104 -0
  34. package/build/cjs/markup/codemirror/html-to-markdown/handlers.js +233 -0
  35. package/build/cjs/markup/codemirror/html-to-markdown/helpers.d.ts +1 -0
  36. package/build/cjs/markup/codemirror/html-to-markdown/helpers.js +21 -0
  37. package/build/cjs/markup/commands/inline.js +18 -8
  38. package/build/cjs/utils/clipboard.d.ts +14 -0
  39. package/build/cjs/utils/clipboard.js +36 -1
  40. package/build/cjs/version.js +1 -1
  41. package/build/esm/bundle/Editor.js +1 -0
  42. package/build/esm/bundle/config/markup.d.ts +41 -17
  43. package/build/esm/bundle/config/markup.js +411 -307
  44. package/build/esm/bundle/config/wysiwyg.d.ts +29 -18
  45. package/build/esm/bundle/config/wysiwyg.js +499 -284
  46. package/build/esm/bundle/sticky/sticky.css +1 -1
  47. package/build/esm/bundle/types.d.ts +2 -0
  48. package/build/esm/extensions/behavior/Clipboard/utils.d.ts +1 -0
  49. package/build/esm/extensions/behavior/Clipboard/utils.js +1 -0
  50. package/build/esm/extensions/markdown/CodeBlock/handle-paste.js +2 -14
  51. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.d.ts +7 -0
  52. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/const.js +7 -0
  53. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.d.ts +1 -1
  54. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
  55. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.d.ts +1 -1
  56. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/schema.js +7 -7
  57. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/serializer.d.ts +1 -1
  58. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/serializer.js +2 -2
  59. package/build/esm/extensions/yfm/Checkbox/const.d.ts +1 -1
  60. package/build/esm/extensions/yfm/Checkbox/const.js +1 -1
  61. package/build/esm/extensions/yfm/Checkbox/index.d.ts +2 -2
  62. package/build/esm/extensions/yfm/Checkbox/index.js +3 -38
  63. package/build/esm/extensions/yfm/Checkbox/nodeviews.d.ts +16 -0
  64. package/build/esm/extensions/yfm/Checkbox/nodeviews.js +52 -0
  65. package/build/esm/extensions/yfm/YfmFile/YfmFileSpecs/const.d.ts +12 -0
  66. package/build/esm/extensions/yfm/YfmFile/YfmFileSpecs/const.js +21 -2
  67. package/build/esm/extensions/yfm/YfmFile/YfmFileSpecs/index.d.ts +8 -1
  68. package/build/esm/extensions/yfm/YfmFile/YfmFileSpecs/index.js +29 -6
  69. package/build/esm/markup/codemirror/create.d.ts +1 -0
  70. package/build/esm/markup/codemirror/create.js +40 -3
  71. package/build/esm/markup/codemirror/html-to-markdown/converters.d.ts +111 -0
  72. package/build/esm/markup/codemirror/html-to-markdown/converters.js +210 -0
  73. package/build/esm/markup/codemirror/html-to-markdown/handlers.d.ts +104 -0
  74. package/build/esm/markup/codemirror/html-to-markdown/handlers.js +215 -0
  75. package/build/esm/markup/codemirror/html-to-markdown/helpers.d.ts +1 -0
  76. package/build/esm/markup/codemirror/html-to-markdown/helpers.js +17 -0
  77. package/build/esm/markup/commands/inline.js +18 -8
  78. package/build/esm/utils/clipboard.d.ts +14 -0
  79. package/build/esm/utils/clipboard.js +32 -0
  80. package/build/esm/version.js +1 -1
  81. package/build/styles.css +1 -1
  82. package/package.json +9 -7
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Interface defining methods for visiting different types of HTML nodes.
3
+ * Each method corresponds to a specific HTML element type and returns its Markdown representation.
4
+ */
5
+ export interface HTMLNodeVisitor {
6
+ /** Converts a text node to Markdown */
7
+ visitText(node: Text): string;
8
+ /** Converts an anchor element to Markdown link syntax */
9
+ visitLink(node: HTMLAnchorElement): string;
10
+ /** Converts a header element to Markdown heading syntax */
11
+ visitHeader(node: HTMLElement, level: number): string;
12
+ /** Converts a paragraph element to Markdown */
13
+ visitParagraph(node: HTMLElement): string;
14
+ /** Converts formatting elements (bold, italic, etc.) to Markdown */
15
+ visitFormatting(node: HTMLElement): string;
16
+ /** Converts code elements to Markdown inline code syntax */
17
+ visitCode(node: HTMLElement): string;
18
+ /** Handles generic HTML elements with no specific Markdown conversion */
19
+ visitGeneric(node: HTMLElement): string;
20
+ /** Converts an HTML div element to Markdown format, adding a single newline */
21
+ visitDiv(node: HTMLElement): string;
22
+ /** Converts an HTML br element to a newline in Markdown */
23
+ visitBr(): string;
24
+ /** Converts a table row element to Markdown */
25
+ visitTableRow(node: HTMLTableRowElement): string;
26
+ /** Converts an HTML table element to Markdown table format */
27
+ visitTable(node: HTMLTableElement): string;
28
+ /** Convert img tag to Markdown image format */
29
+ visitImage(node: HTMLImageElement): string;
30
+ }
31
+ /**
32
+ * Main converter class that implements the visitor interface to convert HTML to Markdown.
33
+ * Uses the Chain of Responsibility pattern for handling different node types.
34
+ */
35
+ export declare class MarkdownConverter implements HTMLNodeVisitor {
36
+ private handler;
37
+ constructor();
38
+ /**
39
+ * Converts a text node to Markdown, escaping special characters.
40
+ */
41
+ visitText(node: Text): string;
42
+ /**
43
+ * Converts an HTML anchor element to Markdown link syntax.
44
+ */
45
+ visitLink(node: HTMLAnchorElement): string;
46
+ /**
47
+ * Converts an HTML heading element to Markdown heading syntax.
48
+ */
49
+ visitHeader(node: HTMLElement, level: number): string;
50
+ /**
51
+ * Converts an HTML paragraph to Markdown format.
52
+ */
53
+ visitParagraph(node: HTMLElement): string;
54
+ /**
55
+ * Applies Markdown formatting (bold, italic, etc.) to text content.
56
+ */
57
+ visitFormatting(node: HTMLElement): string;
58
+ /**
59
+ * Converts HTML code elements to Markdown inline code syntax.
60
+ */
61
+ visitCode(node: HTMLElement): string;
62
+ /**
63
+ * Handles generic HTML elements by processing their children.
64
+ */
65
+ visitGeneric(node: HTMLElement): string;
66
+ /**
67
+ * Converts an HTML div element to Markdown format, adding a single newline.
68
+ */
69
+ visitDiv(node: HTMLElement): string;
70
+ /**
71
+ * Converts an HTML br element to a newline in Markdown.
72
+ */
73
+ visitBr(): string;
74
+ /**
75
+ * Converts an HTML table row element to Markdown table row format.
76
+ */
77
+ visitTableRow(node: HTMLTableRowElement): string;
78
+ /**
79
+ * Converts an HTML table element to Markdown table format.
80
+ */
81
+ visitTable(node: HTMLTableElement): string;
82
+ /**
83
+ * Converts img tag to Markdown image format
84
+ */
85
+ visitImage(node: HTMLImageElement): string;
86
+ /**
87
+ * Processes a single node using the handler chain.
88
+ */
89
+ processNode(node: Node): string;
90
+ /**
91
+ * Creates and links together handlers in a specific order implementing the Chain of Responsibility pattern.
92
+ * @returns The first handler in the chain
93
+ */
94
+ private setupHandlerChain;
95
+ /**
96
+ * Recursively collects and processes text content from a node and its children.
97
+ */
98
+ private collectTextContent;
99
+ /**
100
+ * Collects raw text content from code elements.
101
+ */
102
+ private collectCodeContent;
103
+ /**
104
+ * Processes all child nodes of a given node.
105
+ */
106
+ private processChildren;
107
+ /**
108
+ * Gets the first handler in the chain.
109
+ */
110
+ private getHandler;
111
+ }
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MarkdownConverter = void 0;
4
+ const handlers_1 = require("./handlers");
5
+ const helpers_1 = require("./helpers");
6
+ /**
7
+ * Main converter class that implements the visitor interface to convert HTML to Markdown.
8
+ * Uses the Chain of Responsibility pattern for handling different node types.
9
+ */
10
+ class MarkdownConverter {
11
+ constructor() {
12
+ // Set up the chain of responsibility for handling different node types
13
+ this.handler = this.setupHandlerChain();
14
+ }
15
+ /**
16
+ * Converts a text node to Markdown, escaping special characters.
17
+ */
18
+ visitText(node) {
19
+ return (node.textContent || '').replace(/\n+/g, '').replace(/([<>])/g, '\\$1');
20
+ }
21
+ /**
22
+ * Converts an HTML anchor element to Markdown link syntax.
23
+ */
24
+ visitLink(node) {
25
+ var _a;
26
+ const linkText = this.collectTextContent(node);
27
+ const url = node.href || '';
28
+ // Handle links with formatted content vs plain text differently
29
+ const formattedText = node.childNodes.length === 1 && ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.nodeType) === Node.TEXT_NODE
30
+ ? (0, helpers_1.applyFormatting)(linkText, node) // Plain text link
31
+ : Array.from(node.childNodes)
32
+ .map((child) => {
33
+ if (child.nodeType === Node.ELEMENT_NODE) {
34
+ return (0, helpers_1.applyFormatting)(child.textContent || '', child);
35
+ }
36
+ return child.textContent || '';
37
+ })
38
+ .join(''); // Apply formatting for each formatted child node
39
+ return `[${formattedText}](${url} "${linkText.replace(/"/g, '\\"')}")`;
40
+ }
41
+ /**
42
+ * Converts an HTML heading element to Markdown heading syntax.
43
+ */
44
+ visitHeader(node, level) {
45
+ const headerContent = this.collectTextContent(node);
46
+ return '#'.repeat(level) + ' ' + headerContent + '\n';
47
+ }
48
+ /**
49
+ * Converts an HTML paragraph to Markdown format.
50
+ */
51
+ visitParagraph(node) {
52
+ const content = this.processChildren(node);
53
+ return content.trim() + '\n\n';
54
+ }
55
+ /**
56
+ * Applies Markdown formatting (bold, italic, etc.) to text content.
57
+ */
58
+ visitFormatting(node) {
59
+ var _a;
60
+ if (node.childNodes.length === 1 && ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.nodeType) === Node.TEXT_NODE) {
61
+ const text = this.collectTextContent(node);
62
+ return (0, helpers_1.applyFormatting)(text, node);
63
+ }
64
+ return (0, helpers_1.applyFormatting)(this.visitGeneric(node), node);
65
+ }
66
+ /**
67
+ * Converts HTML code elements to Markdown inline code syntax.
68
+ */
69
+ visitCode(node) {
70
+ const codeContent = this.collectCodeContent(node);
71
+ if (codeContent.includes('\n')) {
72
+ return '```\n' + codeContent + '\n```\n';
73
+ }
74
+ else if (codeContent.includes('`')) {
75
+ return '`` ' + codeContent + ' ``';
76
+ }
77
+ else {
78
+ return `\`${codeContent}\``;
79
+ }
80
+ }
81
+ /**
82
+ * Handles generic HTML elements by processing their children.
83
+ */
84
+ visitGeneric(node) {
85
+ return this.processChildren(node);
86
+ }
87
+ /**
88
+ * Converts an HTML div element to Markdown format, adding a single newline.
89
+ */
90
+ visitDiv(node) {
91
+ const content = this.processChildren(node);
92
+ return content + '\n'; // Add a single newline for <div>
93
+ }
94
+ /**
95
+ * Converts an HTML br element to a newline in Markdown.
96
+ */
97
+ visitBr() {
98
+ return '\n'; // Single newline for <br>
99
+ }
100
+ /**
101
+ * Converts an HTML table row element to Markdown table row format.
102
+ */
103
+ visitTableRow(node) {
104
+ const cells = Array.from(node.children).map((cell) => {
105
+ return this.visitGeneric(cell).trim() || '';
106
+ });
107
+ return '||\n' + cells.join('\n|\n') + '\n||';
108
+ }
109
+ /**
110
+ * Converts an HTML table element to Markdown table format.
111
+ */
112
+ visitTable(node) {
113
+ const rows = [];
114
+ const tableRows = Array.from(node.querySelectorAll('tr'));
115
+ tableRows.forEach((row) => {
116
+ rows.push(this.visitTableRow(row));
117
+ });
118
+ return '\n\n#|\n' + rows.join('\n') + '\n|#\n\n';
119
+ }
120
+ /**
121
+ * Converts img tag to Markdown image format
122
+ */
123
+ visitImage(node) {
124
+ const imgElement = node;
125
+ const altText = imgElement.alt || '';
126
+ const src = imgElement.src || '';
127
+ return `![${altText}](${src})`;
128
+ }
129
+ /**
130
+ * Processes a single node using the handler chain.
131
+ */
132
+ processNode(node) {
133
+ const result = this.getHandler().handle(node, this);
134
+ return result;
135
+ }
136
+ /**
137
+ * Creates and links together handlers in a specific order implementing the Chain of Responsibility pattern.
138
+ * @returns The first handler in the chain
139
+ */
140
+ setupHandlerChain() {
141
+ // Create handlers for each type of node
142
+ const textHandler = new handlers_1.TextNodeHandler();
143
+ const linkHandler = new handlers_1.LinkHandler();
144
+ const headerHandler = new handlers_1.HeaderHandler();
145
+ const paragraphHandler = new handlers_1.ParagraphHandler();
146
+ const formattingHandler = new handlers_1.FormattingHandler();
147
+ const codeHandler = new handlers_1.CodeHandler();
148
+ const genericHandler = new handlers_1.GenericHandler();
149
+ const orderedListHandler = new handlers_1.OrderedListHandler();
150
+ const unorderedListHandler = new handlers_1.UnorderedListHandler();
151
+ const divHandler = new handlers_1.DivHandler();
152
+ const brHandler = new handlers_1.BrHandler();
153
+ const tableRowHandler = new handlers_1.TableRowHandler();
154
+ const tableHandler = new handlers_1.TableHandler();
155
+ const imageHandler = new handlers_1.ImageHandler(); // New handler for <img>
156
+ // Chain handlers together in priority order
157
+ textHandler
158
+ .setNext(linkHandler)
159
+ .setNext(headerHandler)
160
+ .setNext(paragraphHandler)
161
+ .setNext(divHandler)
162
+ .setNext(brHandler)
163
+ .setNext(orderedListHandler)
164
+ .setNext(unorderedListHandler)
165
+ .setNext(formattingHandler)
166
+ .setNext(codeHandler)
167
+ .setNext(imageHandler) // Add image handler
168
+ .setNext(tableHandler)
169
+ .setNext(tableRowHandler)
170
+ .setNext(genericHandler);
171
+ return textHandler;
172
+ }
173
+ /**
174
+ * Recursively collects and processes text content from a node and its children.
175
+ */
176
+ collectTextContent(node) {
177
+ // handle seo elements (hide it's content)
178
+ if (node.className === 'visually-hidden') {
179
+ return '';
180
+ }
181
+ if (node.nodeType === Node.TEXT_NODE) {
182
+ return this.visitText(node);
183
+ }
184
+ return Array.from(node.childNodes)
185
+ .map((child) => this.collectTextContent(child))
186
+ .join('');
187
+ }
188
+ /**
189
+ * Collects raw text content from code elements.
190
+ */
191
+ collectCodeContent(node) {
192
+ if (node.nodeType === Node.TEXT_NODE) {
193
+ return node.textContent || '';
194
+ }
195
+ return Array.from(node.childNodes)
196
+ .map((child) => this.collectCodeContent(child))
197
+ .join('');
198
+ }
199
+ /**
200
+ * Processes all child nodes of a given node.
201
+ */
202
+ processChildren(node) {
203
+ return Array.from(node.childNodes)
204
+ .map((child) => this.processNode(child))
205
+ .join('');
206
+ }
207
+ /**
208
+ * Gets the first handler in the chain.
209
+ */
210
+ getHandler() {
211
+ return this.handler;
212
+ }
213
+ }
214
+ exports.MarkdownConverter = MarkdownConverter;
@@ -0,0 +1,104 @@
1
+ import { HTMLNodeVisitor } from './converters';
2
+ /**
3
+ * Base handler class implementing the Chain of Responsibility pattern for HTML node processing.
4
+ * Each concrete handler decides whether it can process a node or should pass it to the next handler.
5
+ */
6
+ export declare abstract class NodeHandler {
7
+ protected next: NodeHandler | null;
8
+ /**
9
+ * Sets up the next handler in the chain
10
+ */
11
+ setNext(handler: NodeHandler): NodeHandler;
12
+ /**
13
+ * Process the given node or delegate to the next handler
14
+ */
15
+ abstract handle(node: Node, visitor: HTMLNodeVisitor): string;
16
+ /**
17
+ * Delegates processing to the next handler in the chain
18
+ */
19
+ protected handleNext(node: Node, visitor: HTMLNodeVisitor): string;
20
+ }
21
+ /**
22
+ * Handles text nodes, converting them to markdown text
23
+ */
24
+ export declare class TextNodeHandler extends NodeHandler {
25
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
26
+ }
27
+ /**
28
+ * Handles anchor elements, converting them to markdown links
29
+ */
30
+ export declare class LinkHandler extends NodeHandler {
31
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
32
+ }
33
+ /**
34
+ * Handles header elements (h1-h6), converting them to markdown headers
35
+ */
36
+ export declare class HeaderHandler extends NodeHandler {
37
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
38
+ }
39
+ /**
40
+ * Handles paragraph elements, converting them to markdown paragraphs
41
+ */
42
+ export declare class ParagraphHandler extends NodeHandler {
43
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
44
+ }
45
+ /**
46
+ * Handles text formatting elements (b, strong, i, em), converting them to markdown formatting
47
+ */
48
+ export declare class FormattingHandler extends NodeHandler {
49
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
50
+ }
51
+ /**
52
+ * Handles code elements, converting them to markdown code blocks or inline code
53
+ */
54
+ export declare class CodeHandler extends NodeHandler {
55
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
56
+ }
57
+ /**
58
+ * Fallback handler for any HTML elements not handled by other specific handlers
59
+ */
60
+ export declare class GenericHandler extends NodeHandler {
61
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
62
+ }
63
+ /**
64
+ * Handles ordered list elements, converting them to markdown ordered lists
65
+ */
66
+ export declare class OrderedListHandler extends NodeHandler {
67
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
68
+ }
69
+ /**
70
+ * Handles unordered list elements, converting them to markdown unordered lists
71
+ */
72
+ export declare class UnorderedListHandler extends NodeHandler {
73
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
74
+ }
75
+ /**
76
+ * Handles div elements, converting them to markdown paragraphs
77
+ */
78
+ export declare class DivHandler extends NodeHandler {
79
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
80
+ }
81
+ /**
82
+ * Handles br elements, converting them to markdown newlines
83
+ */
84
+ export declare class BrHandler extends NodeHandler {
85
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
86
+ }
87
+ /**
88
+ * Handles table row elements, converting them to markdown table rows
89
+ */
90
+ export declare class TableRowHandler extends NodeHandler {
91
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
92
+ }
93
+ /**
94
+ * Handles table elements, converting them to markdown tables
95
+ */
96
+ export declare class TableHandler extends NodeHandler {
97
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
98
+ }
99
+ /**
100
+ * Handles image elements, converting them to markdown images
101
+ */
102
+ export declare class ImageHandler extends NodeHandler {
103
+ handle(node: Node, visitor: HTMLNodeVisitor): string;
104
+ }
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImageHandler = exports.TableHandler = exports.TableRowHandler = exports.BrHandler = exports.DivHandler = exports.UnorderedListHandler = exports.OrderedListHandler = exports.GenericHandler = exports.CodeHandler = exports.FormattingHandler = exports.ParagraphHandler = exports.HeaderHandler = exports.LinkHandler = exports.TextNodeHandler = exports.NodeHandler = void 0;
4
+ /**
5
+ * Base handler class implementing the Chain of Responsibility pattern for HTML node processing.
6
+ * Each concrete handler decides whether it can process a node or should pass it to the next handler.
7
+ */
8
+ class NodeHandler {
9
+ constructor() {
10
+ this.next = null;
11
+ }
12
+ /**
13
+ * Sets up the next handler in the chain
14
+ */
15
+ setNext(handler) {
16
+ this.next = handler;
17
+ return handler;
18
+ }
19
+ /**
20
+ * Delegates processing to the next handler in the chain
21
+ */
22
+ handleNext(node, visitor) {
23
+ if (this.next) {
24
+ return this.next.handle(node, visitor);
25
+ }
26
+ return '';
27
+ }
28
+ }
29
+ exports.NodeHandler = NodeHandler;
30
+ /**
31
+ * Handles text nodes, converting them to markdown text
32
+ */
33
+ class TextNodeHandler extends NodeHandler {
34
+ handle(node, visitor) {
35
+ if (node.nodeType === Node.TEXT_NODE) {
36
+ return visitor.visitText(node);
37
+ }
38
+ return this.handleNext(node, visitor);
39
+ }
40
+ }
41
+ exports.TextNodeHandler = TextNodeHandler;
42
+ /**
43
+ * Handles anchor elements, converting them to markdown links
44
+ */
45
+ class LinkHandler extends NodeHandler {
46
+ handle(node, visitor) {
47
+ if (node.nodeType === Node.ELEMENT_NODE &&
48
+ node.tagName.toLowerCase() === 'a') {
49
+ return visitor.visitLink(node);
50
+ }
51
+ return this.handleNext(node, visitor);
52
+ }
53
+ }
54
+ exports.LinkHandler = LinkHandler;
55
+ /**
56
+ * Handles header elements (h1-h6), converting them to markdown headers
57
+ */
58
+ class HeaderHandler extends NodeHandler {
59
+ handle(node, visitor) {
60
+ if (node.nodeType !== Node.ELEMENT_NODE) {
61
+ return this.handleNext(node, visitor);
62
+ }
63
+ const tagName = node.tagName.toLowerCase();
64
+ const headerMatch = tagName.match(/^h([1-6])$/);
65
+ if (headerMatch) {
66
+ const headerLevel = parseInt(headerMatch[1], 10);
67
+ return visitor.visitHeader(node, headerLevel);
68
+ }
69
+ return this.handleNext(node, visitor);
70
+ }
71
+ }
72
+ exports.HeaderHandler = HeaderHandler;
73
+ /**
74
+ * Handles paragraph elements, converting them to markdown paragraphs
75
+ */
76
+ class ParagraphHandler extends NodeHandler {
77
+ handle(node, visitor) {
78
+ if (node.nodeType !== Node.ELEMENT_NODE) {
79
+ return this.handleNext(node, visitor);
80
+ }
81
+ if (node.tagName.toLowerCase() === 'p') {
82
+ return visitor.visitParagraph(node);
83
+ }
84
+ return this.handleNext(node, visitor);
85
+ }
86
+ }
87
+ exports.ParagraphHandler = ParagraphHandler;
88
+ /**
89
+ * Handles text formatting elements (b, strong, i, em), converting them to markdown formatting
90
+ */
91
+ class FormattingHandler extends NodeHandler {
92
+ handle(node, visitor) {
93
+ var _a;
94
+ if (node.nodeType !== Node.ELEMENT_NODE) {
95
+ return this.handleNext(node, visitor);
96
+ }
97
+ const element = node;
98
+ const tagName = element.tagName.toLowerCase();
99
+ const formattingTags = ['b', 'strong', 'i', 'em', 'span'];
100
+ if (formattingTags.includes(tagName) &&
101
+ !['a', 'code', 'pre'].includes(((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.tagName.toLowerCase()) || '')) {
102
+ return visitor.visitFormatting(element);
103
+ }
104
+ return this.handleNext(node, visitor);
105
+ }
106
+ }
107
+ exports.FormattingHandler = FormattingHandler;
108
+ /**
109
+ * Handles code elements, converting them to markdown code blocks or inline code
110
+ */
111
+ class CodeHandler extends NodeHandler {
112
+ handle(node, visitor) {
113
+ if (node.nodeType !== Node.ELEMENT_NODE) {
114
+ return this.handleNext(node, visitor);
115
+ }
116
+ if (node.tagName.toLowerCase() === 'code' ||
117
+ node.tagName.toLowerCase() === 'pre') {
118
+ return visitor.visitCode(node);
119
+ }
120
+ return this.handleNext(node, visitor);
121
+ }
122
+ }
123
+ exports.CodeHandler = CodeHandler;
124
+ /**
125
+ * Fallback handler for any HTML elements not handled by other specific handlers
126
+ */
127
+ class GenericHandler extends NodeHandler {
128
+ handle(node, visitor) {
129
+ return visitor.visitGeneric(node);
130
+ }
131
+ }
132
+ exports.GenericHandler = GenericHandler;
133
+ /**
134
+ * Handles ordered list elements, converting them to markdown ordered lists
135
+ */
136
+ class OrderedListHandler extends NodeHandler {
137
+ handle(node, visitor) {
138
+ if (node.nodeType === Node.ELEMENT_NODE &&
139
+ node.tagName.toLowerCase() === 'ol') {
140
+ const items = Array.from(node.childNodes)
141
+ .filter((child) => child.nodeType === Node.ELEMENT_NODE &&
142
+ child.tagName.toLowerCase() === 'li')
143
+ .map((item, index) => `${index + 1}. ${visitor.visitGeneric(item)}`)
144
+ .join('\n');
145
+ return items + '\n';
146
+ }
147
+ return this.handleNext(node, visitor);
148
+ }
149
+ }
150
+ exports.OrderedListHandler = OrderedListHandler;
151
+ /**
152
+ * Handles unordered list elements, converting them to markdown unordered lists
153
+ */
154
+ class UnorderedListHandler extends NodeHandler {
155
+ handle(node, visitor) {
156
+ if (node.nodeType === Node.ELEMENT_NODE &&
157
+ node.tagName.toLowerCase() === 'ul') {
158
+ const items = Array.from(node.childNodes)
159
+ .filter((child) => child.nodeType === Node.ELEMENT_NODE &&
160
+ child.tagName.toLowerCase() === 'li')
161
+ .map((item) => `- ${visitor.visitGeneric(item)}`)
162
+ .join('\n');
163
+ return items + '\n';
164
+ }
165
+ return this.handleNext(node, visitor);
166
+ }
167
+ }
168
+ exports.UnorderedListHandler = UnorderedListHandler;
169
+ /**
170
+ * Handles div elements, converting them to markdown paragraphs
171
+ */
172
+ class DivHandler extends NodeHandler {
173
+ handle(node, visitor) {
174
+ if (node.nodeType === Node.ELEMENT_NODE &&
175
+ node.tagName.toLowerCase() === 'div') {
176
+ return visitor.visitDiv(node);
177
+ }
178
+ return this.handleNext(node, visitor);
179
+ }
180
+ }
181
+ exports.DivHandler = DivHandler;
182
+ /**
183
+ * Handles br elements, converting them to markdown newlines
184
+ */
185
+ class BrHandler extends NodeHandler {
186
+ handle(node, visitor) {
187
+ if (node.nodeType === Node.ELEMENT_NODE &&
188
+ node.tagName.toLowerCase() === 'br') {
189
+ return visitor.visitBr();
190
+ }
191
+ return this.handleNext(node, visitor);
192
+ }
193
+ }
194
+ exports.BrHandler = BrHandler;
195
+ /**
196
+ * Handles table row elements, converting them to markdown table rows
197
+ */
198
+ class TableRowHandler extends NodeHandler {
199
+ handle(node, visitor) {
200
+ if (node.nodeType === Node.ELEMENT_NODE &&
201
+ node.tagName.toLowerCase() === 'tr') {
202
+ return visitor.visitTableRow(node);
203
+ }
204
+ return this.handleNext(node, visitor);
205
+ }
206
+ }
207
+ exports.TableRowHandler = TableRowHandler;
208
+ /**
209
+ * Handles table elements, converting them to markdown tables
210
+ */
211
+ class TableHandler extends NodeHandler {
212
+ handle(node, visitor) {
213
+ if (node.nodeType === Node.ELEMENT_NODE &&
214
+ node.tagName.toLowerCase() === 'table') {
215
+ return visitor.visitTable(node);
216
+ }
217
+ return this.handleNext(node, visitor);
218
+ }
219
+ }
220
+ exports.TableHandler = TableHandler;
221
+ /**
222
+ * Handles image elements, converting them to markdown images
223
+ */
224
+ class ImageHandler extends NodeHandler {
225
+ handle(node, visitor) {
226
+ if (node.nodeType === Node.ELEMENT_NODE &&
227
+ node.tagName.toLowerCase() === 'img') {
228
+ return visitor.visitImage(node);
229
+ }
230
+ return this.handleNext(node, visitor);
231
+ }
232
+ }
233
+ exports.ImageHandler = ImageHandler;
@@ -0,0 +1 @@
1
+ export declare function applyFormatting(text: string, element: HTMLElement): string;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyFormatting = void 0;
4
+ function applyFormatting(text, element) {
5
+ // Check for italic formatting (either through tags or CSS)
6
+ const hasItalic = element.tagName.toLowerCase() === 'i' ||
7
+ element.tagName.toLowerCase() === 'em' ||
8
+ element.style.fontStyle === 'italic';
9
+ // Check for bold formatting (either through tags or CSS font-weight)
10
+ const hasBold = element.tagName.toLowerCase() === 'b' ||
11
+ element.tagName.toLowerCase() === 'strong' ||
12
+ parseInt(element.style.fontWeight, 10) >= 600;
13
+ // Apply markdown formatting in specific order
14
+ let formatted = text;
15
+ if (hasItalic)
16
+ formatted = `*${formatted}*`; // Wrap in single asterisks for italic
17
+ if (hasBold)
18
+ formatted = `**${formatted}**`; // Wrap in double asterisks for bold
19
+ return formatted;
20
+ }
21
+ exports.applyFormatting = applyFormatting;