@markuplint/spec-generator 4.6.19-dev.110 → 4.7.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/CHANGELOG.md +14 -0
- package/README.md +80 -1
- package/lib/aria.js +7 -8
- package/lib/fetch.d.ts +2 -1
- package/lib/scraping.js +0 -1
- package/lib/utils.d.ts +3 -1
- package/lib/utils.js +0 -1
- package/package.json +11 -12
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [4.7.0](https://github.com/markuplint/markuplint/compare/@markuplint/spec-generator@4.6.19...@markuplint/spec-generator@4.7.0) (2025-08-13)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- ensure that each `clean` command correctly removes build files ([110b78e](https://github.com/markuplint/markuplint/commit/110b78e85379d29a84ca68325127344a87a570b6))
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- **spec-generator:** update ARIA spec scraping for ARIA 1.3 page structure ([f614b54](https://github.com/markuplint/markuplint/commit/f614b54b6e495fd52783ac3fa5e5ca199f5632a3))
|
|
15
|
+
|
|
16
|
+
## [4.6.19](https://github.com/markuplint/markuplint/compare/@markuplint/spec-generator@4.6.18...@markuplint/spec-generator@4.6.19) (2025-04-13)
|
|
17
|
+
|
|
18
|
+
**Note:** Version bump only for package @markuplint/spec-generator
|
|
19
|
+
|
|
6
20
|
## [4.6.18](https://github.com/markuplint/markuplint/compare/@markuplint/spec-generator@4.6.17...@markuplint/spec-generator@4.6.18) (2025-03-09)
|
|
7
21
|
|
|
8
22
|
**Note:** Version bump only for package @markuplint/spec-generator
|
package/README.md
CHANGED
|
@@ -1,3 +1,82 @@
|
|
|
1
1
|
# @markuplint/spec-generator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Private builder used to generate `@markuplint/html-spec`.
|
|
4
|
+
|
|
5
|
+
It assembles an Extended Spec JSON from the HTML element source files and external references
|
|
6
|
+
(MDN, WAI‑ARIA, HTML‑ARIA), then writes `index.json` in `@markuplint/html-spec`.
|
|
7
|
+
|
|
8
|
+
## How it is invoked
|
|
9
|
+
|
|
10
|
+
Called from `packages/@markuplint/html-spec/build.mjs`:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
await main({
|
|
14
|
+
outputFilePath: 'index.json',
|
|
15
|
+
htmlFilePattern: 'src/spec.*.json',
|
|
16
|
+
commonAttrsFilePath: 'src/spec-common.attributes.json',
|
|
17
|
+
commonContentsFilePath: 'src/spec-common.contents.json',
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You normally don't run this directly; use:
|
|
22
|
+
|
|
23
|
+
- From repo root: `yarn up:gen`
|
|
24
|
+
- Only html-spec: `yarn workspace @markuplint/html-spec run gen`
|
|
25
|
+
|
|
26
|
+
## What it does
|
|
27
|
+
|
|
28
|
+
1. Read element sources
|
|
29
|
+
|
|
30
|
+
- Load every `src/spec.*.json` and infer the element name from the filename (e.g. `spec.a.json` → `a`).
|
|
31
|
+
|
|
32
|
+
2. Enrich from MDN
|
|
33
|
+
|
|
34
|
+
- Fetch the MDN element page and populate missing metadata:
|
|
35
|
+
- `cite`, `description`, `categories`, `omission`, attribute flags
|
|
36
|
+
- Existing fields in `src/spec.*.json` take precedence over scraped values
|
|
37
|
+
- Attributes are merged name-by-name; manual entries win
|
|
38
|
+
|
|
39
|
+
3. Add obsolete elements
|
|
40
|
+
|
|
41
|
+
- Inject HTML obsolete elements (WHATWG list) and some deprecated SVG elements if not present.
|
|
42
|
+
|
|
43
|
+
4. Load shared data
|
|
44
|
+
|
|
45
|
+
- `def['#globalAttrs']` from `src/spec-common.attributes.json`
|
|
46
|
+
- `def['#contentModels']` from `src/spec-common.contents.json` (`models` key)
|
|
47
|
+
|
|
48
|
+
5. Build ARIA definitions
|
|
49
|
+
|
|
50
|
+
- Scrape WAI‑ARIA (1.1/1.2/1.3) and Graphics‑ARIA, plus HTML‑ARIA cross‑refs, to produce
|
|
51
|
+
`def['#aria']` (roles, properties, synonyms, defaults, and equivalent HTML attrs).
|
|
52
|
+
|
|
53
|
+
6. Emit Extended Spec JSON
|
|
54
|
+
|
|
55
|
+
- `{ cites, def: { #globalAttrs, #aria, #contentModels }, specs: [...] }` → `index.json`
|
|
56
|
+
(Pretty‑printed by the caller)
|
|
57
|
+
|
|
58
|
+
## Source of truth vs. generated data
|
|
59
|
+
|
|
60
|
+
- Source of truth for element specs is in `@markuplint/html-spec/src/`.
|
|
61
|
+
- This generator is purely a build step; do not edit the output `index.json` by hand.
|
|
62
|
+
|
|
63
|
+
## Precedence rules (important)
|
|
64
|
+
|
|
65
|
+
- Manual data in `src/spec.*.json` overrides MDN‑scraped values on conflict.
|
|
66
|
+
- Attribute objects are merged per name; manual keys win, MDN may fill missing flags.
|
|
67
|
+
- Shared files under `src/spec-common.*.json` are imported as‑is.
|
|
68
|
+
|
|
69
|
+
## Network and caching
|
|
70
|
+
|
|
71
|
+
- Uses live HTTP fetch against MDN/W3C specs. There is an in‑process cache for the current run only.
|
|
72
|
+
- If a fetch fails, the entry may be left empty; re‑run later or edit your manual source to cover it.
|
|
73
|
+
|
|
74
|
+
## When to change this package
|
|
75
|
+
|
|
76
|
+
- Only when the scraping targets change (DOM structure/URLs), or when the Extended Spec shape evolves
|
|
77
|
+
in `@markuplint/ml-spec`.
|
|
78
|
+
|
|
79
|
+
## See also
|
|
80
|
+
|
|
81
|
+
- `@markuplint/html-spec` README — how to edit the element sources.
|
|
82
|
+
- `@markuplint/ml-spec` README — schema shapes, generation, and spec merging.
|
package/lib/aria.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* global cheerio */
|
|
2
1
|
import { fetch } from './fetch.js';
|
|
3
2
|
import { arrayUnique, nameCompare } from './utils.js';
|
|
4
3
|
export async function getAria() {
|
|
@@ -80,7 +79,7 @@ async function getRoles(version, graphicsAria = false) {
|
|
|
80
79
|
/\[deprecated in aria 1\.\d]/i) === -1
|
|
81
80
|
? undefined
|
|
82
81
|
: true;
|
|
83
|
-
const $features = $el.find('.role-features tr');
|
|
82
|
+
const $features = $el.find('.role-features tr, table.def');
|
|
84
83
|
const generalization = $features
|
|
85
84
|
.find('.role-parent a')
|
|
86
85
|
.toArray()
|
|
@@ -193,8 +192,8 @@ async function getProps(version, roles) {
|
|
|
193
192
|
.toArray()
|
|
194
193
|
.map(el => {
|
|
195
194
|
const href = $(el).prop('href');
|
|
196
|
-
const hashIndex = href
|
|
197
|
-
const hash = hashIndex === -1 ? undefined : href
|
|
195
|
+
const hashIndex = href?.indexOf('#');
|
|
196
|
+
const hash = hashIndex === -1 ? undefined : href?.slice(hashIndex);
|
|
198
197
|
return hash?.slice(1);
|
|
199
198
|
})
|
|
200
199
|
.filter((s) => !!s));
|
|
@@ -203,9 +202,9 @@ async function getProps(version, roles) {
|
|
|
203
202
|
const className = $section.attr('class');
|
|
204
203
|
const type = className && /property/i.test(className) ? 'property' : 'state';
|
|
205
204
|
const deprecated = (className && /deprecated/i.test(className)) || undefined;
|
|
206
|
-
const $value = $section.find(`table.${type}-
|
|
205
|
+
const $value = $section.find(`table .${type}-value, table .property-value, .state-features .property-value`);
|
|
207
206
|
const value = $value.text().trim();
|
|
208
|
-
const $valueDescriptions = $section.find('table.value-descriptions tbody tr');
|
|
207
|
+
const $valueDescriptions = $section.find('table:is(.value-descriptions, .def:has(.value-description)) tbody tr');
|
|
209
208
|
const valueDescriptions = {};
|
|
210
209
|
$valueDescriptions.each((_, $tr) => {
|
|
211
210
|
const name = $($tr)
|
|
@@ -213,7 +212,7 @@ async function getProps(version, roles) {
|
|
|
213
212
|
.text()
|
|
214
213
|
.replaceAll(/\(default\)\s*:?/gi, '')
|
|
215
214
|
.trim();
|
|
216
|
-
const desc = $($tr).find('.value-description').text().trim();
|
|
215
|
+
const desc = $($tr).find('.value-description').text().trim().replaceAll(/\s+/g, ' ');
|
|
217
216
|
valueDescriptions[name] = desc;
|
|
218
217
|
});
|
|
219
218
|
const enumValues = [];
|
|
@@ -227,7 +226,7 @@ async function getProps(version, roles) {
|
|
|
227
226
|
.trim());
|
|
228
227
|
enumValues.push(...values);
|
|
229
228
|
}
|
|
230
|
-
const $defaultValue = $section.find('table.value-descriptions .value-name .default');
|
|
229
|
+
const $defaultValue = $section.find('table:is(.value-descriptions, .def:has(.value-description)) .value-name .default');
|
|
231
230
|
const defaultValue = $defaultValue
|
|
232
231
|
.text()
|
|
233
232
|
.replaceAll(/\(default\)/gi, '')
|
package/lib/fetch.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import * as cheerio from 'cheerio';
|
|
2
|
+
export declare function fetch(url: string): Promise<cheerio.CheerioAPI>;
|
|
2
3
|
export declare function fetchText(url: string): Promise<string>;
|
|
3
4
|
export declare function getReferences(): string[];
|
package/lib/scraping.js
CHANGED
package/lib/utils.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type * as cheerio from 'cheerio';
|
|
2
|
+
import type { AnyNode } from 'domhandler';
|
|
1
3
|
type HasName = {
|
|
2
4
|
readonly name: string;
|
|
3
5
|
};
|
|
4
6
|
export declare function nameCompare(a: HasName | string, b: HasName | string): 1 | 0 | -1;
|
|
5
7
|
export declare function sortObjectByKey<T>(o: T): T;
|
|
6
8
|
export declare function arrayUnique<T extends HasName>(array: readonly T[]): T[];
|
|
7
|
-
export declare function getThisOutline($: cheerio.
|
|
9
|
+
export declare function getThisOutline($: cheerio.CheerioAPI, $start: cheerio.Cheerio<AnyNode>): cheerio.Cheerio<AnyNode>;
|
|
8
10
|
export declare function mergeAttributes<T>(fromDocs: T, fromJSON: T): T;
|
|
9
11
|
export declare function keys<T, K = keyof T>(object: T): K[];
|
|
10
12
|
export declare function getName(origin: string): {
|
package/lib/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/spec-generator",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
4
4
|
"description": "Generates @markuplint/html-spec",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"private": false,
|
|
9
8
|
"type": "module",
|
|
10
9
|
"exports": {
|
|
11
10
|
".": {
|
|
@@ -19,22 +18,22 @@
|
|
|
19
18
|
"scripts": {
|
|
20
19
|
"build": "tsc --project tsconfig.build.json",
|
|
21
20
|
"dev": "tsc --watch --project tsconfig.build.json",
|
|
22
|
-
"clean": "tsc --build --clean"
|
|
21
|
+
"clean": "tsc --build --clean tsconfig.build.json"
|
|
23
22
|
},
|
|
24
23
|
"dependencies": {
|
|
25
|
-
"@types/cheerio": "0.
|
|
24
|
+
"@types/cheerio": "1.0.0",
|
|
26
25
|
"ajv": "8.17.1",
|
|
27
|
-
"cheerio": "1.
|
|
26
|
+
"cheerio": "1.1.2",
|
|
28
27
|
"cli-progress": "3.12.0",
|
|
29
|
-
"fast-xml-parser": "5.2.
|
|
30
|
-
"glob": "11.0.
|
|
31
|
-
"strip-json-comments": "5.0.
|
|
28
|
+
"fast-xml-parser": "5.2.5",
|
|
29
|
+
"glob": "11.0.3",
|
|
30
|
+
"strip-json-comments": "5.0.3"
|
|
32
31
|
},
|
|
33
32
|
"devDependencies": {
|
|
34
|
-
"@markuplint/ml-spec": "4.9.
|
|
35
|
-
"@markuplint/test-tools": "4.5.
|
|
33
|
+
"@markuplint/ml-spec": "4.9.7",
|
|
34
|
+
"@markuplint/test-tools": "4.5.20",
|
|
36
35
|
"@types/cli-progress": "3.11.6",
|
|
37
|
-
"type-fest": "4.
|
|
36
|
+
"type-fest": "4.41.0"
|
|
38
37
|
},
|
|
39
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "acbf53f7e30d7a59f850a0f279b617383266dab3"
|
|
40
39
|
}
|