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
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file regex-patterns.test.js
|
|
3
|
+
* @description Comprehensive test suite for centralized regex patterns
|
|
4
|
+
*
|
|
5
|
+
* This test verifies that all regex patterns in the centralized module
|
|
6
|
+
* work correctly and maintain backwards compatibility.
|
|
7
|
+
*
|
|
8
|
+
* @requires Jest testing framework
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
templateTags,
|
|
14
|
+
externalReferences,
|
|
15
|
+
escaping,
|
|
16
|
+
paths,
|
|
17
|
+
versions,
|
|
18
|
+
search,
|
|
19
|
+
gitignore,
|
|
20
|
+
whitespace,
|
|
21
|
+
urls,
|
|
22
|
+
utils
|
|
23
|
+
} = require('./regex-patterns');
|
|
24
|
+
|
|
25
|
+
// Tests for verifying all centralized regex patterns work correctly
|
|
26
|
+
describe('Centralized Regex Patterns Test Suite', () => {
|
|
27
|
+
|
|
28
|
+
// Tests for regex patterns that handle template tag markup
|
|
29
|
+
describe('Template Tags Patterns', () => {
|
|
30
|
+
|
|
31
|
+
// Test: Can the system identify all types of template tag markup?
|
|
32
|
+
test('replacer pattern identifies template tags', () => {
|
|
33
|
+
const testCases = [
|
|
34
|
+
'[[def: term]]',
|
|
35
|
+
'[[insert:path/file]]',
|
|
36
|
+
'[[xref: spec, term, alias]]'
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
testCases.forEach(testCase => {
|
|
40
|
+
// Reset regex state for global regex
|
|
41
|
+
templateTags.replacer.lastIndex = 0;
|
|
42
|
+
expect(templateTags.replacer.test(testCase)).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Test: Can the system split comma-separated arguments correctly?
|
|
47
|
+
test('argsSeparator splits comma-separated values', () => {
|
|
48
|
+
const input = 'term, alias, extra';
|
|
49
|
+
const result = input.split(templateTags.argsSeparator);
|
|
50
|
+
expect(result).toEqual(['term', 'alias', 'extra']);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Test: Can the system replace template variables with actual values?
|
|
54
|
+
test('variableInterpolation replaces template variables', () => {
|
|
55
|
+
const template = 'Hello ${name}, version ${version}';
|
|
56
|
+
const result = template.replace(templateTags.variableInterpolation, (match, p1) => {
|
|
57
|
+
const vars = { name: 'World', version: '1.0' };
|
|
58
|
+
return vars[p1.trim()] || match;
|
|
59
|
+
});
|
|
60
|
+
expect(result).toBe('Hello World, version 1.0');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Tests for regex patterns that handle external specification references
|
|
65
|
+
describe('External References Patterns', () => {
|
|
66
|
+
|
|
67
|
+
// Test: Can the system find all external reference markup in content?
|
|
68
|
+
test('allXTrefs finds external references', () => {
|
|
69
|
+
const content = 'Text with [[xref:spec,term]] and [[tref:spec2,term2]].';
|
|
70
|
+
const matches = content.match(externalReferences.allXTrefs);
|
|
71
|
+
expect(matches).toHaveLength(2);
|
|
72
|
+
expect(matches[0]).toBe('[[xref:spec,term]]');
|
|
73
|
+
expect(matches[1]).toBe('[[tref:spec2,term2]]');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Test: Can the system distinguish between xref and tref reference types?
|
|
77
|
+
test('referenceType extracts xref/tref type', () => {
|
|
78
|
+
const xrefMatch = '[[xref:spec,term]]'.match(externalReferences.referenceType);
|
|
79
|
+
const trefMatch = '[[tref:spec,term]]'.match(externalReferences.referenceType);
|
|
80
|
+
|
|
81
|
+
expect(xrefMatch[1]).toBe('xref');
|
|
82
|
+
expect(trefMatch[1]).toBe('tref');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Test: Can the system extract specification names from tref markup?
|
|
86
|
+
test('trefSpecExtractor gets spec name from tref', () => {
|
|
87
|
+
const match = '[[tref:myspec,term]]'.match(externalReferences.trefSpecExtractor);
|
|
88
|
+
expect(match[1]).toBe('myspec');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Tests for regex patterns that handle character escaping
|
|
93
|
+
describe('Escaping Patterns', () => {
|
|
94
|
+
|
|
95
|
+
// Test: Can the system escape special regex characters properly?
|
|
96
|
+
test('specialChars can be used for escaping', () => {
|
|
97
|
+
const input = 'test.file+regex*chars';
|
|
98
|
+
const escaped = input.replace(escaping.specialChars, '\\$&');
|
|
99
|
+
expect(escaped).toContain('\\.');
|
|
100
|
+
expect(escaped).toContain('\\+');
|
|
101
|
+
expect(escaped).toContain('\\*');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Test: Can the system match escaped placeholder patterns?
|
|
105
|
+
test('placeholderRegex matches escaped placeholders', () => {
|
|
106
|
+
const content = 'Text with __SPEC_UP_ESCAPED_TAG__ here';
|
|
107
|
+
expect(escaping.placeholderRegex.test(content)).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Tests for regex patterns that handle file path operations
|
|
112
|
+
describe('Path Patterns', () => {
|
|
113
|
+
|
|
114
|
+
// Test: Can the system remove trailing slashes from paths?
|
|
115
|
+
test('trailingSlash removes trailing slashes', () => {
|
|
116
|
+
const testCases = [
|
|
117
|
+
{ input: 'path/to/dir/', expected: 'path/to/dir' },
|
|
118
|
+
{ input: 'path/to/dir', expected: 'path/to/dir' }
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
testCases.forEach(({ input, expected }) => {
|
|
122
|
+
const result = input.replace(paths.trailingSlash, '');
|
|
123
|
+
expect(result).toBe(expected);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Tests for regex patterns that handle version directory naming
|
|
129
|
+
describe('Version Patterns', () => {
|
|
130
|
+
|
|
131
|
+
// Test: Can the system identify valid version directory names?
|
|
132
|
+
test('pattern matches version directories', () => {
|
|
133
|
+
expect(versions.pattern.test('v1')).toBe(true);
|
|
134
|
+
expect(versions.pattern.test('v123')).toBe(true);
|
|
135
|
+
expect(versions.pattern.test('version1')).toBe(false);
|
|
136
|
+
expect(versions.pattern.test('1')).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Tests for regex patterns that handle whitespace normalization
|
|
141
|
+
describe('Whitespace Patterns', () => {
|
|
142
|
+
|
|
143
|
+
// Test: Can the system collapse multiple whitespace characters?
|
|
144
|
+
test('oneOrMore collapses multiple spaces', () => {
|
|
145
|
+
const input = 'text with spaces';
|
|
146
|
+
const result = input.replace(whitespace.oneOrMore, ' ');
|
|
147
|
+
expect(result).toBe('text with spaces');
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Tests for regex patterns that handle URL parsing
|
|
152
|
+
describe('URL Patterns', () => {
|
|
153
|
+
|
|
154
|
+
// Test: Can the system extract base URLs from version URLs?
|
|
155
|
+
test('versionsBase extracts base URL', () => {
|
|
156
|
+
const testUrl = 'https://example.com/spec/versions/v1/';
|
|
157
|
+
const match = testUrl.match(urls.versionsBase);
|
|
158
|
+
expect(match[1]).toBe('https://example.com/spec');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Tests for utility functions that help with regex operations
|
|
163
|
+
describe('Utility Functions', () => {
|
|
164
|
+
|
|
165
|
+
// Test: Can the utility function escape regex special characters?
|
|
166
|
+
test('escapeRegexChars escapes special characters', () => {
|
|
167
|
+
const result = utils.escapeRegexChars('test.file');
|
|
168
|
+
expect(result).toBe('test\\.file');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Test: Can the utility create regex patterns for external references?
|
|
172
|
+
test('createXTrefRegex creates working regex', () => {
|
|
173
|
+
const regex = utils.createXTrefRegex('spec1', 'term1');
|
|
174
|
+
regex.lastIndex = 0; // Reset state
|
|
175
|
+
expect(regex.test('[[xref: spec1, term1]]')).toBe(true);
|
|
176
|
+
regex.lastIndex = 0; // Reset state
|
|
177
|
+
expect(regex.test('[[tref: spec1, term1, alias]]')).toBe(true);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Test: Can the utility convert gitignore patterns to working regex?
|
|
181
|
+
test('createGitignoreRegex converts globs to regex', () => {
|
|
182
|
+
const regex = utils.createGitignoreRegex('*.js');
|
|
183
|
+
expect(regex.test('file.js')).toBe(true);
|
|
184
|
+
expect(regex.test('file.txt')).toBe(false);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Tests verifying patterns work together in realistic scenarios
|
|
189
|
+
describe('Pattern Integration Tests', () => {
|
|
190
|
+
|
|
191
|
+
// Test: Do all patterns work correctly with realistic specification content?
|
|
192
|
+
test('processes realistic spec content', () => {
|
|
193
|
+
const specContent = `
|
|
194
|
+
# Test Specification
|
|
195
|
+
|
|
196
|
+
This defines [[def: test-term]] and references [[xref: external-spec, external-term]].
|
|
197
|
+
|
|
198
|
+
[[insert: sections/intro.md]]
|
|
199
|
+
|
|
200
|
+
Version directory: v1
|
|
201
|
+
`;
|
|
202
|
+
|
|
203
|
+
// Test that patterns can find their respective content
|
|
204
|
+
expect(templateTags.replacer.test(specContent)).toBe(true);
|
|
205
|
+
expect(externalReferences.allXTrefs.test(specContent)).toBe(true);
|
|
206
|
+
expect(versions.pattern.test('v1')).toBe(true);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Test: Do the patterns handle unusual or malformed input without errors?
|
|
210
|
+
test('handles edge cases gracefully', () => {
|
|
211
|
+
const edgeCases = [
|
|
212
|
+
'',
|
|
213
|
+
'[[]]',
|
|
214
|
+
'[[def:]]',
|
|
215
|
+
'no patterns here',
|
|
216
|
+
'[[def: term with unicode: tëst]]'
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
edgeCases.forEach(testCase => {
|
|
220
|
+
// Should not throw errors
|
|
221
|
+
expect(() => templateTags.replacer.test(testCase)).not.toThrow();
|
|
222
|
+
expect(() => externalReferences.allXTrefs.test(testCase)).not.toThrow();
|
|
223
|
+
expect(() => utils.escapeRegexChars(testCase)).not.toThrow();
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Tests ensuring patterns perform well with large content
|
|
229
|
+
describe('Performance Validation', () => {
|
|
230
|
+
|
|
231
|
+
// Test: Can the patterns process large amounts of content quickly?
|
|
232
|
+
test('handles large content efficiently', () => {
|
|
233
|
+
const largeContent = Array(1000).fill('[[def: term]] some text [[xref:spec,term]]').join(' ');
|
|
234
|
+
|
|
235
|
+
const startTime = Date.now();
|
|
236
|
+
const matches = largeContent.match(templateTags.replacer);
|
|
237
|
+
const endTime = Date.now();
|
|
238
|
+
|
|
239
|
+
expect(matches).toBeTruthy();
|
|
240
|
+
expect(endTime - startTime).toBeLessThan(100); // Should be fast
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Tests ensuring patterns maintain compatibility with existing content
|
|
245
|
+
describe('Backwards Compatibility Validation', () => {
|
|
246
|
+
|
|
247
|
+
// Test: Do the patterns still work with all historical template tag formats?
|
|
248
|
+
test('template tag replacer works with all historical patterns', () => {
|
|
249
|
+
const historicalExamples = [
|
|
250
|
+
'[[def: simple-term]]',
|
|
251
|
+
'[[def: term-with-dashes, alias-with-dashes]]',
|
|
252
|
+
'[[xref: external-spec, external-term]]',
|
|
253
|
+
'[[tref: another-spec, another-term, custom-alias]]',
|
|
254
|
+
'[[insert: path/to/file.md]]'
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
historicalExamples.forEach(example => {
|
|
258
|
+
// Reset regex state for global regex
|
|
259
|
+
templateTags.replacer.lastIndex = 0;
|
|
260
|
+
expect(templateTags.replacer.test(example)).toBe(true);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Test: Do external reference patterns work with existing specification formats?
|
|
265
|
+
test('external reference patterns maintain format compatibility', () => {
|
|
266
|
+
const externalRefContent = `
|
|
267
|
+
This specification references [[xref: RFC7515, JSON Web Signature]].
|
|
268
|
+
It also uses [[tref: KERI, Key Event Receipt Infrastructure, KERI protocol]].
|
|
269
|
+
Multiple refs: [[xref: spec1, term1]] and [[tref: spec2, term2, alias2]].
|
|
270
|
+
`;
|
|
271
|
+
|
|
272
|
+
const matches = externalRefContent.match(externalReferences.allXTrefs);
|
|
273
|
+
expect(matches).toHaveLength(4);
|
|
274
|
+
|
|
275
|
+
// Verify each match follows expected format
|
|
276
|
+
matches.forEach(match => {
|
|
277
|
+
expect(match).toMatch(/^\[\[(?:x|t)ref:\s*[^,\]]+(?:,\s*[^,\]]+)*\]\]$/);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
});
|
package/templates/template.html
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
7
|
<meta name="description" content="${description}">
|
|
8
8
|
<meta name="author" content="${author}">
|
|
9
|
+
<meta property="spec-up-t:github-repo-info" content="${githubRepoInfo}">
|
|
9
10
|
<link rel="icon" href="${specFavicon}" type="image/x-icon">
|
|
10
11
|
<meta name="generator" content="Spec-Up-T" />
|
|
11
12
|
<title>${title}</title>
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
<body features="${features}">
|
|
22
23
|
<!-- Skip to content link for accessibility -->
|
|
23
24
|
<a href="#content" class="screen-reader-text">Skip to content</a>
|
|
24
|
-
|
|
25
|
+
|
|
25
26
|
${assetsSvg}
|
|
26
27
|
|
|
27
28
|
<!-- Icons for hamburger menu, dark/light buttons -->
|
|
@@ -108,12 +109,19 @@
|
|
|
108
109
|
<path
|
|
109
110
|
d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z" />
|
|
110
111
|
</symbol>
|
|
112
|
+
<symbol id="box-arrow-up-right" viewBox="0 0 16 16">
|
|
113
|
+
<path fill-rule="evenodd"
|
|
114
|
+
d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z" />
|
|
115
|
+
<path fill-rule="evenodd"
|
|
116
|
+
d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z" />
|
|
117
|
+
</symbol>
|
|
111
118
|
</svg>
|
|
112
119
|
|
|
113
120
|
<header id="header" class="navbar sticky-top p-0 shadow">
|
|
114
121
|
<!-- Left-aligned elements -->
|
|
115
|
-
<button class="nav-link d-print-none px-3 d-md-none" type="button" data-bs-toggle="offcanvas"
|
|
116
|
-
|
|
122
|
+
<button class="nav-link d-print-none px-3 d-md-none" type="button" data-bs-toggle="offcanvas"
|
|
123
|
+
data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false"
|
|
124
|
+
aria-label="Toggle navigation">
|
|
117
125
|
<svg class="bi">
|
|
118
126
|
<use xlink:href="#list" />
|
|
119
127
|
</svg>
|
|
@@ -122,7 +130,7 @@
|
|
|
122
130
|
<a id="logo" href="${specLogoLink}">
|
|
123
131
|
<img class="d-print-none m-1" src="${specLogo}" alt="" />
|
|
124
132
|
</a>
|
|
125
|
-
|
|
133
|
+
|
|
126
134
|
<!-- Spacer to push the following elements to the right -->
|
|
127
135
|
<div class="flex-grow-1"></div>
|
|
128
136
|
|
|
@@ -178,19 +186,19 @@
|
|
|
178
186
|
</div>
|
|
179
187
|
|
|
180
188
|
<!-- Container width toggle -->
|
|
181
|
-
<button id="container_toggle" title="Toggle wide/narrow layout" type="button"
|
|
189
|
+
<button id="container_toggle" title="Toggle wide/narrow layout" type="button"
|
|
190
|
+
class="btn btn-sm btn-outline-secondary me-2">
|
|
182
191
|
<span class="visually-hidden">Toggle wide/narrow layout</span>
|
|
183
192
|
<i class="bi bi-arrows-angle-expand"></i>
|
|
184
193
|
</button>
|
|
185
194
|
|
|
186
195
|
<!-- Font size -->
|
|
187
196
|
<div class="adjust-font-size btn-group me-2" role="group">
|
|
188
|
-
<button title="Decrease font size" type="button"
|
|
189
|
-
|
|
190
|
-
class="visually-hidden">Decrease font size</span>
|
|
197
|
+
<button title="Decrease font size" type="button" class="btn btn-outline-secondary m-0 border-end-0"
|
|
198
|
+
id="decreaseBtn"><span class="visually-hidden">Decrease font size</span>
|
|
191
199
|
</button>
|
|
192
|
-
<button title="Increase font size" type="button"
|
|
193
|
-
|
|
200
|
+
<button title="Increase font size" type="button" class="btn btn-outline-secondary m-0 border-start-0"
|
|
201
|
+
id="increaseBtn">
|
|
194
202
|
<span class="visually-hidden">Increase font size</span>
|
|
195
203
|
</button>
|
|
196
204
|
</div>
|
|
@@ -209,8 +217,10 @@
|
|
|
209
217
|
</div>
|
|
210
218
|
<div id="toc" class="offcanvas-body d-md-flex flex-column p-0 pt-lg-3 overflow-y-auto">
|
|
211
219
|
${toc}
|
|
212
|
-
<
|
|
213
|
-
|
|
220
|
+
<div class="spec-footer mt-3">
|
|
221
|
+
<a class="mx-auto p-2" href="https://github.com/trustoverip/spec-up-t"
|
|
222
|
+
target="_blank" rel="noopener">Powered By Spec-Up-T</a>
|
|
223
|
+
</div>
|
|
214
224
|
</div>
|
|
215
225
|
</div>
|
|
216
226
|
</div>
|
|
@@ -244,21 +254,46 @@
|
|
|
244
254
|
</div>
|
|
245
255
|
<div class="offcanvas-body p-0">
|
|
246
256
|
<a target="_blank" rel="noopener" class="btn btn-menu-item m-0 mb-1 border-start-0 border-end-0"
|
|
247
|
-
href="https://
|
|
248
|
-
<button class="button-token-input btn btn-menu-item m-0 mb-1 border-start-0 border-end-0" type="button"
|
|
257
|
+
href="https://trustoverip.github.io/spec-up-t-website/docs/user-interface-overview/specification/#explanation-of-the-buttons-in-the-specification">Help</a>
|
|
258
|
+
<button class="button-token-input btn btn-menu-item m-0 mb-1 border-start-0 border-end-0" type="button"
|
|
259
|
+
aria-label="Enter GitHub Token">
|
|
249
260
|
Enter GitHub Token
|
|
250
261
|
</button>
|
|
251
|
-
<button id="repo_issues" issue-count animate class="btn btn-menu-item m-0 mb-1 border-start-0 border-end-0"
|
|
252
|
-
data-bs-toggle="offcanvas" data-bs-target="#offcanvasIssues"
|
|
262
|
+
<button id="repo_issues" issue-count animate class="btn btn-menu-item m-0 mb-1 border-start-0 border-end-0"
|
|
263
|
+
type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasIssues"
|
|
264
|
+
aria-controls="offcanvasIssues">
|
|
253
265
|
Issues
|
|
254
266
|
</button>
|
|
255
|
-
<!-- href added via JS -->
|
|
256
|
-
<a id="snapshotLink" class="btn btn-menu-item m-0 mb-1 border-start-0 border-end-0" href="#">Snapshots</a>
|
|
257
267
|
<hr>
|
|
258
|
-
<
|
|
259
|
-
|
|
268
|
+
<div class="ps-3 pe-3">
|
|
269
|
+
<p class="mb-2 fw-bold">Repository Information:</p>
|
|
270
|
+
<div id="github-repo-info" class="small text-muted">
|
|
271
|
+
<div class="d-flex align-items-center mb-1">
|
|
272
|
+
<i class="bi bi-person-circle me-2"></i>
|
|
273
|
+
<span>Account: <span id="repo-account">Loading...</span></span>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="d-flex align-items-center mb-1">
|
|
276
|
+
<i class="bi bi-git me-2"></i>
|
|
277
|
+
<span>Repository: <span id="repo-name">Loading...</span></span>
|
|
278
|
+
</div>
|
|
279
|
+
<div class="d-flex align-items-center mb-2">
|
|
280
|
+
<i class="bi bi-tree me-2"></i>
|
|
281
|
+
<span>Branch: <span id="repo-branch">Loading...</span></span>
|
|
282
|
+
</div>
|
|
283
|
+
<a id="repo-url" href="#" target="_blank" rel="noopener"
|
|
284
|
+
class="btn btn-sm btn-outline-secondary ms-0">
|
|
285
|
+
<i class="bi bi-github me-1"></i>
|
|
286
|
+
View on GitHub
|
|
287
|
+
</a>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<hr>
|
|
291
|
+
<div class="ps-3 pe-3">
|
|
292
|
+
<p class="mb-2 fw-bold">External Specifications:</p>
|
|
293
|
+
${externalSpecsList}
|
|
294
|
+
</div>
|
|
260
295
|
<hr>
|
|
261
|
-
<p id="w3c-state">W3C Recommendation, ${currentDate}</p>
|
|
296
|
+
<p class="ps-3 pe-3" id="w3c-state">W3C Recommendation, ${currentDate}</p>
|
|
262
297
|
</div>
|
|
263
298
|
</div>
|
|
264
299
|
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file This file creates an alphabet index for the terms
|
|
3
|
-
* @author Kor Dwarshuis
|
|
4
|
-
* @version 0.0.1
|
|
5
|
-
* @since 2024-09-19
|
|
6
|
-
*/
|
|
7
|
-
function createAlphabetIndex() {
|
|
8
|
-
// Check if the terms and definitions list exists
|
|
9
|
-
// If it doesn't exist, exit the function
|
|
10
|
-
// This prevents errors when the script is run on pages without the terms and definitions list
|
|
11
|
-
// and ensures that the script only runs when necessary
|
|
12
|
-
const termsListElement = document.querySelector(".terms-and-definitions-list");
|
|
13
|
-
const dtElements = termsListElement ? termsListElement.querySelectorAll("dt") : [];
|
|
14
|
-
|
|
15
|
-
if (dtElements.length === 0) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const terminologySectionUtilityContainer = document.getElementById("terminology-section-utility-container");
|
|
20
|
-
const alphabetIndex = {};
|
|
21
|
-
|
|
22
|
-
dtElements.forEach(dt => {
|
|
23
|
-
const span = dt.querySelector("span");
|
|
24
|
-
if (span?.id) {
|
|
25
|
-
const termId = span.id;
|
|
26
|
-
const firstChar = termId.charAt(termId.indexOf("term:") + 5).toUpperCase();
|
|
27
|
-
if (!alphabetIndex[firstChar]) {
|
|
28
|
-
alphabetIndex[firstChar] = span.id;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const alphabetIndexContainer = document.createElement("div");
|
|
34
|
-
alphabetIndexContainer.className = "alphabet-index-container";
|
|
35
|
-
|
|
36
|
-
// Create number of terms element
|
|
37
|
-
const numberOfTerms = document.createElement("p");
|
|
38
|
-
numberOfTerms.className = "number-of-terms";
|
|
39
|
-
numberOfTerms.textContent = `– There are ${dtElements.length} terms –`;
|
|
40
|
-
|
|
41
|
-
terminologySectionUtilityContainer.appendChild(numberOfTerms);
|
|
42
|
-
|
|
43
|
-
/*
|
|
44
|
-
The key advantage of localeCompare over simple comparison operators (<, >) is that it:
|
|
45
|
-
- Properly handles language-specific sorting rules (via locale settings)
|
|
46
|
-
- Correctly compares strings containing special characters or accents
|
|
47
|
-
- Can be configured to be case-insensitive
|
|
48
|
-
*/
|
|
49
|
-
Object.keys(alphabetIndex).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).forEach(char => {
|
|
50
|
-
const link = document.createElement("a");
|
|
51
|
-
link.href = `#${alphabetIndex[char]}`;
|
|
52
|
-
link.textContent = char;
|
|
53
|
-
alphabetIndexContainer.appendChild(link);
|
|
54
|
-
});
|
|
55
|
-
terminologySectionUtilityContainer.appendChild(alphabetIndexContainer);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
document.addEventListener("DOMContentLoaded", function () {
|
|
59
|
-
createAlphabetIndex();
|
|
60
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
function hideShowUtilityContainer() {
|
|
2
|
-
// Check if the terms and definitions list exists
|
|
3
|
-
// If it doesn't exist, exit the function
|
|
4
|
-
// This prevents errors when the script is run on pages without the terms and definitions list
|
|
5
|
-
// and ensures that the script only runs when necessary
|
|
6
|
-
const termsListElement = document.querySelector(".terms-and-definitions-list");
|
|
7
|
-
const dtElements = termsListElement ? termsListElement.querySelectorAll("dt") : [];
|
|
8
|
-
|
|
9
|
-
if (dtElements.length === 0) {
|
|
10
|
-
document.getElementById("terminology-section-utility-container")?.remove();
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
document.addEventListener("DOMContentLoaded", function () {
|
|
15
|
-
hideShowUtilityContainer();
|
|
16
|
-
});
|
package/assets/js/index.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
(function(){
|
|
3
|
-
|
|
4
|
-
/* GitHub Issues */
|
|
5
|
-
|
|
6
|
-
let source = specConfig.source;
|
|
7
|
-
if (source) {
|
|
8
|
-
if (source.host === 'github') {
|
|
9
|
-
fetch(`https://api.github.com/repos/${ source.account + '/' + source.repo }/issues`)
|
|
10
|
-
.then(response => response.json())
|
|
11
|
-
.then(issues => {
|
|
12
|
-
let count = issues.length;
|
|
13
|
-
document.querySelectorAll('[issue-count]').forEach(node => {
|
|
14
|
-
node.setAttribute('issue-count', count)
|
|
15
|
-
});
|
|
16
|
-
repo_issue_list.innerHTML = issues.map(issue => {
|
|
17
|
-
return `<li class="repo-issue">
|
|
18
|
-
<detail-box>
|
|
19
|
-
<section>${md.render(issue.body || '')}</section>
|
|
20
|
-
<header class="repo-issue-title">
|
|
21
|
-
<span class="repo-issue-number">${issue.number}</span>
|
|
22
|
-
<span class="repo-issue-link">
|
|
23
|
-
<a href="${issue.html_url}" target="_blank">${issue.title}</a>
|
|
24
|
-
</span>
|
|
25
|
-
<span detail-box-toggle></span>
|
|
26
|
-
</header>
|
|
27
|
-
</detail-box>
|
|
28
|
-
</li>`
|
|
29
|
-
}).join('');
|
|
30
|
-
Prism.highlightAllUnder(repo_issue_list);
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/* Mermaid Diagrams */
|
|
36
|
-
|
|
37
|
-
mermaid.initialize({
|
|
38
|
-
startOnLoad: true,
|
|
39
|
-
theme: 'neutral'
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
/* Charts */
|
|
43
|
-
|
|
44
|
-
document.querySelectorAll('.chartjs').forEach(chart => {
|
|
45
|
-
new Chart(chart, JSON.parse(chart.textContent));
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
/* Tooltips */
|
|
49
|
-
let tipMap = new WeakMap();
|
|
50
|
-
delegateEvent('pointerover', '.term-reference, .spec-reference', (e, anchor) => {
|
|
51
|
-
const id = anchor.getAttribute('data-local-href') || anchor.getAttribute('href') || '';
|
|
52
|
-
let term = document.getElementById(id.replace('#', ''));
|
|
53
|
-
if (!term || tipMap.has(anchor)) return;
|
|
54
|
-
let container = term.closest('dt, td:first-child');
|
|
55
|
-
if (!container) return;
|
|
56
|
-
let tip = {
|
|
57
|
-
allowHTML: true,
|
|
58
|
-
inlinePositioning: true
|
|
59
|
-
};
|
|
60
|
-
switch (container.tagName) {
|
|
61
|
-
case 'DT':
|
|
62
|
-
tip.content = container.nextElementSibling.textContent;
|
|
63
|
-
break;
|
|
64
|
-
case 'TD':
|
|
65
|
-
let table = container.closest('table');
|
|
66
|
-
let tds = Array.from(container.closest('tr').children);
|
|
67
|
-
tds.shift();
|
|
68
|
-
if (table) {
|
|
69
|
-
let headings = Array.from(table.querySelectorAll('thead th'));
|
|
70
|
-
headings.shift();
|
|
71
|
-
if (headings.length) {
|
|
72
|
-
tip.content = `
|
|
73
|
-
<header>${container.textContent}</header>
|
|
74
|
-
<table>
|
|
75
|
-
${headings.map((th, i) => {
|
|
76
|
-
return `<tr><td>${th.textContent}:</td><td>${tds[i] ? tds[i].textContent : ''}</td></tr>`
|
|
77
|
-
}).join('')}
|
|
78
|
-
</table>`;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (tip.content) tipMap.set(anchor, tippy(anchor, tip));
|
|
85
|
-
}, { passive: true });
|
|
86
|
-
|
|
87
|
-
})();
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @author Kor Dwarshuis
|
|
3
|
-
* @contact kor@dwarshuis.com
|
|
4
|
-
* @created 2024-09-07
|
|
5
|
-
* @description This script adds a button next to the search bar that allows users to download the page as a PDF.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
function pdfDownload() {
|
|
9
|
-
fetch('./index.pdf', { method: 'HEAD' })
|
|
10
|
-
.then(response => {
|
|
11
|
-
if (response.ok) {
|
|
12
|
-
let buttonPdfDownload = document.createElement("a");
|
|
13
|
-
buttonPdfDownload.classList.add("button-pdf-download");
|
|
14
|
-
buttonPdfDownload.classList.add("btn", "d-block", "btn-sm", "btn-outline-secondary");
|
|
15
|
-
buttonPdfDownload.target = "_blank";
|
|
16
|
-
buttonPdfDownload.rel = "noopener noreferrer";
|
|
17
|
-
buttonPdfDownload.href = "./index.pdf";
|
|
18
|
-
buttonPdfDownload.title = "Download this page as a PDF";
|
|
19
|
-
|
|
20
|
-
// Add PDF icon with transparent fill and text for better visual representation
|
|
21
|
-
buttonPdfDownload.innerHTML = `
|
|
22
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" class="me-1" viewBox="0 0 16 16">
|
|
23
|
-
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0H4zm0 1h5v4h4v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zm7 4h-1V2l3 3h-2z"/>
|
|
24
|
-
<path d="M6.5 10.5a.5.5 0 0 1-.5-.5V7.5a.5.5 0 0 1 .5-.5H8a.5.5 0 0 1 .5.5V10a.5.5 0 0 1-.5.5H6.5z"/>
|
|
25
|
-
</svg>
|
|
26
|
-
`;
|
|
27
|
-
|
|
28
|
-
// Add additional styling directly to the button
|
|
29
|
-
buttonPdfDownload.style.display = "inline-flex";
|
|
30
|
-
buttonPdfDownload.style.alignItems = "center";
|
|
31
|
-
buttonPdfDownload.style.justifyContent = "center";
|
|
32
|
-
|
|
33
|
-
document.querySelector('.service-menu').prepend(buttonPdfDownload);
|
|
34
|
-
} else {
|
|
35
|
-
console.log('PDF file does not exist. No PDF download button will be added.');
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
.catch(error => {
|
|
39
|
-
console.error('Error checking PDF file:', error);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
document.addEventListener("DOMContentLoaded", function () {
|
|
45
|
-
pdfDownload();
|
|
46
|
-
});
|