spec-up-t 1.1.53 → 1.1.54

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.
@@ -30,7 +30,14 @@ function createAlphabetIndex() {
30
30
  numberOfTerms.textContent = `– There are ${dtElements.length} terms –`;
31
31
 
32
32
  terminologySectionUtilityContainer.appendChild(numberOfTerms);
33
- Object.keys(alphabetIndex).sort().forEach(char => {
33
+
34
+ /*
35
+ The key advantage of localeCompare over simple comparison operators (<, >) is that it:
36
+ - Properly handles language-specific sorting rules (via locale settings)
37
+ - Correctly compares strings containing special characters or accents
38
+ - Can be configured to be case-insensitive
39
+ */
40
+ Object.keys(alphabetIndex).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).forEach(char => {
34
41
  const link = document.createElement("a");
35
42
  link.href = `#${alphabetIndex[char]}`;
36
43
  link.textContent = char;
package/branches.md CHANGED
@@ -16,6 +16,15 @@
16
16
  Hierbij wordt de hele repository gedownload. Dit is een experiment om te kijken of ik de hele repository kan downloaden en dan de bestanden kan gebruiken die ik nodig heb. In plaats van de search API te gebruiken met zijn strakke limieten.
17
17
 
18
18
 
19
+ ## fix/ordering
20
+
21
+ De volgorde van de termen. Hoofdletter kleine letter probleem
22
+
23
+ ## fix/xtref
24
+
25
+ Tref creeren via index.html
26
+
27
+
19
28
  ## test/fixtref
20
29
 
21
30
  Bewaren, maar kan weg als ik uiteindelijk een andere oplossing heb gevonden.
package/index.js CHANGED
@@ -102,7 +102,15 @@ module.exports = async function (options = {}) {
102
102
  function renderRefGroup(type) {
103
103
  let group = specGroups[type];
104
104
  if (!group) return '';
105
- let html = Object.keys(group).sort().reduce((html, name) => {
105
+
106
+ /*
107
+ The key advantage of localeCompare over simple comparison operators (<, >) is that it:
108
+
109
+ - Properly handles language-specific sorting rules (via locale settings)
110
+ - Correctly compares strings containing special characters or accents
111
+ - Can be configured to be case-insensitive
112
+ */
113
+ let html = Object.keys(group).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).reduce((html, name) => {
106
114
  let ref = group[name];
107
115
  return html += `
108
116
  <dt id="ref:${name}">${name}</dt>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-up-t",
3
- "version": "1.1.53",
3
+ "version": "1.1.54",
4
4
  "description": "Technical specification drafting tool that generates rich specification documents from markdown. Forked from https://github.com/decentralized-identity/spec-up by Daniel Buchner (https://github.com/csuwildcat)",
5
5
  "main": "./index",
6
6
  "repository": {
@@ -94,6 +94,111 @@ module.exports = function (md, templates = {}) {
94
94
  if (targetIndex !== -1 && idx > targetIndex && !classAdded) {
95
95
  tokens[idx].attrPush(['class', 'terms-and-definitions-list']);
96
96
  classAdded = true;
97
+
98
+ /* Sort terms and definitions alphabetically
99
+ Sort dt/dd pairs case-insensitively based on dt content
100
+
101
+ 1: Token-based Markdown Processing: Spec-Up-T uses a token-based approach to parse and render Markdown. When Markdown is processed, it's converted into a series of tokens that represent different elements (like dt_open, dt_content, dt_close, dd_open, dd_content, dd_close). We're not dealing with simple strings but with structured tokens.
102
+
103
+ 2: Preserving Relationships: When sorting terms, we need to ensure that each definition term (<dt>) stays connected to its corresponding definition description (<dd>). It's not as simple as sorting an array of strings - we're sorting complex structures.
104
+
105
+ 3: Implementation Details: The implementation includes:
106
+
107
+ - Finding the terminology section in the document
108
+ - Collecting term starts, ends, and their contents
109
+ - Creating a sorted index based on case-insensitive comparisons
110
+ - Rebuilding the token array in the correct order
111
+ - Ensuring all relationships between terms and definitions are preserved
112
+ - Handling special cases and edge conditions
113
+
114
+ The complexity is unavoidable because:
115
+
116
+ - We're working with the markdown-it rendering pipeline, not just manipulating DOM
117
+ - The terms and definitions exist as tokens before they become HTML
118
+ - We need to preserve all the token relationships while reordering
119
+ - We're intercepting the rendering process to modify the token structure
120
+
121
+ If we were just sorting DOM elements after the page rendered, it would be simpler. But by doing the sorting during the Markdown processing, we ensure the HTML output is correct from the beginning, which is more efficient and leads to better performance.
122
+ */
123
+ let dtStartIndices = [];
124
+ let dtEndIndices = [];
125
+ let dtContents = [];
126
+
127
+ // First pass: collect all dt blocks and their contents
128
+ for (let i = idx + 1; i < tokens.length; i++) {
129
+ if (tokens[i].type === 'dl_close') {
130
+ break;
131
+ }
132
+ if (tokens[i].type === 'dt_open') {
133
+ const startIdx = i;
134
+ let content = '';
135
+
136
+ // Find the end of this dt block and capture its content
137
+ for (let j = i + 1; j < tokens.length; j++) {
138
+ if (tokens[j].type === 'dt_close') {
139
+ dtStartIndices.push(startIdx);
140
+ dtEndIndices.push(j);
141
+ dtContents.push(content.toLowerCase()); // Store lowercase for case-insensitive sorting
142
+ break;
143
+ }
144
+ // Collect the content inside the dt (including spans with term IDs)
145
+ if (tokens[j].content) {
146
+ content += tokens[j].content;
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ // Create indices sorted by case-insensitive term content
153
+ const sortedIndices = dtContents.map((_, idx) => idx)
154
+ .sort((a, b) => dtContents[a].localeCompare(dtContents[b]));
155
+
156
+ // Reorder the tokens based on the sorted indices
157
+ if (sortedIndices.length > 0) {
158
+ // Create a new array of tokens
159
+ const newTokens = tokens.slice(0, idx + 1); // Include dl_open
160
+
161
+ // For each dt/dd pair in sorted order
162
+ for (let i = 0; i < sortedIndices.length; i++) {
163
+ const originalIndex = sortedIndices[i];
164
+ const dtStart = dtStartIndices[originalIndex];
165
+ const dtEnd = dtEndIndices[originalIndex];
166
+
167
+ // Add dt tokens
168
+ for (let j = dtStart; j <= dtEnd; j++) {
169
+ newTokens.push(tokens[j]);
170
+ }
171
+
172
+ // Find and add dd tokens
173
+ let ddFound = false;
174
+ for (let j = dtEnd + 1; j < tokens.length; j++) {
175
+ if (tokens[j].type === 'dt_open' || tokens[j].type === 'dl_close') {
176
+ break;
177
+ }
178
+ if (tokens[j].type === 'dd_open') {
179
+ ddFound = true;
180
+ }
181
+ if (ddFound) {
182
+ newTokens.push(tokens[j]);
183
+ if (tokens[j].type === 'dd_close') {
184
+ break;
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ // Add the closing dl token
191
+ for (let i = idx + 1; i < tokens.length; i++) {
192
+ if (tokens[i].type === 'dl_close') {
193
+ newTokens.push(tokens[i]);
194
+ break;
195
+ }
196
+ }
197
+
198
+ // Replace the old tokens with the new sorted ones
199
+ tokens.splice(idx, newTokens.length, ...newTokens);
200
+ }
201
+ // END Sort terms and definitions alphabetically
97
202
  }
98
203
 
99
204
  let lastDdIndex = -1;