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.
- package/.sonarlint/connectedMode.json +5 -0
- package/assets/compiled/body.js +35 -32
- package/assets/compiled/head.css +7 -5
- package/assets/compiled/head.js +3 -3
- package/assets/css/add-bootstrap-classes-to-images.css +34 -0
- package/assets/css/adjust-font-size.css +6 -11
- package/assets/css/backToTop.css +0 -1
- package/assets/css/image-full-size.css +44 -0
- package/assets/css/index.css +1 -2
- package/assets/css/pdf-styles.css +23 -27
- package/assets/css/repo-issues.css +0 -6
- package/assets/css/search.css +0 -1
- package/assets/css/sidebar-toc.css +13 -12
- package/assets/css/terms-and-definitions.css +43 -37
- package/assets/js/add-bootstrap-classes-to-images.js +98 -0
- package/assets/js/add-href-to-snapshot-link.js +2 -1
- package/assets/js/addAnchorsToTerms.js +0 -1
- package/assets/js/adjust-font-size.js +0 -9
- package/assets/js/create-alphabet-index.js +12 -3
- package/assets/js/create-term-filter.js +12 -0
- package/assets/js/custom-elements.js +13 -18
- package/assets/js/declare-markdown-it.js +1 -1
- package/assets/js/hide-show-utility-container.js +17 -0
- package/assets/js/highlightMenuItems.js +3 -3
- package/assets/js/image-full-size.js +76 -0
- package/assets/js/index.js +1 -5
- package/assets/js/insert-trefs.js +2 -2
- package/assets/js/modal.js +3 -3
- package/assets/js/search.js +15 -3
- package/assets/js/utils.js +2 -3
- package/index.js +7 -17
- package/package.json +2 -2
- package/src/README.md +3 -3
- package/src/add-remove-xref-source.js +0 -2
- package/src/asset-map.json +5 -0
- package/src/collect-external-references.js +187 -179
- package/src/collectExternalReferences/fetchTermsFromIndex.js +2 -1
- package/src/config/paths.js +2 -2
- package/src/create-external-specs-list.js +1 -1
- package/src/create-term-index.js +126 -22
- package/src/fix-markdown-files.js +152 -90
- package/src/health-check/external-specs-checker.js +173 -94
- package/src/health-check/output-gitignore-checker.js +327 -191
- package/src/health-check/specs-configuration-checker.js +288 -210
- package/src/health-check/term-references-checker.js +200 -123
- package/src/health-check/tref-term-checker.js +264 -179
- package/src/health-check.js +52 -36
- package/src/init.js +1 -4
- package/src/insert-term-index.js +5 -5
- package/src/install-from-boilerplate/add-scripts-keys.js +3 -1
- package/src/install-from-boilerplate/boilerplate/gitignore +2 -1
- package/src/install-from-boilerplate/config-system-files.js +9 -1
- package/src/install-from-boilerplate/copy-system-files.js +1 -1
- package/src/markdown-it-extensions.js +199 -106
- package/src/references.js +1 -2
- package/src/utils/doesUrlExist.js +7 -5
- package/src/utils/fetch.js +14 -14
- package/templates/template.html +1 -2
- package/assets/js/insert-xrefs.js +0 -370
- package/src/create-term-relations.js +0 -131
- package/src/prepare-tref.js +0 -174
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for custom template syntax [[example]] used throughout the markdown parsing
|
|
5
|
+
* These constants define how template markers are identified and processed
|
|
6
|
+
*/
|
|
7
|
+
const levels = 2; // Number of bracket characters used for template markers
|
|
8
|
+
const openString = '['.repeat(levels); // Opening delimiter for template markers, e.g., '[['
|
|
9
|
+
const closeString = ']'.repeat(levels); // Closing delimiter for template markers, e.g., ']]'
|
|
10
|
+
// Regular expression to extract template type and arguments from content between delimiters
|
|
11
|
+
// Captures: 1st group = template type (e.g., "ref", "tref"), 2nd group = optional arguments
|
|
6
12
|
const contentRegex = /\s*([^\s\[\]:]+):?\s*([^\]\n]+)?/i;
|
|
7
13
|
|
|
8
14
|
module.exports = function (md, templates = {}) {
|
|
@@ -23,7 +29,7 @@ module.exports = function (md, templates = {}) {
|
|
|
23
29
|
const token = tokens[idx];
|
|
24
30
|
const classIndex = token.attrIndex('class');
|
|
25
31
|
const tableClasses = 'table table-striped table-bordered table-hover';
|
|
26
|
-
|
|
32
|
+
|
|
27
33
|
if (classIndex < 0) {
|
|
28
34
|
token.attrPush(['class', tableClasses]);
|
|
29
35
|
} else {
|
|
@@ -34,12 +40,12 @@ module.exports = function (md, templates = {}) {
|
|
|
34
40
|
.split(' ')
|
|
35
41
|
.filter(cls => !existingClasses.includes(cls))
|
|
36
42
|
.join(' ');
|
|
37
|
-
|
|
43
|
+
|
|
38
44
|
if (classesToAdd) {
|
|
39
45
|
token.attrs[classIndex][1] = existingClasses + ' ' + classesToAdd;
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
|
-
|
|
48
|
+
|
|
43
49
|
// Add the responsive wrapper div before the table
|
|
44
50
|
return '<div class="table-responsive">' + originalTableRender(tokens, idx, options, env, self);
|
|
45
51
|
};
|
|
@@ -50,30 +56,43 @@ module.exports = function (md, templates = {}) {
|
|
|
50
56
|
return originalTableCloseRender(tokens, idx, options, env, self) + '</div>';
|
|
51
57
|
};
|
|
52
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Custom template syntax rule for markdown-it
|
|
61
|
+
* Processes template markers like [[template-type:arg1,arg2]] in markdown content
|
|
62
|
+
* and converts them to tokens that can be processed by template renderers
|
|
63
|
+
*/
|
|
53
64
|
md.inline.ruler.after('emphasis', 'templates', function templates_ruler(state, silent) {
|
|
54
|
-
|
|
65
|
+
// Get the current parsing position
|
|
55
66
|
var start = state.pos;
|
|
67
|
+
// Check if we're at a template opening marker
|
|
56
68
|
let prefix = state.src.slice(start, start + levels);
|
|
57
69
|
if (prefix !== openString) return false;
|
|
70
|
+
// Find the matching closing marker
|
|
58
71
|
var indexOfClosingBrace = state.src.indexOf(closeString, start);
|
|
59
72
|
|
|
60
73
|
if (indexOfClosingBrace > 0) {
|
|
61
|
-
|
|
74
|
+
// Extract the template content using regex
|
|
62
75
|
let match = contentRegex.exec(state.src.slice(start + levels, indexOfClosingBrace));
|
|
63
76
|
if (!match) return false;
|
|
64
77
|
|
|
78
|
+
// Get template type and find a matching template handler
|
|
65
79
|
let type = match[1];
|
|
66
80
|
let template = templates.find(t => t.filter(type) && t);
|
|
67
81
|
if (!template) return false;
|
|
68
82
|
|
|
83
|
+
// Parse template arguments (comma-separated)
|
|
69
84
|
let args = match[2] ? match[2].trim().split(/\s*,+\s*/) : [];
|
|
85
|
+
// Create a template token to be processed during rendering
|
|
70
86
|
let token = state.push('template', '', 0);
|
|
71
87
|
token.content = match[0];
|
|
72
88
|
token.info = { type, template, args };
|
|
89
|
+
|
|
90
|
+
// If the template has a parse function, use it to preprocess the token
|
|
73
91
|
if (template.parse) {
|
|
74
92
|
token.content = template.parse(token, type, ...args) || token.content;
|
|
75
93
|
}
|
|
76
94
|
|
|
95
|
+
// Advance the parser position past the template
|
|
77
96
|
state.pos = indexOfClosingBrace + levels;
|
|
78
97
|
return true;
|
|
79
98
|
}
|
|
@@ -81,6 +100,10 @@ module.exports = function (md, templates = {}) {
|
|
|
81
100
|
return false;
|
|
82
101
|
});
|
|
83
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Renderer for template tokens
|
|
105
|
+
* Takes template tokens created during parsing and renders them using their associated template handler
|
|
106
|
+
*/
|
|
84
107
|
md.renderer.rules.template = function (tokens, idx, options, env, renderer) {
|
|
85
108
|
let token = tokens[idx];
|
|
86
109
|
let template = token.info.template;
|
|
@@ -90,7 +113,16 @@ module.exports = function (md, templates = {}) {
|
|
|
90
113
|
return token.content;
|
|
91
114
|
}
|
|
92
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Regular expression to extract domains and path segments from URLs
|
|
118
|
+
* Used to add path-related attributes to links for styling and behavior
|
|
119
|
+
*/
|
|
93
120
|
let pathSegmentRegex = /(?:http[s]*:\/\/([^\/]*)|(?:\/([^\/?]*)))/g;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Custom link_open renderer that adds path attributes for styling and behavior
|
|
124
|
+
* Extracts domain and path segments from href attributes and adds them as path-X attributes
|
|
125
|
+
*/
|
|
94
126
|
md.renderer.rules.link_open = function (tokens, idx, options, env, renderer) {
|
|
95
127
|
let token = tokens[idx];
|
|
96
128
|
let attrs = token.attrs.reduce((str, attr) => {
|
|
@@ -105,6 +137,7 @@ module.exports = function (md, templates = {}) {
|
|
|
105
137
|
return str += name + '="' + value + '" ';
|
|
106
138
|
}, '');
|
|
107
139
|
let anchor = `<a ${attrs}>`;
|
|
140
|
+
// Special handling for auto-detected links (linkify)
|
|
108
141
|
return token.markup === 'linkify' ? anchor + '<span>' : anchor;
|
|
109
142
|
}
|
|
110
143
|
|
|
@@ -120,131 +153,180 @@ module.exports = function (md, templates = {}) {
|
|
|
120
153
|
// Variable to keep track of whether the class has been added to the first <dl> after the target HTML
|
|
121
154
|
let classAdded = false;
|
|
122
155
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Helper function to locate a specific marker in the token stream
|
|
158
|
+
* Used to identify the terminology section in the document
|
|
159
|
+
*
|
|
160
|
+
* @param {Array} tokens - The token array to search through
|
|
161
|
+
* @param {String} targetHtml - The HTML string to look for in token content
|
|
162
|
+
* @return {Number} The index of the token containing targetHtml, or -1 if not found
|
|
163
|
+
*/
|
|
164
|
+
function findTargetIndex(tokens, targetHtml) {
|
|
128
165
|
for (let i = 0; i < tokens.length; i++) {
|
|
129
166
|
if (tokens[i].content && tokens[i].content.includes(targetHtml)) {
|
|
130
|
-
|
|
131
|
-
break;
|
|
167
|
+
return i;
|
|
132
168
|
}
|
|
133
169
|
}
|
|
170
|
+
return -1;
|
|
171
|
+
}
|
|
134
172
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// First pass - check for and mark empty dt elements
|
|
145
|
-
// This scan identifies definition terms that have no content (empty dt elements)
|
|
146
|
-
// which is one of the root causes of the issues we're fixing
|
|
147
|
-
for (let i = idx + 1; i < tokens.length; i++) {
|
|
173
|
+
/**
|
|
174
|
+
* Helper function to identify and mark empty definition term elements
|
|
175
|
+
* Empty dt elements cause rendering and styling issues, so we mark them for special handling
|
|
176
|
+
*
|
|
177
|
+
* @param {Array} tokens - The token array to process
|
|
178
|
+
* @param {Number} startIdx - The index in the token array to start processing from
|
|
179
|
+
*/
|
|
180
|
+
function markEmptyDtElements(tokens, startIdx) {
|
|
181
|
+
for (let i = startIdx; i < tokens.length; i++) {
|
|
148
182
|
if (tokens[i].type === 'dl_close') {
|
|
149
|
-
break;
|
|
183
|
+
break; // Stop when we reach the end of this definition list
|
|
150
184
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
tokens[i + 1].isEmpty = true;
|
|
161
|
-
}
|
|
185
|
+
|
|
186
|
+
// An empty dt element is one where dt_open is immediately followed by dt_close
|
|
187
|
+
// with no content in between
|
|
188
|
+
if (tokens[i].type === 'dt_open' &&
|
|
189
|
+
i + 1 < tokens.length &&
|
|
190
|
+
tokens[i + 1].type === 'dt_close') {
|
|
191
|
+
// Mark both opening and closing tokens so they can be skipped during rendering
|
|
192
|
+
tokens[i].isEmpty = true;
|
|
193
|
+
tokens[i + 1].isEmpty = true;
|
|
162
194
|
}
|
|
163
195
|
}
|
|
196
|
+
}
|
|
164
197
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Helper function to add a 'last-dd' class to a dd token
|
|
200
|
+
* This enables special styling for the last definition description in a group
|
|
201
|
+
*
|
|
202
|
+
* @param {Array} tokens - The token array containing the dd token
|
|
203
|
+
* @param {Number} ddIndex - The index of the dd_open token to modify
|
|
204
|
+
*/
|
|
205
|
+
function addLastDdClass(tokens, ddIndex) {
|
|
206
|
+
if (ddIndex === -1) return;
|
|
207
|
+
|
|
208
|
+
const ddToken = tokens[ddIndex];
|
|
209
|
+
const classIndex = ddToken.attrIndex('class');
|
|
210
|
+
if (classIndex < 0) {
|
|
211
|
+
ddToken.attrPush(['class', 'last-dd']);
|
|
212
|
+
} else {
|
|
213
|
+
ddToken.attrs[classIndex][1] += ' last-dd';
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Helper function to process definition description elements
|
|
219
|
+
* Identifies and marks the last dd element in each dt/dd group for special styling
|
|
220
|
+
*
|
|
221
|
+
* @param {Array} tokens - The token array to process
|
|
222
|
+
* @param {Number} startIdx - The index in the token array to start processing from
|
|
223
|
+
*/
|
|
224
|
+
function processLastDdElements(tokens, startIdx) {
|
|
225
|
+
let lastDdIndex = -1; // Tracks the most recent dd_open token
|
|
226
|
+
|
|
227
|
+
for (let i = startIdx; i < tokens.length; i++) {
|
|
169
228
|
if (tokens[i].type === 'dl_close') {
|
|
170
|
-
// Add class to the last <dd> before closing <dl>
|
|
171
|
-
|
|
172
|
-
const ddToken = tokens[lastDdIndex];
|
|
173
|
-
const classIndex = ddToken.attrIndex('class');
|
|
174
|
-
if (classIndex < 0) {
|
|
175
|
-
ddToken.attrPush(['class', 'last-dd']);
|
|
176
|
-
} else {
|
|
177
|
-
ddToken.attrs[classIndex][1] += ' last-dd';
|
|
178
|
-
}
|
|
179
|
-
}
|
|
229
|
+
// Add class to the last <dd> before closing the entire <dl>
|
|
230
|
+
addLastDdClass(tokens, lastDdIndex);
|
|
180
231
|
break;
|
|
181
232
|
}
|
|
182
233
|
|
|
183
|
-
if (tokens[i].type === 'dt_open') {
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
continue; // Skip to the next iteration without processing this empty dt
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Add class to the last <dd> before a new <dt>
|
|
191
|
-
if (lastDdIndex !== -1) {
|
|
192
|
-
const ddToken = tokens[lastDdIndex];
|
|
193
|
-
const classIndex = ddToken.attrIndex('class');
|
|
194
|
-
if (classIndex < 0) {
|
|
195
|
-
ddToken.attrPush(['class', 'last-dd']);
|
|
196
|
-
} else {
|
|
197
|
-
ddToken.attrs[classIndex][1] += ' last-dd';
|
|
198
|
-
}
|
|
199
|
-
lastDdIndex = -1; // Reset for the next series
|
|
200
|
-
}
|
|
234
|
+
if (tokens[i].type === 'dt_open' && !tokens[i].isEmpty) {
|
|
235
|
+
// When we find a non-empty dt, mark the previous dd as the last one in its group
|
|
236
|
+
addLastDdClass(tokens, lastDdIndex);
|
|
237
|
+
lastDdIndex = -1; // Reset for the next group
|
|
201
238
|
}
|
|
202
239
|
|
|
203
240
|
if (tokens[i].type === 'dd_open') {
|
|
204
|
-
lastDdIndex = i;
|
|
241
|
+
lastDdIndex = i; // Track the most recently seen dd_open
|
|
205
242
|
}
|
|
206
243
|
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Custom renderer for definition list opening tags
|
|
248
|
+
* Handles special styling for terminology sections and processes definition terms and descriptions
|
|
249
|
+
* This function was refactored to reduce cognitive complexity by extracting helper functions
|
|
250
|
+
*
|
|
251
|
+
* @param {Array} tokens - The token array being processed
|
|
252
|
+
* @param {Number} idx - The index of the current token
|
|
253
|
+
* @param {Object} options - Rendering options
|
|
254
|
+
* @param {Object} env - Environment variables
|
|
255
|
+
* @param {Object} self - Reference to the renderer
|
|
256
|
+
* @return {String} The rendered HTML output
|
|
257
|
+
*/
|
|
258
|
+
md.renderer.rules.dl_open = function (tokens, idx, options, env, self) {
|
|
259
|
+
const targetHtml = 'terminology-section-start-h7vc6omi2hr2880';
|
|
260
|
+
let targetIndex = findTargetIndex(tokens, targetHtml);
|
|
261
|
+
|
|
262
|
+
// Add class to the first <dl> only if it comes after the target HTML
|
|
263
|
+
if (targetIndex !== -1 && idx > targetIndex && !classAdded) {
|
|
264
|
+
tokens[idx].attrPush(['class', 'terms-and-definitions-list']);
|
|
265
|
+
classAdded = true;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// First pass - mark empty dt elements
|
|
269
|
+
markEmptyDtElements(tokens, idx + 1);
|
|
270
|
+
|
|
271
|
+
// Second pass - process last dd elements
|
|
272
|
+
processLastDdElements(tokens, idx + 1);
|
|
207
273
|
|
|
208
274
|
return originalRender(tokens, idx, options, env, self);
|
|
209
275
|
};
|
|
210
|
-
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Helper function to determine if a definition term is transcluded from another source
|
|
279
|
+
* Transcluded terms require special styling and handling
|
|
280
|
+
*
|
|
281
|
+
* @param {Array} tokens - The token array to process
|
|
282
|
+
* @param {Number} dtOpenIndex - The index of the dt_open token to check
|
|
283
|
+
* @return {Boolean} True if the term is transcluded, false otherwise
|
|
284
|
+
*/
|
|
285
|
+
function isTermTranscluded(tokens, dtOpenIndex) {
|
|
286
|
+
for (let i = dtOpenIndex + 1; i < tokens.length; i++) {
|
|
287
|
+
if (tokens[i].type === 'dt_close') {
|
|
288
|
+
break; // Only examine tokens within this definition term
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Look for inline content that contains template tokens of type 'tref'
|
|
292
|
+
// These are transcluded term references
|
|
293
|
+
if (tokens[i].type === 'inline' && tokens[i].children) {
|
|
294
|
+
for (let child of tokens[i].children) {
|
|
295
|
+
if (child.type === 'template' &&
|
|
296
|
+
child.info &&
|
|
297
|
+
child.info.type === 'tref') {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
|
|
211
306
|
// Override the rendering of dt elements to properly handle transcluded terms
|
|
212
307
|
const originalDtRender = md.renderer.rules.dt_open || function (tokens, idx, options, env, self) {
|
|
213
308
|
return self.renderToken(tokens, idx, options);
|
|
214
309
|
};
|
|
215
|
-
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Custom renderer for definition term opening tags
|
|
313
|
+
* Handles special cases like empty terms and transcluded terms
|
|
314
|
+
*
|
|
315
|
+
* @param {Array} tokens - The token array being processed
|
|
316
|
+
* @param {Number} idx - The index of the current token
|
|
317
|
+
* @param {Object} options - Rendering options
|
|
318
|
+
* @param {Object} env - Environment variables
|
|
319
|
+
* @param {Object} self - Reference to the renderer
|
|
320
|
+
* @return {String} The rendered HTML output or empty string for skipped elements
|
|
321
|
+
*/
|
|
216
322
|
md.renderer.rules.dt_open = function (tokens, idx, options, env, self) {
|
|
217
|
-
// Skip rendering empty dt elements
|
|
218
|
-
// When a dt has been marked as empty, we return an empty string
|
|
219
|
-
// instead of rendering the <dt> tag. This effectively removes empty dt tags
|
|
220
|
-
// from the output HTML.
|
|
323
|
+
// Skip rendering empty dt elements that were marked during preprocessing
|
|
221
324
|
if (tokens[idx].isEmpty) {
|
|
222
325
|
return '';
|
|
223
326
|
}
|
|
224
|
-
|
|
225
|
-
// Check if this dt is part of a transcluded term
|
|
226
|
-
|
|
227
|
-
let isTranscluded = false;
|
|
228
|
-
for (let i = idx + 1; i < tokens.length; i++) {
|
|
229
|
-
if (tokens[i].type === 'dt_close') {
|
|
230
|
-
break;
|
|
231
|
-
}
|
|
232
|
-
// Look for child tokens that are template tokens with type 'tref'
|
|
233
|
-
// These represent transcluded terms from external sources
|
|
234
|
-
if (tokens[i].type === 'inline' &&
|
|
235
|
-
tokens[i].children &&
|
|
236
|
-
tokens[i].children.some(child =>
|
|
237
|
-
child.type === 'template' &&
|
|
238
|
-
child.info &&
|
|
239
|
-
child.info.type === 'tref')) {
|
|
240
|
-
isTranscluded = true;
|
|
241
|
-
break;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Add a class for transcluded terms to ensure proper styling
|
|
246
|
-
// This helps maintain consistent styling for transcluded terms
|
|
247
|
-
if (isTranscluded) {
|
|
327
|
+
|
|
328
|
+
// Check if this dt is part of a transcluded term and add appropriate class
|
|
329
|
+
if (isTermTranscluded(tokens, idx)) {
|
|
248
330
|
const classIndex = tokens[idx].attrIndex('class');
|
|
249
331
|
if (classIndex < 0) {
|
|
250
332
|
tokens[idx].attrPush(['class', 'transcluded-xref-term']);
|
|
@@ -252,15 +334,26 @@ module.exports = function (md, templates = {}) {
|
|
|
252
334
|
tokens[idx].attrs[classIndex][1] += ' transcluded-xref-term';
|
|
253
335
|
}
|
|
254
336
|
}
|
|
255
|
-
|
|
337
|
+
|
|
256
338
|
return originalDtRender(tokens, idx, options, env, self);
|
|
257
339
|
};
|
|
258
|
-
|
|
340
|
+
|
|
259
341
|
// Similarly override dt_close to skip empty dts
|
|
260
342
|
const originalDtCloseRender = md.renderer.rules.dt_close || function (tokens, idx, options, env, self) {
|
|
261
343
|
return self.renderToken(tokens, idx, options);
|
|
262
344
|
};
|
|
263
|
-
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Custom renderer for definition term closing tags
|
|
348
|
+
* Ensures empty terms are not rendered in the final output
|
|
349
|
+
*
|
|
350
|
+
* @param {Array} tokens - The token array being processed
|
|
351
|
+
* @param {Number} idx - The index of the current token
|
|
352
|
+
* @param {Object} options - Rendering options
|
|
353
|
+
* @param {Object} env - Environment variables
|
|
354
|
+
* @param {Object} self - Reference to the renderer
|
|
355
|
+
* @return {String} The rendered HTML output or empty string for skipped elements
|
|
356
|
+
*/
|
|
264
357
|
md.renderer.rules.dt_close = function (tokens, idx, options, env, self) {
|
|
265
358
|
// Skip rendering the closing </dt> tag for empty dt elements
|
|
266
359
|
// This completes the fix for empty dt elements by ensuring neither
|
package/src/references.js
CHANGED
|
@@ -4,12 +4,11 @@ const axios = require('axios').default;
|
|
|
4
4
|
const spaceRegex = /\s+/g;
|
|
5
5
|
|
|
6
6
|
function validateReferences(references, definitions, render) {
|
|
7
|
-
const resolvedRefs = [];
|
|
8
7
|
const unresolvedRefs = [];
|
|
9
8
|
[...new Set(references)].forEach(
|
|
10
9
|
ref => {
|
|
11
10
|
if(render.includes(`id="term:${ref.replace(spaceRegex, '-').toLowerCase()}"`)) {
|
|
12
|
-
|
|
11
|
+
// Reference is resolved
|
|
13
12
|
} else {
|
|
14
13
|
unresolvedRefs.push(ref);
|
|
15
14
|
}
|
|
@@ -10,13 +10,15 @@ async function doesUrlExist(url) {
|
|
|
10
10
|
const response = await axios.head(url, { timeout: 5000 });
|
|
11
11
|
return response.status === 200;
|
|
12
12
|
} catch (error) {
|
|
13
|
+
// Handle specific error cases for better logging/debugging
|
|
13
14
|
if (error.response && error.response.status === 404) {
|
|
14
|
-
|
|
15
|
+
console.debug('URL does not exist:', url);
|
|
16
|
+
} else if (error.code === 'ENOTFOUND' || error.code === 'ECONNABORTED') {
|
|
17
|
+
console.debug('Network issues with URL:', url);
|
|
18
|
+
} else {
|
|
19
|
+
console.debug('Failed to check URL:', url, error.message);
|
|
15
20
|
}
|
|
16
|
-
|
|
17
|
-
return false; // Network issues
|
|
18
|
-
}
|
|
19
|
-
return false; // Fail-safe return
|
|
21
|
+
return false;
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
|
package/src/utils/fetch.js
CHANGED
|
@@ -5,13 +5,13 @@ const fs = require('fs');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Fetches the
|
|
8
|
+
* Fetches the .cache/specs-generated.json file and returns it as a JavaScript object
|
|
9
9
|
* @returns {Object} The parsed contents of specs-generated.json
|
|
10
10
|
*/
|
|
11
11
|
function fetchSpecs() {
|
|
12
12
|
try {
|
|
13
|
-
// Resolve path to
|
|
14
|
-
const specsPath = path.resolve(process.cwd(), '
|
|
13
|
+
// Resolve path to .cache/specs-generated.json from the project root
|
|
14
|
+
const specsPath = path.resolve(process.cwd(), '.cache', 'specs-generated.json');
|
|
15
15
|
|
|
16
16
|
// Read the file synchronously
|
|
17
17
|
const specsContent = fs.readFileSync(specsPath, 'utf8');
|
|
@@ -21,19 +21,19 @@ function fetchSpecs() {
|
|
|
21
21
|
|
|
22
22
|
return specs;
|
|
23
23
|
} catch (error) {
|
|
24
|
-
console.error('Error fetching
|
|
24
|
+
console.error('Error fetching .cache/specs-generated.json:', error.message);
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* Fetches the
|
|
30
|
+
* Fetches the .cache/xtrefs-data.json file and returns it as a JavaScript object
|
|
31
31
|
* @returns {Object} The parsed contents of xtrefs-data.json
|
|
32
32
|
*/
|
|
33
33
|
function fetchExternalTerms() {
|
|
34
34
|
try {
|
|
35
|
-
// Resolve path to
|
|
36
|
-
const xtrefsPath = path.resolve(process.cwd(), '
|
|
35
|
+
// Resolve path to .cache/xtrefs-data.json from the project root
|
|
36
|
+
const xtrefsPath = path.resolve(process.cwd(), '.cache', 'xtrefs-data.json');
|
|
37
37
|
|
|
38
38
|
// Read the file synchronously
|
|
39
39
|
const xtrefsContent = fs.readFileSync(xtrefsPath, 'utf8');
|
|
@@ -43,7 +43,7 @@ function fetchExternalTerms() {
|
|
|
43
43
|
|
|
44
44
|
return xtrefs;
|
|
45
45
|
} catch (error) {
|
|
46
|
-
console.error('Error fetching
|
|
46
|
+
console.error('Error fetching .cache/xtrefs-data.json:', error.message);
|
|
47
47
|
return null;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -54,8 +54,8 @@ function fetchExternalTerms() {
|
|
|
54
54
|
*/
|
|
55
55
|
async function fetchSpecsAsync() {
|
|
56
56
|
try {
|
|
57
|
-
// Resolve path to
|
|
58
|
-
const specsPath = path.resolve(process.cwd(), '
|
|
57
|
+
// Resolve path to .cache/specs-generated.json from the project root
|
|
58
|
+
const specsPath = path.resolve(process.cwd(), '.cache', 'specs-generated.json');
|
|
59
59
|
|
|
60
60
|
// Read the file asynchronously
|
|
61
61
|
const specsContent = await fs.promises.readFile(specsPath, 'utf8');
|
|
@@ -65,7 +65,7 @@ async function fetchSpecsAsync() {
|
|
|
65
65
|
|
|
66
66
|
return specs;
|
|
67
67
|
} catch (error) {
|
|
68
|
-
console.error('Error fetching
|
|
68
|
+
console.error('Error fetching .cache/specs-generated.json:', error.message);
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -76,8 +76,8 @@ async function fetchSpecsAsync() {
|
|
|
76
76
|
*/
|
|
77
77
|
async function fetchExternalTermsAsync() {
|
|
78
78
|
try {
|
|
79
|
-
// Resolve path to
|
|
80
|
-
const xtrefsPath = path.resolve(process.cwd(), '
|
|
79
|
+
// Resolve path to .cache/xtrefs-data.json from the project root
|
|
80
|
+
const xtrefsPath = path.resolve(process.cwd(), '.cache', 'xtrefs-data.json');
|
|
81
81
|
|
|
82
82
|
// Read the file asynchronously
|
|
83
83
|
const xtrefsContent = await fs.promises.readFile(xtrefsPath, 'utf8');
|
|
@@ -87,7 +87,7 @@ async function fetchExternalTermsAsync() {
|
|
|
87
87
|
|
|
88
88
|
return xtrefs;
|
|
89
89
|
} catch (error) {
|
|
90
|
-
console.error('Error fetching
|
|
90
|
+
console.error('Error fetching .cache/xtrefs-data.json:', error.message);
|
|
91
91
|
return null;
|
|
92
92
|
}
|
|
93
93
|
}
|
package/templates/template.html
CHANGED
|
@@ -122,8 +122,7 @@
|
|
|
122
122
|
<a id="logo" href="${specLogoLink}">
|
|
123
123
|
<img class="d-print-none m-1" src="${specLogo}" alt="" />
|
|
124
124
|
</a>
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
|
|
127
126
|
<!-- Spacer to push the following elements to the right -->
|
|
128
127
|
<div class="flex-grow-1"></div>
|
|
129
128
|
|