@hcengineering/text-markdown 0.7.18 → 0.7.20
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.
|
@@ -1163,4 +1163,49 @@ describe("markdownToMarkup -> markupToMarkdown", () => {
|
|
|
1163
1163
|
});
|
|
1164
1164
|
});
|
|
1165
1165
|
});
|
|
1166
|
+
describe("normalizeMarkdown", () => {
|
|
1167
|
+
it("handles null and undefined inputs", () => {
|
|
1168
|
+
expect((0, import_compare.normalizeMarkdown)(null)).toBe("");
|
|
1169
|
+
expect((0, import_compare.normalizeMarkdown)(void 0)).toBe("");
|
|
1170
|
+
expect((0, import_compare.normalizeMarkdown)("")).toBe("");
|
|
1171
|
+
});
|
|
1172
|
+
it("handles non-string inputs", () => {
|
|
1173
|
+
expect((0, import_compare.normalizeMarkdown)(123)).toBe("");
|
|
1174
|
+
expect((0, import_compare.normalizeMarkdown)({})).toBe("");
|
|
1175
|
+
expect((0, import_compare.normalizeMarkdown)([])).toBe("");
|
|
1176
|
+
});
|
|
1177
|
+
it("normalizes line endings", () => {
|
|
1178
|
+
expect((0, import_compare.normalizeMarkdown)("line1\r\nline2\rline3\nline4")).toBe("line1\nline2\nline3\nline4");
|
|
1179
|
+
});
|
|
1180
|
+
it("removes trailing whitespace and empty lines", () => {
|
|
1181
|
+
expect((0, import_compare.normalizeMarkdown)("line1 \n \nline2 \n\n\nline3")).toBe("line1\nline2\nline3");
|
|
1182
|
+
});
|
|
1183
|
+
it("normalizes HTML tag attributes", () => {
|
|
1184
|
+
const input = '<img src="test.jpg" alt="test" width="100">';
|
|
1185
|
+
const expected = '<img alt="test" src="test.jpg" width="100" />';
|
|
1186
|
+
expect((0, import_compare.normalizeMarkdown)(input)).toBe(expected);
|
|
1187
|
+
});
|
|
1188
|
+
it("handles void elements correctly", () => {
|
|
1189
|
+
expect((0, import_compare.normalizeMarkdown)('<img src="test.jpg">')).toBe('<img src="test.jpg" />');
|
|
1190
|
+
expect((0, import_compare.normalizeMarkdown)("<br>")).toBe("<br />");
|
|
1191
|
+
expect((0, import_compare.normalizeMarkdown)("<hr>")).toBe("<hr />");
|
|
1192
|
+
});
|
|
1193
|
+
it("handles non-void elements correctly", () => {
|
|
1194
|
+
expect((0, import_compare.normalizeMarkdown)('<div class="test">')).toBe('<div class="test">');
|
|
1195
|
+
expect((0, import_compare.normalizeMarkdown)("<span>")).toBe("<span>");
|
|
1196
|
+
});
|
|
1197
|
+
it("sorts attributes alphabetically", () => {
|
|
1198
|
+
const input = '<img width="100" src="test.jpg" height="200" alt="test">';
|
|
1199
|
+
const expected = '<img alt="test" height="200" src="test.jpg" width="100" />';
|
|
1200
|
+
expect((0, import_compare.normalizeMarkdown)(input)).toBe(expected);
|
|
1201
|
+
});
|
|
1202
|
+
it("handles attributes without values", () => {
|
|
1203
|
+
expect((0, import_compare.normalizeMarkdown)('<input type="checkbox" checked>')).toBe('<input checked type="checkbox" />');
|
|
1204
|
+
});
|
|
1205
|
+
it("handles mixed content", () => {
|
|
1206
|
+
const input = 'Text before\r\n<img alt="test" src="image.jpg"> \n\nText after ';
|
|
1207
|
+
const expected = 'Text before\n<img alt="test" src="image.jpg" />\nText after';
|
|
1208
|
+
expect((0, import_compare.normalizeMarkdown)(input)).toBe(expected);
|
|
1209
|
+
});
|
|
1210
|
+
});
|
|
1166
1211
|
//# sourceMappingURL=markdown.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/__tests__/markdown.test.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright \u00A9 2025 Hardcore Engineering Inc.\n//\n// Licensed under the Eclipse Public License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License. You may\n// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nimport { MarkupNode, MarkupNodeType, MarkupMarkType } from '@hcengineering/text-core'\nimport { markdownToMarkup, markupToMarkdown } from '..'\nimport { isMarkdownsEquals } from '../compare'\n\nconst refUrl: string = 'ref://'\nconst imageUrl: string = 'http://localhost'\nconst options = { refUrl, imageUrl }\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace jest {\n interface Matchers<R> {\n toEqualMarkdown: (expected: string) => R\n }\n }\n}\n\nexpect.extend({\n toEqualMarkdown (received: string, expected: string) {\n const pass = isMarkdownsEquals(received, expected)\n return {\n message: () =>\n pass\n ? `Expected markdown strings NOT to be equal:\\n Received:\\n${received}\\n Expected:\\n${expected}`\n : `Expected markdown strings to be equal:\\n Received:\\n${received}\\n Expected:\\n${expected}`,\n pass\n }\n }\n})\n\ndescribe('markdownToMarkup', () => {\n const tests: Array<{ name: string, markdown: string, markup: object }> = [\n {\n name: 'simple text',\n markdown: 'Lorem ipsum dolor sit amet.',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Lorem ipsum dolor sit amet.',\n marks: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'text with heading',\n markdown: `# Lorem ipsum\n\nLorem ipsum dolor sit amet.\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'Lorem ipsum',\n marks: []\n }\n ]\n },\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Lorem ipsum dolor sit amet.',\n marks: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'bullet list',\n markdown: `# bullet list\n- list item 1\n- list item 2\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'bullet list',\n marks: []\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'todos',\n markdown: `# TODO\n- [ ] todo 1\n- [x] todo 2\n `,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'TODO',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'todos followed by list items',\n markdown: `# todo and list\n- [ ] todo 1\n- [x] todo 2\n- list item 1\n- list item 2\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'todo and list',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'todos followed by list items',\n markdown: `# mixed lists\n- [ ] todo 1\n- list item 1\n- [x] todo 2\n- list item 2\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'mixed lists',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 1',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 1',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'nested todos',\n markdown: `# nested todos\n- [ ] todo\n - [x] sub todo\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'nested todos',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'nested lists',\n markdown: `# nested lists\n- [ ] todo\n - sub list item\n - [x] sub todo\n- list item\n - [x] sub todo\n - sub list item\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'nested lists',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo',\n marks: []\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub list item',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub list item',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'nested todos',\n markdown: `# nested todos\n- [ ] todo\n - [x] sub todo\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'nested todos',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'mermaid diagram',\n markdown: '```mermaid\\ngraph TD;\\n\\tA-->B;\\n\\tA-->C;\\n\\tB-->D;\\n\\tC-->D;\\n```',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'mermaid',\n attrs: {\n language: 'mermaid'\n },\n content: [\n {\n marks: [],\n text: 'graph TD;\\n\\tA-->B;\\n\\tA-->C;\\n\\tB-->D;\\n\\tC-->D;',\n type: 'text'\n }\n ]\n }\n ]\n }\n },\n {\n name: 'embed',\n markdown: '<a href=\"http://localhost/embed\" data-type=\"embed\">http://localhost/embed</a>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'embed',\n attrs: { src: 'http://localhost/embed' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'embed-uri-escape',\n markdown:\n '<a href=\"http://localhost/embed%20spaces\" data-type=\"embed\">http://localhost/embed spaces</a>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'embed',\n attrs: { src: 'http://localhost/embed spaces' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'embed-html-escape',\n markdown:\n '<a href=\"http://localhost/embed%3Chtml%3E\" data-type=\"embed\">http://localhost/embed<html></a>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'embed',\n attrs: { src: 'http://localhost/embed<html>' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'multiline image alt',\n markdown: '',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'image',\n attrs: { src: 'http://example.com/image.png', alt: 'line0\\n\\nline1' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'image in a table cell',\n markdown:\n '<table><tbody><tr><td><p>Some text</p><p> <img src=\"files/image_1.png\" alt=\"image-alt\"/></p></td></tr></tbody></table>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'table',\n content: [\n {\n type: 'tableRow',\n content: [\n {\n type: 'tableCell',\n attrs: {\n colspan: undefined,\n rowspan: undefined,\n colwidth: undefined\n },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Some text'\n }\n ]\n },\n {\n type: 'paragraph',\n attrs: {\n textAlign: null\n },\n content: [\n {\n type: 'text',\n text: ' '\n },\n {\n type: 'image',\n attrs: {\n src: 'files/image_1.png',\n alt: 'image-alt',\n 'file-id': null,\n title: null\n }\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textColor',\n markdown: '<span style=\"color: #abcdef\" data-color=\"#abcdef\">colored</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'colored',\n marks: [{ type: 'textColor' as MarkupMarkType, attrs: { color: '#abcdef' } }]\n }\n ]\n }\n ]\n }\n }\n ]\n\n describe('to markup', () => {\n tests.forEach(({ name, markdown, markup }) => {\n it(name, () => {\n const parsed = markdownToMarkup(markdown, options)\n expect(parsed).toEqual(markup)\n })\n })\n })\n\n describe('to markdown', () => {\n tests.forEach(({ name, markdown, markup }) => {\n it(name, () => {\n const serialized = markupToMarkdown(markup as MarkupNode, options)\n expect(serialized).toEqualMarkdown(markdown)\n })\n })\n })\n})\n\ndescribe('markupToMarkdown', () => {\n const tests: Array<{ name: string, markdown: string, markup: object }> = [\n {\n name: 'links',\n markdown: `[Link](https://example.com)\n\n[Link with spaces](<https://example.com/with spaces>)\n\n[Link with spaces and braces](<https://example.com/\\\\<with spaces\\\\>>)`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Link',\n marks: [{ type: 'link', attrs: { href: 'https://example.com' } }]\n }\n ]\n },\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Link with spaces',\n marks: [{ type: 'link', attrs: { href: 'https://example.com/with spaces' } }]\n }\n ]\n },\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Link with spaces and braces',\n marks: [{ type: 'link', attrs: { href: 'https://example.com/<with spaces>' } }]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textColor',\n markdown: '<span style=\"color: #abcdef\" data-color=\"#abcdef\">colored</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'colored',\n marks: [{ type: 'textColor' as MarkupMarkType, attrs: { color: '#abcdef' } }]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textColor + italic',\n markdown: '<span style=\"color: #abcdef\" data-color=\"#abcdef\">*styled*</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'styled',\n marks: [\n { type: 'textColor' as MarkupMarkType, attrs: { color: '#abcdef' } },\n { type: MarkupMarkType.em }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textStyle with font-family',\n markdown: '<span style=\"font-family: Arial\">arial</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'arial',\n marks: [{ type: MarkupMarkType.textStyle, attrs: { fontFamily: 'Arial' } }]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textStyle with multiple properties',\n markdown: '<span style=\"font-family: Arial; font-size: 16px; font-weight: bold\">styled</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'styled',\n marks: [\n {\n type: MarkupMarkType.textStyle,\n attrs: { fontFamily: 'Arial', fontSize: '16px', fontWeight: 'bold' }\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textStyle with color (no data-color)',\n markdown: '<span style=\"color: red\">red</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'red',\n marks: [{ type: MarkupMarkType.textStyle, attrs: { color: 'red' } }]\n }\n ]\n }\n ]\n }\n }\n ]\n\n describe('to markdown', () => {\n tests.forEach(({ name, markdown, markup }) => {\n it(name, () => {\n const result = markupToMarkdown(markup as MarkupNode, options)\n expect(result).toEqual(markdown)\n })\n })\n })\n})\n\ndescribe('markdownToMarkup -> markupToMarkdown', () => {\n const tests: Array<{ name: string, markdown: string, alternate?: string }> = [\n { name: 'Italic', markdown: '*Asteriscs* and _Underscores_' },\n { name: 'Bold', markdown: '**Asteriscs** and __Underscores__' },\n { name: 'Bullet list with asteriscs', markdown: 'Asterisks :\\r\\n* Firstly\\r\\n* Secondly' },\n { name: 'Bullet list with dashes', markdown: 'Dashes :\\r\\n- Firstly\\r\\n- Secondly' },\n { name: 'TODO list with asteriscs', markdown: '* [ ] Take\\n* [ ] Do\\n\\n' },\n { name: 'TODO list with dashes', markdown: '- [x] Take\\n- [ ] Do\\n\\n' },\n {\n name: 'Different markers',\n markdown:\n 'Asterisks bulleted list:\\r\\n* Asterisks: *Italic* and **Bold*** Underscores: _Italic_ and __Bold__\\r\\n\\r\\nDash bulleted list:\\r\\n- Asterisks: *Italic* and **Bold**\\r\\n- Underscores: _Italic_ and __Bold__\\r\\n-'\n },\n { name: 'Single line comment', markdown: '<!-- Do not erase me -->' },\n {\n name: 'Multsiline comment',\n markdown:\n '\"<!--\\r\\n\\r\\nPlease title your PR as follows: `module: description` (e.g. `time: fix date format`).\\r\\nAlways start with the thing you are fixing, then describe the fix.\\r\\nDon\\'t use past tense (e.g. \"fixed foo bar\").\\r\\n\\r\\nExplain what your PR does and why.\\r\\n\\r\\nIf you are adding a new function, please document it and add tests:\\r\\n\\r\\n```\\r\\n// foo does foo and bar\\r\\nfn foo() {\\r\\n\\r\\n// file_test.v\\r\\nfn test_foo() {\\r\\n assert foo() == ...\\r\\n ...\\r\\n}\\r\\n```\\r\\n\\r\\nIf you are fixing a bug, please add a test that covers it.\\r\\n\\r\\nBefore submitting a PR, please run `v test-all` .\\r\\nSee also `TESTS.md`.\\r\\n\\r\\nI try to process PRs as soon as possible. They should be handled within 24 hours.\\r\\n\\r\\nApplying labels to PRs is not needed.\\r\\n\\r\\nThanks a lot for your contribution!\\r\\n\\r\\n-->\\r\\n\\r\\nThis PR fix issue #22424\\r\\n\\r\\n\\r\\n\"'\n },\n {\n name: 'Link',\n markdown: 'See [link](https://example.com)'\n },\n {\n name: 'Link with spaces',\n markdown: 'See [link](<https://example.com/with spaces>)',\n alternate: 'See [link](https://example.com/with%20spaces)'\n },\n {\n name: 'Link with spaces and braces',\n markdown: 'See [link](<https://example.com/\\\\<with spaces\\\\>>)',\n alternate: 'See [link](https://example.com/%3Cwith%20spaces%3E)'\n },\n {\n name: 'Codeblock',\n markdown: '```typescript\\nconst x: number = 42;\\n```'\n },\n {\n name: 'Image',\n markdown: '<img width=\"320\" height=\"160\" src=\"http://example.com/image\" alt=\"image\">'\n },\n {\n name: 'Images',\n markdown: `\n<img width=\"250\" height=\"330\" src=\"https://github.com/user-attachments/assets/f348e016-3f7d-45b1-b8a0-9098e9961885\" alt=\"Screenshot 2025-09-11 at 15 42 40\" />\n\n<img width=\"250\" height=\"230\" alt=\"Screenshot 2025-09-11 at 15 43 42\" src=\"https://github.com/user-attachments/assets/4502eba1-1f55-44df-b691-c4d3d3d3d67d\" >\n\n<img src=\"https://github.com/user-attachments/assets/e21431a3-2062-4b0b-9c8f-d06c92ede741\" alt=\"Screenshot 2025-09-11 at 15 43 50\" width=\"250\" height=\"210\" >`\n },\n {\n name: 'Image with multiline alt',\n markdown: ''\n },\n {\n name: 'Table',\n markdown:\n '<table><tbody><tr><th><p>Header 1</p></th><th><p>Header 2</p></th></tr><tr><td><p>Cell 1</p></td><td><p>Cell 2</p></td></tr><tr><td><p>Cell 3</p></td><td><p>Cell 4</p></td></tr></tbody></table>'\n },\n {\n name: 'Complex table',\n markdown:\n '<table><tbody><tr><td colspan=\"2\" colwidth=\"320\"><p>Header</p></td></tr><tr><td rowspan=\"2\"><p>Cell 1</p></td><td><p>Cell 2</p></td></tr><tr><td><p>Cell 3</p></td></tr></tbody></table>'\n },\n {\n name: 'Sub',\n markdown: '<sub>View in Huly <a href=\"http://localhost:8080/guest/github?token=token\">TSK-50</a></sub>'\n }\n // {\n // name: 'Malformed',\n // markdown: '<foo>try to parse me</bar></buzz>'\n // }\n ]\n\n tests.forEach(({ name, markdown, alternate }) => {\n it(name, () => {\n const json = markdownToMarkup(markdown, options)\n const serialized = markupToMarkdown(json, options)\n expect(serialized).toEqualMarkdown(alternate ?? markdown)\n })\n })\n})\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["//\n// Copyright \u00A9 2025 Hardcore Engineering Inc.\n//\n// Licensed under the Eclipse Public License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License. You may\n// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\nimport { MarkupNode, MarkupNodeType, MarkupMarkType } from '@hcengineering/text-core'\nimport { markdownToMarkup, markupToMarkdown } from '..'\nimport { isMarkdownsEquals, normalizeMarkdown } from '../compare'\n\nconst refUrl: string = 'ref://'\nconst imageUrl: string = 'http://localhost'\nconst options = { refUrl, imageUrl }\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace jest {\n interface Matchers<R> {\n toEqualMarkdown: (expected: string) => R\n }\n }\n}\n\nexpect.extend({\n toEqualMarkdown (received: string, expected: string) {\n const pass = isMarkdownsEquals(received, expected)\n return {\n message: () =>\n pass\n ? `Expected markdown strings NOT to be equal:\\n Received:\\n${received}\\n Expected:\\n${expected}`\n : `Expected markdown strings to be equal:\\n Received:\\n${received}\\n Expected:\\n${expected}`,\n pass\n }\n }\n})\n\ndescribe('markdownToMarkup', () => {\n const tests: Array<{ name: string, markdown: string, markup: object }> = [\n {\n name: 'simple text',\n markdown: 'Lorem ipsum dolor sit amet.',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Lorem ipsum dolor sit amet.',\n marks: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'text with heading',\n markdown: `# Lorem ipsum\n\nLorem ipsum dolor sit amet.\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'Lorem ipsum',\n marks: []\n }\n ]\n },\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Lorem ipsum dolor sit amet.',\n marks: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'bullet list',\n markdown: `# bullet list\n- list item 1\n- list item 2\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'bullet list',\n marks: []\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'todos',\n markdown: `# TODO\n- [ ] todo 1\n- [x] todo 2\n `,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'TODO',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'todos followed by list items',\n markdown: `# todo and list\n- [ ] todo 1\n- [x] todo 2\n- list item 1\n- list item 2\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'todo and list',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 1',\n marks: []\n }\n ]\n }\n ]\n },\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'todos followed by list items',\n markdown: `# mixed lists\n- [ ] todo 1\n- list item 1\n- [x] todo 2\n- list item 2\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'mixed lists',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 1',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 1',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item 2',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'nested todos',\n markdown: `# nested todos\n- [ ] todo\n - [x] sub todo\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'nested todos',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'nested lists',\n markdown: `# nested lists\n- [ ] todo\n - sub list item\n - [x] sub todo\n- list item\n - [x] sub todo\n - sub list item\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'nested lists',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo',\n marks: []\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub list item',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'list item',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n },\n {\n type: 'bulletList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'listItem',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub list item',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'nested todos',\n markdown: `# nested todos\n- [ ] todo\n - [x] sub todo\n`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'heading',\n attrs: { level: 1, marker: '#' },\n content: [\n {\n type: 'text',\n text: 'nested todos',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: false },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'todo',\n marks: []\n }\n ]\n },\n {\n type: 'todoList',\n attrs: {\n bullet: '-'\n },\n content: [\n {\n type: 'todoItem',\n attrs: { checked: true },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'sub todo',\n marks: []\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'mermaid diagram',\n markdown: '```mermaid\\ngraph TD;\\n\\tA-->B;\\n\\tA-->C;\\n\\tB-->D;\\n\\tC-->D;\\n```',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'mermaid',\n attrs: {\n language: 'mermaid'\n },\n content: [\n {\n marks: [],\n text: 'graph TD;\\n\\tA-->B;\\n\\tA-->C;\\n\\tB-->D;\\n\\tC-->D;',\n type: 'text'\n }\n ]\n }\n ]\n }\n },\n {\n name: 'embed',\n markdown: '<a href=\"http://localhost/embed\" data-type=\"embed\">http://localhost/embed</a>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'embed',\n attrs: { src: 'http://localhost/embed' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'embed-uri-escape',\n markdown:\n '<a href=\"http://localhost/embed%20spaces\" data-type=\"embed\">http://localhost/embed spaces</a>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'embed',\n attrs: { src: 'http://localhost/embed spaces' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'embed-html-escape',\n markdown:\n '<a href=\"http://localhost/embed%3Chtml%3E\" data-type=\"embed\">http://localhost/embed<html></a>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'embed',\n attrs: { src: 'http://localhost/embed<html>' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'multiline image alt',\n markdown: '',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'image',\n attrs: { src: 'http://example.com/image.png', alt: 'line0\\n\\nline1' },\n content: []\n }\n ]\n }\n ]\n }\n },\n {\n name: 'image in a table cell',\n markdown:\n '<table><tbody><tr><td><p>Some text</p><p> <img src=\"files/image_1.png\" alt=\"image-alt\"/></p></td></tr></tbody></table>',\n markup: {\n type: 'doc',\n content: [\n {\n type: 'table',\n content: [\n {\n type: 'tableRow',\n content: [\n {\n type: 'tableCell',\n attrs: {\n colspan: undefined,\n rowspan: undefined,\n colwidth: undefined\n },\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Some text'\n }\n ]\n },\n {\n type: 'paragraph',\n attrs: {\n textAlign: null\n },\n content: [\n {\n type: 'text',\n text: ' '\n },\n {\n type: 'image',\n attrs: {\n src: 'files/image_1.png',\n alt: 'image-alt',\n 'file-id': null,\n title: null\n }\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textColor',\n markdown: '<span style=\"color: #abcdef\" data-color=\"#abcdef\">colored</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'colored',\n marks: [{ type: 'textColor' as MarkupMarkType, attrs: { color: '#abcdef' } }]\n }\n ]\n }\n ]\n }\n }\n ]\n\n describe('to markup', () => {\n tests.forEach(({ name, markdown, markup }) => {\n it(name, () => {\n const parsed = markdownToMarkup(markdown, options)\n expect(parsed).toEqual(markup)\n })\n })\n })\n\n describe('to markdown', () => {\n tests.forEach(({ name, markdown, markup }) => {\n it(name, () => {\n const serialized = markupToMarkdown(markup as MarkupNode, options)\n expect(serialized).toEqualMarkdown(markdown)\n })\n })\n })\n})\n\ndescribe('markupToMarkdown', () => {\n const tests: Array<{ name: string, markdown: string, markup: object }> = [\n {\n name: 'links',\n markdown: `[Link](https://example.com)\n\n[Link with spaces](<https://example.com/with spaces>)\n\n[Link with spaces and braces](<https://example.com/\\\\<with spaces\\\\>>)`,\n markup: {\n type: 'doc',\n content: [\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Link',\n marks: [{ type: 'link', attrs: { href: 'https://example.com' } }]\n }\n ]\n },\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Link with spaces',\n marks: [{ type: 'link', attrs: { href: 'https://example.com/with spaces' } }]\n }\n ]\n },\n {\n type: 'paragraph',\n content: [\n {\n type: 'text',\n text: 'Link with spaces and braces',\n marks: [{ type: 'link', attrs: { href: 'https://example.com/<with spaces>' } }]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textColor',\n markdown: '<span style=\"color: #abcdef\" data-color=\"#abcdef\">colored</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'colored',\n marks: [{ type: 'textColor' as MarkupMarkType, attrs: { color: '#abcdef' } }]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textColor + italic',\n markdown: '<span style=\"color: #abcdef\" data-color=\"#abcdef\">*styled*</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'styled',\n marks: [\n { type: 'textColor' as MarkupMarkType, attrs: { color: '#abcdef' } },\n { type: MarkupMarkType.em }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textStyle with font-family',\n markdown: '<span style=\"font-family: Arial\">arial</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'arial',\n marks: [{ type: MarkupMarkType.textStyle, attrs: { fontFamily: 'Arial' } }]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textStyle with multiple properties',\n markdown: '<span style=\"font-family: Arial; font-size: 16px; font-weight: bold\">styled</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'styled',\n marks: [\n {\n type: MarkupMarkType.textStyle,\n attrs: { fontFamily: 'Arial', fontSize: '16px', fontWeight: 'bold' }\n }\n ]\n }\n ]\n }\n ]\n }\n },\n {\n name: 'textStyle with color (no data-color)',\n markdown: '<span style=\"color: red\">red</span>',\n markup: {\n type: MarkupNodeType.doc,\n content: [\n {\n type: MarkupNodeType.paragraph,\n content: [\n {\n type: MarkupNodeType.text,\n text: 'red',\n marks: [{ type: MarkupMarkType.textStyle, attrs: { color: 'red' } }]\n }\n ]\n }\n ]\n }\n }\n ]\n\n describe('to markdown', () => {\n tests.forEach(({ name, markdown, markup }) => {\n it(name, () => {\n const result = markupToMarkdown(markup as MarkupNode, options)\n expect(result).toEqual(markdown)\n })\n })\n })\n})\n\ndescribe('markdownToMarkup -> markupToMarkdown', () => {\n const tests: Array<{ name: string, markdown: string, alternate?: string }> = [\n { name: 'Italic', markdown: '*Asteriscs* and _Underscores_' },\n { name: 'Bold', markdown: '**Asteriscs** and __Underscores__' },\n { name: 'Bullet list with asteriscs', markdown: 'Asterisks :\\r\\n* Firstly\\r\\n* Secondly' },\n { name: 'Bullet list with dashes', markdown: 'Dashes :\\r\\n- Firstly\\r\\n- Secondly' },\n { name: 'TODO list with asteriscs', markdown: '* [ ] Take\\n* [ ] Do\\n\\n' },\n { name: 'TODO list with dashes', markdown: '- [x] Take\\n- [ ] Do\\n\\n' },\n {\n name: 'Different markers',\n markdown:\n 'Asterisks bulleted list:\\r\\n* Asterisks: *Italic* and **Bold*** Underscores: _Italic_ and __Bold__\\r\\n\\r\\nDash bulleted list:\\r\\n- Asterisks: *Italic* and **Bold**\\r\\n- Underscores: _Italic_ and __Bold__\\r\\n-'\n },\n { name: 'Single line comment', markdown: '<!-- Do not erase me -->' },\n {\n name: 'Multsiline comment',\n markdown:\n '\"<!--\\r\\n\\r\\nPlease title your PR as follows: `module: description` (e.g. `time: fix date format`).\\r\\nAlways start with the thing you are fixing, then describe the fix.\\r\\nDon\\'t use past tense (e.g. \"fixed foo bar\").\\r\\n\\r\\nExplain what your PR does and why.\\r\\n\\r\\nIf you are adding a new function, please document it and add tests:\\r\\n\\r\\n```\\r\\n// foo does foo and bar\\r\\nfn foo() {\\r\\n\\r\\n// file_test.v\\r\\nfn test_foo() {\\r\\n assert foo() == ...\\r\\n ...\\r\\n}\\r\\n```\\r\\n\\r\\nIf you are fixing a bug, please add a test that covers it.\\r\\n\\r\\nBefore submitting a PR, please run `v test-all` .\\r\\nSee also `TESTS.md`.\\r\\n\\r\\nI try to process PRs as soon as possible. They should be handled within 24 hours.\\r\\n\\r\\nApplying labels to PRs is not needed.\\r\\n\\r\\nThanks a lot for your contribution!\\r\\n\\r\\n-->\\r\\n\\r\\nThis PR fix issue #22424\\r\\n\\r\\n\\r\\n\"'\n },\n {\n name: 'Link',\n markdown: 'See [link](https://example.com)'\n },\n {\n name: 'Link with spaces',\n markdown: 'See [link](<https://example.com/with spaces>)',\n alternate: 'See [link](https://example.com/with%20spaces)'\n },\n {\n name: 'Link with spaces and braces',\n markdown: 'See [link](<https://example.com/\\\\<with spaces\\\\>>)',\n alternate: 'See [link](https://example.com/%3Cwith%20spaces%3E)'\n },\n {\n name: 'Codeblock',\n markdown: '```typescript\\nconst x: number = 42;\\n```'\n },\n {\n name: 'Image',\n markdown: '<img width=\"320\" height=\"160\" src=\"http://example.com/image\" alt=\"image\">'\n },\n {\n name: 'Images',\n markdown: `\n<img width=\"250\" height=\"330\" src=\"https://github.com/user-attachments/assets/f348e016-3f7d-45b1-b8a0-9098e9961885\" alt=\"Screenshot 2025-09-11 at 15 42 40\" />\n\n<img width=\"250\" height=\"230\" alt=\"Screenshot 2025-09-11 at 15 43 42\" src=\"https://github.com/user-attachments/assets/4502eba1-1f55-44df-b691-c4d3d3d3d67d\" >\n\n<img src=\"https://github.com/user-attachments/assets/e21431a3-2062-4b0b-9c8f-d06c92ede741\" alt=\"Screenshot 2025-09-11 at 15 43 50\" width=\"250\" height=\"210\" >`\n },\n {\n name: 'Image with multiline alt',\n markdown: ''\n },\n {\n name: 'Table',\n markdown:\n '<table><tbody><tr><th><p>Header 1</p></th><th><p>Header 2</p></th></tr><tr><td><p>Cell 1</p></td><td><p>Cell 2</p></td></tr><tr><td><p>Cell 3</p></td><td><p>Cell 4</p></td></tr></tbody></table>'\n },\n {\n name: 'Complex table',\n markdown:\n '<table><tbody><tr><td colspan=\"2\" colwidth=\"320\"><p>Header</p></td></tr><tr><td rowspan=\"2\"><p>Cell 1</p></td><td><p>Cell 2</p></td></tr><tr><td><p>Cell 3</p></td></tr></tbody></table>'\n },\n {\n name: 'Sub',\n markdown: '<sub>View in Huly <a href=\"http://localhost:8080/guest/github?token=token\">TSK-50</a></sub>'\n }\n // {\n // name: 'Malformed',\n // markdown: '<foo>try to parse me</bar></buzz>'\n // }\n ]\n\n tests.forEach(({ name, markdown, alternate }) => {\n it(name, () => {\n const json = markdownToMarkup(markdown, options)\n const serialized = markupToMarkdown(json, options)\n expect(serialized).toEqualMarkdown(alternate ?? markdown)\n })\n })\n})\n\ndescribe('normalizeMarkdown', () => {\n it('handles null and undefined inputs', () => {\n expect(normalizeMarkdown(null as any)).toBe('')\n expect(normalizeMarkdown(undefined as any)).toBe('')\n expect(normalizeMarkdown('')).toBe('')\n })\n\n it('handles non-string inputs', () => {\n expect(normalizeMarkdown(123 as any)).toBe('')\n expect(normalizeMarkdown({} as any)).toBe('')\n expect(normalizeMarkdown([] as any)).toBe('')\n })\n\n it('normalizes line endings', () => {\n expect(normalizeMarkdown('line1\\r\\nline2\\rline3\\nline4')).toBe('line1\\nline2\\nline3\\nline4')\n })\n\n it('removes trailing whitespace and empty lines', () => {\n expect(normalizeMarkdown('line1 \\n \\nline2 \\n\\n\\nline3')).toBe('line1\\nline2\\nline3')\n })\n\n it('normalizes HTML tag attributes', () => {\n const input = '<img src=\"test.jpg\" alt=\"test\" width=\"100\">'\n const expected = '<img alt=\"test\" src=\"test.jpg\" width=\"100\" />'\n expect(normalizeMarkdown(input)).toBe(expected)\n })\n\n it('handles void elements correctly', () => {\n expect(normalizeMarkdown('<img src=\"test.jpg\">')).toBe('<img src=\"test.jpg\" />')\n expect(normalizeMarkdown('<br>')).toBe('<br />')\n expect(normalizeMarkdown('<hr>')).toBe('<hr />')\n })\n\n it('handles non-void elements correctly', () => {\n expect(normalizeMarkdown('<div class=\"test\">')).toBe('<div class=\"test\">')\n expect(normalizeMarkdown('<span>')).toBe('<span>')\n })\n\n it('sorts attributes alphabetically', () => {\n const input = '<img width=\"100\" src=\"test.jpg\" height=\"200\" alt=\"test\">'\n const expected = '<img alt=\"test\" height=\"200\" src=\"test.jpg\" width=\"100\" />'\n expect(normalizeMarkdown(input)).toBe(expected)\n })\n\n it('handles attributes without values', () => {\n expect(normalizeMarkdown('<input type=\"checkbox\" checked>')).toBe('<input checked type=\"checkbox\" />')\n })\n\n it('handles mixed content', () => {\n const input = 'Text before\\r\\n<img alt=\"test\" src=\"image.jpg\"> \\n\\nText after '\n const expected = 'Text before\\n<img alt=\"test\" src=\"image.jpg\" />\\nText after'\n expect(normalizeMarkdown(input)).toBe(expected)\n })\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/compare.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(compare_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(compare_exports);
|
|
27
27
|
function calcS\u00F8rensenDiceCoefficient(a, b) {
|
|
28
|
+
if (a == null || b == null) return 0;
|
|
28
29
|
const first = a.replace(/\s+/g, "");
|
|
29
30
|
const second = b.replace(/\s+/g, "");
|
|
30
31
|
if (first === second) return 1;
|
|
@@ -44,7 +45,9 @@ function calcS\u00F8rensenDiceCoefficient(a, b) {
|
|
|
44
45
|
intersectionSize++;
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
const denominator = first.length + second.length - 2;
|
|
49
|
+
if (denominator <= 0) return 0;
|
|
50
|
+
return 2 * intersectionSize / denominator;
|
|
48
51
|
}
|
|
49
52
|
__name(calcS\u00F8rensenDiceCoefficient, "calcS\xF8rensenDiceCoefficient");
|
|
50
53
|
function isMarkdownsEquals(source1, source2) {
|
|
@@ -54,9 +57,10 @@ function isMarkdownsEquals(source1, source2) {
|
|
|
54
57
|
}
|
|
55
58
|
__name(isMarkdownsEquals, "isMarkdownsEquals");
|
|
56
59
|
function normalizeMarkdown(source) {
|
|
60
|
+
if (source == null || typeof source !== "string") return "";
|
|
57
61
|
const tagRegex = /<(\w+)([^>]*?)(\/?)>/g;
|
|
58
62
|
const attrRegex = /(\w+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/g;
|
|
59
|
-
source = source.replace(/\r
|
|
63
|
+
source = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
60
64
|
source = source.split("\n").map((it) => it.trimEnd()).filter((it) => it.length > 0).join("\n");
|
|
61
65
|
source = source.replace(tagRegex, (match, tagName, attributes) => {
|
|
62
66
|
const attrs = {};
|
package/lib/compare.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/compare.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright \u00A9 2025 Hardcore Engineering Inc.\n//\n// Licensed under the Eclipse Public License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License. You may\n// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * Calculate S\u00F8rensen\u2013Dice coefficient\n */\nexport function calcS\u00F8rensenDiceCoefficient (a: string, b: string): number {\n const first = a.replace(/\\s+/g, '')\n const second = b.replace(/\\s+/g, '')\n\n if (first === second) return 1 // identical or empty\n if (first.length < 2 || second.length < 2) return 0 // if either is a 0-letter or 1-letter string\n\n const firstBigrams = new Map<string, number>()\n for (let i = 0; i < first.length - 1; i++) {\n const bigram = first.substring(i, i + 2)\n const count = (firstBigrams.get(bigram) ?? 0) + 1\n\n firstBigrams.set(bigram, count)\n }\n\n let intersectionSize = 0\n for (let i = 0; i < second.length - 1; i++) {\n const bigram = second.substring(i, i + 2)\n const count = firstBigrams.get(bigram) ?? 0\n\n if (count > 0) {\n firstBigrams.set(bigram, count - 1)\n intersectionSize++\n }\n }\n\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,SAAS,iCAA6B,GAAW,GAAmB;AACzE,QAAM,QAAQ,EAAE,QAAQ,QAAQ,EAAE;AAClC,QAAM,SAAS,EAAE,QAAQ,QAAQ,EAAE;AAEnC,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,MAAM,SAAS,KAAK,OAAO,SAAS,EAAG,QAAO;AAElD,QAAM,eAAe,oBAAI,IAAoB;AAC7C,WAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAM,SAAS,MAAM,UAAU,GAAG,IAAI,CAAC;AACvC,UAAM,SAAS,aAAa,IAAI,MAAM,KAAK,KAAK;AAEhD,iBAAa,IAAI,QAAQ,KAAK;AAAA,EAChC;AAEA,MAAI,mBAAmB;AACvB,WAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,UAAM,SAAS,OAAO,UAAU,GAAG,IAAI,CAAC;AACxC,UAAM,QAAQ,aAAa,IAAI,MAAM,KAAK;AAE1C,QAAI,QAAQ,GAAG;AACb,mBAAa,IAAI,QAAQ,QAAQ,CAAC;AAClC;AAAA,IACF;AAAA,EACF;AAEA,
|
|
4
|
+
"sourcesContent": ["//\n// Copyright \u00A9 2025 Hardcore Engineering Inc.\n//\n// Licensed under the Eclipse Public License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License. You may\n// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n//\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n/**\n * Calculate S\u00F8rensen\u2013Dice coefficient\n */\nexport function calcS\u00F8rensenDiceCoefficient (a: string, b: string): number {\n if (a == null || b == null) return 0\n\n const first = a.replace(/\\s+/g, '')\n const second = b.replace(/\\s+/g, '')\n\n if (first === second) return 1 // identical or empty\n if (first.length < 2 || second.length < 2) return 0 // if either is a 0-letter or 1-letter string\n\n const firstBigrams = new Map<string, number>()\n for (let i = 0; i < first.length - 1; i++) {\n const bigram = first.substring(i, i + 2)\n const count = (firstBigrams.get(bigram) ?? 0) + 1\n\n firstBigrams.set(bigram, count)\n }\n\n let intersectionSize = 0\n for (let i = 0; i < second.length - 1; i++) {\n const bigram = second.substring(i, i + 2)\n const count = firstBigrams.get(bigram) ?? 0\n\n if (count > 0) {\n firstBigrams.set(bigram, count - 1)\n intersectionSize++\n }\n }\n\n const denominator = first.length + second.length - 2\n if (denominator <= 0) return 0\n\n return (2.0 * intersectionSize) / denominator\n}\n\n/**\n * Perform markdown diff/comparison to understand do we have a major differences.\n */\nexport function isMarkdownsEquals (source1: string, source2: string): boolean {\n const normalized1 = normalizeMarkdown(source1)\n const normalized2 = normalizeMarkdown(source2)\n return normalized1 === normalized2\n}\n\nexport function normalizeMarkdown (source: string): string {\n if (source == null || typeof source !== 'string') return ''\n\n const tagRegex = /<(\\w+)([^>]*?)(\\/?)>/g\n const attrRegex = /(\\w+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?/g\n\n // Normalize line endings to LF\n source = source.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\n // Remove extra blank lines\n source = source\n .split('\\n')\n .map((it) => it.trimEnd())\n .filter((it) => it.length > 0)\n .join('\\n')\n\n // Normalize HTML tags\n source = source.replace(tagRegex, (match, tagName, attributes) => {\n const attrs: Record<string, string> = {}\n\n let attrMatch = attrRegex.exec(attributes)\n while (attrMatch !== null) {\n const attrName = attrMatch[1]\n const attrValue = attrMatch[2] ?? attrMatch[3] ?? attrMatch[4] ?? ''\n attrs[attrName] = attrValue\n attrMatch = attrRegex.exec(attributes)\n }\n\n // Sort attributes by name for consistent order\n const sortedAttrs = Object.keys(attrs)\n .sort()\n .map((key) => {\n const value = attrs[key]\n return value !== '' ? `${key}=\"${value}\"` : key\n })\n .join(' ')\n\n // Normalize to self-closing format for void elements\n const voidElements = [\n 'img',\n 'br',\n 'hr',\n 'input',\n 'meta',\n 'area',\n 'base',\n 'col',\n 'embed',\n 'link',\n 'param',\n 'source',\n 'track',\n 'wbr'\n ]\n const isVoidElement = voidElements.includes(tagName.toLowerCase())\n\n if (sortedAttrs !== '') {\n return isVoidElement ? `<${tagName} ${sortedAttrs} />` : `<${tagName} ${sortedAttrs}>`\n } else {\n return isVoidElement ? `<${tagName} />` : `<${tagName}>`\n }\n })\n\n return source\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,SAAS,iCAA6B,GAAW,GAAmB;AACzE,MAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AAEnC,QAAM,QAAQ,EAAE,QAAQ,QAAQ,EAAE;AAClC,QAAM,SAAS,EAAE,QAAQ,QAAQ,EAAE;AAEnC,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,MAAM,SAAS,KAAK,OAAO,SAAS,EAAG,QAAO;AAElD,QAAM,eAAe,oBAAI,IAAoB;AAC7C,WAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAM,SAAS,MAAM,UAAU,GAAG,IAAI,CAAC;AACvC,UAAM,SAAS,aAAa,IAAI,MAAM,KAAK,KAAK;AAEhD,iBAAa,IAAI,QAAQ,KAAK;AAAA,EAChC;AAEA,MAAI,mBAAmB;AACvB,WAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,UAAM,SAAS,OAAO,UAAU,GAAG,IAAI,CAAC;AACxC,UAAM,QAAQ,aAAa,IAAI,MAAM,KAAK;AAE1C,QAAI,QAAQ,GAAG;AACb,mBAAa,IAAI,QAAQ,QAAQ,CAAC;AAClC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,SAAS,OAAO,SAAS;AACnD,MAAI,eAAe,EAAG,QAAO;AAE7B,SAAQ,IAAM,mBAAoB;AACpC;AAhCgB;AAqCT,SAAS,kBAAmB,SAAiB,SAA0B;AAC5E,QAAM,cAAc,kBAAkB,OAAO;AAC7C,QAAM,cAAc,kBAAkB,OAAO;AAC7C,SAAO,gBAAgB;AACzB;AAJgB;AAMT,SAAS,kBAAmB,QAAwB;AACzD,MAAI,UAAU,QAAQ,OAAO,WAAW,SAAU,QAAO;AAEzD,QAAM,WAAW;AACjB,QAAM,YAAY;AAGlB,WAAS,OAAO,QAAQ,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI;AAG1D,WAAS,OACN,MAAM,IAAI,EACV,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,EACxB,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,EAC5B,KAAK,IAAI;AAGZ,WAAS,OAAO,QAAQ,UAAU,CAAC,OAAO,SAAS,eAAe;AAChE,UAAM,QAAgC,CAAC;AAEvC,QAAI,YAAY,UAAU,KAAK,UAAU;AACzC,WAAO,cAAc,MAAM;AACzB,YAAM,WAAW,UAAU,CAAC;AAC5B,YAAM,YAAY,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK;AAClE,YAAM,QAAQ,IAAI;AAClB,kBAAY,UAAU,KAAK,UAAU;AAAA,IACvC;AAGA,UAAM,cAAc,OAAO,KAAK,KAAK,EAClC,KAAK,EACL,IAAI,CAAC,QAAQ;AACZ,YAAM,QAAQ,MAAM,GAAG;AACvB,aAAO,UAAU,KAAK,GAAG,GAAG,KAAK,KAAK,MAAM;AAAA,IAC9C,CAAC,EACA,KAAK,GAAG;AAGX,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,gBAAgB,aAAa,SAAS,QAAQ,YAAY,CAAC;AAEjE,QAAI,gBAAgB,IAAI;AACtB,aAAO,gBAAgB,IAAI,OAAO,IAAI,WAAW,QAAQ,IAAI,OAAO,IAAI,WAAW;AAAA,IACrF,OAAO;AACL,aAAO,gBAAgB,IAAI,OAAO,QAAQ,IAAI,OAAO;AAAA,IACvD;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAhEgB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
import { MarkupNode, MarkupNodeType, MarkupMarkType } from '@hcengineering/text-core'
|
|
17
17
|
import { markdownToMarkup, markupToMarkdown } from '..'
|
|
18
|
-
import { isMarkdownsEquals } from '../compare'
|
|
18
|
+
import { isMarkdownsEquals, normalizeMarkdown } from '../compare'
|
|
19
19
|
|
|
20
20
|
const refUrl: string = 'ref://'
|
|
21
21
|
const imageUrl: string = 'http://localhost'
|
|
@@ -1195,3 +1195,58 @@ describe('markdownToMarkup -> markupToMarkdown', () => {
|
|
|
1195
1195
|
})
|
|
1196
1196
|
})
|
|
1197
1197
|
})
|
|
1198
|
+
|
|
1199
|
+
describe('normalizeMarkdown', () => {
|
|
1200
|
+
it('handles null and undefined inputs', () => {
|
|
1201
|
+
expect(normalizeMarkdown(null as any)).toBe('')
|
|
1202
|
+
expect(normalizeMarkdown(undefined as any)).toBe('')
|
|
1203
|
+
expect(normalizeMarkdown('')).toBe('')
|
|
1204
|
+
})
|
|
1205
|
+
|
|
1206
|
+
it('handles non-string inputs', () => {
|
|
1207
|
+
expect(normalizeMarkdown(123 as any)).toBe('')
|
|
1208
|
+
expect(normalizeMarkdown({} as any)).toBe('')
|
|
1209
|
+
expect(normalizeMarkdown([] as any)).toBe('')
|
|
1210
|
+
})
|
|
1211
|
+
|
|
1212
|
+
it('normalizes line endings', () => {
|
|
1213
|
+
expect(normalizeMarkdown('line1\r\nline2\rline3\nline4')).toBe('line1\nline2\nline3\nline4')
|
|
1214
|
+
})
|
|
1215
|
+
|
|
1216
|
+
it('removes trailing whitespace and empty lines', () => {
|
|
1217
|
+
expect(normalizeMarkdown('line1 \n \nline2 \n\n\nline3')).toBe('line1\nline2\nline3')
|
|
1218
|
+
})
|
|
1219
|
+
|
|
1220
|
+
it('normalizes HTML tag attributes', () => {
|
|
1221
|
+
const input = '<img src="test.jpg" alt="test" width="100">'
|
|
1222
|
+
const expected = '<img alt="test" src="test.jpg" width="100" />'
|
|
1223
|
+
expect(normalizeMarkdown(input)).toBe(expected)
|
|
1224
|
+
})
|
|
1225
|
+
|
|
1226
|
+
it('handles void elements correctly', () => {
|
|
1227
|
+
expect(normalizeMarkdown('<img src="test.jpg">')).toBe('<img src="test.jpg" />')
|
|
1228
|
+
expect(normalizeMarkdown('<br>')).toBe('<br />')
|
|
1229
|
+
expect(normalizeMarkdown('<hr>')).toBe('<hr />')
|
|
1230
|
+
})
|
|
1231
|
+
|
|
1232
|
+
it('handles non-void elements correctly', () => {
|
|
1233
|
+
expect(normalizeMarkdown('<div class="test">')).toBe('<div class="test">')
|
|
1234
|
+
expect(normalizeMarkdown('<span>')).toBe('<span>')
|
|
1235
|
+
})
|
|
1236
|
+
|
|
1237
|
+
it('sorts attributes alphabetically', () => {
|
|
1238
|
+
const input = '<img width="100" src="test.jpg" height="200" alt="test">'
|
|
1239
|
+
const expected = '<img alt="test" height="200" src="test.jpg" width="100" />'
|
|
1240
|
+
expect(normalizeMarkdown(input)).toBe(expected)
|
|
1241
|
+
})
|
|
1242
|
+
|
|
1243
|
+
it('handles attributes without values', () => {
|
|
1244
|
+
expect(normalizeMarkdown('<input type="checkbox" checked>')).toBe('<input checked type="checkbox" />')
|
|
1245
|
+
})
|
|
1246
|
+
|
|
1247
|
+
it('handles mixed content', () => {
|
|
1248
|
+
const input = 'Text before\r\n<img alt="test" src="image.jpg"> \n\nText after '
|
|
1249
|
+
const expected = 'Text before\n<img alt="test" src="image.jpg" />\nText after'
|
|
1250
|
+
expect(normalizeMarkdown(input)).toBe(expected)
|
|
1251
|
+
})
|
|
1252
|
+
})
|
package/src/compare.ts
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* Calculate Sørensen–Dice coefficient
|
|
18
18
|
*/
|
|
19
19
|
export function calcSørensenDiceCoefficient (a: string, b: string): number {
|
|
20
|
+
if (a == null || b == null) return 0
|
|
21
|
+
|
|
20
22
|
const first = a.replace(/\s+/g, '')
|
|
21
23
|
const second = b.replace(/\s+/g, '')
|
|
22
24
|
|
|
@@ -42,7 +44,10 @@ export function calcSørensenDiceCoefficient (a: string, b: string): number {
|
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
const denominator = first.length + second.length - 2
|
|
48
|
+
if (denominator <= 0) return 0
|
|
49
|
+
|
|
50
|
+
return (2.0 * intersectionSize) / denominator
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
/**
|
|
@@ -55,11 +60,13 @@ export function isMarkdownsEquals (source1: string, source2: string): boolean {
|
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
export function normalizeMarkdown (source: string): string {
|
|
63
|
+
if (source == null || typeof source !== 'string') return ''
|
|
64
|
+
|
|
58
65
|
const tagRegex = /<(\w+)([^>]*?)(\/?)>/g
|
|
59
66
|
const attrRegex = /(\w+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/g
|
|
60
67
|
|
|
61
68
|
// Normalize line endings to LF
|
|
62
|
-
source = source.replace(/\r
|
|
69
|
+
source = source.replace(/\r\n/g, '\n').replace(/\r/g, '\n')
|
|
63
70
|
|
|
64
71
|
// Remove extra blank lines
|
|
65
72
|
source = source
|
package/types/compare.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,wBAAgB,2BAA2B,CAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,wBAAgB,2BAA2B,CAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAgCzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAI5E;AAED,wBAAgB,iBAAiB,CAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgEzD"}
|