spec-up-t 1.3.0 → 1.4.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/.github/copilot-instructions.md +13 -0
- package/assets/compiled/body.js +18 -12
- package/assets/compiled/head.css +8 -6
- package/assets/css/collapse-definitions.css +0 -1
- package/assets/css/counter.css +10 -22
- package/assets/css/create-pdf.css +4 -2
- package/assets/css/create-term-filter.css +4 -4
- package/assets/css/definition-buttons-container.css +60 -0
- package/assets/css/{pdf-download.css → download-pdf-docx.css} +9 -5
- package/assets/css/insert-trefs.css +7 -0
- package/assets/css/sidebar-toc.css +2 -1
- package/assets/css/terms-and-definitions.css +73 -22
- package/assets/js/add-href-to-snapshot-link.js +16 -9
- package/assets/js/addAnchorsToTerms.js +2 -2
- package/assets/js/charts.js +10 -0
- package/assets/js/collapse-definitions.js +13 -2
- package/assets/js/collapse-meta-info.js +11 -9
- package/assets/js/definition-button-container-utils.js +82 -0
- package/assets/js/download-pdf-docx.js +68 -0
- package/assets/js/edit-term-buttons.js +77 -20
- package/assets/js/github-issues.js +35 -0
- package/assets/js/github-repo-info.js +144 -0
- package/assets/js/highlight-heading-plus-sibling-nodes.test.js +18 -0
- package/assets/js/insert-trefs.js +62 -13
- package/assets/js/mermaid-diagrams.js +11 -0
- package/assets/js/terminology-section-utility-container/README.md +107 -0
- package/assets/js/terminology-section-utility-container/create-alphabet-index.js +17 -0
- package/assets/js/{create-term-filter.js → terminology-section-utility-container/create-term-filter.js} +11 -44
- package/assets/js/terminology-section-utility-container/hide-show-utility-container.js +21 -0
- package/assets/js/terminology-section-utility-container/search.js +203 -0
- package/assets/js/terminology-section-utility-container.js +203 -0
- package/assets/js/tooltips.js +283 -0
- package/config/asset-map.json +26 -18
- package/index.js +57 -390
- package/package.json +5 -2
- package/src/add-remove-xref-source.js +20 -21
- package/src/collect-external-references.js +8 -337
- package/src/collect-external-references.test.js +440 -33
- package/src/configure.js +8 -109
- package/src/create-docx.js +7 -6
- package/src/create-pdf.js +15 -14
- package/src/freeze-spec-data.js +46 -0
- package/src/git-info.test.js +76 -0
- package/src/health-check/destination-gitignore-checker.js +5 -3
- package/src/health-check/external-specs-checker.js +5 -4
- package/src/health-check/specs-configuration-checker.js +2 -1
- package/src/health-check/term-references-checker.js +5 -3
- package/src/health-check/terms-intro-checker.js +2 -1
- package/src/health-check/tref-term-checker.js +8 -7
- package/src/health-check.js +8 -7
- package/src/init.js +3 -2
- package/src/install-from-boilerplate/add-gitignore-entries.js +3 -2
- package/src/install-from-boilerplate/add-scripts-keys.js +5 -4
- package/src/install-from-boilerplate/boilerplate/.github/workflows/menu.yml +74 -97
- package/src/install-from-boilerplate/boilerplate/README.md +1 -1
- package/src/install-from-boilerplate/boilerplate/spec/example-markup-in-markdown.md +1 -1
- package/src/install-from-boilerplate/boilerplate/spec/spec-head.md +2 -2
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/composability.md +3 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/compost.md +3 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/fertilizer.md +3 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/mulch.md +3 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/pruning.md +3 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/seedling.md +3 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/soil.md +11 -0
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/watering.md +3 -0
- package/src/install-from-boilerplate/boilerplate/specs.json +24 -10
- package/src/install-from-boilerplate/config-scripts-keys.js +3 -3
- package/src/install-from-boilerplate/config-system-files.js +0 -1
- package/src/install-from-boilerplate/copy-boilerplate.js +2 -1
- package/src/install-from-boilerplate/copy-system-files.js +4 -3
- package/src/install-from-boilerplate/custom-update.js +12 -1
- package/src/install-from-boilerplate/help.txt +1 -1
- package/src/install-from-boilerplate/menu.sh +6 -6
- package/src/json-key-validator.js +17 -11
- package/src/markdown-it/README.md +207 -0
- package/src/markdown-it/definition-lists.js +397 -0
- package/src/markdown-it/index.js +83 -0
- package/src/markdown-it/link-enhancement.js +98 -0
- package/src/markdown-it/plugins.js +118 -0
- package/src/markdown-it/table-enhancement.js +97 -0
- package/src/markdown-it/template-tag-syntax.js +152 -0
- package/src/parsers/index.js +16 -0
- package/src/parsers/spec-parser.js +152 -0
- package/src/parsers/spec-parser.test.js +109 -0
- package/src/parsers/template-tag-parser.js +277 -0
- package/src/parsers/template-tag-parser.test.js +107 -0
- package/src/pipeline/configuration/configure-starterpack.js +200 -0
- package/src/{create-external-specs-list.js → pipeline/configuration/create-external-specs-list.js} +13 -12
- package/src/{create-term-index.js → pipeline/configuration/create-term-index.js} +19 -18
- package/src/{create-versions-index.js → pipeline/configuration/create-versions-index.js} +4 -3
- package/src/{insert-term-index.js → pipeline/configuration/insert-term-index.js} +2 -2
- package/src/pipeline/configuration/prepare-spec-configuration.js +70 -0
- package/src/pipeline/parsing/apply-markdown-it-extensions.js +35 -0
- package/src/pipeline/parsing/create-markdown-parser.js +94 -0
- package/src/pipeline/parsing/create-markdown-parser.test.js +49 -0
- package/src/{html-dom-processor.js → pipeline/postprocessing/definition-list-postprocessor.js} +69 -10
- package/src/{escape-handler.js → pipeline/preprocessing/escape-processor.js} +3 -1
- package/src/{fix-markdown-files.js → pipeline/preprocessing/normalize-terminology-markdown.js} +41 -31
- package/src/pipeline/references/collect-external-references.js +307 -0
- package/src/pipeline/references/external-references-service.js +231 -0
- package/src/pipeline/references/fetch-terms-from-index.js +198 -0
- package/src/pipeline/references/match-term.js +34 -0
- package/src/{collectExternalReferences/matchTerm.test.js → pipeline/references/match-term.test.js} +8 -2
- package/src/pipeline/references/process-xtrefs-data.js +94 -0
- package/src/pipeline/references/xtref-utils.js +166 -0
- package/src/pipeline/rendering/render-spec-document.js +146 -0
- package/src/pipeline/rendering/render-utils.js +154 -0
- package/src/utils/LOGGER.md +81 -0
- package/src/utils/{doesUrlExist.js → does-url-exist.js} +4 -3
- package/src/utils/fetch.js +5 -4
- package/src/utils/file-opener.js +3 -2
- package/src/utils/git-info.js +77 -0
- package/src/utils/logger.js +74 -0
- package/src/utils/regex-patterns.js +471 -0
- package/src/utils/regex-patterns.test.js +281 -0
- package/templates/template.html +56 -21
- package/assets/js/create-alphabet-index.js +0 -60
- package/assets/js/hide-show-utility-container.js +0 -16
- package/assets/js/index.js +0 -87
- package/assets/js/pdf-download.js +0 -46
- package/assets/js/search.js +0 -365
- package/src/collectExternalReferences/fetchTermsFromIndex.js +0 -284
- package/src/collectExternalReferences/matchTerm.js +0 -32
- package/src/collectExternalReferences/processXTrefsData.js +0 -108
- package/src/freeze.js +0 -90
- package/src/install-from-boilerplate/boilerplate/.github/workflows/fetch-and-push-xrefs.yml.old +0 -42
- package/src/install-from-boilerplate/boilerplate/.github/workflows/render-specs.yml +0 -47
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/term-1.md +0 -13
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/term-2.md +0 -3
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/term-3.md +0 -3
- package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/term-4.md +0 -3
- package/src/markdown-it-extensions.js +0 -395
- package/src/references.js +0 -114
- /package/assets/css/{bootstrap.min.css → embedded-libraries/bootstrap.min.css} +0 -0
- /package/assets/css/{prism.css → embedded-libraries/prism.css} +0 -0
- /package/assets/css/{prism.dark.css → embedded-libraries/prism.dark.css} +0 -0
- /package/assets/css/{prism.default.css → embedded-libraries/prism.default.css} +0 -0
- /package/assets/js/{bootstrap.bundle.min.js → embedded-libraries/bootstrap.bundle.min.js} +0 -0
- /package/assets/js/{chart.js → embedded-libraries/chart.js} +0 -0
- /package/assets/js/{diff.min.js → embedded-libraries/diff.min.js} +0 -0
- /package/assets/js/{font-awesome.js → embedded-libraries/font-awesome.js} +0 -0
- /package/assets/js/{mermaid.js → embedded-libraries/mermaid.js} +0 -0
- /package/assets/js/{notyf.js → embedded-libraries/notyf.js} +0 -0
- /package/assets/js/{popper.js → embedded-libraries/popper.js} +0 -0
- /package/assets/js/{prism.dark.js → embedded-libraries/prism.dark.js} +0 -0
- /package/assets/js/{prism.default.js → embedded-libraries/prism.default.js} +0 -0
- /package/assets/js/{prism.js → embedded-libraries/prism.js} +0 -0
- /package/assets/js/{tippy.js → embedded-libraries/tippy.js} +0 -0
- /package/src/{escape-mechanism.js → pipeline/preprocessing/escape-placeholder-utils.js} +0 -0
- /package/src/utils/{isLineWithDefinition.js → is-line-with-definition.js} +0 -0
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { ESCAPED_PLACEHOLDER } = require('./escape-handler');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Configuration for custom template syntax [[example]] used throughout the markdown parsing
|
|
7
|
-
* These constants define how template markers are identified and processed
|
|
8
|
-
*/
|
|
9
|
-
const levels = 2; // Number of bracket characters used for template markers
|
|
10
|
-
const openString = '['.repeat(levels); // Opening delimiter for template markers, e.g., '[['
|
|
11
|
-
const closeString = ']'.repeat(levels); // Closing delimiter for template markers, e.g., ']]'
|
|
12
|
-
// Regular expression to extract template type and arguments from content between delimiters
|
|
13
|
-
// Captures: 1st group = template type (e.g., "ref", "tref"), 2nd group = optional arguments
|
|
14
|
-
const contentRegex = /\s*([^\s\[\]:]+):?\s*([^\]\n]+)?/i;
|
|
15
|
-
|
|
16
|
-
module.exports = function (md, templates = {}) {
|
|
17
|
-
|
|
18
|
-
// Add table renderer to apply Bootstrap classes to all tables by default
|
|
19
|
-
const originalTableRender = md.renderer.rules.table_open || function (tokens, idx, options, env, self) {
|
|
20
|
-
return self.renderToken(tokens, idx, options);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// Save the original table_close renderer
|
|
24
|
-
const originalTableCloseRender = md.renderer.rules.table_close || function (tokens, idx, options, env, self) {
|
|
25
|
-
return self.renderToken(tokens, idx, options);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
// Override table_open to add both the classes and open a wrapper div
|
|
29
|
-
md.renderer.rules.table_open = function (tokens, idx, options, env, self) {
|
|
30
|
-
// Add Bootstrap classes to the table element
|
|
31
|
-
const token = tokens[idx];
|
|
32
|
-
const classIndex = token.attrIndex('class');
|
|
33
|
-
const tableClasses = 'table table-striped table-bordered table-hover';
|
|
34
|
-
|
|
35
|
-
if (classIndex < 0) {
|
|
36
|
-
token.attrPush(['class', tableClasses]);
|
|
37
|
-
} else {
|
|
38
|
-
// If a class attribute already exists, append our classes
|
|
39
|
-
const existingClasses = token.attrs[classIndex][1];
|
|
40
|
-
// Only add classes that aren't already present
|
|
41
|
-
const classesToAdd = tableClasses
|
|
42
|
-
.split(' ')
|
|
43
|
-
.filter(cls => !existingClasses.includes(cls))
|
|
44
|
-
.join(' ');
|
|
45
|
-
|
|
46
|
-
if (classesToAdd) {
|
|
47
|
-
token.attrs[classIndex][1] = existingClasses + ' ' + classesToAdd;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Add the responsive wrapper div before the table
|
|
52
|
-
return '<div class="table-responsive-md">' + originalTableRender(tokens, idx, options, env, self);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Override table_close to close the wrapper div
|
|
56
|
-
md.renderer.rules.table_close = function (tokens, idx, options, env, self) {
|
|
57
|
-
// Close the table and add the closing div
|
|
58
|
-
return originalTableCloseRender(tokens, idx, options, env, self) + '</div>';
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Custom template syntax rule for markdown-it
|
|
63
|
-
* Processes template markers like [[template-type:arg1,arg2]] in markdown content
|
|
64
|
-
* and converts them to tokens that can be processed by template renderers
|
|
65
|
-
*/
|
|
66
|
-
md.inline.ruler.after('emphasis', 'templates', function templates_ruler(state, silent) {
|
|
67
|
-
// Get the current parsing position
|
|
68
|
-
var start = state.pos;
|
|
69
|
-
|
|
70
|
-
// Check if we're at an escaped placeholder - if so, skip processing
|
|
71
|
-
if (state.src.slice(start, start + ESCAPED_PLACEHOLDER.length) === ESCAPED_PLACEHOLDER) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Check if we're at a template opening marker
|
|
76
|
-
let prefix = state.src.slice(start, start + levels);
|
|
77
|
-
if (prefix !== openString) return false;
|
|
78
|
-
// Find the matching closing marker
|
|
79
|
-
var indexOfClosingBrace = state.src.indexOf(closeString, start);
|
|
80
|
-
|
|
81
|
-
if (indexOfClosingBrace > 0) {
|
|
82
|
-
// Extract the template content using regex
|
|
83
|
-
let match = contentRegex.exec(state.src.slice(start + levels, indexOfClosingBrace));
|
|
84
|
-
if (!match) return false;
|
|
85
|
-
|
|
86
|
-
// Get template type and find a matching template handler
|
|
87
|
-
let type = match[1];
|
|
88
|
-
let template = templates.find(t => t.filter(type) && t);
|
|
89
|
-
if (!template) return false;
|
|
90
|
-
|
|
91
|
-
// Parse template arguments (comma-separated)
|
|
92
|
-
let args = match[2] ? match[2].trim().split(/\s*,+\s*/) : [];
|
|
93
|
-
// Create a template token to be processed during rendering
|
|
94
|
-
let token = state.push('template', '', 0);
|
|
95
|
-
token.content = match[0];
|
|
96
|
-
token.info = { type, template, args };
|
|
97
|
-
|
|
98
|
-
// If the template has a parse function, use it to preprocess the token
|
|
99
|
-
if (template.parse) {
|
|
100
|
-
token.content = template.parse(token, type, ...args) || token.content;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Advance the parser position past the template
|
|
104
|
-
state.pos = indexOfClosingBrace + levels;
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return false;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Renderer for template tokens
|
|
113
|
-
* Takes template tokens created during parsing and renders them using their associated template handler
|
|
114
|
-
*/
|
|
115
|
-
md.renderer.rules.template = function (tokens, idx, options, env, renderer) {
|
|
116
|
-
let token = tokens[idx];
|
|
117
|
-
let template = token.info.template;
|
|
118
|
-
if (template.render) {
|
|
119
|
-
return template.render(token, token.info.type, ...token.info.args) || (openString + token.content + closeString);
|
|
120
|
-
}
|
|
121
|
-
return token.content;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Regular expression to extract domains and path segments from URLs
|
|
126
|
-
* Used to add path-related attributes to links for styling and behavior
|
|
127
|
-
*/
|
|
128
|
-
let pathSegmentRegex = /(?:http[s]*:\/\/([^\/]*)|(?:\/([^\/?]*)))/g;
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Custom link_open renderer that adds path attributes for styling and behavior
|
|
132
|
-
* Extracts domain and path segments from href attributes and adds them as path-X attributes
|
|
133
|
-
*/
|
|
134
|
-
md.renderer.rules.link_open = function (tokens, idx, options, env, renderer) {
|
|
135
|
-
let token = tokens[idx];
|
|
136
|
-
let attrs = token.attrs.reduce((str, attr) => {
|
|
137
|
-
let name = attr[0];
|
|
138
|
-
let value = attr[1];
|
|
139
|
-
if (name === 'href') {
|
|
140
|
-
let index = 0;
|
|
141
|
-
value.replace(pathSegmentRegex, (m, domain, seg) => {
|
|
142
|
-
str += `path-${index++}="${domain || seg}"`;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
return str += name + '="' + value + '" ';
|
|
146
|
-
}, '');
|
|
147
|
-
let anchor = `<a ${attrs}>`;
|
|
148
|
-
// Special handling for auto-detected links (linkify)
|
|
149
|
-
return token.markup === 'linkify' ? anchor + '<span>' : anchor;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
md.renderer.rules.link_close = function (tokens, idx, options, env, renderer) {
|
|
153
|
-
return tokens[idx].markup === 'linkify' ? '</span></a>' : '</a>';
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Add class to <dl> and the last <dd> in each series after a <dt>
|
|
157
|
-
const originalRender = md.renderer.rules.dl_open || function (tokens, idx, options, env, self) {
|
|
158
|
-
return self.renderToken(tokens, idx, options);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
// Variable to keep track of whether the class has been added to the first <dl> after the target HTML
|
|
162
|
-
let classAdded = false;
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Helper function to locate a specific marker in the token stream
|
|
166
|
-
* Used to identify the terminology section in the document
|
|
167
|
-
*
|
|
168
|
-
* @param {Array} tokens - The token array to search through
|
|
169
|
-
* @param {String} targetHtml - The HTML string to look for in token content
|
|
170
|
-
* @return {Number} The index of the token containing targetHtml, or -1 if not found
|
|
171
|
-
*/
|
|
172
|
-
function findTargetIndex(tokens, targetHtml) {
|
|
173
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
174
|
-
if (tokens[i].content && tokens[i].content.includes(targetHtml)) {
|
|
175
|
-
return i;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return -1;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Helper function to identify and mark empty definition term elements
|
|
183
|
-
* Empty dt elements cause rendering and styling issues, so we mark them for special handling
|
|
184
|
-
*
|
|
185
|
-
* @param {Array} tokens - The token array to process
|
|
186
|
-
* @param {Number} startIdx - The index in the token array to start processing from
|
|
187
|
-
*/
|
|
188
|
-
function markEmptyDtElements(tokens, startIdx) {
|
|
189
|
-
for (let i = startIdx; i < tokens.length; i++) {
|
|
190
|
-
if (tokens[i].type === 'dl_close') {
|
|
191
|
-
break; // Stop when we reach the end of this definition list
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// An empty dt element is one where dt_open is immediately followed by dt_close
|
|
195
|
-
// with no content in between
|
|
196
|
-
if (tokens[i].type === 'dt_open' &&
|
|
197
|
-
i + 1 < tokens.length &&
|
|
198
|
-
tokens[i + 1].type === 'dt_close') {
|
|
199
|
-
// Mark both opening and closing tokens so they can be skipped during rendering
|
|
200
|
-
tokens[i].isEmpty = true;
|
|
201
|
-
tokens[i + 1].isEmpty = true;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Helper function to process definition description elements
|
|
209
|
-
* Identifies and marks the last dd element in each dt/dd group for special styling
|
|
210
|
-
*
|
|
211
|
-
* @param {Array} tokens - The token array to process
|
|
212
|
-
* @param {Number} startIdx - The index in the token array to start processing from
|
|
213
|
-
*/
|
|
214
|
-
function processLastDdElements(tokens, startIdx) {
|
|
215
|
-
let lastDdIndex = -1; // Tracks the most recent dd_open token
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Helper function to check if a definition list contains spec references
|
|
221
|
-
* Spec references have dt elements with id attributes starting with "ref:"
|
|
222
|
-
*
|
|
223
|
-
* @param {Array} tokens - The token array to search through
|
|
224
|
-
* @param {Number} startIdx - The index to start searching from (after dl_open)
|
|
225
|
-
* @return {Boolean} True if the dl contains spec references, false otherwise
|
|
226
|
-
*/
|
|
227
|
-
function containsSpecReferences(tokens, startIdx) {
|
|
228
|
-
for (let i = startIdx; i < tokens.length; i++) {
|
|
229
|
-
if (tokens[i].type === 'dl_close') {
|
|
230
|
-
break; // Stop when we reach the end of this definition list
|
|
231
|
-
}
|
|
232
|
-
if (isDtRef(tokens[i])) {
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
if (isHtmlRef(tokens[i])) {
|
|
236
|
-
return true;
|
|
237
|
-
}
|
|
238
|
-
if (isInlineRef(tokens[i])) {
|
|
239
|
-
return true;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return false;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
function isDtRef(token) {
|
|
246
|
-
if (token.type !== 'dt_open' || !token.attrs) return false;
|
|
247
|
-
return token.attrs.some(attr => attr[0] === 'id' && attr[1].startsWith('ref:'));
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function isHtmlRef(token) {
|
|
251
|
-
if (token.type !== 'html_block' && token.type !== 'html_inline') return false;
|
|
252
|
-
return token.content && token.content.includes('id="ref:');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function isInlineRef(token) {
|
|
256
|
-
if (token.type !== 'inline') return false;
|
|
257
|
-
return token.content && token.content.includes('id="ref:');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Custom renderer for definition list opening tags
|
|
262
|
-
* Handles special styling for terminology sections and processes definition terms and descriptions
|
|
263
|
-
* This function was refactored to reduce cognitive complexity by extracting helper functions
|
|
264
|
-
*
|
|
265
|
-
* IMPORTANT FIX: This function now checks if a <dl> already has a class attribute OR contains
|
|
266
|
-
* spec references (dt elements with id="ref:...") before adding the 'terms-and-definitions-list'
|
|
267
|
-
* class. This prevents spec reference lists from being incorrectly classified as term definition lists.
|
|
268
|
-
*
|
|
269
|
-
* @param {Array} tokens - The token array being processed
|
|
270
|
-
* @param {Number} idx - The index of the current token
|
|
271
|
-
* @param {Object} options - Rendering options
|
|
272
|
-
* @param {Object} env - Environment variables
|
|
273
|
-
* @param {Object} self - Reference to the renderer
|
|
274
|
-
* @return {String} The rendered HTML output
|
|
275
|
-
*/
|
|
276
|
-
md.renderer.rules.dl_open = function (tokens, idx, options, env, self) {
|
|
277
|
-
const targetHtml = 'terminology-section-start';
|
|
278
|
-
let targetIndex = findTargetIndex(tokens, targetHtml);
|
|
279
|
-
|
|
280
|
-
// Check if the dl already has a class attribute (e.g., reference-list)
|
|
281
|
-
const existingClassIndex = tokens[idx].attrIndex('class');
|
|
282
|
-
const hasExistingClass = existingClassIndex >= 0;
|
|
283
|
-
|
|
284
|
-
// Check if this dl contains spec references (dt elements with id="ref:...")
|
|
285
|
-
const hasSpecReferences = containsSpecReferences(tokens, idx + 1);
|
|
286
|
-
|
|
287
|
-
// Only add terms-and-definitions-list class if:
|
|
288
|
-
// 1. It comes after the target HTML
|
|
289
|
-
// 2. We haven't added the class yet
|
|
290
|
-
// 3. The dl doesn't already have a class (to avoid overriding reference-list)
|
|
291
|
-
// 4. The dl doesn't contain spec references
|
|
292
|
-
if (targetIndex !== -1 && idx > targetIndex && !classAdded && !hasExistingClass && !hasSpecReferences) {
|
|
293
|
-
tokens[idx].attrPush(['class', 'terms-and-definitions-list']);
|
|
294
|
-
classAdded = true;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// First pass - mark empty dt elements
|
|
298
|
-
markEmptyDtElements(tokens, idx + 1);
|
|
299
|
-
|
|
300
|
-
// Second pass - process last dd elements
|
|
301
|
-
processLastDdElements(tokens, idx + 1);
|
|
302
|
-
|
|
303
|
-
return originalRender(tokens, idx, options, env, self);
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* Helper function to determine if a definition term is transcluded from another source
|
|
308
|
-
* Transcluded terms require special styling and handling
|
|
309
|
-
*
|
|
310
|
-
* @param {Array} tokens - The token array to process
|
|
311
|
-
* @param {Number} dtOpenIndex - The index of the dt_open token to check
|
|
312
|
-
* @return {Boolean} True if the term is transcluded, false otherwise
|
|
313
|
-
*/
|
|
314
|
-
function isTermTranscluded(tokens, dtOpenIndex) {
|
|
315
|
-
for (let i = dtOpenIndex + 1; i < tokens.length; i++) {
|
|
316
|
-
if (tokens[i].type === 'dt_close') {
|
|
317
|
-
break; // Only examine tokens within this definition term
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Look for inline content that contains template tokens of type 'tref'
|
|
321
|
-
// These are transcluded term references
|
|
322
|
-
if (tokens[i].type === 'inline' && tokens[i].children) {
|
|
323
|
-
for (let child of tokens[i].children) {
|
|
324
|
-
if (child.type === 'template' &&
|
|
325
|
-
child.info &&
|
|
326
|
-
child.info.type === 'tref') {
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return false;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Override the rendering of dt elements to properly handle transcluded terms
|
|
336
|
-
const originalDtRender = md.renderer.rules.dt_open || function (tokens, idx, options, env, self) {
|
|
337
|
-
return self.renderToken(tokens, idx, options);
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Custom renderer for definition term opening tags
|
|
342
|
-
* Handles special cases like empty terms and transcluded terms
|
|
343
|
-
*
|
|
344
|
-
* @param {Array} tokens - The token array being processed
|
|
345
|
-
* @param {Number} idx - The index of the current token
|
|
346
|
-
* @param {Object} options - Rendering options
|
|
347
|
-
* @param {Object} env - Environment variables
|
|
348
|
-
* @param {Object} self - Reference to the renderer
|
|
349
|
-
* @return {String} The rendered HTML output or empty string for skipped elements
|
|
350
|
-
*/
|
|
351
|
-
md.renderer.rules.dt_open = function (tokens, idx, options, env, self) {
|
|
352
|
-
// Skip rendering empty dt elements that were marked during preprocessing
|
|
353
|
-
if (tokens[idx].isEmpty) {
|
|
354
|
-
return '';
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Check if this dt is part of a transcluded term and add appropriate class
|
|
358
|
-
if (isTermTranscluded(tokens, idx)) {
|
|
359
|
-
const classIndex = tokens[idx].attrIndex('class');
|
|
360
|
-
if (classIndex < 0) {
|
|
361
|
-
tokens[idx].attrPush(['class', 'transcluded-xref-term']);
|
|
362
|
-
} else {
|
|
363
|
-
tokens[idx].attrs[classIndex][1] += ' transcluded-xref-term';
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return originalDtRender(tokens, idx, options, env, self);
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
// Similarly override dt_close to skip empty dts
|
|
371
|
-
const originalDtCloseRender = md.renderer.rules.dt_close || function (tokens, idx, options, env, self) {
|
|
372
|
-
return self.renderToken(tokens, idx, options);
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Custom renderer for definition term closing tags
|
|
377
|
-
* Ensures empty terms are not rendered in the final output
|
|
378
|
-
*
|
|
379
|
-
* @param {Array} tokens - The token array being processed
|
|
380
|
-
* @param {Number} idx - The index of the current token
|
|
381
|
-
* @param {Object} options - Rendering options
|
|
382
|
-
* @param {Object} env - Environment variables
|
|
383
|
-
* @param {Object} self - Reference to the renderer
|
|
384
|
-
* @return {String} The rendered HTML output or empty string for skipped elements
|
|
385
|
-
*/
|
|
386
|
-
md.renderer.rules.dt_close = function (tokens, idx, options, env, self) {
|
|
387
|
-
// Skip rendering the closing </dt> tag for empty dt elements
|
|
388
|
-
// This completes the fix for empty dt elements by ensuring neither
|
|
389
|
-
// the opening nor closing tags are rendered
|
|
390
|
-
if (tokens[idx].isEmpty) {
|
|
391
|
-
return '';
|
|
392
|
-
}
|
|
393
|
-
return originalDtCloseRender(tokens, idx, options, env, self);
|
|
394
|
-
};
|
|
395
|
-
};
|
package/src/references.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
const {JSDOM} = require("jsdom");
|
|
2
|
-
const axios = require('axios').default;
|
|
3
|
-
|
|
4
|
-
const spaceRegex = /\s+/g;
|
|
5
|
-
|
|
6
|
-
function validateReferences(references, definitions, render) {
|
|
7
|
-
const unresolvedRefs = [];
|
|
8
|
-
[...new Set(references)].forEach(
|
|
9
|
-
ref => {
|
|
10
|
-
if(render.includes(`id="term:${ref.replace(spaceRegex, '-').toLowerCase()}"`)) {
|
|
11
|
-
// Reference is resolved
|
|
12
|
-
} else {
|
|
13
|
-
unresolvedRefs.push(ref);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
);
|
|
17
|
-
if (unresolvedRefs.length > 0 ) {
|
|
18
|
-
console.log('ℹ️ Unresolved References: ', unresolvedRefs)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const danglingDefs = [];
|
|
22
|
-
definitions.forEach(defs => {
|
|
23
|
-
let found = defs.some(def => render.includes(`href="#term:${def.replace(spaceRegex, '-').toLowerCase()}"`))
|
|
24
|
-
if (!found) {
|
|
25
|
-
danglingDefs.push(defs[0]);
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
if(danglingDefs.length > 0) {
|
|
29
|
-
console.log('ℹ️ Dangling Definitions: ', danglingDefs)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function findExternalSpecByKey(config, key) {
|
|
34
|
-
for (const spec of config.specs) {
|
|
35
|
-
if (spec.external_specs) {
|
|
36
|
-
for (const externalSpec of spec.external_specs) {
|
|
37
|
-
if (externalSpec.external_spec === key) {
|
|
38
|
-
return externalSpec;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function fetchExternalSpecs(spec) {
|
|
47
|
-
try {
|
|
48
|
-
let results = await Promise.all(
|
|
49
|
-
spec.external_specs.map(s => {
|
|
50
|
-
const url = s["gh_page"];
|
|
51
|
-
return axios.get(url).catch(error => ({ error, url }));
|
|
52
|
-
})
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const failed = results.filter(r => r && r.error);
|
|
56
|
-
if (failed.length > 0) {
|
|
57
|
-
failed.forEach(f => {
|
|
58
|
-
const msg = f.error.response
|
|
59
|
-
? `HTTP ${f.error.response.status} for ${f.url}`
|
|
60
|
-
: `Network error for ${f.url}: ${f.error.message}`;
|
|
61
|
-
console.error("❌ External spec fetch failed:", msg);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Map results to objects keyed by external_spec if status is 200, otherwise null.
|
|
66
|
-
// This ensures only successful fetches are included, and failed ones are filtered out.
|
|
67
|
-
results = results
|
|
68
|
-
.map((r, index) =>
|
|
69
|
-
r && r.status === 200
|
|
70
|
-
? { [spec.external_specs[index].external_spec]: r.data }
|
|
71
|
-
: null
|
|
72
|
-
)
|
|
73
|
-
.filter(r => r); // Remove null values (failed fetches)
|
|
74
|
-
|
|
75
|
-
return results.map(r =>
|
|
76
|
-
createNewDLWithTerms(Object.keys(r)[0], Object.values(r)[0])
|
|
77
|
-
);
|
|
78
|
-
} catch (e) {
|
|
79
|
-
console.error("❌ Unexpected error in fetchExternalSpecs:", e);
|
|
80
|
-
return [];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
function createNewDLWithTerms(title, html) {
|
|
86
|
-
const dom = new JSDOM(html);
|
|
87
|
-
const document = dom.window.document;
|
|
88
|
-
|
|
89
|
-
const newDl = document.createElement('dl');
|
|
90
|
-
newDl.setAttribute('id', title);
|
|
91
|
-
|
|
92
|
-
const terms = document.querySelectorAll('dt span[id^="term:"]');
|
|
93
|
-
|
|
94
|
-
terms.forEach(term => {
|
|
95
|
-
const modifiedId = `term:${title}:${term.id.split(':')[1]}`;
|
|
96
|
-
term.id = modifiedId;
|
|
97
|
-
const dt = term.closest('dt');
|
|
98
|
-
const dd = dt.nextElementSibling;
|
|
99
|
-
|
|
100
|
-
newDl.appendChild(dt.cloneNode(true));
|
|
101
|
-
if (dd && dd.tagName === 'DD') {
|
|
102
|
-
newDl.appendChild(dd.cloneNode(true));
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
return newDl.outerHTML;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
module.exports = {
|
|
110
|
-
findExternalSpecByKey,
|
|
111
|
-
validateReferences,
|
|
112
|
-
fetchExternalSpecs,
|
|
113
|
-
createNewDLWithTerms
|
|
114
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|