support matcher function for markdown transformers#4500
support matcher function for markdown transformers#4500xinyuan0801 wants to merge 2 commits intofacebook:mainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
It would really help to see some example where string match will do any different than reg exp |
I think the key insight here is to not make regexp the only way to do string match. regexp is a powerful tool and i have no doubt it can do most string match needed in markdown plugin, but it does comes with some limitations.
I will give an example comparison with the matcher: (
textContent: string,
): {index: number; matchText: string[]} | null => {
// Find the index of the start of the markdown image tag.
const start = textContent.indexOf('![');
if (start < 0) return null;
// Identify the end of the alt text and extract it.
const endBracket = textContent.indexOf(']', start);
if (endBracket < 0) return null;
const altText = textContent.substring(start + 2, endBracket);
// Identify the start and end of the URL and extract it.
const startParen = textContent.indexOf('(', endBracket);
if (startParen < 0) return null;
const endParen = textContent.indexOf(')', startParen);
if (endParen < 0) return null;
const url = textContent.substring(startParen + 1, endParen);
// Return the start index and an array with the complete markdown tag, alt text, and URL.
return {index: start, matchText: [``, altText, url]};
}The |
Background
As outlined in issue #4481, the current implementation requires the use of complex regular expressions to match a transformer in Markdown. This solution can be quite convoluted and difficult to manage for more complex scenarios.
Purpose of this PR
This Pull Request proposes the introduction of a
matcherproperty to bothElementTransformerandTextMatchTransformer, aiming to offer a more flexible and intuitive method for matching patterns. This is an optional property.ElementTransformer
In the context of
ElementTransformer, thematcherproperty is a function of type(textContent: string) => Array<string> | null. This function takes thetextContentas input and finds all matching substrings or return null if none is found. It is an optional property ofElementTransformer.When the
matcherfunction is provided, the transformer will use it to find the matching patterns. If thematcherproperty is absent, the transformer will fall back to the existingregExpproperty to find matches.TextMatchTransformer
As for
TextMatchTransformer, thematcherproperty takes the form of a function(textContent: string) => {index: number; matchText: Array<string>} | null. This function operates similarly to theElementTransformer's matcher, with the addition of anindexproperty, mirroring theindexproperty found inRegExpMatchArray. This is required by therunTextMatchTransformersfunction.By implementing these changes, we anticipate a more versatile and user-friendly approach to finding matches within our Markdown transformers, reducing the reliance on complex regular expressions.
Usage
an example usage of the matcher property can be
where the
matcherwill handle the pattern finding.Something To Note
In this PR, the type of the
replaceparameter inTextMatchTransformerhas been updated from(node: TextNode, match: RegExpMatchArray) => voidto(node: TextNode, match: Array<string>) => void. This change was made because it was determined that the additional properties provided byRegExpMatchArrayare not necessary for the current usage of the function.By aligning the type of the
matchparameter inTextMatchTransformerwith thereplacefunction inElementTransformer, which is of typeArray<string>, we ensure consistency and simplicity in the codebase.Fixes #4481