diff --git a/.glossary.yaml b/.glossary.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6fdfceb055d377ec1e41cc8df4656407f7e90598 --- /dev/null +++ b/.glossary.yaml @@ -0,0 +1,3 @@ +HTML: HyperText Markup Language +API: Application Programming Interface +URL: Uniform Resource Locator \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs index 0c117f4b793c2badaa9042d3cf4a3fffc30a7857..efd8e468c228842c6b22d251ed3ee05e94f6cacb 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,8 +1,73 @@ import nextra from 'nextra' +import { visit } from 'unist-util-visit' +import fs from 'fs' +import path from 'path' +import yaml from 'js-yaml' + +var transformer = function (ast) { + const glossaryPath = path.join(process.cwd(), '/.glossary.yaml') + var acronyms = {} + + try { + const fileContents = fs.readFileSync(glossaryPath, 'utf8') + acronyms = yaml.load(fileContents) + } catch (error) { + console.error('Error loading glossary:', error) + } + + var acronymsRegExp = new RegExp( + '\\b('.concat(Object.keys(acronyms).join('|'), ')\\b'), + 'g', + ) + + visit(ast, 'paragraph', function (node) { + // Replace acronyms in text nodes + node.children = node.children + .map(function (child) { + if (child.type === 'text') { + // check if the text node contains an acronym + // if so, we return multiple new abbrev and text nodes + const newChildren = child.value + .split(acronymsRegExp) + .map(function (part) { + if (acronyms[part]) { + return { + type: 'abbr', + data: { + hName: 'abbr', + hChildren: [ + { + type: 'text', + value: part, + }, + ], + hProperties: { + title: acronyms[part], + }, + }, + } + } else { + return { + type: 'text', + value: part, + } + } + }) + return newChildren + } + + return [child] + }) + .flat() + }) + + return ast +} + +const remarkAbbrev = function () { + return transformer +} -/** - * @type {import('next').NextConfig} - */ const nextConfig = { output: 'export', images: { @@ -12,6 +77,9 @@ const nextConfig = { const withNextra = nextra({ theme: 'nextra-theme-docs', themeConfig: './theme.config.tsx', + mdxOptions: { + remarkPlugins: [remarkAbbrev], + }, }) export default withNextra(nextConfig) diff --git a/package-lock.json b/package-lock.json index 781005b189ffe8f6de749723eff45d0fd9123e33..6db7ac5057ed85b0a9578088cf2870d11677d0a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@heroicons/react": "^2.2.0", "dotenv": "^16.4.7", "eslint-config-prettier": "^9.1.0", + "js-yaml": "^4.1.0", "next": "^14.2.18", "nextra": "3.2.5", "nextra-theme-docs": "3.2.5", @@ -3813,8 +3814,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0", - "peer": true + "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.2", @@ -9543,7 +9543,6 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, diff --git a/package.json b/package.json index e09571d99ca367d6e92d59482626ad5f26230c3f..e732bc833b68f0d73c862f66cea075d22bc2eb4a 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@heroicons/react": "^2.2.0", "dotenv": "^16.4.7", "eslint-config-prettier": "^9.1.0", + "js-yaml": "^4.1.0", "next": "^14.2.18", "nextra": "3.2.5", "nextra-theme-docs": "3.2.5",