refactor: use function findMatchingParser to reduce duplicate code (#1367)

* refactor: Use function findMatchingParser to reduce duplicate code

* chore: declare type Parser
pull/1372/head
远浅 2 years ago committed by GitHub
parent 4ee8cf08c6
commit 2ba0dbf50b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,67 +1,79 @@
import { matcher } from "./matcher"; import { matcher } from "./matcher";
import { blockElementParserList, inlineElementParserList } from "./parser"; import { blockElementParserList, inlineElementParserList } from "./parser";
export const marked = ( type Parser = {
markdownStr: string, name: string;
blockParsers = blockElementParserList, regexp: RegExp;
inlineParsers = inlineElementParserList renderer: (rawStr: string) => JSX.Element | string;
): string | JSX.Element => { };
for (const parser of blockParsers) {
const matchResult = matcher(markdownStr, parser.regexp);
if (!matchResult) {
continue;
}
const matchedStr = matchResult[0];
const retainContent = markdownStr.slice(matchedStr.length);
if (parser.name === "br") {
return (
<>
{parser.renderer(matchedStr)}
{marked(retainContent, blockParsers, inlineParsers)}
</>
);
} else {
if (retainContent === "") {
return parser.renderer(matchedStr);
} else if (retainContent.startsWith("\n")) {
return (
<>
{parser.renderer(matchedStr)}
{marked(retainContent.slice(1), blockParsers, inlineParsers)}
</>
);
}
}
}
let matchedInlineParser = undefined; const findMatchingParser = (parsers: Parser[], markdownStr: string): Parser | undefined => {
let matchedParser = undefined;
let matchedIndex = -1; let matchedIndex = -1;
for (const parser of inlineParsers) { for (const parser of parsers) {
const matchResult = matcher(markdownStr, parser.regexp); const matchResult = matcher(markdownStr, parser.regexp);
if (!matchResult) { if (!matchResult) {
continue; continue;
} }
if (parser.name === "plain text" && matchedInlineParser !== undefined) { if (parser.name === "plain text" && matchedParser !== undefined) {
continue; continue;
} }
const startIndex = matchResult.index as number; const startIndex = matchResult.index as number;
if (matchedInlineParser === undefined || matchedIndex > startIndex) { if (matchedParser === undefined || matchedIndex > startIndex) {
matchedInlineParser = parser; matchedParser = parser;
matchedIndex = startIndex; matchedIndex = startIndex;
} }
} }
return matchedParser;
};
export const marked = (
markdownStr: string,
blockParsers = blockElementParserList,
inlineParsers = inlineElementParserList
): string | JSX.Element => {
const matchedBlockParser = findMatchingParser(blockParsers, markdownStr);
if (matchedBlockParser) {
const matchResult = matcher(markdownStr, matchedBlockParser.regexp);
if (matchResult) {
const matchedStr = matchResult[0];
const retainContent = markdownStr.slice(matchedStr.length);
if (matchedBlockParser.name === "br") {
return (
<>
{matchedBlockParser.renderer(matchedStr)}
{marked(retainContent, blockParsers, inlineParsers)}
</>
);
} else {
if (retainContent === "") {
return matchedBlockParser.renderer(matchedStr);
} else if (retainContent.startsWith("\n")) {
return (
<>
{matchedBlockParser.renderer(matchedStr)}
{marked(retainContent.slice(1), blockParsers, inlineParsers)}
</>
);
}
}
}
}
const matchedInlineParser = findMatchingParser(inlineParsers, markdownStr);
if (matchedInlineParser) { if (matchedInlineParser) {
const matchResult = matcher(markdownStr, matchedInlineParser.regexp); const matchResult = matcher(markdownStr, matchedInlineParser.regexp);
if (matchResult) { if (matchResult) {
const matchedStr = matchResult[0]; const matchedStr = matchResult[0];
const matchedLength = matchedStr.length; const matchedLength = matchedStr.length;
const prefixStr = markdownStr.slice(0, matchedIndex); const mIndex = matchResult.index || 0;
const suffixStr = markdownStr.slice(matchedIndex + matchedLength); const prefixStr = markdownStr.slice(0, mIndex);
const suffixStr = markdownStr.slice(mIndex + matchedLength);
return ( return (
<> <>
{marked(prefixStr, [], inlineParsers)} {marked(prefixStr, [], inlineParsers)}
@ -83,70 +95,52 @@ interface MatchedNode {
export const getMatchedNodes = (markdownStr: string): MatchedNode[] => { export const getMatchedNodes = (markdownStr: string): MatchedNode[] => {
const matchedNodeList: MatchedNode[] = []; const matchedNodeList: MatchedNode[] = [];
const walkthough = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => { const walkthrough = (markdownStr: string, blockParsers = blockElementParserList, inlineParsers = inlineElementParserList): string => {
for (const parser of blockParsers) { const matchedBlockParser = findMatchingParser(blockParsers, markdownStr);
const matchResult = matcher(markdownStr, parser.regexp); if (matchedBlockParser) {
if (!matchResult) { const matchResult = matcher(markdownStr, matchedBlockParser.regexp);
continue; if (matchResult) {
} const matchedStr = matchResult[0];
const matchedStr = matchResult[0]; const retainContent = markdownStr.slice(matchedStr.length);
const retainContent = markdownStr.slice(matchedStr.length); matchedNodeList.push({
matchedNodeList.push({ parserName: matchedBlockParser.name,
parserName: parser.name, matchedContent: matchedStr,
matchedContent: matchedStr, });
});
if (parser.name === "br") { if (matchedBlockParser.name === "br") {
return walkthough(retainContent, blockParsers, inlineParsers); return walkthrough(retainContent, blockParsers, inlineParsers);
} else { } else {
if (parser.name !== "code block") { if (matchedBlockParser.name !== "code block") {
walkthough(matchedStr, [], inlineParsers); walkthrough(matchedStr, [], inlineParsers);
}
if (retainContent.startsWith("\n")) {
return walkthrough(retainContent.slice(1), blockParsers, inlineParsers);
}
} }
if (retainContent.startsWith("\n")) { return "";
return walkthough(retainContent.slice(1), blockParsers, inlineParsers);
}
}
return "";
}
let matchedInlineParser = undefined;
let matchedIndex = -1;
for (const parser of inlineParsers) {
const matchResult = matcher(markdownStr, parser.regexp);
if (!matchResult) {
continue;
}
if (parser.name === "plain text" && matchedInlineParser !== undefined) {
continue;
}
const startIndex = matchResult.index as number;
if (matchedInlineParser === undefined || matchedIndex > startIndex) {
matchedInlineParser = parser;
matchedIndex = startIndex;
} }
} }
const matchedInlineParser = findMatchingParser(inlineParsers, markdownStr);
if (matchedInlineParser) { if (matchedInlineParser) {
const matchResult = matcher(markdownStr, matchedInlineParser.regexp); const matchResult = matcher(markdownStr, matchedInlineParser.regexp);
if (matchResult) { if (matchResult) {
const matchedStr = matchResult[0]; const matchedStr = matchResult[0];
const matchedLength = matchedStr.length; const matchedLength = matchedStr.length;
const suffixStr = markdownStr.slice(matchedIndex + matchedLength); const mIndex = matchResult.index || 0;
const suffixStr = markdownStr.slice(mIndex + matchedLength);
matchedNodeList.push({ matchedNodeList.push({
parserName: matchedInlineParser.name, parserName: matchedInlineParser.name,
matchedContent: matchedStr, matchedContent: matchedStr,
}); });
return walkthough(suffixStr, [], inlineParsers); return walkthrough(suffixStr, [], inlineParsers);
} }
} }
return markdownStr; return markdownStr;
}; };
walkthough(markdownStr); walkthrough(markdownStr);
return matchedNodeList; return matchedNodeList;
}; };

Loading…
Cancel
Save