diff --git a/website/plugins/index.mjs b/website/plugins/index.mjs index f8068096f..ed4ea36e4 100644 --- a/website/plugins/index.mjs +++ b/website/plugins/index.mjs @@ -4,9 +4,11 @@ import remarkUnwrapImages from 'remark-unwrap-images' import remarkCustomAttrs from './remarkCustomAttrs.mjs' import remarkWrapSections from './remarkWrapSections.mjs' import remarkCodeBlocks from './remarkCodeBlocks.mjs' +import remarkFindAndReplace from './remarkFindAndReplace.mjs' const remarkPlugins = [ remarkGfm, + remarkFindAndReplace, remarkUnwrapImages, remarkCustomAttrs, remarkCodeBlocks, diff --git a/website/plugins/remarkFindAndReplace.mjs b/website/plugins/remarkFindAndReplace.mjs new file mode 100644 index 000000000..ddd55730f --- /dev/null +++ b/website/plugins/remarkFindAndReplace.mjs @@ -0,0 +1,42 @@ +import { visit } from 'unist-util-visit' +import { replacements } from '../meta/dynamicMeta.mjs' + +const prefix = '%%' + +// Attaches prefix to the start of the string. +const attachPrefix = (str) => (prefix || '') + str + +// RegExp to find any replacement keys. +const regexp = RegExp( + '(' + + Object.keys(replacements) + .map((key) => attachPrefix(key)) + .join('|') + + ')', + 'g' +) + +// Removes prefix from the start of the string. +const stripPrefix = (str) => (prefix ? str.replace(RegExp(`^${prefix}`), '') : str) + +const replacer = (_match, name) => replacements[stripPrefix(name)] + +const remarkFindAndReplace = () => (markdownAST) => { + // Go through all text, html, code, inline code, and links. + visit(markdownAST, ['text', 'html', 'code', 'link'], (node) => { + if (node.type === 'link') { + // For links, the text value is replaced by text node, so we change the + // URL value. + const processedText = node.url.replace(regexp, replacer) + node.url = processedText + } else { + // For all other nodes, replace the node value. + const processedText = node.value.replace(regexp, replacer) + node.value = processedText + } + }) + + return markdownAST +} + +export default remarkFindAndReplace