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

* refactor: Use function findMatchingParser to reduce duplicate code

* chore: declare type Parser
This commit is contained in:
远浅 2023-03-17 20:46:07 +08:00 committed by GitHub
parent 4ee8cf08c6
commit 2ba0dbf50b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

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