/
githubmirror
/
bootstrap
Обзор
Документация
Войти
/
githubmirror
/
bootstrap
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
site/src/libs/remark.ts
161 строка
5 KB
Julien Déramond
Fix several typos in comments within TypeScript files in `site/src/libs`
02 июл 2025, 00:06
Не верифицирован
02 июл 2025, 00:06
879d1d1
Код
Авторство
О чём код?
import type { Root } from 'mdast' import type { MdxJsxAttribute, MdxJsxExpressionAttribute } from 'mdast-util-mdx-jsx' import type { Plugin } from 'unified' import { visit } from 'unist-util-visit' import { getConfig } from './config' import { getVersionedDocsPath } from './path' // [[config:foo]] // [[config:foo.bar]] const configRegExp = /\[\[config:(?<name>[\w\.]+)]]/g // [[docsref:/foo]] // [[docsref:/foo/bar#baz]] const docsrefRegExp = /\[\[docsref:(?<path>[\w\.\/#-]+)]]/g // A remark plugin to replace config values embedded in markdown (or MDX) files. // For example, [[config:foo]] will be replaced with the value of the `foo` key in the `config.yml` file. // Nested values are also supported, e.g. [[config:foo.bar]]. // Note: this also works in frontmatter. // Note: this plugin is meant to facilitate the migration from Hugo to Astro while keeping the differences to a minimum. // At some point, this plugin should maybe be removed and embrace a more MDX-friendly syntax. export const remarkBsConfig: Plugin<[], Root> = function () { return function remarkBsConfigPlugin(ast, file) { if (containsFrontmatter(file.data.astro)) { replaceInFrontmatter(file.data.astro.frontmatter, replaceConfigInText) } // https://github.com/syntax-tree/mdast#nodes // https://github.com/syntax-tree/mdast-util-mdx-jsx#nodes visit(ast, ['code', 'definition', 'image', 'inlineCode', 'link', 'mdxJsxFlowElement', 'text'], (node) => { switch (node.type) { case 'code': case 'inlineCode': case 'text': { node.value = replaceConfigInText(node.value) break } case 'image': { if (node.alt) { node.alt = replaceConfigInText(node.alt) } node.url = replaceConfigInText(node.url) break } case 'definition': case 'link': { node.url = replaceConfigInText(node.url) break } case 'mdxJsxFlowElement': { node.attributes = replaceConfigInAttributes(node.attributes) break } } }) } } // A remark plugin to add versioned docs links in markdown (or MDX) files. // For example, [[docsref:/foo]] will be replaced with the `/docs/${docs_version}/foo` value with the `docs_version` // value being read from the `config.yml` file. // Note: this also works in frontmatter. // Note: this plugin is meant to facilitate the migration from Hugo to Astro while keeping the differences to a minimum. // At some point, this plugin should maybe be removed and embrace a more MDX-friendly syntax. export const remarkBsDocsref: Plugin<[], Root> = function () { return function remarkBsDocsrefPlugin(ast, file) { if (containsFrontmatter(file.data.astro)) { replaceInFrontmatter(file.data.astro.frontmatter, replaceDocsrefInText) } // https://github.com/syntax-tree/mdast#nodes // https://github.com/syntax-tree/mdast-util-mdx-jsx#nodes visit(ast, ['definition', 'link', 'mdxJsxTextElement'], (node) => { switch (node.type) { case 'definition': case 'link': { node.url = replaceDocsrefInText(node.url) break } case 'mdxJsxTextElement': { node.attributes = replaceDocsrefInAttributes(node.attributes) break } } }) } } export function replaceConfigInText(text: string) { return text.replace(configRegExp, (_match, path) => { const value = getConfigValueAtPath(path) if (!value) { throw new Error(`Failed to find a valid configuration value for '${path}'.`) } return value }) } function replaceConfigInAttributes(attributes: (MdxJsxAttribute | MdxJsxExpressionAttribute)[]) { return attributes.map((attribute) => { if (attribute.type === 'mdxJsxAttribute' && typeof attribute.value === 'string') { attribute.value = replaceConfigInText(attribute.value) } return attribute }) } function replaceDocsrefInText(text: string) { return text.replace(docsrefRegExp, (_match, path) => { return getVersionedDocsPath(path) }) } function replaceDocsrefInAttributes(attributes: (MdxJsxAttribute | MdxJsxExpressionAttribute)[]) { return attributes.map((attribute) => { if (attribute.type === 'mdxJsxAttribute' && typeof attribute.value === 'string') { attribute.value = replaceDocsrefInText(attribute.value) } return attribute }) } function getConfigValueAtPath(path: string) { const config = getConfig() const value = path.split('.').reduce((values, part) => { if (!values || typeof values !== 'object') { return undefined } return (values as any)?.[part] }, config as unknown) return typeof value === 'string' ? value : undefined } function replaceInFrontmatter(record: Record<string, unknown>, replacer: (value: string) => string) { for (const [key, value] of Object.entries(record)) { if (typeof value === 'string') { record[key] = replacer(value) } else if (Array.isArray(value)) { record[key] = value.map((arrayValue) => { return typeof arrayValue === 'string' ? replacer(arrayValue) : typeof arrayValue === 'object' ? replaceInFrontmatter(arrayValue, replacer) : arrayValue }) } } return record } function containsFrontmatter(data: unknown): data is { frontmatter: Record<string, unknown> } { return data != undefined && typeof data === 'object' && 'frontmatter' in data }