spec-up-t 1.2.3 → 1.2.5

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.
Files changed (61) hide show
  1. package/.sonarlint/connectedMode.json +5 -0
  2. package/assets/compiled/body.js +35 -32
  3. package/assets/compiled/head.css +7 -5
  4. package/assets/compiled/head.js +3 -3
  5. package/assets/css/add-bootstrap-classes-to-images.css +34 -0
  6. package/assets/css/adjust-font-size.css +6 -11
  7. package/assets/css/backToTop.css +0 -1
  8. package/assets/css/image-full-size.css +44 -0
  9. package/assets/css/index.css +1 -2
  10. package/assets/css/pdf-styles.css +23 -27
  11. package/assets/css/repo-issues.css +0 -6
  12. package/assets/css/search.css +0 -1
  13. package/assets/css/sidebar-toc.css +13 -12
  14. package/assets/css/terms-and-definitions.css +43 -37
  15. package/assets/js/add-bootstrap-classes-to-images.js +98 -0
  16. package/assets/js/add-href-to-snapshot-link.js +2 -1
  17. package/assets/js/addAnchorsToTerms.js +0 -1
  18. package/assets/js/adjust-font-size.js +0 -9
  19. package/assets/js/create-alphabet-index.js +12 -3
  20. package/assets/js/create-term-filter.js +12 -0
  21. package/assets/js/custom-elements.js +13 -18
  22. package/assets/js/declare-markdown-it.js +1 -1
  23. package/assets/js/hide-show-utility-container.js +17 -0
  24. package/assets/js/highlightMenuItems.js +3 -3
  25. package/assets/js/image-full-size.js +76 -0
  26. package/assets/js/index.js +1 -5
  27. package/assets/js/insert-trefs.js +2 -2
  28. package/assets/js/modal.js +3 -3
  29. package/assets/js/search.js +15 -3
  30. package/assets/js/utils.js +2 -3
  31. package/index.js +7 -17
  32. package/package.json +2 -2
  33. package/src/README.md +3 -3
  34. package/src/add-remove-xref-source.js +0 -2
  35. package/src/asset-map.json +5 -0
  36. package/src/collect-external-references.js +187 -179
  37. package/src/collectExternalReferences/fetchTermsFromIndex.js +2 -1
  38. package/src/config/paths.js +2 -2
  39. package/src/create-external-specs-list.js +1 -1
  40. package/src/create-term-index.js +126 -22
  41. package/src/fix-markdown-files.js +152 -90
  42. package/src/health-check/external-specs-checker.js +173 -94
  43. package/src/health-check/output-gitignore-checker.js +327 -191
  44. package/src/health-check/specs-configuration-checker.js +288 -210
  45. package/src/health-check/term-references-checker.js +200 -123
  46. package/src/health-check/tref-term-checker.js +264 -179
  47. package/src/health-check.js +52 -36
  48. package/src/init.js +1 -4
  49. package/src/insert-term-index.js +5 -5
  50. package/src/install-from-boilerplate/add-scripts-keys.js +3 -1
  51. package/src/install-from-boilerplate/boilerplate/gitignore +2 -1
  52. package/src/install-from-boilerplate/config-system-files.js +9 -1
  53. package/src/install-from-boilerplate/copy-system-files.js +1 -1
  54. package/src/markdown-it-extensions.js +199 -106
  55. package/src/references.js +1 -2
  56. package/src/utils/doesUrlExist.js +7 -5
  57. package/src/utils/fetch.js +14 -14
  58. package/templates/template.html +1 -2
  59. package/assets/js/insert-xrefs.js +0 -370
  60. package/src/create-term-relations.js +0 -131
  61. package/src/prepare-tref.js +0 -174
@@ -1,370 +0,0 @@
1
- /**
2
- * @file This file fetches and displays commit hashes by matching elements with `x-term-reference` class against the `allXTrefs` global object.
3
- * Example:
4
- * const allXTrefs = {
5
- "xtrefs": [
6
- {
7
- "externalSpec": "test-1",
8
- "term": "Aal",
9
- "repoUrl": "https://github.com/blockchainbird/spec-up-xref-test-1",
10
- "terms_dir": "spec/term-definitions",
11
- "owner": "blockchainbird",
12
- "repo": "spec-up-xref-test-1",
13
- "site": "https://blockchainbird.github.io/spec-up-xref-test-1/",
14
- "commitHash": [
15
- "f66951f1d378490289caab9c51141b44a0438365",
16
- "content": "[[def: AAL]]:\n\n~ See: [[ref: authenticator assurance level]].\n\n~ This is an addition, for testing purposes.\n"
17
- ]
18
- },
19
- {…}
20
- ]
21
- };
22
- * @author Kor Dwarshuis
23
- * @version 0.0.1
24
- * @license MIT
25
- * @since 2024-06-09
26
- */
27
-
28
-
29
-
30
- function fetchCommitHashes() {
31
-
32
- let tipMap = new WeakMap();
33
-
34
- async function insertGitHubTermRealTime(match, element) {
35
- const div = document.createElement('div');
36
- div.classList.add('fetched-xref-term');
37
- div.classList.add('transcluded-xref-term');
38
- div.innerHTML = "<p class='loadertext'>Loading external reference</p><div class='loader'></div>";
39
- element.parentNode.insertBefore(div, element.nextSibling);
40
-
41
- // Promise.all waits for both termPromise and delayPromise to complete if termPromise finishes within 2000 ms.If termPromise takes longer than 2000 ms, the delay is effectively bypassed because Promise.all only cares about both promises finishing, regardless of the time taken by each.
42
-
43
- // Start fetching the GitHub term asynchronously
44
- const termPromise = fetchGitHubTerm(savedToken, match);
45
-
46
- // Create a delay of 2000 ms
47
- const delayPromise = new Promise(resolve => setTimeout(resolve, 2000));
48
-
49
- // Wait for whichever completes last between termPromise and delayPromise. The square brackets are used for array destructuring. In this context, the code is awaiting the resolution of multiple promises (termPromise and delayPromise) using Promise.all. The result of Promise.all is an array, and the square brackets are used to extract the first element of that array into the variable term.
50
- const [term] = await Promise.all([termPromise, delayPromise]);
51
-
52
- const timestamp = Date.now();
53
- const date = new Date(timestamp);
54
- const options = {
55
- year: 'numeric',
56
- month: 'long',
57
- day: 'numeric',
58
- hour: '2-digit',
59
- minute: '2-digit',
60
- second: '2-digit'
61
- };
62
- const humanReadableDate = date.toLocaleDateString('en-US', options);
63
-
64
- // Now that either both are complete or the term has taken longer than 2000 ms, continue with your code
65
- div.innerHTML = "<p class='transclusion-heading'>Current definition</p><small>" + humanReadableDate + "</small>" + term;
66
- }
67
- // Check if allXTrefs is undefined or does not exist
68
- if (typeof allXTrefs === 'undefined' || allXTrefs === null) {
69
- console.log('allXTrefs is not defined or does not exist. We will continue without it.');
70
- return;
71
- }
72
-
73
- // Load GitHub API token from local storage if it exists
74
- const savedToken = localStorage.getItem('githubToken');
75
-
76
- // Markdown parser, assuming markdown-it and markdown-it-deflist are globally available
77
- const md = window.markdownit().use(window.markdownitDeflist);
78
-
79
- // A: Debounce function to delay execution, so the error message is not displayed too often, since we do not know of often and how many times the error will be triggered.
80
- function debounce(func, wait) {
81
- let timeout;
82
- return function (...args) {
83
- clearTimeout(timeout);
84
- timeout = setTimeout(() => func.apply(this, args), wait);
85
- };
86
- }
87
-
88
- // B: Debounced “GitHub API rate limit exceeded” error message
89
- const debouncedError = debounce(() => {
90
- notyf.error('GitHub API rate limit exceeded. See <a target="_blank" rel="noopener" href="https://blockchainbird.github.io/spec-up-t-website/docs/getting-started/github-token">documentation</a> for more info.');
91
- }, 3000); // Delay in milliseconds
92
-
93
- /**
94
- * Fetches the content of a term file from GitHub using the GitHub API.
95
- * Compares the fetched content with the locally stored version and displays the diff in a modal.
96
- *
97
- * @param {string} savedToken - GitHub API token for authentication
98
- * @param {Object} match - The matched term object containing repository and term information
99
- */
100
- function fetchGitHubContent(savedToken, match) {
101
- // Create a headers object with the Authorization header if a GitHub API token is set
102
- const headers = {};
103
- if (savedToken && savedToken.length > 0) {
104
- headers['Authorization'] = `token ${savedToken}`;
105
- }
106
-
107
- fetch('https://api.github.com/repos/' + match.owner + '/' + match.repo + '/contents/' + match.terms_dir + '/' + match.term.replace(/ /g, '-').toLowerCase() + '.md', { headers: headers })
108
- .then(response => {
109
- if (response.status === 403 && response.headers.get('X-RateLimit-Remaining') === '0') {
110
- const resetTime = new Date(response.headers.get('X-RateLimit-Reset') * 1000);
111
- console.error(`❌ Github API rate limit exceeded. Try again after ${resetTime}. See https://blockchainbird.github.io/spec-up-t-website/docs/getting-started/github-token for more info.`);
112
-
113
- // Call the debounced error function
114
- debouncedError();
115
- return true;
116
- } else {
117
- console.log(`ℹ️ Github API rate limit: ${response.headers.get('X-RateLimit-Remaining')} requests remaining. See https://blockchainbird.github.io/spec-up-t-website/docs/getting-started/github-token for more info.`);
118
- }
119
-
120
- return response.json();
121
- })
122
- .then(data => {
123
- // Decode base64 encoded content
124
- const decodedContent = atob(data.content);
125
-
126
- // Diff the content of the current term-file with the content of stored version
127
- // See https://www.npmjs.com/package/diff , examples
128
- const diff = Diff.diffChars(match.content, decodedContent),
129
- fragment = document.createDocumentFragment();
130
-
131
- diff.forEach((part) => {
132
- // green for additions, red for deletions
133
- // grey for common parts
134
- const color = part.added ? 'green' :
135
- part.removed ? 'red' : 'grey';
136
-
137
- const backgroundColor = part.added ? '#ddd' :
138
- part.removed ? '#ddd' : 'white';
139
-
140
- span = document.createElement('span');
141
- span.style.color = color;
142
- span.style.backgroundColor = backgroundColor;
143
-
144
- span.appendChild(document
145
- .createTextNode(part.value));
146
- fragment.appendChild(span);
147
- });
148
- // Create a temporary container to hold the fragment
149
- const tempContainer = document.createElement('div');
150
- tempContainer.innerHTML = '<h1>Diff xref (local snapshot) and latest version</h1>';
151
- tempContainer.appendChild(fragment);
152
- // Replace newlines with <br> tags
153
- tempContainer.innerHTML = tempContainer.innerHTML.replace(/\n/g, '<br>');
154
- showModal(tempContainer.innerHTML);
155
- })
156
- .catch(error => {
157
- console.error('Error fetching content:', error);
158
- });
159
- }
160
-
161
- async function fetchGitHubTerm(savedToken, match) {
162
- function processSpecUpMarkdown(markdown) {
163
-
164
- // Replace all occurrences of [[def: ]] with ''
165
- const defRegex = /\[\[def: ([^\]]+)\]\]/g;
166
- markdown = markdown.replace(defRegex, '');
167
-
168
- // // Replace all occurrences of [[ref: ]] with <a href="#"></a>
169
- // const refRegex = /\[\[ref: ([^\]]+)\]\]/g;
170
- // markdown = markdown.replace(refRegex, '<a class="x-term-reference" data-local-href="ref:$1">$1</a>');
171
-
172
- return md.render(markdown);
173
- }
174
-
175
- const headers = {};
176
- if (savedToken && savedToken.length > 0) {
177
- headers['Authorization'] = `token ${savedToken}`;
178
- }
179
-
180
- try {
181
- const response = await fetch('https://api.github.com/repos/' + match.owner + '/' + match.repo + '/contents/' + match.terms_dir + '/' + match.term.replace(/ /g, '-').toLowerCase() + '.md', { headers: headers });
182
-
183
- if (response.status === 403 && response.headers.get('X-RateLimit-Remaining') === '0') {
184
- const resetTime = new Date(response.headers.get('X-RateLimit-Reset') * 1000);
185
- console.error(`❌ Github API rate limit exceeded. Try again after ${resetTime}. See https://blockchainbird.github.io/spec-up-t-website/docs/getting-started/github-token for more info.`);
186
-
187
- debouncedError();
188
- return true;
189
- } else {
190
- console.log(`ℹ️ Github API rate limit: ${response.headers.get('X-RateLimit-Remaining')} requests remaining. See https://blockchainbird.github.io/spec-up-t-website/docs/getting-started/github-token for more info.`);
191
- }
192
-
193
- const data = await response.json();
194
- const decodedContent = atob(data.content);
195
- const processedContent = processSpecUpMarkdown(decodedContent);
196
- return processedContent;
197
- } catch (error) {
198
- console.error('Error fetching content:', error);
199
- }
200
- }
201
-
202
- // get all elements with class “x-term-reference”
203
- const elements = document.querySelectorAll('.x-term-reference');
204
-
205
- elements.forEach((element) => {
206
- // Get the value of the data-local-href attribute
207
- const href = element.getAttribute('data-local-href');
208
-
209
- // split href on “:” and create array
210
- const splitHref = href.split(':');
211
-
212
- // allXTrefs is an object that is available in the global scope
213
- allXTrefs.xtrefs.forEach((match) => {
214
-
215
- //TODO: remove toLowerCase() or not?
216
- if (match.externalSpec === splitHref[1] && match.term.toLowerCase() === splitHref[2].toLowerCase()) {
217
-
218
- // If no commit hash is found, display a message and return
219
- if (!match.commitHash) {
220
- /**
221
- * Error message element shown when no cross-reference is found
222
- * Displayed directly after the term reference element
223
- */
224
- const noXTrefFoundMessage = document.createElement('span');
225
- noXTrefFoundMessage.classList.add('no-xref-found-message');
226
- noXTrefFoundMessage.innerHTML = 'No xref found.';
227
- element.parentNode.insertBefore(noXTrefFoundMessage, element.nextSibling);
228
-
229
- return
230
- };
231
-
232
- // To be used in the future
233
- const commitHashShort = match.commitHash && match.commitHash ? match.commitHash.substring(0, 7) : 'No hash';
234
-
235
- // Comment out all UI elements except tooltip
236
-
237
- // Diff of the latest commit hash of a term file and the referenced commit hash
238
-
239
- // Button that links to GitHub comparison between referenced commit and current main branch
240
- // Shows the difference between the referenced version and latest version on GitHub
241
-
242
- const diff = document.createElement('a');
243
- diff.href = 'https://github.com/' + match.owner + '/' + match.repo + '/compare/' + match.commitHash + '../main';
244
- diff.target = '_blank';
245
- diff.rel = 'noopener noreferrer';
246
- diff.classList.add('diff', 'xref-info-links', 'btn');
247
- diff.innerHTML = '<svg icon><use xlink:href="#svg-github"></use></svg> Xref &lt; &gt; <svg icon><use xlink:href="#svg-github"></use></svg> Now';
248
- diff.title = 'A Diff between the current commit hash of the definition and the commit hash referenced when the link was created.';
249
- element.parentNode.insertBefore(diff, element.nextSibling);
250
-
251
- // Latest version of a term-file
252
-
253
- // Button that links to the latest version of the term file on GitHub
254
- // Takes the user to the most current version in the repository
255
-
256
- const latestVersion = document.createElement('a');
257
- latestVersion.href = 'https://github.com/' + match.owner + '/' + match.repo + '/blob/main/' + match.terms_dir + '/' + match.term.replace(/ /g, '-').toLowerCase() + '.md';
258
- latestVersion.target = '_blank';
259
- latestVersion.rel = 'noopener noreferrer';
260
- latestVersion.classList.add('latest-version', 'xref-info-links', 'btn');
261
- latestVersion.innerHTML = '<svg icon><use xlink:href="#svg-github"></use></svg> Now';
262
- latestVersion.title = 'Go to the repo page of the definition‘s latest version.';
263
- diff.parentNode.insertBefore(latestVersion, element.nextSibling);
264
-
265
- // Exact commit hash at the time of referencing the file
266
-
267
- // Button that links to the exact commit version of the term file referenced in the document
268
- // Shows the historical version that was used when creating the reference
269
-
270
- const exactCommitHash = document.createElement('a');
271
- exactCommitHash.href = 'https://github.com/' + match.owner + '/' + match.repo + '/blob/' + match.commitHash + '/' + match.terms_dir + '/' + match.term.replace(/ /g, '-').toLowerCase() + '.md';
272
- exactCommitHash.target = '_blank';
273
- exactCommitHash.rel = 'noopener noreferrer';
274
- exactCommitHash.classList.add('exact-commit-hash', 'xref-info-links', 'btn');
275
- exactCommitHash.innerHTML = '<svg icon><use xlink:href="#svg-github"></use></svg> Xref';
276
- exactCommitHash.title = 'Go to the repo page of the definition‘s version referenced when the link was created.';
277
- latestVersion.parentNode.insertBefore(exactCommitHash, element.nextSibling);
278
-
279
- // Diff of the latest version and the referenced version in a modal
280
-
281
- // Button that opens a modal showing the diff between referenced version and latest version
282
- // Displays changes inline within the current page context
283
-
284
- const showDiffModal = document.createElement('button');
285
- showDiffModal.classList.add('show-diff-modal', 'xref-info-links', 'btn');
286
- showDiffModal.innerHTML = 'Xref &lt; &gt; <svg icon><use xlink:href="#svg-github"></use></svg> Now';
287
- showDiffModal.title = 'Show diff between the latest version and the referenced version';
288
- latestVersion.parentNode.insertBefore(showDiffModal, element.nextSibling);
289
- showDiffModal.addEventListener('click', function (event) {
290
- event.preventDefault();
291
- fetchGitHubContent(savedToken, match);
292
- });
293
-
294
- // The stored version of the term-file
295
- // Button that opens a modal showing only the locally stored version of the term
296
- // Displays the exact content that was stored when the reference was created
297
-
298
- const localStoredTerm = document.createElement('button');
299
- localStoredTerm.classList.add('show-diff-modal', 'xref-info-links', 'btn');
300
- localStoredTerm.innerHTML = 'Xref';
301
- localStoredTerm.title = 'Show the stored version of the term-file';
302
- showDiffModal.parentNode.insertBefore(localStoredTerm, element.nextSibling);
303
-
304
-
305
-
306
- // Replace all occurrences of [[def: ]] with ''
307
- const defRegex = /\[\[def: ([^\]]+)\]\]/g;
308
- match.content = match.content.replace(defRegex, '');
309
-
310
- // const content = md.render(match.content);
311
- const content = match.content;
312
- localStoredTerm.addEventListener('click', function (event) {
313
- event.preventDefault();
314
- showModal(`
315
- <h1>Term definition (local snapshot)</h1>
316
- <table>
317
- <tr>
318
- <th>Commit hash</th>
319
- <td>${match.commitHash}</td>
320
- </tr>
321
- <tr>
322
- <th>Content</th>
323
- <td>${content}</td>
324
- </tr>
325
- </table>
326
- `);
327
- });
328
-
329
- const div = document.createElement('div');
330
- div.classList.add('local-snapshot-xref-term');
331
- div.classList.add('transcluded-xref-term');
332
- div.innerHTML = `<p class='transclusion-heading'>Snapshot</p><p>Commit Hash: ${match.commitHash}</p> ${content}`;
333
- element.parentNode.insertBefore(div, element.nextSibling);
334
-
335
- insertGitHubTermRealTime(match, element);
336
-
337
- // Tooltip functionality
338
- delegateEvent('pointerover', '.x-term-reference', (e, anchor) => {
339
- // Get the matching term from your data
340
- const href = anchor.getAttribute('data-local-href');
341
- const splitHref = href.split(':');
342
-
343
- // Find matching term in allXTrefs
344
- const match = allXTrefs.xtrefs.find(m =>
345
- m.externalSpec === splitHref[1] &&
346
- m.term.toLowerCase() === splitHref[2].toLowerCase());
347
-
348
- if (!match || tipMap.has(anchor)) return;
349
-
350
- // Create tooltip with content
351
- let tip = {
352
- // content: md.render(match.content.replace(/\[\[def: ([^\]]+)\]\]/g, '')),
353
- // content: `<dl>` + md.render(match.content.replace(/\[\[def: ([^\]]+)\]\]/g, '')) + `</dl>`,
354
- content: match.content.replace(/\[\[def: ([^\]]+)\]\]/g, ''),
355
- allowHTML: true,
356
- inlinePositioning: true
357
- };
358
-
359
- if (tip.content) tipMap.set(anchor, tippy(anchor, tip));
360
- }, { passive: true });
361
-
362
-
363
- }
364
- });
365
- });
366
- }
367
-
368
- document.addEventListener("DOMContentLoaded", function () {
369
- fetchCommitHashes();
370
- });
@@ -1,131 +0,0 @@
1
- /**
2
- * @file This file creates a json and a js file with an an object that contains the relations between terms
3
- * @author Kor Dwarshuis
4
- * @version 1.0.0
5
- * @since 2024-06-22
6
- */
7
-
8
-
9
- const fs = require('fs-extra');
10
- const path = require('path');
11
- const config = fs.readJsonSync('specs.json');
12
- const { shouldProcessFile } = require('./utils/file-filter');
13
-
14
- const specTermDirectoryName = config.specs.map(spec => spec.spec_directory + '/' + spec.spec_terms_directory);
15
-
16
-
17
- // Create a path for the output file in the project root
18
-
19
- // // A: to the directory that will be published
20
- // const outputPathJSON = path.join(config.specs[0].output_path, 'term-relations-data.json');
21
- // const outputPathJS = path.join(config.specs[0].output_path, 'term-relations-data.js');
22
-
23
- // B: to the “output” directory
24
- const outputPathJSON = path.join('output', 'term-relations-data.json');
25
- const outputPathJS = path.join('output', 'term-relations-data.js');
26
-
27
- // Create directory named “output” in the project root if it does not yet exist
28
- if (!fs.existsSync('output')) {
29
- fs.mkdirSync('output');
30
- }
31
-
32
- // Create directory named “output” in the project root if it does not yet exist
33
- if (!fs.existsSync(config.specs[0].output_path)) {
34
- fs.mkdirSync(config.specs[0].output_path);
35
- }
36
-
37
- function createTermRelations() {
38
- let allDefs = {};
39
- allDefs.defs = new Set();
40
-
41
- // Go through all directories that contain files with a term and definition
42
- specTermDirectoryName.forEach(specDirectory => {
43
- // read directory
44
- fs.readdirSync(specDirectory).forEach(file => {
45
- // read file
46
- if (shouldProcessFile(file)) {
47
- const markdown = fs.readFileSync(`${specDirectory}/${file}`, 'utf8');
48
-
49
- let regexDef = /\[\[def:.*?\]\]/g;
50
- let regexRef = /\[\[ref:.*?\]\]/g;
51
- let regexXref = /\[\[xref:.*?\]\]/g;
52
-
53
- let entry = {};
54
-
55
- if (regexDef.test(markdown)) {
56
- const defs = markdown.match(regexDef);
57
- let refs = markdown.match(regexRef);
58
- let xrefs = markdown.match(regexXref);
59
-
60
- defs.forEach(def => {
61
- // remove “[[def:” from the beginning of every value in allMatches
62
- def = def.replace(/\[\[def:/, '');
63
-
64
- // remove “]]” from the end of every value in allMatches
65
- def = def.replace(/\]\]/, '');
66
-
67
- // trim every entry of allMatches
68
- def = def.trim();
69
-
70
- // Split the input on the first comma
71
- let [term, rest] = def.split(/,(.+)/);
72
-
73
- // Trim the term
74
- term = term.trim();
75
-
76
- entry.term = term;
77
- // Split the rest into an array of synonyms if it exists, otherwise use a placeholder
78
- let synonyms = rest ? rest.split(',').map(s => s.trim()) : [];
79
- entry.synonyms = synonyms;
80
- });
81
-
82
- if (refs !== null) {
83
- entry.refs = [];
84
- refs.forEach(ref => {
85
- // remove “[[ref:” from the beginning of every value in allMatches
86
- ref = ref.replace(/\[\[ref:/, '');
87
- // remove “]]” from the end of every value in allMatches
88
- ref = ref.replace(/\]\]/, '');
89
- // trim every entry of allMatches
90
- ref = ref.trim();
91
- entry.refs.push(ref);
92
- });
93
- }
94
-
95
- if (xrefs !== null) {
96
- entry.xrefs = [];
97
- xrefs.forEach(xref => {
98
- // remove “[[xref:” from the beginning of every value in allMatches
99
- xref = xref.replace(/\[\[xref:/, '');
100
- // remove “]]” from the end of every value in allMatches
101
- xref = xref.replace(/\]\]/, '');
102
- // trim every entry of allMatches
103
- xref = xref.trim();
104
- entry.xrefs.push(xref);
105
- });
106
- }
107
- }
108
- allDefs.defs.add(entry);
109
- }
110
- });
111
- })
112
- // Convert the Set back to an Array if needed
113
- allDefs.defs = Array.from(allDefs.defs);
114
-
115
- // Convert allXrefsStr to a JSON string with indentation
116
- const allDefsStr = JSON.stringify(allDefs, null, 2);
117
-
118
- // Write the JSON code to a .json file
119
- fs.writeFileSync(outputPathJSON, allDefsStr, 'utf8');
120
-
121
-
122
- // Create the JS code for the assignment
123
- const stringReadyForFileWrite = `const allTermRelations = ${allDefsStr};`;
124
-
125
- // Write the JS code to a .js file
126
- fs.writeFileSync(outputPathJS, stringReadyForFileWrite, 'utf8');
127
- }
128
-
129
- module.exports = {
130
- createTermRelations
131
- }
@@ -1,174 +0,0 @@
1
- /**
2
- * @file prepare-tref.js
3
- * @description This module provides functionality to process markdown files in a directory recursively,
4
- * searching for specific `[[tref:]]` references, and replacing them with detailed information
5
- * fetched from a local JSON file (`xtrefs-data.json`). The information includes metadata such as
6
- * owner, repository, commit hash, and content. If no matching reference is found, a placeholder
7
- * message is written to the file.
8
- *
9
- * The module includes:
10
- * - A helper function `getLocalXTrefContent` to retrieve reference data from the JSON file.
11
- * - A main function `prepareTref` to process directories and markdown files, replacing tref references.
12
- *
13
- * This is useful for dynamically enriching markdown documentation with external reference details.
14
- *
15
- * @requires fs - Node.js file system module for reading and writing files.
16
- * @requires path - Node.js path module for handling file paths.
17
- * @requires dedent - A utility for removing indentation from multi-line strings.
18
- *
19
- * @module prepareTref
20
- */
21
-
22
- const fs = require('fs');
23
- const path = require('path');
24
- const dedent = require('dedent');
25
- const { shouldProcessFile } = require('./utils/file-filter');
26
-
27
- function getLocalXTrefContent(externalSpec, term) {
28
- const filePath = path.join('output', 'xtrefs-data.json');
29
-
30
- try {
31
- const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
32
- const xtrefs = data.xtrefs;
33
-
34
- for (const xtref of xtrefs) {
35
- if (xtref.externalSpec === externalSpec && xtref.term === term) {
36
- // Validate that required properties exist
37
- if (!xtref.content || !xtref.owner || !xtref.repo || !xtref.repoUrl) {
38
- console.warn(`Warning: Incomplete data for ${externalSpec}, ${term}`);
39
- }
40
-
41
- return {
42
- content: xtref.content || "No content available",
43
- commitHash: xtref.commitHash || "Not available",
44
- owner: xtref.owner || "Unknown",
45
- repo: xtref.repo || "Unknown",
46
- repoUrl: xtref.repoUrl || "#",
47
- avatarUrl: xtref.avatarUrl || ""
48
- };
49
- }
50
- }
51
- } catch (err) {
52
- console.error(`Error reading xtrefs-data.json: ${err}`);
53
- }
54
-
55
- return {
56
- content: `Term '${term}' not found in external specification '${externalSpec}'`,
57
- commitHash: "Not available",
58
- owner: "Unknown",
59
- repo: "Unknown",
60
- repoUrl: "#",
61
- avatarUrl: ""
62
- };
63
- }
64
-
65
- // Function to process markdown files in a directory recursively
66
- function prepareTref(directory) {
67
- // Helper function to process a directory
68
- function processDirectory(directory) {
69
- try {
70
- // Read the contents of the directory synchronously
71
- const items = fs.readdirSync(directory, { withFileTypes: true });
72
-
73
- // Loop through each item in the directory
74
- items.forEach(item => {
75
- const itemPath = path.join(directory, item.name);
76
- if (item.isDirectory()) {
77
- // If the item is a directory, call processDirectory recursively
78
- processDirectory(itemPath);
79
- } else if (item.isFile() && shouldProcessFile(item.name)) {
80
- try {
81
- // Read the file synchronously
82
- let data = fs.readFileSync(itemPath, 'utf8');
83
-
84
- // Split the content into lines
85
- let lines = data.split('\n');
86
-
87
- // Variable to store content after the span or tref line
88
- let contentAfterSpan = '';
89
- const spanMarker = '<span style="display: none;">End of included external content. Add your optional custom content below.</span>';
90
- const spanIndex = data.indexOf(spanMarker);
91
-
92
- if (spanIndex !== -1) {
93
- // If span marker exists, take content after it
94
- contentAfterSpan = data.substring(spanIndex + spanMarker.length);
95
- } else {
96
- // If span marker doesn't exist, find the tref line and keep everything after it
97
- let trefLineIndex = -1;
98
- for (let i = 0; i < lines.length; i++) {
99
- if (lines[i].startsWith('[[tref:')) {
100
- trefLineIndex = i;
101
- break;
102
- }
103
- }
104
- if (trefLineIndex !== -1 && trefLineIndex < lines.length - 1) {
105
- contentAfterSpan = lines.slice(trefLineIndex + 1).join('\n');
106
- }
107
- }
108
-
109
- for (let i = 0; i < lines.length; i++) {
110
- if (lines[i].startsWith('[[tref:')) {
111
- const tref = /\[\[tref:(.*?)\]\]/;
112
- const match = lines[i].match(tref);
113
- let currentTref = lines[i]; // Store the current tref line for error handling
114
-
115
- if (match) {
116
- try {
117
- const result = match[1].split(',').map(term => term.trim());
118
-
119
- if (result.length < 2) {
120
- throw new Error(`Invalid tref format. Expected: [[tref:spec,term]], got: ${match[0]}`);
121
- }
122
-
123
- const localXTrefContent = getLocalXTrefContent(result[0], result[1]);
124
-
125
- // Skip processing if essential data is missing
126
- if (!localXTrefContent) {
127
- console.warn(`Warning: No content found for ${result[0]}, ${result[1]}`);
128
- continue;
129
- }
130
-
131
- const defPart = /\[\[def: ([^,]+),.*?\]\]/g;
132
- if (localXTrefContent.content) {
133
- localXTrefContent.content = localXTrefContent.content.replace(defPart, '');
134
- }
135
-
136
- const readyForWrite = dedent`
137
- ${match[0]}
138
- | Property | Value |
139
- | -------- | ----- |
140
- | Owner | ${localXTrefContent.avatarUrl ? `![avatar](${localXTrefContent.avatarUrl})` : ''} ${localXTrefContent.owner} |
141
- | Repo | [${localXTrefContent.repo}](${localXTrefContent.repoUrl}) |
142
- | Commit hash | ${localXTrefContent.commitHash} |
143
-
144
- ${localXTrefContent.content}
145
- ${spanMarker}
146
-
147
- ${contentAfterSpan}
148
-
149
- `;
150
-
151
- fs.writeFileSync(itemPath, readyForWrite, 'utf8');
152
- } catch (err) {
153
- console.error(`Error processing tref: ${err}`);
154
- fs.writeFileSync(itemPath, currentTref + '\n\n' + '\n\nError processing reference: ' + err.message, 'utf8');
155
- }
156
- }
157
- }
158
- }
159
- } catch (err) {
160
- console.error(`Error processing file ${itemPath}: ${err}`);
161
- }
162
- }
163
- });
164
- } catch (err) {
165
- console.error(`❌ Error reading directory: ${err}`);
166
- }
167
- }
168
-
169
- processDirectory(directory);
170
- }
171
-
172
- module.exports = {
173
- prepareTref
174
- };