spec-up-t 1.2.9 → 1.3.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 +2 -1
- package/assets/compiled/body.js +5 -5
- package/assets/compiled/head.css +1 -0
- package/assets/css/counter.css +104 -0
- package/assets/js/addAnchorsToTerms.js +13 -5
- package/assets/js/collapse-definitions.js +0 -3
- package/assets/js/custom-elements.js +25 -27
- package/assets/js/fix-last-dd.js +6 -3
- package/assets/js/highlight-heading-plus-sibling-nodes.js +0 -1
- package/assets/js/highlight-heading-plus-sibling-nodes.test.js +120 -0
- package/assets/js/insert-trefs.js +32 -28
- package/config/asset-map.json +1 -0
- package/index.js +33 -227
- package/package.json +4 -2
- package/sonar-project.properties +7 -0
- package/src/collect-external-references.js +22 -11
- package/src/collect-external-references.test.js +153 -2
- package/src/collectExternalReferences/fetchTermsFromIndex.js +65 -110
- package/src/collectExternalReferences/processXTrefsData.js +9 -11
- package/src/create-docx.js +332 -0
- package/src/create-pdf.js +243 -122
- package/src/fix-markdown-files.js +31 -34
- package/src/html-dom-processor.js +290 -0
- package/src/init.js +3 -0
- package/src/install-from-boilerplate/boilerplate/.github/workflows/menu.yml +51 -36
- package/src/install-from-boilerplate/boilerplate/spec/example-markup-in-markdown.md +0 -1
- package/src/install-from-boilerplate/boilerplate/spec/terms-and-definitions-intro.md +1 -5
- package/src/install-from-boilerplate/config-scripts-keys.js +4 -4
- package/src/install-from-boilerplate/menu.sh +6 -6
- package/src/markdown-it-extensions.js +54 -33
- package/src/references.js +18 -6
- package/templates/template.html +2 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { JSDOM } = require('jsdom');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sorts definition terms in HTML alphabetically (case-insensitive)
|
|
7
|
+
*
|
|
8
|
+
* @param {string} html - The HTML content to process
|
|
9
|
+
* @returns {string} - The HTML with sorted definition terms
|
|
10
|
+
*/
|
|
11
|
+
function sortDefinitionTermsInHtml(html) {
|
|
12
|
+
const dom = new JSDOM(html);
|
|
13
|
+
const document = dom.window.document;
|
|
14
|
+
|
|
15
|
+
// Find the terms and definitions list
|
|
16
|
+
const dlElement = document.querySelector('.terms-and-definitions-list');
|
|
17
|
+
if (!dlElement) return html; // If not found, return the original HTML
|
|
18
|
+
|
|
19
|
+
// Collect all dt/dd pairs
|
|
20
|
+
const pairs = [];
|
|
21
|
+
let currentDt = null;
|
|
22
|
+
let currentDds = [];
|
|
23
|
+
|
|
24
|
+
// Process each child of the dl element
|
|
25
|
+
Array.from(dlElement.children).forEach(child => {
|
|
26
|
+
if (child.tagName === 'DT') {
|
|
27
|
+
// If we already have a dt, save the current pair
|
|
28
|
+
if (currentDt) {
|
|
29
|
+
pairs.push({
|
|
30
|
+
dt: currentDt,
|
|
31
|
+
dds: [...currentDds],
|
|
32
|
+
text: currentDt.textContent.trim().toLowerCase() // Use lowercase for sorting
|
|
33
|
+
});
|
|
34
|
+
currentDds = []; // Reset dds for the next dt
|
|
35
|
+
}
|
|
36
|
+
currentDt = child;
|
|
37
|
+
} else if (child.tagName === 'DD' && currentDt) {
|
|
38
|
+
currentDds.push(child);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Add the last pair if exists
|
|
43
|
+
if (currentDt) {
|
|
44
|
+
pairs.push({
|
|
45
|
+
dt: currentDt,
|
|
46
|
+
dds: [...currentDds],
|
|
47
|
+
text: currentDt.textContent.trim().toLowerCase()
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Sort pairs case-insensitively
|
|
52
|
+
pairs.sort((a, b) => a.text.localeCompare(b.text));
|
|
53
|
+
|
|
54
|
+
// Clear the dl element
|
|
55
|
+
while (dlElement.firstChild) {
|
|
56
|
+
dlElement.removeChild(dlElement.firstChild);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Re-append elements in sorted order
|
|
60
|
+
pairs.forEach(pair => {
|
|
61
|
+
dlElement.appendChild(pair.dt);
|
|
62
|
+
pair.dds.forEach(dd => {
|
|
63
|
+
dlElement.appendChild(dd);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Return the modified HTML
|
|
68
|
+
return dom.serialize();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Fixes broken definition list (dl) structures in the HTML output.
|
|
73
|
+
* Specifically, it addresses the issue where transcluded terms (tref tags) break
|
|
74
|
+
* out of the definition list, creating separate lists instead of a continuous one.
|
|
75
|
+
*
|
|
76
|
+
* The strategy:
|
|
77
|
+
* 1. Find all definition lists (dl elements) in the document
|
|
78
|
+
* 2. Use the dl with class 'terms-and-definitions-list' as the main/target list
|
|
79
|
+
* 3. Process each subsequent node after the this main dl:
|
|
80
|
+
* - If another dl is found, merge all its children into the main dl
|
|
81
|
+
* - If a standalone dt is found, move it and its associated dd elements into the main dl
|
|
82
|
+
* - Remove any empty paragraphs that might be breaking the list continuity
|
|
83
|
+
*
|
|
84
|
+
* This ensures all terms appear in one continuous definition list,
|
|
85
|
+
* regardless of how they were originally rendered in the markdown.
|
|
86
|
+
*
|
|
87
|
+
* @param {string} html - The HTML content to fix
|
|
88
|
+
* @returns {string} - The fixed HTML content with merged definition lists
|
|
89
|
+
*/
|
|
90
|
+
function fixDefinitionListStructure(html) {
|
|
91
|
+
const dom = new JSDOM(html);
|
|
92
|
+
const document = dom.window.document;
|
|
93
|
+
|
|
94
|
+
// Find all dl elements first
|
|
95
|
+
const allDls = Array.from(document.querySelectorAll('dl'));
|
|
96
|
+
|
|
97
|
+
// Then filter to find the one with the terms-and-definitions-list class
|
|
98
|
+
const dlElements = allDls.filter(dl => {
|
|
99
|
+
return dl?.classList?.contains('terms-and-definitions-list');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Find any transcluded term dt elements anywhere in the document
|
|
103
|
+
const transcludedTerms = document.querySelectorAll('dt.transcluded-xref-term');
|
|
104
|
+
|
|
105
|
+
let mainDl = null;
|
|
106
|
+
|
|
107
|
+
// If we have an existing dl with the terms-and-definitions-list class, use it
|
|
108
|
+
if (dlElements.length > 0) {
|
|
109
|
+
mainDl = dlElements[0]; // Use the first one
|
|
110
|
+
}
|
|
111
|
+
// If we have transcluded terms but no main dl, we need to create one
|
|
112
|
+
else if (transcludedTerms.length > 0) {
|
|
113
|
+
// Create a new dl element with the right class
|
|
114
|
+
mainDl = document.createElement('dl');
|
|
115
|
+
mainDl.className = 'terms-and-definitions-list';
|
|
116
|
+
|
|
117
|
+
// Look for the marker
|
|
118
|
+
const marker = document.getElementById('terminology-section-start');
|
|
119
|
+
|
|
120
|
+
if (marker) {
|
|
121
|
+
// Insert the new dl right after the marker
|
|
122
|
+
if (marker.nextSibling) {
|
|
123
|
+
marker.parentNode.insertBefore(mainDl, marker.nextSibling);
|
|
124
|
+
} else {
|
|
125
|
+
marker.parentNode.appendChild(mainDl);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
// Fallback to the original approach if marker isn't found
|
|
129
|
+
const firstTerm = transcludedTerms[0];
|
|
130
|
+
const insertPoint = firstTerm.parentNode;
|
|
131
|
+
insertPoint.parentNode.insertBefore(mainDl, insertPoint);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Safety check - if we still don't have a mainDl, exit early to avoid null reference errors
|
|
136
|
+
if (!mainDl) {
|
|
137
|
+
return html; // Return the original HTML without modifications
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Helper function to collect dt/dd pairs from a node
|
|
142
|
+
* @param {Node} startNode - The node to start collecting from
|
|
143
|
+
* @returns {Array} - Array of elements that are part of the definition group
|
|
144
|
+
*/
|
|
145
|
+
function collectDtDdGroup(startNode) {
|
|
146
|
+
const group = [];
|
|
147
|
+
let currentNode = startNode;
|
|
148
|
+
|
|
149
|
+
// Collect the dt and all following dd elements
|
|
150
|
+
while (currentNode && (currentNode.tagName === 'DT' || currentNode.tagName === 'DD')) {
|
|
151
|
+
group.push(currentNode);
|
|
152
|
+
currentNode = currentNode.nextSibling;
|
|
153
|
+
|
|
154
|
+
// Skip text nodes (whitespace) between elements
|
|
155
|
+
while (currentNode && currentNode.nodeType === 3 && !currentNode.textContent.trim()) {
|
|
156
|
+
currentNode = currentNode.nextSibling;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return group;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Process all transcluded terms and move them with their dd elements
|
|
164
|
+
transcludedTerms.forEach(dt => {
|
|
165
|
+
// Check if this dt is not already inside our main dl
|
|
166
|
+
if (dt.parentElement !== mainDl) {
|
|
167
|
+
// Collect the dt and its associated dd elements
|
|
168
|
+
const group = collectDtDdGroup(dt);
|
|
169
|
+
|
|
170
|
+
// Move all elements in the group to the main dl
|
|
171
|
+
group.forEach(element => {
|
|
172
|
+
if (element.parentNode) {
|
|
173
|
+
const elementClone = element.cloneNode(true);
|
|
174
|
+
mainDl.appendChild(elementClone);
|
|
175
|
+
element.parentNode.removeChild(element);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Remove any empty dt elements that may exist
|
|
182
|
+
const emptyDts = mainDl.querySelectorAll('dt:empty');
|
|
183
|
+
emptyDts.forEach(emptyDt => {
|
|
184
|
+
emptyDt.parentNode.removeChild(emptyDt);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Process all subsequent content after the main dl
|
|
188
|
+
let currentNode = mainDl.nextSibling;
|
|
189
|
+
|
|
190
|
+
// Process all subsequent content
|
|
191
|
+
while (currentNode) {
|
|
192
|
+
// Save the next node before potentially modifying the DOM
|
|
193
|
+
let nextNode = currentNode.nextSibling;
|
|
194
|
+
|
|
195
|
+
// Handle different node types
|
|
196
|
+
if (currentNode.nodeType === 1) { // 1 = Element node
|
|
197
|
+
if (currentNode.tagName === 'DL') {
|
|
198
|
+
// Check if this is a reference list (contains dt elements with id="ref:...")
|
|
199
|
+
const hasRefIds = currentNode.innerHTML.includes('id="ref:') ||
|
|
200
|
+
currentNode.classList.contains('reference-list');
|
|
201
|
+
|
|
202
|
+
if (!hasRefIds) {
|
|
203
|
+
// Only move non-reference definition lists - move all its children to the main dl
|
|
204
|
+
while (currentNode.firstChild) {
|
|
205
|
+
mainDl.appendChild(currentNode.firstChild);
|
|
206
|
+
}
|
|
207
|
+
// Remove the now-empty dl element
|
|
208
|
+
currentNode.parentNode.removeChild(currentNode);
|
|
209
|
+
}
|
|
210
|
+
// If it's a reference list, leave it alone
|
|
211
|
+
}
|
|
212
|
+
else if (currentNode.tagName === 'DT') {
|
|
213
|
+
// Check if this dt has a ref: id (spec reference)
|
|
214
|
+
const hasRefId = currentNode.id?.startsWith('ref:');
|
|
215
|
+
|
|
216
|
+
if (!hasRefId) {
|
|
217
|
+
// Collect the dt and its associated dd elements
|
|
218
|
+
const group = collectDtDdGroup(currentNode);
|
|
219
|
+
|
|
220
|
+
// Move all elements in the group to the main dl
|
|
221
|
+
group.forEach(element => {
|
|
222
|
+
if (element.parentNode) {
|
|
223
|
+
const elementClone = element.cloneNode(true);
|
|
224
|
+
mainDl.appendChild(elementClone);
|
|
225
|
+
element.parentNode.removeChild(element);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Skip the nodes we just processed
|
|
230
|
+
let skipNodes = group.length - 1; // -1 because currentNode will be advanced anyway
|
|
231
|
+
while (skipNodes > 0 && nextNode) {
|
|
232
|
+
const nodeToSkip = nextNode;
|
|
233
|
+
currentNode = nextNode;
|
|
234
|
+
nextNode = nextNode.nextSibling;
|
|
235
|
+
skipNodes--;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// If it's a spec reference dt, leave it alone
|
|
239
|
+
}
|
|
240
|
+
else if (currentNode.tagName === 'DD') {
|
|
241
|
+
// Handle orphaned dd elements - move them to the main dl if they don't belong to a reference
|
|
242
|
+
const dtBefore = currentNode.previousSibling;
|
|
243
|
+
let hasAssociatedDt = false;
|
|
244
|
+
|
|
245
|
+
// Check if there's a dt before this dd (walking backwards through siblings)
|
|
246
|
+
let checkNode = currentNode.previousSibling;
|
|
247
|
+
while (checkNode) {
|
|
248
|
+
// Skip text nodes
|
|
249
|
+
if (checkNode.nodeType === 3 && !checkNode.textContent.trim()) {
|
|
250
|
+
checkNode = checkNode.previousSibling;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (checkNode.tagName === 'DT') {
|
|
255
|
+
hasAssociatedDt = true;
|
|
256
|
+
break;
|
|
257
|
+
} else if (checkNode.tagName !== 'DD') {
|
|
258
|
+
// Found a non-dt, non-dd element, so this dd is orphaned
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
checkNode = checkNode.previousSibling;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// If this dd doesn't have an associated dt in the same context, move it to main dl
|
|
266
|
+
if (!hasAssociatedDt) {
|
|
267
|
+
const ddClone = currentNode.cloneNode(true);
|
|
268
|
+
mainDl.appendChild(ddClone);
|
|
269
|
+
currentNode.parentNode.removeChild(currentNode);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (currentNode.tagName === 'P' &&
|
|
273
|
+
(!currentNode.textContent || currentNode.textContent.trim() === '')) {
|
|
274
|
+
// Remove empty paragraphs - these break the list structure
|
|
275
|
+
currentNode.parentNode.removeChild(currentNode);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Move to the next node we saved earlier
|
|
280
|
+
currentNode = nextNode;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Return the fixed HTML
|
|
284
|
+
return dom.serialize();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
module.exports = {
|
|
288
|
+
sortDefinitionTermsInHtml,
|
|
289
|
+
fixDefinitionListStructure
|
|
290
|
+
};
|
package/src/init.js
CHANGED
|
@@ -5,6 +5,9 @@ const initFlagPath = path.join(outputDir, 'init.flag');
|
|
|
5
5
|
|
|
6
6
|
async function initialize() {
|
|
7
7
|
try {
|
|
8
|
+
// Ensure the .cache directory exists
|
|
9
|
+
await fs.ensureDir(outputDir);
|
|
10
|
+
|
|
8
11
|
// Check if the init script has already run
|
|
9
12
|
if (await fs.pathExists(initFlagPath)) {
|
|
10
13
|
return;
|
|
@@ -9,17 +9,16 @@ on:
|
|
|
9
9
|
required: true
|
|
10
10
|
default: 'Render specification'
|
|
11
11
|
options:
|
|
12
|
-
|
|
12
|
+
- Add content
|
|
13
13
|
- Render specification
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
- Collect external references
|
|
17
|
-
-
|
|
14
|
+
- Export to PDF
|
|
15
|
+
- Export to DOCX
|
|
16
|
+
- Collect external references
|
|
17
|
+
- Add, remove or view xref source
|
|
18
|
+
- Configure
|
|
19
|
+
- Run health check
|
|
20
|
+
- Open documentation website
|
|
18
21
|
- Freeze specification
|
|
19
|
-
# - List references
|
|
20
|
-
# - Show help
|
|
21
|
-
# - Add/remove xref source
|
|
22
|
-
# - Configure specification
|
|
23
22
|
- Custom update
|
|
24
23
|
|
|
25
24
|
jobs:
|
|
@@ -60,9 +59,11 @@ jobs:
|
|
|
60
59
|
MY_PAT: ${{ secrets.MY_PAT }} # Make the secret available as an env var
|
|
61
60
|
run: |
|
|
62
61
|
case "${{ github.event.inputs.script }}" in
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
"Add content")
|
|
63
|
+
echo "You can start adding your content to the markdown files in the 'spec' directory."
|
|
64
|
+
echo "You can do this by editing local files in an editor or by going to your repository on GitHub."
|
|
65
|
+
echo "More info: https://blockchainbird.github.io/spec-up-t-website/docs/various-roles/content-authors-guide/introduction"
|
|
66
|
+
;;
|
|
66
67
|
"Render specification")
|
|
67
68
|
node --no-warnings -e "require('spec-up-t/index.js')({ nowatch: true })"
|
|
68
69
|
git config --global user.email "actions@github.com"
|
|
@@ -71,31 +72,29 @@ jobs:
|
|
|
71
72
|
git commit -m "Render specification: Update files" || echo "No changes to commit"
|
|
72
73
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
73
74
|
;;
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"Collect external references (cached)")
|
|
78
|
-
node --no-warnings -e "require('spec-up-t/src/collect-external-references.js').collectExternalReferences({cache: true})"
|
|
75
|
+
# ...existing code...
|
|
76
|
+
"Export to DOCX")
|
|
77
|
+
node -e "require('spec-up-t/src/create-docx.js')"
|
|
79
78
|
git config --global user.email "actions@github.com"
|
|
80
79
|
git config --global user.name "GitHub Actions"
|
|
81
80
|
git add .
|
|
82
|
-
git commit -m "
|
|
81
|
+
git commit -m "Export to DOCX" || echo "No changes to commit"
|
|
83
82
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
84
83
|
;;
|
|
85
|
-
"Collect external references
|
|
86
|
-
node --no-warnings -e "require('spec-up-t/src/collect-external-references.js').collectExternalReferences({
|
|
84
|
+
"Collect external references")
|
|
85
|
+
node --no-warnings -e "require('spec-up-t/src/collect-external-references.js').collectExternalReferences({ pat: process.env.MY_PAT })"
|
|
87
86
|
git config --global user.email "actions@github.com"
|
|
88
87
|
git config --global user.name "GitHub Actions"
|
|
89
88
|
git add .
|
|
90
|
-
git commit -m "Collect external references
|
|
89
|
+
git commit -m "Collect external references" || echo "No changes to commit"
|
|
91
90
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
92
91
|
;;
|
|
93
|
-
"
|
|
92
|
+
"Export to PDF")
|
|
94
93
|
node -e "require('spec-up-t/src/create-pdf.js')"
|
|
95
94
|
git config --global user.email "actions@github.com"
|
|
96
95
|
git config --global user.name "GitHub Actions"
|
|
97
96
|
git add .
|
|
98
|
-
git commit -m "
|
|
97
|
+
git commit -m "Export to PDF" || echo "No changes to commit"
|
|
99
98
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
100
99
|
;;
|
|
101
100
|
"Freeze specification")
|
|
@@ -106,18 +105,34 @@ jobs:
|
|
|
106
105
|
git commit -m "Freeze specification" || echo "No changes to commit"
|
|
107
106
|
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
108
107
|
;;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
108
|
+
"Add, remove or view xref source")
|
|
109
|
+
node --no-warnings -e "require('spec-up-t/src/add-remove-xref-source.js')"
|
|
110
|
+
git config --global user.email "actions@github.com"
|
|
111
|
+
git config --global user.name "GitHub Actions"
|
|
112
|
+
git add .
|
|
113
|
+
git commit -m "Add, remove or view xref source" || echo "No changes to commit"
|
|
114
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
115
|
+
;;
|
|
116
|
+
"Configure")
|
|
117
|
+
node --no-warnings -e "require('spec-up-t/src/configure.js')"
|
|
118
|
+
git config --global user.email "actions@github.com"
|
|
119
|
+
git config --global user.name "GitHub Actions"
|
|
120
|
+
git add .
|
|
121
|
+
git commit -m "Configure" || echo "No changes to commit"
|
|
122
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
123
|
+
;;
|
|
124
|
+
"Run health check")
|
|
125
|
+
node --no-warnings -e "require('spec-up-t/src/health-check.js')"
|
|
126
|
+
git config --global user.email "actions@github.com"
|
|
127
|
+
git config --global user.name "GitHub Actions"
|
|
128
|
+
git add .
|
|
129
|
+
git commit -m "Run health check" || echo "No changes to commit"
|
|
130
|
+
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:main
|
|
131
|
+
;;
|
|
132
|
+
"Open documentation website")
|
|
133
|
+
echo "Opening documentation website: https://blockchainbird.github.io/spec-up-t-website/"
|
|
134
|
+
echo "Please visit the URL manually: https://blockchainbird.github.io/spec-up-t-website/"
|
|
135
|
+
;;
|
|
121
136
|
"Custom update")
|
|
122
137
|
npm update && node -e "require('spec-up-t/src/install-from-boilerplate/custom-update.js')"
|
|
123
138
|
git config --global user.email "actions@github.com"
|
|
@@ -133,7 +148,7 @@ jobs:
|
|
|
133
148
|
esac
|
|
134
149
|
|
|
135
150
|
- name: Deploy to GitHub Pages
|
|
136
|
-
if: success() && github.event.inputs.script != '
|
|
151
|
+
if: success() && github.event.inputs.script != 'Add content' && github.event.inputs.script != 'Open documentation website' && github.event.inputs.script != 'Configure' && github.event.inputs.script != 'Run health check'
|
|
137
152
|
uses: peaceiris/actions-gh-pages@v3.7.3
|
|
138
153
|
with:
|
|
139
154
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -2,9 +2,9 @@ const configScriptsKeys = {
|
|
|
2
2
|
"edit": "node -e \"require('spec-up-t')()\"",
|
|
3
3
|
"render": "node --no-warnings -e \"require('spec-up-t/index.js')({ nowatch: true })\"",
|
|
4
4
|
"dev": "node -e \"require('spec-up-t')({ dev: true })\"",
|
|
5
|
-
"
|
|
6
|
-
"collectExternalReferencesNoCache": "node --no-warnings -e \"require('spec-up-t/src/collect-external-references.js').collectExternalReferences({cache: false})\"",
|
|
5
|
+
"collectExternalReferences": "node --no-warnings -e \"require('spec-up-t/src/collect-external-references.js').collectExternalReferences()\"",
|
|
7
6
|
"topdf": "node -e \"require('spec-up-t/src/create-pdf.js')\"",
|
|
7
|
+
"todocx": "node -e \"require('spec-up-t/src/create-docx.js')\"",
|
|
8
8
|
"freeze": "node -e \"require('spec-up-t/src/freeze.js')\"",
|
|
9
9
|
"references": "node -e \"require('spec-up-t/src/references.js')\"",
|
|
10
10
|
"help": "cat ./node_modules/spec-up-t/src/install-from-boilerplate/help.txt",
|
|
@@ -20,9 +20,9 @@ const configOverwriteScriptsKeys = {
|
|
|
20
20
|
"edit": true,
|
|
21
21
|
"render": true,
|
|
22
22
|
"dev": true,
|
|
23
|
-
"
|
|
24
|
-
"collectExternalReferencesNoCache": true,
|
|
23
|
+
"collectExternalReferences": true,
|
|
25
24
|
"topdf": true,
|
|
25
|
+
"todocx": true,
|
|
26
26
|
"freeze": true,
|
|
27
27
|
"references": true,
|
|
28
28
|
"help": true,
|
|
@@ -6,8 +6,8 @@ function handle_choice() {
|
|
|
6
6
|
"Add content" "do_add_content"
|
|
7
7
|
"Render specification" "do_render"
|
|
8
8
|
"Export to PDF" "do_topdf"
|
|
9
|
-
"
|
|
10
|
-
"Collect external references
|
|
9
|
+
"Export to DOCX" "do_todocx"
|
|
10
|
+
"Collect external references" "collect_external_references"
|
|
11
11
|
"Add, remove or view xref source" "do_add_remove_xref_source"
|
|
12
12
|
"Configure" "do_configure"
|
|
13
13
|
"Run health check" "do_health_check"
|
|
@@ -47,8 +47,8 @@ function display_intro() {
|
|
|
47
47
|
[0] Add content
|
|
48
48
|
[1] Render specification
|
|
49
49
|
[2] Export to PDF
|
|
50
|
-
[3]
|
|
51
|
-
[4] Collect external references
|
|
50
|
+
[3] Export to DOCX
|
|
51
|
+
[4] Collect external references
|
|
52
52
|
[5] Add, remove or view xref source
|
|
53
53
|
[6] Configure
|
|
54
54
|
[7] Run health check
|
|
@@ -74,8 +74,8 @@ function do_add_content() {
|
|
|
74
74
|
|
|
75
75
|
function do_render() { clear; npm run render; }
|
|
76
76
|
function do_topdf() { clear; npm run topdf; }
|
|
77
|
-
function
|
|
78
|
-
function
|
|
77
|
+
function do_todocx() { clear; npm run todocx; }
|
|
78
|
+
function collect_external_references() { clear; npm run collectExternalReferences; }
|
|
79
79
|
function do_add_remove_xref_source() { clear; npm run addremovexrefsource; }
|
|
80
80
|
function do_configure() { clear; npm run configure; }
|
|
81
81
|
function do_health_check() { clear; npm run healthCheck; }
|
|
@@ -66,12 +66,12 @@ module.exports = function (md, templates = {}) {
|
|
|
66
66
|
md.inline.ruler.after('emphasis', 'templates', function templates_ruler(state, silent) {
|
|
67
67
|
// Get the current parsing position
|
|
68
68
|
var start = state.pos;
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
// Check if we're at an escaped placeholder - if so, skip processing
|
|
71
71
|
if (state.src.slice(start, start + ESCAPED_PLACEHOLDER.length) === ESCAPED_PLACEHOLDER) {
|
|
72
72
|
return false;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
// Check if we're at a template opening marker
|
|
76
76
|
let prefix = state.src.slice(start, start + levels);
|
|
77
77
|
if (prefix !== openString) return false;
|
|
@@ -203,24 +203,6 @@ module.exports = function (md, templates = {}) {
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
/**
|
|
207
|
-
* Helper function to add a 'last-dd' class to a dd token
|
|
208
|
-
* This enables special styling for the last definition description in a group
|
|
209
|
-
*
|
|
210
|
-
* @param {Array} tokens - The token array containing the dd token
|
|
211
|
-
* @param {Number} ddIndex - The index of the dd_open token to modify
|
|
212
|
-
*/
|
|
213
|
-
function addLastDdClass(tokens, ddIndex) {
|
|
214
|
-
if (ddIndex === -1) return;
|
|
215
|
-
|
|
216
|
-
const ddToken = tokens[ddIndex];
|
|
217
|
-
const classIndex = ddToken.attrIndex('class');
|
|
218
|
-
if (classIndex < 0) {
|
|
219
|
-
ddToken.attrPush(['class', 'last-dd']);
|
|
220
|
-
} else {
|
|
221
|
-
ddToken.attrs[classIndex][1] += ' last-dd';
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
206
|
|
|
225
207
|
/**
|
|
226
208
|
* Helper function to process definition description elements
|
|
@@ -232,23 +214,47 @@ module.exports = function (md, templates = {}) {
|
|
|
232
214
|
function processLastDdElements(tokens, startIdx) {
|
|
233
215
|
let lastDdIndex = -1; // Tracks the most recent dd_open token
|
|
234
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) {
|
|
235
228
|
for (let i = startIdx; i < tokens.length; i++) {
|
|
236
229
|
if (tokens[i].type === 'dl_close') {
|
|
237
|
-
//
|
|
238
|
-
addLastDdClass(tokens, lastDdIndex);
|
|
239
|
-
break;
|
|
230
|
+
break; // Stop when we reach the end of this definition list
|
|
240
231
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
// When we find a non-empty dt, mark the previous dd as the last one in its group
|
|
244
|
-
addLastDdClass(tokens, lastDdIndex);
|
|
245
|
-
lastDdIndex = -1; // Reset for the next group
|
|
232
|
+
if (isDtRef(tokens[i])) {
|
|
233
|
+
return true;
|
|
246
234
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
235
|
+
if (isHtmlRef(tokens[i])) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
if (isInlineRef(tokens[i])) {
|
|
239
|
+
return true;
|
|
250
240
|
}
|
|
251
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:');
|
|
252
258
|
}
|
|
253
259
|
|
|
254
260
|
/**
|
|
@@ -256,6 +262,10 @@ module.exports = function (md, templates = {}) {
|
|
|
256
262
|
* Handles special styling for terminology sections and processes definition terms and descriptions
|
|
257
263
|
* This function was refactored to reduce cognitive complexity by extracting helper functions
|
|
258
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
|
+
*
|
|
259
269
|
* @param {Array} tokens - The token array being processed
|
|
260
270
|
* @param {Number} idx - The index of the current token
|
|
261
271
|
* @param {Object} options - Rendering options
|
|
@@ -267,8 +277,19 @@ module.exports = function (md, templates = {}) {
|
|
|
267
277
|
const targetHtml = 'terminology-section-start';
|
|
268
278
|
let targetIndex = findTargetIndex(tokens, targetHtml);
|
|
269
279
|
|
|
270
|
-
//
|
|
271
|
-
|
|
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) {
|
|
272
293
|
tokens[idx].attrPush(['class', 'terms-and-definitions-list']);
|
|
273
294
|
classAdded = true;
|
|
274
295
|
}
|