Skip to content

Commit

Permalink
feat: update marked parsers (#260)
Browse files Browse the repository at this point in the history
* chore: remove external match functions

* chore: update parsers
  • Loading branch information
boojack authored Oct 4, 2022
1 parent 4bd373b commit eaf89aa
Show file tree
Hide file tree
Showing 18 changed files with 88 additions and 173 deletions.
44 changes: 38 additions & 6 deletions web/src/labs/marked/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
import { parserList } from "./parser";
import { blockElementParserList, inlineElementParserList } from "./parser";

export const marked = (markdownStr: string, parsers = parserList) => {
for (const parser of parsers) {
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 => {
for (const parser of blockParsers) {
const startIndex = markdownStr.search(parser.regex);
const matchedLength = parser.match(markdownStr);
const matchedLength = match(markdownStr, parser.regex);

if (startIndex > -1 && matchedLength > 0) {
const prefixStr = markdownStr.slice(0, startIndex);
const matchedStr = markdownStr.slice(startIndex, startIndex + matchedLength);
const suffixStr = markdownStr.slice(startIndex + matchedLength);
markdownStr = marked(prefixStr, parsers) + parser.renderer(matchedStr) + marked(suffixStr, parsers);
break;
return marked(prefixStr, blockParsers, inlineParsers) + parser.renderer(matchedStr) + marked(suffixStr, blockParsers, inlineParsers);
}
}

let matchedInlineParser = undefined;
let matchedIndex = -1;

for (const parser of inlineElementParserList) {
const startIndex = markdownStr.search(parser.regex);
const matchedLength = match(markdownStr, parser.regex);

if (startIndex > -1 && matchedLength > 0) {
if (!matchedInlineParser || matchedIndex > startIndex) {
matchedIndex = startIndex;
matchedInlineParser = parser;
}
}
}

if (matchedInlineParser) {
const matchedLength = match(markdownStr, matchedInlineParser.regex);
const prefixStr = markdownStr.slice(0, matchedIndex);
const matchedStr = markdownStr.slice(matchedIndex, matchedIndex + matchedLength);
const suffixStr = markdownStr.slice(matchedIndex + matchedLength);
return prefixStr + matchedInlineParser.renderer(matchedStr) + marked(suffixStr, [], inlineParsers);
}

return markdownStr;
};
24 changes: 24 additions & 0 deletions web/src/labs/marked/marked.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,30 @@ console.log("hello world!")
},
];

for (const t of tests) {
expect(marked(t.markdown)).toBe(t.want);
}
});
test("parse bold and em text", () => {
const tests = [
{
markdown: `Important: **Minecraft**`,
want: `<p>Important: <strong>Minecraft</strong></p>`,
},
{
markdown: `Em: *Minecraft*`,
want: `<p>Em: <em>Minecraft</em></p>`,
},
{
markdown: `Important: ***Minecraft/123***`,
want: `<p>Important: <strong><em>Minecraft/123</em></strong></p>`,
},
{
markdown: `Important: ***[baidu](https://baidu.com)***`,
want: `<p>Important: <strong><em><a class='link' target='_blank' rel='noreferrer' href='https://baidu.com'>baidu</a></em></strong></p>`,
},
];

for (const t of tests) {
expect(marked(t.markdown)).toBe(t.want);
}
Expand Down
20 changes: 9 additions & 11 deletions web/src/labs/marked/parser/Bold.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
export const BOLD_REG = /\*\*([\S ]+?)\*\*/;
import { marked } from "..";
import Emphasis from "./Emphasis";
import Link from "./Link";

const match = (rawStr: string): number => {
export const BOLD_REG = /\*\*([\S ]+)\*\*/;

const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(BOLD_REG);
if (!matchResult) {
return 0;
return rawStr;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(BOLD_REG, "<strong>$1</strong>");
return parsedStr;
const parsedContent = marked(matchResult[1], [], [Emphasis, Link]);
return `<strong>${parsedContent}</strong>`;
};

export default {
name: "bold",
regex: BOLD_REG,
match,
renderer,
};
11 changes: 0 additions & 11 deletions web/src/labs/marked/parser/CodeBlock.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
export const CODE_BLOCK_REG = /^```(\S*?)\s([\s\S]*?)```(\n?)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(CODE_BLOCK_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(CODE_BLOCK_REG, "<pre lang='$1'>\n$2</pre>$3");
return parsedStr;
Expand All @@ -18,6 +8,5 @@ const renderer = (rawStr: string): string => {
export default {
name: "code block",
regex: CODE_BLOCK_REG,
match,
renderer,
};
13 changes: 1 addition & 12 deletions web/src/labs/marked/parser/DoneList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,18 @@ import { marked } from "..";

export const DONE_LIST_REG = /^- \[x\] ([\S ]+)(\n?)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(DONE_LIST_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(DONE_LIST_REG);
if (!matchResult) {
return rawStr;
}

const parsedContent = marked(matchResult[1], inlineElementParserList);
const parsedContent = marked(matchResult[1], [], inlineElementParserList);
return `<p><span class='todo-block done' data-value='DONE'>✓</span>${parsedContent}</p>${matchResult[2]}`;
};

export default {
name: "done list",
regex: DONE_LIST_REG,
match,
renderer,
};
20 changes: 9 additions & 11 deletions web/src/labs/marked/parser/Emphasis.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
export const EMPHASIS_REG = /\*([\S ]+?)\*/;
import { marked } from "..";
import Bold from "./Bold";
import Link from "./Link";

const match = (rawStr: string): number => {
export const EMPHASIS_REG = /\*([\S ]+)\*/;

const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(EMPHASIS_REG);
if (!matchResult) {
return 0;
return rawStr;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(EMPHASIS_REG, "<em>$1</em>");
return parsedStr;
const parsedContent = marked(matchResult[1], [], [Bold, Link]);
return `<em>${parsedContent}</em>`;
};

export default {
name: "emphasis",
regex: EMPHASIS_REG,
match,
renderer,
};
11 changes: 0 additions & 11 deletions web/src/labs/marked/parser/Image.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
export const IMAGE_REG = /!\[.*?\]\((.+?)\)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(IMAGE_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(IMAGE_REG, "<img class='img' src='$1' />");
return parsedStr;
Expand All @@ -18,6 +8,5 @@ const renderer = (rawStr: string): string => {
export default {
name: "image",
regex: IMAGE_REG,
match,
renderer,
};
11 changes: 0 additions & 11 deletions web/src/labs/marked/parser/InlineCode.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
export const INLINE_CODE_REG = /`([\S ]+?)`/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(INLINE_CODE_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(INLINE_CODE_REG, "<code>$1</code>");
return parsedStr;
Expand All @@ -18,6 +8,5 @@ const renderer = (rawStr: string): string => {
export default {
name: "inline code",
regex: INLINE_CODE_REG,
match,
renderer,
};
11 changes: 0 additions & 11 deletions web/src/labs/marked/parser/Link.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
export const LINK_REG = /\[(.*?)\]\((.+?)\)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(LINK_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(LINK_REG, "<a class='link' target='_blank' rel='noreferrer' href='$2'>$1</a>");
return parsedStr;
Expand All @@ -18,6 +8,5 @@ const renderer = (rawStr: string): string => {
export default {
name: "link",
regex: LINK_REG,
match,
renderer,
};
11 changes: 0 additions & 11 deletions web/src/labs/marked/parser/Mark.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
export const MARK_REG = /@\[([\S ]+?)\]\((\S+?)\)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(MARK_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(MARK_REG, "<span class='memo-link-text' data-value='$2'>$1</span>");
return parsedStr;
Expand All @@ -18,6 +8,5 @@ const renderer = (rawStr: string): string => {
export default {
name: "mark",
regex: MARK_REG,
match,
renderer,
};
13 changes: 1 addition & 12 deletions web/src/labs/marked/parser/OrderedList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,18 @@ import { marked } from "..";

export const ORDERED_LIST_REG = /^(\d+)\. ([\S ]+)(\n?)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(ORDERED_LIST_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(ORDERED_LIST_REG);
if (!matchResult) {
return rawStr;
}

const parsedContent = marked(matchResult[2], inlineElementParserList);
const parsedContent = marked(matchResult[2], [], inlineElementParserList);
return `<p><span class='ol-block'>${matchResult[1]}.</span>${parsedContent}</p>${matchResult[3]}`;
};

export default {
name: "ordered list",
regex: ORDERED_LIST_REG,
match,
renderer,
};
13 changes: 1 addition & 12 deletions web/src/labs/marked/parser/Paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,18 @@ import { marked } from "..";

export const PARAGRAPH_REG = /^([\S ]*)(\n?)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(PARAGRAPH_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const matchResult = rawStr.match(PARAGRAPH_REG);
if (!matchResult) {
return rawStr;
}

const parsedContent = marked(matchResult[1], inlineElementParserList);
const parsedContent = marked(matchResult[1], [], inlineElementParserList);
return `<p>${parsedContent}</p>${matchResult[2]}`;
};

export default {
name: "ordered list",
regex: PARAGRAPH_REG,
match,
renderer,
};
11 changes: 0 additions & 11 deletions web/src/labs/marked/parser/PlainLink.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
export const PLAIN_LINK_REG = /(https?:\/\/[^ ]+)/;

const match = (rawStr: string): number => {
const matchResult = rawStr.match(PLAIN_LINK_REG);
if (!matchResult) {
return 0;
}

const matchStr = matchResult[0];
return matchStr.length;
};

const renderer = (rawStr: string): string => {
const parsedStr = rawStr.replace(PLAIN_LINK_REG, "<a class='link' target='_blank' rel='noreferrer' href='$1'>$1</a>");
return parsedStr;
Expand All @@ -18,6 +8,5 @@ const renderer = (rawStr: string): string => {
export default {
name: "plain link",
regex: PLAIN_LINK_REG,
match,
renderer,
};
Loading

0 comments on commit eaf89aa

Please sign in to comment.