docusaurus-plugin-terminology 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,59 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0] - 2026-10-16
9
+
10
+ ### Added
11
+
12
+ - Zero-configuration, SSR-safe term link tooltips: the theme overrides the MDX
13
+ `a` component and renders term links as `<TermTooltip>`.
14
+ - The public entry point is now a **preset** that registers a dedicated
15
+ `@docusaurus/plugin-content-docs` instance (id `terminology`) rendering term
16
+ pages at a top-level route (`/terms/` by default).
17
+ - Option validation with descriptive error messages.
18
+ - `docsInstance`, `sidebarLabel` and `glossarySlug` options.
19
+ - i18n support for the new top-level layout.
20
+ - `examples/site`: a Docusaurus demo used as an integration test, plus a GitHub
21
+ Pages deployment workflow.
22
+ - CI matrix (Docusaurus `3.7`/`3.10` × React `18`/`19`).
23
+ - TypeScript definitions for the preset and options.
24
+
25
+ ### Changed
26
+
27
+ - Term definitions now live in a **top-level** directory (`terms/`) instead of
28
+ `docs/terms/`.
29
+ - Tooltip rendering moved from a client-side DOM-manipulation module to a
30
+ React component rendered during SSR.
31
+ - Package metadata: `exports`, `files`, `engines` (`node >= 18`), `sideEffects`.
32
+ - `<Glossary />` groups by localized terms with default-locale fallback and uses
33
+ `@docusaurus/Link`.
34
+
35
+ ### Removed
36
+
37
+ - The client-side `theme/tooltip.js` module (CDN tippy, `MutationObserver`,
38
+ polling, debug badge, history patching).
39
+ - The `remark/term-link-transformer.js` remark plugin (replaced by the MDX `a`
40
+ component override).
41
+ - Unused dependencies (`@tippyjs/react`, `unist-util-visit`).
42
+
43
+ ### Fixed
44
+
45
+ - Tooltips no longer depend on a non-existent `extendMarkdownOptions` plugin
46
+ hook, which is why they previously appeared in dev but not in production.
47
+ - Term pages no longer require `_category_.yml` hacks to stay out of the docs
48
+ sidebar.
49
+
50
+ ### Migration
51
+
52
+ See the “Migrating from 0.1.x” section in the [README](./README.md#migrating-from-01x).
53
+
54
+ ## [0.1.0] - 2026-05-11
55
+
56
+ ### Added
57
+
58
+ - Initial release: glossary data from `docs/terms`, tippy.js tooltips via a
59
+ client module, `<Glossary />` component, `hideTermsFromSidebar` option.
package/README.md CHANGED
@@ -1,136 +1,95 @@
1
1
  # docusaurus-plugin-terminology
2
2
 
3
+ Terminology & glossary support for [Docusaurus 3](https://docusaurus.io):
3
4
 
4
- ## Overview
5
+ - 📄 **Term pages** — each term is a Markdown/MDX file rendered as its own page.
6
+ - 💬 **Link tooltips** — links to terms are automatically enhanced with a
7
+ definition tooltip. **Zero configuration**, SSR-safe (the link is in the HTML).
8
+ - 🔤 **Glossary page** — an A–Z glossary generated from your term files.
9
+ - 🌍 **i18n** — locale-aware terms with fallback to the default locale.
10
+ - ⚛️ **React 18 & 19**, Docusaurus 3.7 → 3.10.
5
11
 
6
- Terminology/glossary plugin for [Docusaurus](https://github.com/facebook/docusaurus) 3 with:
7
-
8
- - glossary generation
9
- - term tooltips
10
- - MDX support (Built on MDX AST transformations instead of raw HTML replacement for improved Docusaurus 3 compatibility)
11
- - i18n support
12
- - Tippy.js integration
13
-
14
- This plugin is inspired by [@grnet/docusaurus-terminology](https://github.com/grnet/docusaurus-terminology). It's based on the same general concept but uses MDX remark transformations instead of webpack loader injection and uses a more robust handling of the terms' links.
15
- Compatible with Docusaurus 3.x and React 18.
16
- Tested with Docusaurus 3.7.0.
17
-
18
-
19
- ## Features
12
+ ```md
13
+ Check out [AI](/terms/ai) for more details.
14
+ ```
20
15
 
21
- - Define terms as Markdown files.
22
- - Glossary component: Automatic glossary data aggregation from Markdown term files in `docs/glossary`.
23
- - Tooltips on glossary links: Automatically transforms glossary links into interactive tooltip components.
24
- - Locale-aware glossary support: Supports multiple locales and ensures fallback to the default locale for missing terms.
25
- - Compatible with Docusaurus 3 + React 18
26
- - SSR-safe MDX integration
16
+ renders a normal link that also shows the term's description on hover:
27
17
 
18
+ > Check out <ins>AI</ins><sup>*</sup> *— Artificial Intelligence: the simulation
19
+ > of human intelligence processes by machines.*
28
20
 
29
21
  ## Compatibility
30
22
 
31
- | Package | Version |
32
- |---|---|
33
- | Docusaurus | 3.7.0+ |
34
- | React | 18+ |
35
- | Node.js | 18+ recommended |
36
-
37
- The plugin supports `.md` and `.mdx` files.
23
+ | Package | Supported |
24
+ | --- | --- |
25
+ | Docusaurus | `3.7` – `3.10` (tested against `3.10.2`) |
26
+ | React | `18` and `19` |
27
+ | Node.js | `18+` (Docusaurus `3.10` itself requires `20+`) |
38
28
 
29
+ Both `.md` and `.mdx` term files are supported.
39
30
 
40
31
  ## Installation
41
32
 
42
- Install the plugin using npm or yarn:
43
-
44
33
  ```bash
45
34
  npm install docusaurus-plugin-terminology
46
35
  ```
47
36
 
48
- or
49
-
50
- ```bash
51
- yarn add docusaurus-plugin-terminology
52
- ```
53
-
54
-
55
- ## Configuration
56
-
57
- Add the plugin to `docusaurus.config.js`:
58
-
59
- ```js
60
- plugins: [
61
- [
62
- 'docusaurus-plugin-terminology',
63
- {
64
- // options
65
- termsDir: 'terms', // default: 'terms'
66
- routeBasePath: '/docs/terms/', // default: '/docs/terms/'
67
- hideTermsFromSidebar: true, // when true, plugin will create _category_.yml to hide individual term pages
68
- }
69
- ]
70
- ],
37
+ ## Quick start
38
+
39
+ The package's default export is a **preset**. Register it **after** the classic
40
+ preset so its theme wins theme resolution (this is what makes tooltips work
41
+ without any extra configuration):
42
+
43
+ ```js title="docusaurus.config.js"
44
+ module.exports = {
45
+ presets: [
46
+ ['classic', { /* ... your options ... */ }],
47
+ [
48
+ 'docusaurus-plugin-terminology',
49
+ {
50
+ termsDir: 'terms', // top-level directory, default: 'terms'
51
+ routeBasePath: '/terms/', // public URL, default: '/terms/'
52
+ },
53
+ ],
54
+ ],
55
+ };
71
56
  ```
72
57
 
73
- ---
74
-
75
- ## Usage
76
-
77
- ### Defining terms
78
-
79
- Create a `terms` directory within `docs` (the plugin default).
80
-
81
- Add Markdown files for your terms in that directory.
82
- Structure example:
58
+ Then create a `terms/` directory at the root of your site:
83
59
 
84
60
  ```text
85
- docs/
86
- ├── terms/ # terms definitions
61
+ .
62
+ ├── docs/
63
+ │ └── glossary.md # a page rendering <Glossary />
64
+ ├── terms/
87
65
  │ ├── ai.md
88
66
  │ ├── css.md
89
- │ ├── ftp.md
90
- │ ├── html.md
91
- │ └── ...
92
- └── terms.md # glossary page (id: glossary)
67
+ │ └── ftp.md
68
+ └── docusaurus.config.js
93
69
  ```
94
70
 
95
-
96
- #### Example Term File
97
-
98
- Each file should contain metadata in the frontmatter:
99
-
100
- ```yaml
71
+ ```md title="terms/ai.md"
101
72
  ---
102
- title: AI - »Artificial Intelligence«
103
- description: Intelligence of machines.
73
+ title: AI
74
+ description: Artificial Intelligence — the simulation of human intelligence processes by machines.
104
75
  ---
105
- ```
106
- ```markdown
107
- The capability of computational systems to perform tasks typically associated with human intelligence, such as learning, reasoning, problem-solving, perception, and decision-making. It is a field of research in engineering, mathematics and computer science that develops and studies methods and software that enable machines to perceive their environment and use learning and intelligence to take actions that maximize their chances of achieving defined goals.
108
-
109
- *From [Artificial intelligence - Wikipedia](https://en.wikipedia.org/wiki/Artificial_intelligence#Techniques)*
110
76
 
77
+ Artificial intelligence (AI) is the simulation of human intelligence processes
78
+ by computer systems.
111
79
  ```
112
80
 
113
- ### Linking terms
114
-
115
- Link to terms in your Markdown files using the `/docs/terms/TERM_SLUG` format (or adjust to your `termsDir`).
116
- Example:
81
+ Term pages are now available at `/terms/ai`, `/terms/css`, … and linking to
82
+ them from anywhere in your Markdown shows a tooltip:
117
83
 
118
- ```markdown
119
- [AI](/docs/terms/ai)
84
+ ```md
85
+ See [AI](/terms/ai) and [CSS](/terms/css).
120
86
  ```
121
87
 
122
- The plugin will automatically transform these links into tooltips.
123
-
124
-
125
- ### Glossary Page
88
+ ## Glossary page
126
89
 
127
- The plugin provides a `Glossary` component that displays all glossary terms grouped alphabetically. You can use this component in your custom pages.
90
+ Add a docs page (anywhere in your `docs/`) that renders the glossary component:
128
91
 
129
- #### Create a glossary page
130
-
131
- E.g. `glossary.md` (the file name doesn't matter)
132
-
133
- ```markdown
92
+ ```mdx title="docs/glossary.md"
134
93
  ---
135
94
  id: glossary
136
95
  title: Glossary
@@ -141,73 +100,125 @@ import Glossary from '@theme/Glossary';
141
100
  <Glossary />
142
101
  ```
143
102
 
144
- ### i18n
103
+ `<Glossary />` displays every term (grouped A–Z) with its description and a link
104
+ to its term page.
145
105
 
146
- Localized term definitions can be placed in:
106
+ ## Options
147
107
 
148
- ```text
149
- i18n/de/docusaurus-plugin-content-docs/current/terms/
150
- ```
108
+ | Option | Type | Default | Description |
109
+ | --- | --- | --- | --- |
110
+ | `termsDir` | `string` | `'terms'` | Directory containing the term files, relative to the site root. |
111
+ | `routeBasePath` | `string` | `'/terms/'` | Public URL prefix of the generated term pages, also used to detect term links. |
112
+ | `docsInstance` | `boolean` | `true` | Register a dedicated docs instance for the term pages. Set to `false` for [legacy mode](#legacy-mode). |
113
+ | `hideTermsFromSidebar` | `boolean` | `false` | Legacy mode only: write a `_category_.yml` hiding the term docs from the main sidebar. |
114
+ | `sidebarLabel` | `string` | `'Glossary'` | Legacy mode only: label of the hidden sidebar category. |
115
+ | `glossarySlug` | `string` | `'glossary'` | Legacy mode only: doc id of the glossary page the hidden category links to. |
151
116
 
117
+ Invalid options throw a descriptive error at build time.
152
118
 
153
119
  ## How it works
154
120
 
155
- 1. The plugin scans `docs/terms` (or the directory configured via `termsDir`)
156
- 2. Term metadata is extracted from frontmatter
157
- 3. Markdown links matching `/docs/terms/*` (or matching your `routeBasePath`) are transformed into MDX tooltip components
158
- 4. Generates a static glossary JSON data source for tooltip rendering
159
- 5. Glossary data is exposed globally to Docusaurus theme components
121
+ 1. A dedicated `@docusaurus/plugin-content-docs` instance (id `terminology`)
122
+ renders the files in `termsDir` at `routeBasePath` — no sidebar, no docs
123
+ ordering surprises.
124
+ 2. The terminology plugin reads the same files and exposes a locale-aware
125
+ glossary (name + short description) as global plugin data.
126
+ 3. The terminology theme overrides the MDX `a` component. A normal Markdown link
127
+ is delegated to Docusaurus, while a link pointing at `routeBasePath` is
128
+ rendered as `<TermTooltip>` with the glossary description. Because this
129
+ happens at render time, the link is part of the server-rendered HTML and no
130
+ remark plugin, `MDXComponents` swizzle, or DOM scanning is required.
131
+
132
+ > **Why register the preset after `classic`?** Docusaurus resolves
133
+ > `@theme/MDXComponents/A` by theme priority. Listing the terminology preset
134
+ > last makes its theme the highest-priority provider, which is what lets it
135
+ > override the link component.
160
136
 
137
+ ## Descriptions
161
138
 
162
- ### Internal Architecture
163
- Markdown links
164
- ↓
165
- remark plugin transformation
166
- ↓
167
- <TermTooltip />
168
- ↓
169
- MDX component mapping
170
- ↓
171
- Tippy.js tooltip rendering
139
+ The tooltip text is taken from `description` in the frontmatter when present,
140
+ otherwise from the first paragraph of the term body (Markdown is stripped and
141
+ the result is truncated). `summary` and `excerpt` are also accepted as
142
+ frontmatter aliases.
172
143
 
144
+ ## i18n
173
145
 
174
- ### Styling
146
+ Localized term files are picked up automatically. Supported locations:
175
147
 
176
- Override tooltip styles via CSS.
148
+ ```text
149
+ i18n/<locale>/<termsDir>/ # e.g. i18n/de/terms/ai.md
150
+ i18n/<locale>/docusaurus-plugin-content-docs-terminology/current/
151
+ ```
177
152
 
153
+ Missing localized terms fall back to the default locale, so you only translate
154
+ what you need.
178
155
 
179
- ## File Structure
156
+ ## Styling
180
157
 
181
- The plugin's file structure is as follows:
158
+ Term links use a dotted underline and a tippy.js tooltip. Override the look with
159
+ plain CSS:
182
160
 
161
+ ```css
162
+ .tippy-box[data-theme~='terminology'] {
163
+ /* your styles */
164
+ }
183
165
  ```
184
- docusaurus-plugin-terminology
185
- ├── remark
186
- │ └── term-link-transformer.js
187
- ├── theme
188
- │ ├── Glossary.jsx
189
- │ └── tooltip.js
190
- ├── index.js
191
- ├── LICENSE
192
- └── README.md
166
+
167
+ ## Legacy mode (`0.1.x` layout)
168
+
169
+ If your terms live **inside** `docs/` (e.g. `docs/terms/ai.md`) you can keep that
170
+ layout:
171
+
172
+ ```js
173
+ presets: [
174
+ ['classic', { /* ... */ }],
175
+ [
176
+ 'docusaurus-plugin-terminology',
177
+ {
178
+ docsInstance: false,
179
+ termsDir: 'terms', // -> docs/terms
180
+ routeBasePath: '/docs/terms/',
181
+ hideTermsFromSidebar: true, // hide the term docs in the sidebar
182
+ },
183
+ ],
184
+ ],
193
185
  ```
194
186
 
195
- - `remark/term-link-transformer.js`: Transforms glossary term links in Markdown files into `TermTooltip` components.
196
- - `theme/Glossary.jsx`: Renders the glossary page.
197
- - `theme/tooltip.js`: Handles tooltips for glossary terms.
198
- - `index.js`: Main plugin entry point.
187
+ ## Migrating from `0.1.x`
199
188
 
189
+ `0.2.0` is a breaking release:
200
190
 
201
- ## Contributing
191
+ 1. **Registration changed**: the package is now a preset (registered in
192
+ `presets`) instead of a plugin (in `plugins`).
193
+ 2. **Terms moved to the top level**: move `docs/terms/` to `terms/` and set
194
+ `routeBasePath: '/terms/'`. (Or keep the old layout with `docsInstance: false`.)
195
+ 3. **Links changed**: update links from `/docs/terms/<slug>` to `/terms/<slug>`.
196
+ 4. **Tooltips are zero-config**: the fragile client-side `theme/tooltip.js`
197
+ module was removed — nothing to configure.
198
+
199
+ ## Development
202
200
 
203
- Contributions are welcome! Feel free to open issues or submit pull requests to improve the plugin.
201
+ ```bash
202
+ npm install # install dev dependencies
203
+ npm test # unit tests (Jest)
204
204
 
205
+ cd examples/site
206
+ npm install
207
+ npm start # http://localhost:3000/docusaurus-plugin-terminology/
208
+ npm run build # production build (regression check)
209
+ ```
205
210
 
206
- ## License
211
+ The demo site in [`examples/site`](./examples/site) is the integration test: it
212
+ builds on every CI run against a Docusaurus × React matrix.
207
213
 
208
- This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for details.
214
+ ## Contributing
215
+
216
+ Issues and pull requests are welcome.
217
+
218
+ ## License
209
219
 
220
+ MIT — see [LICENSE](./LICENSE).
210
221
 
211
222
  ## Acknowledgments
212
223
 
213
- This plugin is inspired by [@grnet/docusaurus-terminology](https://github.com/grnet/docusaurus-terminology) and aims to provide a more robust and modern implementation.
224
+ Inspired by [@grnet/docusaurus-terminology](https://github.com/grnet/docusaurus-terminology).
package/index.js CHANGED
@@ -1,181 +1,81 @@
1
- // docusaurus-plugin-terminology/index.js
2
- const path = require('path');
3
- const fs = require('fs');
4
- const matter = require('gray-matter');
1
+ 'use strict';
5
2
 
6
- module.exports = function (context, options = {}) {
3
+ /**
4
+ * docusaurus-plugin-terminology (preset)
5
+ *
6
+ * Public entry point. Registers:
7
+ *
8
+ * 1. a dedicated `@docusaurus/plugin-content-docs` instance rendering the
9
+ * term definitions under a top-level route (default `/terms/`);
10
+ * 2. the terminology content plugin (glossary data + legacy sidebar hiding);
11
+ * 3. the terminology theme (MDX link tooltips + `<Glossary />`).
12
+ *
13
+ * Usage (order matters — keep it *after* the classic preset so that the
14
+ * terminology theme wins the theme resolution):
15
+ *
16
+ * ```js
17
+ * presets: [
18
+ * ['classic', { ... }],
19
+ * ['docusaurus-plugin-terminology', { termsDir: 'terms', routeBasePath: '/terms/' }],
20
+ * ],
21
+ * ```
22
+ */
7
23
 
8
- // Provide sensible defaults and read hide flag
9
- options = Object.assign(
10
- {
11
- termsDir: 'terms',
12
- routeBasePath: '/docs/terms/',
13
- hideTermsFromSidebar: false,
14
- },
15
- options || {}
16
- );
24
+ const path = require('path');
25
+ const terminologyPlugin = require('./plugin');
26
+ const terminologyTheme = require('./theme-plugin');
27
+ const {normalizeOptions} = require('./src/options');
17
28
 
18
- const termsDir = options.termsDir || 'terms';
19
- const routeBasePath = options.routeBasePath || '/docs/terms/';
20
- const hideTermsFromSidebar = options.hideTermsFromSidebar === true;
29
+ const TERMS_DOCS_INSTANCE_ID = 'terminology';
30
+ const CONTENT_DOCS_PLUGIN = '@docusaurus/plugin-content-docs';
21
31
 
22
- //console.log('[plugin] docusaurus-plugin-terminology loaded');
23
- return {
24
- name: 'docusaurus-plugin-terminology',
25
-
26
- extendMarkdownOptions(mdOptions) {
27
- mdOptions.remarkPlugins = mdOptions.remarkPlugins || [];
28
- mdOptions.remarkPlugins.push([
29
- require('./remark/term-link-transformer'),
30
- {
31
- termsDir,
32
- routeBasePath,
33
- },
34
- ]);
35
- //console.log('[plugin] extendMarkdownOptions: registered termLinkTransformer');
36
- },
37
-
38
- /**
39
- * Optionally write a _category_.yml into the terms docs directory (and per-locale equivalents)
40
- * so that the terms directory is represented by a single category entry that can be hidden
41
- * (className: hidden). This prevents the individual generated term files from showing up
42
- * in the main docs sidebar.
43
- */
44
- async loadContent() {
45
- if (!hideTermsFromSidebar) return null;
32
+ function toDocsRouteBasePath(routeBasePath) {
33
+ return String(routeBasePath).replace(/^\/+|\/+$/g, '');
34
+ }
46
35
 
47
- const CATEGORY_FILENAME = '_category_.yml';
48
- const makeCategoryYaml = (label = 'Glossar') => `label: ${label}
49
- className: hidden
50
- collapsed: true
51
- link:
52
- type: doc
53
- id: glossary
54
- `;
36
+ /**
37
+ * @param {import('@docusaurus/types').LoadContext} context
38
+ * @param {object} [options]
39
+ * @returns {import('@docusaurus/types').Preset}
40
+ */
41
+ function terminologyPreset(context, options = {}) {
42
+ const normalized = normalizeOptions(options);
55
43
 
56
- const writeIfMissing = (docsDir) => {
57
- try {
58
- if (!fs.existsSync(docsDir)) return;
59
- const catPath = path.join(docsDir, CATEGORY_FILENAME);
60
- if (fs.existsSync(catPath)) {
61
- // Respect an existing file; do not overwrite
62
- return;
63
- }
64
- fs.writeFileSync(catPath, makeCategoryYaml(), { encoding: 'utf8' });
65
- console.info(`[docusaurus-plugin-terminology] wrote ${CATEGORY_FILENAME} to ${docsDir}`);
66
- } catch (err) {
67
- // Non-fatal: warn and continue
68
- console.warn(`[docusaurus-plugin-terminology] failed to write ${CATEGORY_FILENAME} to ${docsDir}: ${err.message}`);
69
- }
70
- };
44
+ const plugins = [];
71
45
 
72
- // default locale docs dir
73
- const defaultDocsDir = path.resolve(context.siteDir, `docs/${termsDir}`);
74
- writeIfMissing(defaultDocsDir);
46
+ if (normalized.docsInstance) {
47
+ plugins.push([
48
+ CONTENT_DOCS_PLUGIN,
49
+ {
50
+ id: TERMS_DOCS_INSTANCE_ID,
51
+ path: normalized.termsDir,
52
+ routeBasePath: toDocsRouteBasePath(normalized.routeBasePath),
53
+ // The term pages are standalone: no sidebar at all for this instance.
54
+ sidebarPath: false,
55
+ breadcrumbs: false,
56
+ editUrl: undefined,
57
+ },
58
+ ]);
59
+ }
75
60
 
76
- // localized docs dirs (if i18n present)
77
- const { i18n } = context || {};
78
- if (i18n && Array.isArray(i18n.locales)) {
79
- for (const locale of i18n.locales) {
80
- if (locale === i18n.defaultLocale) continue;
81
- const localizedDocsDir = path.resolve(
82
- context.siteDir,
83
- `i18n/${locale}/docusaurus-plugin-content-docs/current/${termsDir}`
84
- );
85
- writeIfMissing(localizedDocsDir);
86
- }
87
- }
61
+ plugins.push([terminologyPlugin, normalized]);
88
62
 
89
- return null;
90
- },
91
-
92
- /**
93
- * Called when content has been loaded.
94
- * Processes glossary terms data for different locales and generates a glossary JSON file.
95
- * @param {Object} context - The context object containing siteDir, i18n, and actions.
96
- */
97
- async contentLoaded({ actions }) {
98
- const { siteDir, i18n } = context;
99
- const { defaultLocale, locales } = i18n;
100
- const { setGlobalData, createData } = actions;
101
-
102
- const termsData = {};
103
-
104
- for (const locale of locales) {
105
- const docsDir = locale === defaultLocale
106
- ? path.resolve(siteDir, `docs/${termsDir}`)
107
- : path.resolve(
108
- siteDir,
109
- `i18n/${locale}/docusaurus-plugin-content-docs/current/${termsDir}`
110
- );
111
-
112
- if (!fs.existsSync(docsDir)) continue;
113
-
114
- const termFiles = fs.readdirSync(docsDir).filter((f) => (f.endsWith('.md') || f.endsWith('.mdx')) && f !== 'index.md');
115
-
116
- const termsArray = [];
117
-
118
- for (const filename of termFiles) {
119
- const slug = filename.replace(/\.mdx?$/, '');
120
- const filepath = path.join(docsDir, filename);
121
- const fileContent = fs.readFileSync(filepath, 'utf-8');
122
- const { data, content } = matter(fileContent);
123
-
124
- termsArray.push({
125
- slug,
126
- name: data.title || slug,
127
- description: data.description || content.trim().split('\n')[0],
128
- });
129
- }
130
-
131
- // Sort termsArray alphabetically by name
132
- termsArray.sort((a, b) => a.name.localeCompare(b.name));
133
-
134
- // Convert sorted array back to object
135
- termsData[locale] = termsArray.reduce((acc, term) => {
136
- acc[term.slug] = {
137
- name: term.name,
138
- description: term.description,
139
- };
140
- return acc;
141
- }, {});
142
- }
143
-
144
- // Fallback: fill in missing terms for other locales using default locale
145
- for (const locale of Object.keys(termsData)) {
146
- if (locale === defaultLocale) continue;
147
- for (const [slug, entry] of Object.entries(termsData[defaultLocale] || {})) {
148
- if (!termsData[locale]?.[slug]) {
149
- if (!termsData[locale]) termsData[locale] = {};
150
- termsData[locale][slug] = entry;
151
- }
152
- }
153
- }
63
+ return {
64
+ plugins,
65
+ // Declared as a preset *theme* on purpose: it is evaluated after the
66
+ // classic theme, which is what lets us override `@theme/MDXComponents/A`.
67
+ themes: [terminologyTheme],
68
+ };
69
+ }
154
70
 
155
- //console.log('[plugin] termsData:', termsData);
156
- //console.log('Current locale:', i18n.currentLocale);
71
+ module.exports = terminologyPreset;
72
+ module.exports.default = terminologyPreset;
73
+ module.exports.terminologyPreset = terminologyPreset;
157
74
 
158
- // Write static glossary JSON file (default locale only)
159
- const outputJson = JSON.stringify(termsData[defaultLocale] || {}, null, 2);
160
- const glossaryDataPath = await createData('glossary.json', outputJson);
161
- //console.log('[plugin] glossary.json generated at:', glossaryDataPath);
162
- //console.log('[plugin] setGlobalData terms:', termsData);
75
+ // Named exports for advanced/legacy use.
76
+ module.exports.plugin = terminologyPlugin;
77
+ module.exports.theme = terminologyTheme;
163
78
 
164
- // Expose for use in components
165
- setGlobalData({
166
- terms: termsData,
167
- glossaryDataPath,
168
- routeBasePath,
169
- termsDir,
170
- });
171
- },
172
-
173
- getThemePath() {
174
- return path.resolve(__dirname, './theme');
175
- },
176
-
177
- getClientModules() {
178
- return [path.resolve(__dirname, './theme/tooltip.js')];
179
- },
180
- };
181
- };
79
+ // Handy for tooling/tests.
80
+ module.exports.TERMS_DOCS_INSTANCE_ID = TERMS_DOCS_INSTANCE_ID;
81
+ module.exports.resolveThemePath = () => path.resolve(__dirname, 'theme');