feat: update marked (#810)

This commit is contained in:
boojack 2022-12-21 18:36:26 +08:00 committed by GitHub
parent 1838e616fd
commit ab07c91d42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 244 additions and 108 deletions

View File

@ -1,25 +1,22 @@
import { blockElementParserList, inlineElementParserList } from "./parser"; import { blockElementParserList, inlineElementParserList } from "./parser";
const match = (rawStr: string, regex: RegExp): number => {
const matchResult = rawStr.match(regex);
if (!matchResult) {
return 0;
}
const matchStr = matchResult[0];
return matchStr.length;
};
export const marked = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => { export const marked = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => {
for (const parser of blockParsers) { for (const parser of blockParsers) {
const startIndex = markdownStr.search(parser.regex); const matchResult = parser.matcher(markdownStr);
const matchedLength = match(markdownStr, parser.regex); if (!matchResult) {
continue;
}
const matchedStr = matchResult[0];
const retainContent = markdownStr.slice(matchedStr.length);
if (startIndex > -1 && matchedLength > 0) { if (parser.name === "br") {
const prefixStr = markdownStr.slice(0, startIndex); return parser.renderer(matchedStr) + marked(retainContent, blockParsers, inlineParsers);
const matchedStr = markdownStr.slice(startIndex, startIndex + matchedLength); } else {
const suffixStr = markdownStr.slice(startIndex + matchedLength); if (retainContent === "") {
return marked(prefixStr, blockParsers, inlineParsers) + parser.renderer(matchedStr) + marked(suffixStr, blockParsers, inlineParsers); return parser.renderer(matchedStr);
} else if (retainContent.startsWith("\n")) {
return parser.renderer(matchedStr) + marked(retainContent.slice(1), blockParsers, inlineParsers);
}
} }
} }
@ -27,27 +24,31 @@ export const marked = (markdownStr: string, blockParsers = blockElementParserLis
let matchedIndex = -1; let matchedIndex = -1;
for (const parser of inlineParsers) { for (const parser of inlineParsers) {
const matchResult = parser.matcher(markdownStr);
if (!matchResult) {
continue;
}
if (parser.name === "plain text" && matchedInlineParser !== undefined) { if (parser.name === "plain text" && matchedInlineParser !== undefined) {
continue; continue;
} }
const startIndex = markdownStr.search(parser.regex); const startIndex = matchResult.index as number;
const matchedLength = match(markdownStr, parser.regex); if (matchedInlineParser === undefined || matchedIndex > startIndex) {
matchedInlineParser = parser;
if (startIndex > -1 && matchedLength > 0) { matchedIndex = startIndex;
if (!matchedInlineParser || matchedIndex > startIndex) {
matchedIndex = startIndex;
matchedInlineParser = parser;
}
} }
} }
if (matchedInlineParser) { if (matchedInlineParser) {
const matchedLength = match(markdownStr, matchedInlineParser.regex); const matchResult = matchedInlineParser.matcher(markdownStr);
const prefixStr = markdownStr.slice(0, matchedIndex); if (matchResult) {
const matchedStr = markdownStr.slice(matchedIndex, matchedIndex + matchedLength); const matchedStr = matchResult[0];
const suffixStr = markdownStr.slice(matchedIndex + matchedLength); const matchedLength = matchedStr.length;
return prefixStr + matchedInlineParser.renderer(matchedStr) + marked(suffixStr, [], inlineParsers); const prefixStr = markdownStr.slice(0, matchedIndex);
const suffixStr = markdownStr.slice(matchedIndex + matchedLength);
return prefixStr + matchedInlineParser.renderer(matchedStr) + marked(suffixStr, [], inlineParsers);
}
} }
return markdownStr; return markdownStr;

View File

@ -7,20 +7,13 @@ describe("test marked parser", () => {
test("horizontal rule", () => { test("horizontal rule", () => {
const tests = [ const tests = [
{ {
markdown: `To create a horizontal rule, use three or more asterisks (***), dashes (---), or underscores (___) on a line by themselves. markdown: `---
---
This is some text after the horizontal rule. This is some text after the horizontal rule.
___ ___
This is some text after the horizontal rule. This is some text after the horizontal rule.
*** ***
This is some text after the horizontal rule.`, This is some text after the horizontal rule.`,
want: `<p>To create a horizontal rule, use three or more asterisks (<em>*</em>), dashes (---), or underscores (___) on a line by themselves.</p> want: `<hr><p>This is some text after the horizontal rule.</p><hr><p>This is some text after the horizontal rule.</p><hr><p>This is some text after the horizontal rule.</p>`,
<hr>
<p>This is some text after the horizontal rule.</p>
<hr>
<p>This is some text after the horizontal rule.</p>
<hr>
<p>This is some text after the horizontal rule.</p>`,
}, },
]; ];
for (const t of tests) { for (const t of tests) {
@ -42,9 +35,7 @@ hello world!
\`\`\`js \`\`\`js
console.log("hello world!") console.log("hello world!")
\`\`\``, \`\`\``,
want: `<p>test code block</p> want: `<p>test code block</p><br><pre><code class="language-js"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"hello world!"</span>)
<p></p>
<pre><code class="language-js"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"hello world!"</span>)
</code></pre>`, </code></pre>`,
}, },
]; ];
@ -59,9 +50,7 @@ console.log("hello world!")
markdown: `My task: markdown: `My task:
- [ ] finish my homework - [ ] finish my homework
- [x] yahaha`, - [x] yahaha`,
want: `<p>My task:</p> want: `<p>My task:</p><p class='li-container'><span class='todo-block todo' data-value='TODO'></span><span>finish my homework</span></p><p class='li-container'><span class='todo-block done' data-value='DONE'>✓</span><span>yahaha</span></p>`,
<p class='li-container'><span class='todo-block todo' data-value='TODO'></span><span>finish my homework</span></p>
<p class='li-container'><span class='todo-block done' data-value='DONE'></span><span>yahaha</span></p>`,
}, },
]; ];
@ -75,9 +64,7 @@ console.log("hello world!")
markdown: `This is a list markdown: `This is a list
* list 123 * list 123
1. 123123`, 1. 123123`,
want: `<p>This is a list</p> want: `<p>This is a list</p><p class='li-container'><span class='ul-block'>•</span><span>list 123</span></p><p class='li-container'><span class='ol-block'>1.</span><span>123123</span></p>`,
<p class='li-container'><span class='ul-block'></span><span>list 123</span></p>
<p class='li-container'><span class='ol-block'>1.</span><span>123123</span></p>`,
}, },
]; ];
@ -88,8 +75,8 @@ console.log("hello world!")
test("parse inline element", () => { test("parse inline element", () => {
const tests = [ const tests = [
{ {
markdown: `Link: [baidu](https://baidu.com)`, markdown: `Link: [baidu](https://baidu.com#1231)`,
want: `<p>Link: <a class='link' target='_blank' rel='noreferrer' href='https://baidu.com'>baidu</a></p>`, want: `<p>Link: <a class='link' target='_blank' rel='noreferrer' href='https://baidu.com#1231'>baidu</a></p>`,
}, },
]; ];
@ -112,8 +99,8 @@ console.log("hello world!")
test("parse plain link", () => { test("parse plain link", () => {
const tests = [ const tests = [
{ {
markdown: `Link:https://baidu.com`, markdown: `Link:https://baidu.com#1231`,
want: `<p>Link:<a class='link' target='_blank' rel='noreferrer' href='https://baidu.com'>https://baidu.com</a></p>`, want: `<p>Link:<a class='link' target='_blank' rel='noreferrer' href='https://baidu.com#1231'>https://baidu.com#1231</a></p>`,
}, },
]; ];
@ -162,8 +149,34 @@ console.log("hello world!")
{ {
markdown: `  line1 markdown: `  line1
  line2`,   line2`,
want: `<p>  line1</p> want: `<p>  line1</p><p>  line2</p>`,
<p>  line2</p>`, },
];
for (const t of tests) {
expect(unescape(marked(t.markdown))).toBe(t.want);
}
});
test("parse tags", () => {
const tests = [
{
markdown: `#123 `,
want: `<p><span class='tag-span'>#123</span> </p>`,
},
{
markdown: `#123#asd`,
want: `<p><span class='tag-span'>#123</span><span class='tag-span'>#asd</span></p>`,
},
{
markdown: `#123`,
want: `<p><span class='tag-span'>#123</span></p>`,
},
{
markdown: `123123#123`,
want: `<p>123123<span class='tag-span'>#123</span></p>`,
},
{
markdown: `123123 #123`,
want: `<p>123123 <span class='tag-span'>#123</span></p>`,
}, },
]; ];
for (const t of tests) { for (const t of tests) {

View File

@ -1,18 +1,24 @@
import { escape } from "lodash"; import { escape } from "lodash";
export const BLOCKQUOTE_REG = /^>\s+(.+)(\n?)/; export const BLOCKQUOTE_REG = /^> ([^\n]+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(BLOCKQUOTE_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(BLOCKQUOTE_REG); const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
return `<blockquote>${escape(matchResult[1])}</blockquote>${matchResult[2]}`; return `<blockquote>${escape(matchResult[1])}</blockquote>`;
}; };
export default { export default {
name: "blockquote", name: "blockquote",
regex: BLOCKQUOTE_REG, regex: BLOCKQUOTE_REG,
matcher,
renderer, renderer,
}; };

View File

@ -3,8 +3,13 @@ import Link from "./Link";
export const BOLD_REG = /\*\*(.+?)\*\*/; export const BOLD_REG = /\*\*(.+?)\*\*/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(BOLD_REG); const matchResult = rawStr.match(BOLD_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -16,5 +21,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "bold", name: "bold",
regex: BOLD_REG, regex: BOLD_REG,
matcher,
renderer, renderer,
}; };

View File

@ -3,8 +3,13 @@ import Link from "./Link";
export const BOLD_EMPHASIS_REG = /\*\*\*(.+?)\*\*\*/; export const BOLD_EMPHASIS_REG = /\*\*\*(.+?)\*\*\*/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(BOLD_EMPHASIS_REG); const matchResult = rawStr.match(BOLD_EMPHASIS_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -16,5 +21,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "bold emphasis", name: "bold emphasis",
regex: BOLD_EMPHASIS_REG, regex: BOLD_EMPHASIS_REG,
matcher,
renderer, renderer,
}; };

View File

@ -0,0 +1,17 @@
export const BR_REG = /^(\n+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(BR_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
return rawStr.replaceAll("\n", "<br>");
};
export default {
name: "br",
regex: BR_REG,
matcher,
renderer,
};

View File

@ -1,10 +1,15 @@
import { escape } from "lodash-es"; import { escape } from "lodash-es";
import hljs from "highlight.js"; import hljs from "highlight.js";
export const CODE_BLOCK_REG = /^```(\S*?)\s([\s\S]*?)```(\n?)/; export const CODE_BLOCK_REG = /^```(\S*?)\s([\s\S]*?)```/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(CODE_BLOCK_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(CODE_BLOCK_REG); const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -21,11 +26,12 @@ const renderer = (rawStr: string): string => {
// do nth // do nth
} }
return `<pre><code class="language-${language}">${highlightedCode}</code></pre>${matchResult[3]}`; return `<pre><code class="language-${language}">${highlightedCode}</code></pre>`;
}; };
export default { export default {
name: "code block", name: "code block",
regex: CODE_BLOCK_REG, regex: CODE_BLOCK_REG,
matcher,
renderer, renderer,
}; };

View File

@ -1,20 +1,26 @@
import { inlineElementParserList } from "."; import { inlineElementParserList } from ".";
import { marked } from ".."; import { marked } from "..";
export const DONE_LIST_REG = /^- \[[xX]\] (.+)(\n?)/; export const DONE_LIST_REG = /^- \[[xX]\] ([^\n]+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(DONE_LIST_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(DONE_LIST_REG); const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
const parsedContent = marked(matchResult[1], [], inlineElementParserList); const parsedContent = marked(matchResult[1], [], inlineElementParserList);
return `<p class='li-container'><span class='todo-block done' data-value='DONE'>✓</span><span>${parsedContent}</span></p>${matchResult[2]}`; return `<p class='li-container'><span class='todo-block done' data-value='DONE'>✓</span><span>${parsedContent}</span></p>`;
}; };
export default { export default {
name: "done list", name: "done list",
regex: DONE_LIST_REG, regex: DONE_LIST_REG,
matcher,
renderer, renderer,
}; };

View File

@ -3,8 +3,13 @@ import Link from "./Link";
export const EMPHASIS_REG = /\*(.+?)\*/; export const EMPHASIS_REG = /\*(.+?)\*/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(EMPHASIS_REG); const matchResult = rawStr.match(EMPHASIS_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -16,5 +21,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "emphasis", name: "emphasis",
regex: EMPHASIS_REG, regex: EMPHASIS_REG,
matcher,
renderer, renderer,
}; };

View File

@ -1,15 +1,18 @@
export const HORIZONTAL_RULES_REG = /^---\n|^\*\*\*\n|^___\n/; export const HORIZONTAL_RULES_REG = /^_{3}|^-{3}|^\*{3}/;
export const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(HORIZONTAL_RULES_REG); const matchResult = rawStr.match(HORIZONTAL_RULES_REG);
if (!matchResult) { return matchResult;
return rawStr; };
}
return `<hr>\n`; // eslint-disable-next-line @typescript-eslint/no-unused-vars
export const renderer = (rawStr: string): string => {
return `<hr>`;
}; };
export default { export default {
name: "horizontal rules", name: "horizontal rules",
regex: HORIZONTAL_RULES_REG, regex: HORIZONTAL_RULES_REG,
matcher,
renderer, renderer,
}; };

View File

@ -3,8 +3,13 @@ import { absolutifyLink } from "../../../helpers/utils";
export const IMAGE_REG = /!\[.*?\]\((.+?)\)/; export const IMAGE_REG = /!\[.*?\]\((.+?)\)/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(IMAGE_REG); const matchResult = rawStr.match(IMAGE_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -16,5 +21,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "image", name: "image",
regex: IMAGE_REG, regex: IMAGE_REG,
matcher,
renderer, renderer,
}; };

View File

@ -2,8 +2,13 @@ import { escape } from "lodash-es";
export const INLINE_CODE_REG = /`(.+?)`/; export const INLINE_CODE_REG = /`(.+?)`/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(INLINE_CODE_REG); const matchResult = rawStr.match(INLINE_CODE_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -14,5 +19,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "inline code", name: "inline code",
regex: INLINE_CODE_REG, regex: INLINE_CODE_REG,
matcher,
renderer, renderer,
}; };

View File

@ -7,8 +7,13 @@ import BoldEmphasis from "./BoldEmphasis";
export const LINK_REG = /\[(.*?)\]\((.+?)\)+/; export const LINK_REG = /\[(.*?)\]\((.+?)\)+/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(LINK_REG); const matchResult = rawStr.match(LINK_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -19,5 +24,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "link", name: "link",
regex: LINK_REG, regex: LINK_REG,
matcher,
renderer, renderer,
}; };

View File

@ -1,20 +1,26 @@
import { inlineElementParserList } from "."; import { inlineElementParserList } from ".";
import { marked } from ".."; import { marked } from "..";
export const ORDERED_LIST_REG = /^(\d+)\. (.+)(\n?)/; export const ORDERED_LIST_REG = /^(\d+)\. (.+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(ORDERED_LIST_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(ORDERED_LIST_REG); const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
const parsedContent = marked(matchResult[2], [], inlineElementParserList); const parsedContent = marked(matchResult[2], [], inlineElementParserList);
return `<p class='li-container'><span class='ol-block'>${matchResult[1]}.</span><span>${parsedContent}</span></p>${matchResult[3]}`; return `<p class='li-container'><span class='ol-block'>${matchResult[1]}.</span><span>${parsedContent}</span></p>`;
}; };
export default { export default {
name: "ordered list", name: "ordered list",
regex: ORDERED_LIST_REG, regex: ORDERED_LIST_REG,
matcher,
renderer, renderer,
}; };

View File

@ -1,20 +1,21 @@
import { inlineElementParserList } from "."; import { inlineElementParserList } from ".";
import { marked } from ".."; import { marked } from "..";
export const PARAGRAPH_REG = /^(.*)(\n?)/; export const PARAGRAPH_REG = /^([^\n]+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(PARAGRAPH_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(PARAGRAPH_REG); const parsedContent = marked(rawStr, [], inlineElementParserList);
if (!matchResult) { return `<p>${parsedContent}</p>`;
return rawStr;
}
const parsedContent = marked(matchResult[1], [], inlineElementParserList);
return `<p>${parsedContent}</p>${matchResult[2]}`;
}; };
export default { export default {
name: "paragraph", name: "paragraph",
regex: PARAGRAPH_REG, regex: PARAGRAPH_REG,
matcher,
renderer, renderer,
}; };

View File

@ -2,8 +2,13 @@ import { escape } from "lodash-es";
export const PLAIN_LINK_REG = /(https?:\/\/[^ ]+)/; export const PLAIN_LINK_REG = /(https?:\/\/[^ ]+)/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(PLAIN_LINK_REG); const matchResult = rawStr.match(PLAIN_LINK_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -14,5 +19,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "plain link", name: "plain link",
regex: PLAIN_LINK_REG, regex: PLAIN_LINK_REG,
matcher,
renderer, renderer,
}; };

View File

@ -2,8 +2,13 @@ import { escape } from "lodash-es";
export const PLAIN_TEXT_REG = /(.+)/; export const PLAIN_TEXT_REG = /(.+)/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(PLAIN_TEXT_REG); const matchResult = rawStr.match(PLAIN_TEXT_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -14,5 +19,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "plain text", name: "plain text",
regex: PLAIN_TEXT_REG, regex: PLAIN_TEXT_REG,
matcher,
renderer, renderer,
}; };

View File

@ -2,8 +2,13 @@ import { marked } from "..";
export const STRIKETHROUGH_REG = /~~(.+?)~~/; export const STRIKETHROUGH_REG = /~~(.+?)~~/;
const renderer = (rawStr: string): string => { const matcher = (rawStr: string) => {
const matchResult = rawStr.match(STRIKETHROUGH_REG); const matchResult = rawStr.match(STRIKETHROUGH_REG);
return matchResult;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
@ -15,5 +20,6 @@ const renderer = (rawStr: string): string => {
export default { export default {
name: "Strikethrough", name: "Strikethrough",
regex: STRIKETHROUGH_REG, regex: STRIKETHROUGH_REG,
matcher,
renderer, renderer,
}; };

View File

@ -2,17 +2,26 @@ import { escape } from "lodash-es";
export const TAG_REG = /#([^\s#]+)/; export const TAG_REG = /#([^\s#]+)/;
const renderer = (rawStr: string): string => { export const matcher = (rawStr: string) => {
const matchResult = rawStr.match(TAG_REG); const matchResult = rawStr.match(TAG_REG);
if (matchResult) {
return matchResult;
}
return null;
};
const renderer = (rawStr: string): string => {
const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
return `<span class='tag-span'>#${escape(matchResult[1])}</span> `; return `<span class='tag-span'>#${escape(matchResult[1])}</span>`;
}; };
export default { export default {
name: "tag", name: "tag",
regex: TAG_REG, regex: TAG_REG,
matcher,
renderer, renderer,
}; };

View File

@ -1,23 +1,26 @@
import { escape } from "lodash-es";
import { inlineElementParserList } from "."; import { inlineElementParserList } from ".";
import { marked } from ".."; import { marked } from "..";
export const TODO_LIST_REG = /^- \[ \] (.+)(\n?)/; export const TODO_LIST_REG = /^- \[ \] ([^\n]+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(TODO_LIST_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(TODO_LIST_REG); const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
const parsedContent = marked(matchResult[1], [], inlineElementParserList); const parsedContent = marked(matchResult[1], [], inlineElementParserList);
return `<p class='li-container'><span class='todo-block todo' data-value='TODO'></span><span>${parsedContent}</span></p>${escape( return `<p class='li-container'><span class='todo-block todo' data-value='TODO'></span><span>${parsedContent}</span></p>`;
matchResult[2]
)}`;
}; };
export default { export default {
name: "todo list", name: "todo list",
regex: TODO_LIST_REG, regex: TODO_LIST_REG,
matcher,
renderer, renderer,
}; };

View File

@ -1,21 +1,26 @@
import { escape } from "lodash-es";
import { inlineElementParserList } from "."; import { inlineElementParserList } from ".";
import { marked } from ".."; import { marked } from "..";
export const UNORDERED_LIST_REG = /^[*-] (.+)(\n?)/; export const UNORDERED_LIST_REG = /^[*-] ([^\n]+)/;
const matcher = (rawStr: string) => {
const matchResult = rawStr.match(UNORDERED_LIST_REG);
return matchResult;
};
const renderer = (rawStr: string): string => { const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(UNORDERED_LIST_REG); const matchResult = matcher(rawStr);
if (!matchResult) { if (!matchResult) {
return rawStr; return rawStr;
} }
const parsedContent = marked(matchResult[1], [], inlineElementParserList); const parsedContent = marked(matchResult[1], [], inlineElementParserList);
return `<p class='li-container'><span class='ul-block'>•</span><span>${parsedContent}</span></p>${escape(matchResult[2])}`; return `<p class='li-container'><span class='ul-block'>•</span><span>${parsedContent}</span></p>`;
}; };
export default { export default {
name: "unordered list", name: "unordered list",
regex: UNORDERED_LIST_REG, regex: UNORDERED_LIST_REG,
matcher,
renderer, renderer,
}; };

View File

@ -4,6 +4,7 @@ import DoneList from "./DoneList";
import OrderedList from "./OrderedList"; import OrderedList from "./OrderedList";
import UnorderedList from "./UnorderedList"; import UnorderedList from "./UnorderedList";
import Paragraph from "./Paragraph"; import Paragraph from "./Paragraph";
import Br from "./Br";
import Tag from "./Tag"; import Tag from "./Tag";
import Image from "./Image"; import Image from "./Image";
import Link from "./Link"; import Link from "./Link";
@ -17,15 +18,20 @@ import Blockquote from "./Blockquote";
import HorizontalRules from "./HorizontalRules"; import HorizontalRules from "./HorizontalRules";
import Strikethrough from "./Strikethrough"; import Strikethrough from "./Strikethrough";
export { CODE_BLOCK_REG } from "./CodeBlock";
export { TODO_LIST_REG } from "./TodoList";
export { DONE_LIST_REG } from "./DoneList";
export { TAG_REG } from "./Tag"; export { TAG_REG } from "./Tag";
export { IMAGE_REG } from "./Image";
export { LINK_REG } from "./Link"; export { LINK_REG } from "./Link";
export { HORIZONTAL_RULES_REG } from "./HorizontalRules";
// The order determines the order of execution. // The order determines the order of execution.
export const blockElementParserList = [HorizontalRules, CodeBlock, Blockquote, TodoList, DoneList, OrderedList, UnorderedList, Paragraph]; export const blockElementParserList = [
Br,
CodeBlock,
Blockquote,
TodoList,
DoneList,
OrderedList,
UnorderedList,
HorizontalRules,
Paragraph,
];
export const inlineElementParserList = [Image, BoldEmphasis, Bold, Emphasis, Link, InlineCode, PlainLink, Strikethrough, Tag, PlainText]; export const inlineElementParserList = [Image, BoldEmphasis, Bold, Emphasis, Link, InlineCode, PlainLink, Strikethrough, Tag, PlainText];
export const parserList = [...blockElementParserList, ...inlineElementParserList];