reffy 20.0.13 → 20.0.15
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/LICENSE +21 -21
- package/README.md +151 -151
- package/index.js +29 -29
- package/package.json +5 -5
- package/reffy.js +324 -324
- package/schemas/browserlib/extract-algorithms.json +52 -52
- package/schemas/browserlib/extract-cssdfn.json +108 -108
- package/schemas/browserlib/extract-dfns.json +90 -90
- package/schemas/browserlib/extract-elements.json +17 -17
- package/schemas/browserlib/extract-events.json +31 -31
- package/schemas/browserlib/extract-headings.json +19 -19
- package/schemas/browserlib/extract-ids.json +7 -7
- package/schemas/browserlib/extract-links.json +12 -12
- package/schemas/browserlib/extract-refs.json +12 -12
- package/schemas/common.json +876 -876
- package/schemas/files/extracts/algorithms.json +12 -12
- package/schemas/files/extracts/css.json +16 -16
- package/schemas/files/extracts/dfns.json +12 -12
- package/schemas/files/extracts/elements.json +12 -12
- package/schemas/files/extracts/events.json +12 -12
- package/schemas/files/extracts/headings.json +12 -12
- package/schemas/files/extracts/ids.json +12 -12
- package/schemas/files/extracts/links.json +12 -12
- package/schemas/files/extracts/refs.json +12 -12
- package/schemas/files/index.json +59 -59
- package/schemas/postprocessing/events.json +50 -50
- package/schemas/postprocessing/idlnames-parsed.json +27 -27
- package/schemas/postprocessing/idlnames.json +17 -17
- package/schemas/postprocessing/idlparsed.json +67 -67
- package/src/browserlib/clone-and-clean.mjs +24 -24
- package/src/browserlib/create-outline.mjs +353 -353
- package/src/browserlib/extract-algorithms.mjs +723 -723
- package/src/browserlib/extract-cddl.mjs +125 -125
- package/src/browserlib/extract-dfns.mjs +1093 -1093
- package/src/browserlib/extract-headings.mjs +76 -76
- package/src/browserlib/extract-ids.mjs +28 -28
- package/src/browserlib/extract-links.mjs +45 -45
- package/src/browserlib/extract-references.mjs +308 -308
- package/src/browserlib/extract-webidl.mjs +89 -89
- package/src/browserlib/get-absolute-url.mjs +29 -29
- package/src/browserlib/get-code-elements.mjs +20 -20
- package/src/browserlib/get-generator.mjs +26 -26
- package/src/browserlib/get-lastmodified-date.mjs +13 -13
- package/src/browserlib/get-revision.mjs +12 -12
- package/src/browserlib/get-title.mjs +14 -14
- package/src/browserlib/informative-selector.mjs +24 -24
- package/src/browserlib/map-ids-to-headings.mjs +173 -173
- package/src/browserlib/reffy.json +85 -85
- package/src/browserlib/trim-spaces.mjs +35 -35
- package/src/cli/check-missing-dfns.js +587 -587
- package/src/cli/merge-crawl-results.js +132 -132
- package/src/cli/parse-webidl.js +447 -447
- package/src/lib/css-grammar-parse-tree.schema.json +109 -109
- package/src/lib/css-grammar-parser.js +440 -440
- package/src/lib/fetch.js +51 -51
- package/src/lib/markdown-report.js +360 -360
- package/src/lib/mock-server.js +218 -218
- package/src/lib/post-processor.js +322 -322
- package/src/lib/throttled-queue.js +129 -129
- package/src/postprocessing/annotate-links.js +41 -41
- package/src/postprocessing/csscomplete.js +48 -48
- package/src/postprocessing/idlnames.js +391 -391
- package/src/postprocessing/idlparsed.js +179 -179
- package/src/postprocessing/patch-dfns.js +51 -51
- package/src/specs/missing-css-rules.json +197 -197
- package/src/specs/spec-equivalents.json +149 -149
- package/src/browserlib/extract-editors.mjs~ +0 -14
- package/src/browserlib/extract-events.mjs~ +0 -3
- package/src/browserlib/generate-es-dfn-report.sh~ +0 -4
- package/src/browserlib/get-revision.mjs~ +0 -7
- package/src/cli/csstree-grammar-check.js +0 -28
- package/src/cli/csstree-grammar-check.js~ +0 -10
- package/src/cli/csstree-grammar-parser.js +0 -11
- package/src/cli/csstree-grammar-parser.js~ +0 -1
- package/src/cli/extract-editors.js~ +0 -38
- package/src/cli/process-specs.js~ +0 -28
- package/src/postprocessing/annotate-links.js~ +0 -8
- package/src/postprocessing/events.js~ +0 -245
|
@@ -1,173 +1,173 @@
|
|
|
1
|
-
import createOutline from './create-outline.mjs';
|
|
2
|
-
import getAbsoluteUrl from './get-absolute-url.mjs';
|
|
3
|
-
|
|
4
|
-
// Regular expression to capture the numbering of a heading. The expression
|
|
5
|
-
// extracts numbers such as "1.", "A.", "A.3", "13.3.4.". Notes:
|
|
6
|
-
// - A top-level number always ends with a ".", except in CSS 2.1, some IETF RFCs
|
|
7
|
-
// and WebGL specs.
|
|
8
|
-
// - There may be no final "." in sublevels (Bikeshed adds one, not ReSpec)
|
|
9
|
-
// - Top level appendices (e.g. in CSS 2.1, IETF RFCs and Bikeshed specs) start
|
|
10
|
-
// with "Appendix", sometimes followed by ":"
|
|
11
|
-
const reNumber = /^([A-Z\d]\.|[A-Z](\.\d+)+\.?|\d+(\.\d+)+\.?|\d|Appendix [A-Z][\.:])\s/;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Retrieve a "cleaned" version of the node's text content, without aside notes
|
|
15
|
-
* such as links to tests, MDN or references.
|
|
16
|
-
*
|
|
17
|
-
* Note that this is mainly intended for CSS Color 3, which has test annotations
|
|
18
|
-
* within headings.
|
|
19
|
-
*/
|
|
20
|
-
function getCleanTextContent(node) {
|
|
21
|
-
const asideSelector = 'aside, .mdn-anno, .wpt-tests-block, .annotation';
|
|
22
|
-
const cleanedNode = node.cloneNode(true);
|
|
23
|
-
const annotations = cleanedNode.querySelectorAll(asideSelector);
|
|
24
|
-
annotations.forEach(n => n.remove());
|
|
25
|
-
return cleanedNode.textContent.trim().replace(/\s+/g, ' ');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Generate a mapping between elements that have an ID (or a "name") and the
|
|
30
|
-
* closest heading (that also has an ID) under which these elements appear in
|
|
31
|
-
* the DOM tree.
|
|
32
|
-
*
|
|
33
|
-
* The main difficulty is that the structure of a DOM tree does not necessarily
|
|
34
|
-
* follow the structure of the outline of the document, which means that there
|
|
35
|
-
* is no direct way to tell the conceptual section where an element is defined
|
|
36
|
-
* just by looking at its list of ancestors in the DOM tree.
|
|
37
|
-
*
|
|
38
|
-
* In practice, the outline of the document needs to be prepared accordingly to
|
|
39
|
-
* the HTML spec before the mapping can be done.
|
|
40
|
-
*
|
|
41
|
-
* @function
|
|
42
|
-
* @public
|
|
43
|
-
* @return {Object} A mapping table, where keys are IDs of all elements in the
|
|
44
|
-
* document, and values are IDs of the heading elements under which these
|
|
45
|
-
* elements are defined. The table only contains IDs for which there exists
|
|
46
|
-
* such a heading.
|
|
47
|
-
*/
|
|
48
|
-
export default function () {
|
|
49
|
-
// Special-casing ecmascript specs which use special markup for sections
|
|
50
|
-
// <emu-clause>
|
|
51
|
-
if (document.querySelector("emu-clause")) {
|
|
52
|
-
return esMapIdToHeadings();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// Get a flat list of all conceptual sections
|
|
57
|
-
function flattenSections(outline) {
|
|
58
|
-
return outline
|
|
59
|
-
.concat(outline.flatMap(section => flattenSections(section.subSections)))
|
|
60
|
-
.concat(outline.flatMap(section => flattenSections(section.subRoots)));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const { outline, nodeToSection } = createOutline(document.body);
|
|
64
|
-
const sections = flattenSections(outline);
|
|
65
|
-
|
|
66
|
-
// Compute once whether we created a single page version out of multiple pages
|
|
67
|
-
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
68
|
-
|
|
69
|
-
const mappingTable = {};
|
|
70
|
-
[...document.querySelectorAll('[id],[name]')].forEach(node => {
|
|
71
|
-
let parentSection = nodeToSection.get(node);
|
|
72
|
-
while (parentSection) {
|
|
73
|
-
if (parentSection.heading !== '__implied') {
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
parentSection = sections.find(section =>
|
|
77
|
-
section.subSections.includes(parentSection) ||
|
|
78
|
-
section.subRoots.includes(parentSection));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Compute the absolute URL with fragment
|
|
82
|
-
// (Note the crawler merges pages of a multi-page spec in the first page
|
|
83
|
-
// to ease parsing logic, and we want to get back to the URL of the page)
|
|
84
|
-
const idAttr = node.id ? 'id' : 'name';
|
|
85
|
-
const nodeid = getAbsoluteUrl(node, { singlePage, attribute: idAttr });
|
|
86
|
-
let href = nodeid;
|
|
87
|
-
|
|
88
|
-
if (parentSection) {
|
|
89
|
-
const ids = [];
|
|
90
|
-
|
|
91
|
-
const heading = parentSection.heading;
|
|
92
|
-
const anchor = heading.querySelector('a[name]');
|
|
93
|
-
if (anchor) {
|
|
94
|
-
ids.push(anchor.getAttribute('name'));
|
|
95
|
-
href = getAbsoluteUrl(anchor, { singlePage, attribute: 'name' });
|
|
96
|
-
}
|
|
97
|
-
if (heading.id) {
|
|
98
|
-
ids.push(heading.id);
|
|
99
|
-
href = getAbsoluteUrl(heading, { singlePage });
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (parentSection.root && parentSection.root.id) {
|
|
103
|
-
ids.push(parentSection.root.id);
|
|
104
|
-
href = getAbsoluteUrl(parentSection.root, { singlePage });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const trimmedText = getCleanTextContent(heading);
|
|
108
|
-
const match = trimmedText.match(reNumber);
|
|
109
|
-
const number = match ? match[1] : null;
|
|
110
|
-
|
|
111
|
-
const mapping = {};
|
|
112
|
-
if (ids.length) {
|
|
113
|
-
mapping.id = ids.pop();
|
|
114
|
-
}
|
|
115
|
-
mapping.href = href;
|
|
116
|
-
mapping.title = trimmedText.replace(reNumber, '');
|
|
117
|
-
if (ids.length) {
|
|
118
|
-
mapping.alternateIds = ids;
|
|
119
|
-
}
|
|
120
|
-
mappingTable[nodeid] = mapping;
|
|
121
|
-
|
|
122
|
-
if (number) {
|
|
123
|
-
// Store the number without the final "." or ":"
|
|
124
|
-
// (and without the "Appendix" prefix in the CSS 2.1 case)
|
|
125
|
-
mappingTable[nodeid].number = number.replace(/[\.:]$/, '').replace(/^Appendix /, '');
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
return mappingTable;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function esMapIdToHeadings() {
|
|
134
|
-
// Based on https://tc39.es/ecmarkup/
|
|
135
|
-
// and actual emu-* tags used in the ecmascript spec with ids
|
|
136
|
-
const ignoreTags = ["emu-xref"];
|
|
137
|
-
const sectionTags = ["emu-intro", "emu-clause", "emu-annex"];
|
|
138
|
-
|
|
139
|
-
// Compute once whether we created a single page version out of multiple pages
|
|
140
|
-
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
141
|
-
|
|
142
|
-
let mappingTable = {};
|
|
143
|
-
[...document.querySelectorAll(`[id]:not(${ignoreTags.join(',')}`)]
|
|
144
|
-
.forEach(el => {
|
|
145
|
-
const section = el.closest(`${sectionTags.map(t => `${t}[id]`).join(',')}`);
|
|
146
|
-
|
|
147
|
-
// These are spec UI-related ids, so not a loss
|
|
148
|
-
if (!section) return;
|
|
149
|
-
|
|
150
|
-
const heading = section.querySelector("h1");
|
|
151
|
-
const trimmedText = getCleanTextContent(heading);
|
|
152
|
-
const nodeid = getAbsoluteUrl(el, { singlePage });
|
|
153
|
-
const href = getAbsoluteUrl(section, { singlePage });
|
|
154
|
-
|
|
155
|
-
const match = trimmedText.match(reNumber);
|
|
156
|
-
const number = match ? match[1] : null;
|
|
157
|
-
|
|
158
|
-
const mapping = {};
|
|
159
|
-
if (section.id) {
|
|
160
|
-
mapping.id = section.id;
|
|
161
|
-
}
|
|
162
|
-
mapping.href = href;
|
|
163
|
-
mapping.title = trimmedText.replace(reNumber, '');
|
|
164
|
-
mappingTable[nodeid] = mapping;
|
|
165
|
-
|
|
166
|
-
if (number) {
|
|
167
|
-
// Store the number without the final "."
|
|
168
|
-
mappingTable[nodeid].number = number.replace(/\.$/, '');
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
return mappingTable;
|
|
173
|
-
}
|
|
1
|
+
import createOutline from './create-outline.mjs';
|
|
2
|
+
import getAbsoluteUrl from './get-absolute-url.mjs';
|
|
3
|
+
|
|
4
|
+
// Regular expression to capture the numbering of a heading. The expression
|
|
5
|
+
// extracts numbers such as "1.", "A.", "A.3", "13.3.4.". Notes:
|
|
6
|
+
// - A top-level number always ends with a ".", except in CSS 2.1, some IETF RFCs
|
|
7
|
+
// and WebGL specs.
|
|
8
|
+
// - There may be no final "." in sublevels (Bikeshed adds one, not ReSpec)
|
|
9
|
+
// - Top level appendices (e.g. in CSS 2.1, IETF RFCs and Bikeshed specs) start
|
|
10
|
+
// with "Appendix", sometimes followed by ":"
|
|
11
|
+
const reNumber = /^([A-Z\d]\.|[A-Z](\.\d+)+\.?|\d+(\.\d+)+\.?|\d|Appendix [A-Z][\.:])\s/;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Retrieve a "cleaned" version of the node's text content, without aside notes
|
|
15
|
+
* such as links to tests, MDN or references.
|
|
16
|
+
*
|
|
17
|
+
* Note that this is mainly intended for CSS Color 3, which has test annotations
|
|
18
|
+
* within headings.
|
|
19
|
+
*/
|
|
20
|
+
function getCleanTextContent(node) {
|
|
21
|
+
const asideSelector = 'aside, .mdn-anno, .wpt-tests-block, .annotation';
|
|
22
|
+
const cleanedNode = node.cloneNode(true);
|
|
23
|
+
const annotations = cleanedNode.querySelectorAll(asideSelector);
|
|
24
|
+
annotations.forEach(n => n.remove());
|
|
25
|
+
return cleanedNode.textContent.trim().replace(/\s+/g, ' ');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generate a mapping between elements that have an ID (or a "name") and the
|
|
30
|
+
* closest heading (that also has an ID) under which these elements appear in
|
|
31
|
+
* the DOM tree.
|
|
32
|
+
*
|
|
33
|
+
* The main difficulty is that the structure of a DOM tree does not necessarily
|
|
34
|
+
* follow the structure of the outline of the document, which means that there
|
|
35
|
+
* is no direct way to tell the conceptual section where an element is defined
|
|
36
|
+
* just by looking at its list of ancestors in the DOM tree.
|
|
37
|
+
*
|
|
38
|
+
* In practice, the outline of the document needs to be prepared accordingly to
|
|
39
|
+
* the HTML spec before the mapping can be done.
|
|
40
|
+
*
|
|
41
|
+
* @function
|
|
42
|
+
* @public
|
|
43
|
+
* @return {Object} A mapping table, where keys are IDs of all elements in the
|
|
44
|
+
* document, and values are IDs of the heading elements under which these
|
|
45
|
+
* elements are defined. The table only contains IDs for which there exists
|
|
46
|
+
* such a heading.
|
|
47
|
+
*/
|
|
48
|
+
export default function () {
|
|
49
|
+
// Special-casing ecmascript specs which use special markup for sections
|
|
50
|
+
// <emu-clause>
|
|
51
|
+
if (document.querySelector("emu-clause")) {
|
|
52
|
+
return esMapIdToHeadings();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
// Get a flat list of all conceptual sections
|
|
57
|
+
function flattenSections(outline) {
|
|
58
|
+
return outline
|
|
59
|
+
.concat(outline.flatMap(section => flattenSections(section.subSections)))
|
|
60
|
+
.concat(outline.flatMap(section => flattenSections(section.subRoots)));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { outline, nodeToSection } = createOutline(document.body);
|
|
64
|
+
const sections = flattenSections(outline);
|
|
65
|
+
|
|
66
|
+
// Compute once whether we created a single page version out of multiple pages
|
|
67
|
+
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
68
|
+
|
|
69
|
+
const mappingTable = {};
|
|
70
|
+
[...document.querySelectorAll('[id],[name]')].forEach(node => {
|
|
71
|
+
let parentSection = nodeToSection.get(node);
|
|
72
|
+
while (parentSection) {
|
|
73
|
+
if (parentSection.heading !== '__implied') {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
parentSection = sections.find(section =>
|
|
77
|
+
section.subSections.includes(parentSection) ||
|
|
78
|
+
section.subRoots.includes(parentSection));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Compute the absolute URL with fragment
|
|
82
|
+
// (Note the crawler merges pages of a multi-page spec in the first page
|
|
83
|
+
// to ease parsing logic, and we want to get back to the URL of the page)
|
|
84
|
+
const idAttr = node.id ? 'id' : 'name';
|
|
85
|
+
const nodeid = getAbsoluteUrl(node, { singlePage, attribute: idAttr });
|
|
86
|
+
let href = nodeid;
|
|
87
|
+
|
|
88
|
+
if (parentSection) {
|
|
89
|
+
const ids = [];
|
|
90
|
+
|
|
91
|
+
const heading = parentSection.heading;
|
|
92
|
+
const anchor = heading.querySelector('a[name]');
|
|
93
|
+
if (anchor) {
|
|
94
|
+
ids.push(anchor.getAttribute('name'));
|
|
95
|
+
href = getAbsoluteUrl(anchor, { singlePage, attribute: 'name' });
|
|
96
|
+
}
|
|
97
|
+
if (heading.id) {
|
|
98
|
+
ids.push(heading.id);
|
|
99
|
+
href = getAbsoluteUrl(heading, { singlePage });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (parentSection.root && parentSection.root.id) {
|
|
103
|
+
ids.push(parentSection.root.id);
|
|
104
|
+
href = getAbsoluteUrl(parentSection.root, { singlePage });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const trimmedText = getCleanTextContent(heading);
|
|
108
|
+
const match = trimmedText.match(reNumber);
|
|
109
|
+
const number = match ? match[1] : null;
|
|
110
|
+
|
|
111
|
+
const mapping = {};
|
|
112
|
+
if (ids.length) {
|
|
113
|
+
mapping.id = ids.pop();
|
|
114
|
+
}
|
|
115
|
+
mapping.href = href;
|
|
116
|
+
mapping.title = trimmedText.replace(reNumber, '');
|
|
117
|
+
if (ids.length) {
|
|
118
|
+
mapping.alternateIds = ids;
|
|
119
|
+
}
|
|
120
|
+
mappingTable[nodeid] = mapping;
|
|
121
|
+
|
|
122
|
+
if (number) {
|
|
123
|
+
// Store the number without the final "." or ":"
|
|
124
|
+
// (and without the "Appendix" prefix in the CSS 2.1 case)
|
|
125
|
+
mappingTable[nodeid].number = number.replace(/[\.:]$/, '').replace(/^Appendix /, '');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return mappingTable;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function esMapIdToHeadings() {
|
|
134
|
+
// Based on https://tc39.es/ecmarkup/
|
|
135
|
+
// and actual emu-* tags used in the ecmascript spec with ids
|
|
136
|
+
const ignoreTags = ["emu-xref"];
|
|
137
|
+
const sectionTags = ["emu-intro", "emu-clause", "emu-annex"];
|
|
138
|
+
|
|
139
|
+
// Compute once whether we created a single page version out of multiple pages
|
|
140
|
+
const singlePage = !document.querySelector('[data-reffy-page]');
|
|
141
|
+
|
|
142
|
+
let mappingTable = {};
|
|
143
|
+
[...document.querySelectorAll(`[id]:not(${ignoreTags.join(',')}`)]
|
|
144
|
+
.forEach(el => {
|
|
145
|
+
const section = el.closest(`${sectionTags.map(t => `${t}[id]`).join(',')}`);
|
|
146
|
+
|
|
147
|
+
// These are spec UI-related ids, so not a loss
|
|
148
|
+
if (!section) return;
|
|
149
|
+
|
|
150
|
+
const heading = section.querySelector("h1");
|
|
151
|
+
const trimmedText = getCleanTextContent(heading);
|
|
152
|
+
const nodeid = getAbsoluteUrl(el, { singlePage });
|
|
153
|
+
const href = getAbsoluteUrl(section, { singlePage });
|
|
154
|
+
|
|
155
|
+
const match = trimmedText.match(reNumber);
|
|
156
|
+
const number = match ? match[1] : null;
|
|
157
|
+
|
|
158
|
+
const mapping = {};
|
|
159
|
+
if (section.id) {
|
|
160
|
+
mapping.id = section.id;
|
|
161
|
+
}
|
|
162
|
+
mapping.href = href;
|
|
163
|
+
mapping.title = trimmedText.replace(reNumber, '');
|
|
164
|
+
mappingTable[nodeid] = mapping;
|
|
165
|
+
|
|
166
|
+
if (number) {
|
|
167
|
+
// Store the number without the final "."
|
|
168
|
+
mappingTable[nodeid].number = number.replace(/\.$/, '');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
});
|
|
172
|
+
return mappingTable;
|
|
173
|
+
}
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"label": "Title",
|
|
4
|
-
"href": "./get-title.mjs",
|
|
5
|
-
"property": "title",
|
|
6
|
-
"metadata": true
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
"label": "Authoring tool",
|
|
10
|
-
"href": "./get-generator.mjs",
|
|
11
|
-
"property": "generator",
|
|
12
|
-
"metadata": true
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"label": "Date",
|
|
16
|
-
"href": "./get-lastmodified-date.mjs",
|
|
17
|
-
"property": "date",
|
|
18
|
-
"metadata": true
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"label": "Revision ID",
|
|
22
|
-
"href": "./get-revision.mjs",
|
|
23
|
-
"property": "revision",
|
|
24
|
-
"metadata": true
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"label": "Algorithms",
|
|
28
|
-
"href": "./extract-algorithms.mjs",
|
|
29
|
-
"property": "algorithms"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
"label": "Links",
|
|
33
|
-
"href": "./extract-links.mjs",
|
|
34
|
-
"property": "links"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"label": "References",
|
|
38
|
-
"href": "./extract-references.mjs",
|
|
39
|
-
"property": "refs"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"label": "Events",
|
|
43
|
-
"href": "./extract-events.mjs",
|
|
44
|
-
"property": "events"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"label": "Web IDL",
|
|
48
|
-
"href": "./extract-webidl.mjs",
|
|
49
|
-
"property": "idl",
|
|
50
|
-
"extractsPerSeries": true
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"label": "CSS",
|
|
54
|
-
"href": "./extract-cssdfn.mjs",
|
|
55
|
-
"property": "css",
|
|
56
|
-
"extractsPerSeries": true
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"label": "Terms",
|
|
60
|
-
"href": "./extract-dfns.mjs",
|
|
61
|
-
"property": "dfns",
|
|
62
|
-
"needsIdToHeadingMap": true
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"label": "Elements",
|
|
66
|
-
"href": "./extract-elements.mjs",
|
|
67
|
-
"property": "elements"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"label": "Headings",
|
|
71
|
-
"href": "./extract-headings.mjs",
|
|
72
|
-
"property": "headings"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"label": "IDs",
|
|
76
|
-
"href": "./extract-ids.mjs",
|
|
77
|
-
"property": "ids",
|
|
78
|
-
"needsIdToHeadingMap": true
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"label": "CDDL",
|
|
82
|
-
"href": "./extract-cddl.mjs",
|
|
83
|
-
"property": "cddl"
|
|
84
|
-
}
|
|
85
|
-
]
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"label": "Title",
|
|
4
|
+
"href": "./get-title.mjs",
|
|
5
|
+
"property": "title",
|
|
6
|
+
"metadata": true
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"label": "Authoring tool",
|
|
10
|
+
"href": "./get-generator.mjs",
|
|
11
|
+
"property": "generator",
|
|
12
|
+
"metadata": true
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"label": "Date",
|
|
16
|
+
"href": "./get-lastmodified-date.mjs",
|
|
17
|
+
"property": "date",
|
|
18
|
+
"metadata": true
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"label": "Revision ID",
|
|
22
|
+
"href": "./get-revision.mjs",
|
|
23
|
+
"property": "revision",
|
|
24
|
+
"metadata": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"label": "Algorithms",
|
|
28
|
+
"href": "./extract-algorithms.mjs",
|
|
29
|
+
"property": "algorithms"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"label": "Links",
|
|
33
|
+
"href": "./extract-links.mjs",
|
|
34
|
+
"property": "links"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"label": "References",
|
|
38
|
+
"href": "./extract-references.mjs",
|
|
39
|
+
"property": "refs"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"label": "Events",
|
|
43
|
+
"href": "./extract-events.mjs",
|
|
44
|
+
"property": "events"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"label": "Web IDL",
|
|
48
|
+
"href": "./extract-webidl.mjs",
|
|
49
|
+
"property": "idl",
|
|
50
|
+
"extractsPerSeries": true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"label": "CSS",
|
|
54
|
+
"href": "./extract-cssdfn.mjs",
|
|
55
|
+
"property": "css",
|
|
56
|
+
"extractsPerSeries": true
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"label": "Terms",
|
|
60
|
+
"href": "./extract-dfns.mjs",
|
|
61
|
+
"property": "dfns",
|
|
62
|
+
"needsIdToHeadingMap": true
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"label": "Elements",
|
|
66
|
+
"href": "./extract-elements.mjs",
|
|
67
|
+
"property": "elements"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"label": "Headings",
|
|
71
|
+
"href": "./extract-headings.mjs",
|
|
72
|
+
"property": "headings"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"label": "IDs",
|
|
76
|
+
"href": "./extract-ids.mjs",
|
|
77
|
+
"property": "ids",
|
|
78
|
+
"needsIdToHeadingMap": true
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"label": "CDDL",
|
|
82
|
+
"href": "./extract-cddl.mjs",
|
|
83
|
+
"property": "cddl"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Helper function that trims individual lines in a code block, removing as
|
|
3
|
-
* much space as possible from the beginning of the page while preserving
|
|
4
|
-
* indentation.
|
|
5
|
-
*
|
|
6
|
-
* Typically useful for CDDL and IDL extracts
|
|
7
|
-
*
|
|
8
|
-
* Rules followed:
|
|
9
|
-
* - Always trim the first line
|
|
10
|
-
* - Remove whitespaces from the end of each line
|
|
11
|
-
* - Replace lines that contain spaces with empty lines
|
|
12
|
-
* - Drop same number of leading whitespaces from all other lines
|
|
13
|
-
*/
|
|
14
|
-
export default function trimSpaces(code) {
|
|
15
|
-
const lines = code.trim().split('\n');
|
|
16
|
-
const toRemove = lines
|
|
17
|
-
.slice(1)
|
|
18
|
-
.filter(line => line.search(/\S/) > -1)
|
|
19
|
-
.reduce(
|
|
20
|
-
(min, line) => Math.min(min, line.search(/\S/)),
|
|
21
|
-
Number.MAX_VALUE);
|
|
22
|
-
return lines
|
|
23
|
-
.map(line => {
|
|
24
|
-
let firstRealChar = line.search(/\S/);
|
|
25
|
-
if (firstRealChar === -1) {
|
|
26
|
-
return '';
|
|
27
|
-
}
|
|
28
|
-
else if (firstRealChar === 0) {
|
|
29
|
-
return line.replace(/\s+$/, '');
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
return line.substring(toRemove).replace(/\s+$/, '');
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
.join('\n');
|
|
1
|
+
/**
|
|
2
|
+
* Helper function that trims individual lines in a code block, removing as
|
|
3
|
+
* much space as possible from the beginning of the page while preserving
|
|
4
|
+
* indentation.
|
|
5
|
+
*
|
|
6
|
+
* Typically useful for CDDL and IDL extracts
|
|
7
|
+
*
|
|
8
|
+
* Rules followed:
|
|
9
|
+
* - Always trim the first line
|
|
10
|
+
* - Remove whitespaces from the end of each line
|
|
11
|
+
* - Replace lines that contain spaces with empty lines
|
|
12
|
+
* - Drop same number of leading whitespaces from all other lines
|
|
13
|
+
*/
|
|
14
|
+
export default function trimSpaces(code) {
|
|
15
|
+
const lines = code.trim().split('\n');
|
|
16
|
+
const toRemove = lines
|
|
17
|
+
.slice(1)
|
|
18
|
+
.filter(line => line.search(/\S/) > -1)
|
|
19
|
+
.reduce(
|
|
20
|
+
(min, line) => Math.min(min, line.search(/\S/)),
|
|
21
|
+
Number.MAX_VALUE);
|
|
22
|
+
return lines
|
|
23
|
+
.map(line => {
|
|
24
|
+
let firstRealChar = line.search(/\S/);
|
|
25
|
+
if (firstRealChar === -1) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
else if (firstRealChar === 0) {
|
|
29
|
+
return line.replace(/\s+$/, '');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return line.substring(toRemove).replace(/\s+$/, '');
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.join('\n');
|
|
36
36
|
}
|