@markuplint/html-spec 4.16.1 → 4.17.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.
@@ -0,0 +1,170 @@
1
+ # ビルドパイプライン
2
+
3
+ ソースファイルと外部データから `index.json` がどのように生成されるかを解説します。
4
+
5
+ ## 概要
6
+
7
+ `@markuplint/html-spec` は `@markuplint/spec-generator` を使用して、単一の統合 `index.json` ファイルを生成します。ビルドプロセス:
8
+
9
+ 1. `src/` から 177 個の要素 JSON 仕様ファイルと 2 個の共通定義ファイルを読み込む
10
+ 2. MDN Web Docs、W3C ARIA 仕様、HTML Living Standard から外部データをフェッチ
11
+ 3. 手動仕様と外部データをマージ(手動データが常に優先)
12
+ 4. 統合結果を `index.json` に出力(約 48K 行、約 1.4MB)
13
+
14
+ ビルドは外部データをライブでフェッチするため、ネットワーク依存です。クリーンな実行で数分かかります。
15
+
16
+ ## ビルドフロー図
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ subgraph inputs ["ソースファイル(html-spec)"]
21
+ specFiles["src/spec.*.json\n(177 要素ファイル)"]
22
+ commonAttrs["src/spec-common.attributes.json\n(19 グローバル属性カテゴリ)"]
23
+ commonContents["src/spec-common.contents.json\n(コンテンツモデルマクロ)"]
24
+ end
25
+
26
+ subgraph build ["ビルド"]
27
+ buildScript["build.mjs"]
28
+ specGen["@markuplint/spec-generator"]
29
+ end
30
+
31
+ subgraph external ["外部データソース"]
32
+ mdn["MDN Web Docs"]
33
+ aria["W3C ARIA(1.1 / 1.2 / 1.3)"]
34
+ svg["SVG / Graphics ARIA"]
35
+ end
36
+
37
+ subgraph output ["出力"]
38
+ indexJson["index.json\n(48K+ 行)"]
39
+ end
40
+
41
+ specFiles --> buildScript
42
+ commonAttrs --> buildScript
43
+ commonContents --> buildScript
44
+ buildScript --> specGen
45
+
46
+ mdn --> specGen
47
+ aria --> specGen
48
+ svg --> specGen
49
+
50
+ specGen -->|"手動データ優先で\nマージ"| indexJson
51
+ ```
52
+
53
+ ## ビルドエントリポイント
54
+
55
+ `build.mjs` が `@markuplint/spec-generator` の `main()` を呼び出します。
56
+
57
+ ```javascript
58
+ import path from 'node:path';
59
+ import { main } from '@markuplint/spec-generator';
60
+
61
+ await main({
62
+ outputFilePath: path.resolve(import.meta.dirname, 'index.json'),
63
+ htmlFilePattern: path.resolve(import.meta.dirname, 'src', 'spec.*.json'),
64
+ commonAttrsFilePath: path.resolve(import.meta.dirname, 'src', 'spec-common.attributes.json'),
65
+ commonContentsFilePath: path.resolve(import.meta.dirname, 'src', 'spec-common.contents.json'),
66
+ });
67
+ ```
68
+
69
+ | オプション | 説明 |
70
+ | ------------------------ | ------------------------------------------ |
71
+ | `outputFilePath` | `index.json` の出力先パス |
72
+ | `htmlFilePattern` | 要素仕様ファイルにマッチする glob パターン |
73
+ | `commonAttrsFilePath` | グローバル属性定義ファイルのパス |
74
+ | `commonContentsFilePath` | コンテンツモデルマクロ定義ファイルのパス |
75
+
76
+ ## 外部データソース
77
+
78
+ spec-generator はビルド時に以下の外部ソースからデータをフェッチします。
79
+
80
+ | ソース | 提供データ |
81
+ | ----------------------------------------- | ------------------------------------------------------------ |
82
+ | MDN Web Docs(HTML) | 要素の説明、コンテンツカテゴリ、属性メタデータ、互換性フラグ |
83
+ | MDN Web Docs(SVG) | SVG 要素の説明、非推奨要素リスト |
84
+ | WAI-ARIA 1.1(`w3.org/TR/wai-aria-1.1/`) | ロール定義、プロパティ、ステート |
85
+ | WAI-ARIA 1.2(`w3.org/TR/wai-aria-1.2/`) | 更新されたロール定義 |
86
+ | WAI-ARIA 1.3(`w3c.github.io/aria/`) | 最新の Editor's Draft |
87
+ | Graphics ARIA | グラフィックス固有 ARIA ロール |
88
+ | HTML-ARIA(`w3.org/TR/html-aria/`) | HTML 属性から ARIA プロパティへのマッピング |
89
+
90
+ spec-generator の内部アーキテクチャ(スクレイピング、キャッシュ、モジュール構成)の詳細は `@markuplint/spec-generator` 自身のドキュメントを参照してください。
91
+
92
+ ## データ優先順位ルール
93
+
94
+ 手動仕様と外部データが重複する場合:
95
+
96
+ | データ | ソース | 優先度 |
97
+ | -------------- | --------------- | -------------------------- |
98
+ | `contentModel` | 手動仕様のみ | 最高(スクレイピングなし) |
99
+ | `aria` | 手動仕様のみ | 最高(スクレイピングなし) |
100
+ | `globalAttrs` | 手動仕様のみ | 最高(スクレイピングなし) |
101
+ | `attributes` | 手動仕様 + MDN | 手動が優先、MDN が補完 |
102
+ | `description` | MDN のみ | MDN のみ |
103
+ | `categories` | MDN のみ | MDN のみ |
104
+ | `cite` | 手動仕様 or MDN | 手動仕様があれば優先 |
105
+ | 互換性フラグ | 手動仕様 + MDN | 手動が優先、MDN が補完 |
106
+
107
+ ポイント:
108
+
109
+ - **手動データが常に優先** -- MDN スクレイピングデータを上書きする
110
+ - `attributes` は、手動仕様に同名の属性がない場合のみ MDN データが追加される
111
+ - `contentModel` と `aria` はスクレイピングされない -- `src/spec.*.json` からのみ取得
112
+ - `cite` URL はデフォルトで MDN ページだが、要素ごとにオーバーライド可能
113
+
114
+ **属性マージの詳細動作:**
115
+
116
+ 1. **仕様ファイルに属性定義あり** -- MDN データ(description、互換性フラグ)がマージ
117
+ されるが、仕様ファイル側の値が優先される。例えば、仕様ファイルで `"deprecated": true`
118
+ を設定し、MDN が deprecated フラグを付けていない場合、仕様ファイルの値が使われる。
119
+ 2. **MDN にのみ属性あり** -- MDN のメタデータとともにそのまま追加される。
120
+ 3. **仕様ファイルにのみ属性あり** -- MDN による補完なしにそのまま使用される。
121
+
122
+ ## 生成出力構造
123
+
124
+ `index.json` は `@markuplint/ml-spec` の `ExtendedSpec` 型に従います。
125
+
126
+ ```typescript
127
+ {
128
+ cites: string[]; // フェッチされた全 URL のソート済みリスト
129
+ def: {
130
+ "#globalAttrs": { ... }, // 19 グローバル属性カテゴリ
131
+ "#aria": { // バージョン別 ARIA 定義
132
+ "1.1": { roles, props, graphicsRoles },
133
+ "1.2": { roles, props, graphicsRoles },
134
+ "1.3": { roles, props, graphicsRoles }
135
+ },
136
+ "#contentModels": { ... } // コンテンツモデルカテゴリマクロ
137
+ },
138
+ specs: ElementSpec[] // 要素仕様配列(アルファベット順、SVG は末尾)
139
+ }
140
+ ```
141
+
142
+ - `cites` -- フェッチされた全 URL(トレーサビリティ用)
143
+ - `def["#globalAttrs"]` -- `spec-common.attributes.json` から
144
+ - `def["#aria"]` -- W3C ARIA 仕様からスクレイピング
145
+ - `def["#contentModels"]` -- `spec-common.contents.json` から
146
+ - `specs` -- マージ済み要素仕様の配列
147
+
148
+ ## ビルドコマンド
149
+
150
+ | コマンド | 説明 |
151
+ | ------------------------------------------------------- | ---------------------------------------------- |
152
+ | `yarn workspace @markuplint/html-spec run gen` | フル生成(ビルド + Prettier フォーマット) |
153
+ | `yarn workspace @markuplint/html-spec run gen:build` | 生成のみ |
154
+ | `yarn workspace @markuplint/html-spec run gen:prettier` | Prettier で `index.json` をフォーマット |
155
+ | `yarn up:gen` | リポジトリルートから全 spec パッケージを再生成 |
156
+
157
+ `gen` は `npm-run-all` を使用して `gen:build` → `gen:prettier` を順次実行します。
158
+
159
+ ## エクスポート
160
+
161
+ パッケージは 2 通りの方法でデータをエクスポートします。
162
+
163
+ ```json
164
+ {
165
+ ".": { "import": { "default": "./index.js", "types": "./index.d.ts" } },
166
+ "./json": "./index.json"
167
+ }
168
+ ```
169
+
170
+ 型付きラッパーのインポート、または `./json` サブパスによる生の JSON アクセスが可能です。
@@ -0,0 +1,171 @@
1
+ # Build Pipeline
2
+
3
+ This document describes how `index.json` is generated from the source files and external data.
4
+
5
+ ## Overview
6
+
7
+ The `@markuplint/html-spec` package uses `@markuplint/spec-generator` to produce a single consolidated `index.json` file. The build process:
8
+
9
+ 1. Reads 177 per-element JSON spec files and 2 common definition files from `src/`
10
+ 2. Fetches external data from MDN Web Docs, W3C ARIA specifications, and the HTML Living Standard
11
+ 3. Merges manual specifications with external data (manual data takes precedence)
12
+ 4. Writes the consolidated output to `index.json` (~48K lines, ~1.4MB)
13
+
14
+ The build is network-dependent because external data is fetched live. Expect several minutes on a clean run.
15
+
16
+ ## Build Flow Diagram
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ subgraph inputs ["Source Files (html-spec)"]
21
+ specFiles["src/spec.*.json\n(177 element files)"]
22
+ commonAttrs["src/spec-common.attributes.json\n(19 global attribute categories)"]
23
+ commonContents["src/spec-common.contents.json\n(content model macros)"]
24
+ end
25
+
26
+ subgraph build ["Build"]
27
+ buildScript["build.mjs"]
28
+ specGen["@markuplint/spec-generator"]
29
+ end
30
+
31
+ subgraph external ["External Data Sources"]
32
+ mdn["MDN Web Docs"]
33
+ aria["W3C ARIA (1.1 / 1.2 / 1.3)"]
34
+ svg["SVG / Graphics ARIA"]
35
+ end
36
+
37
+ subgraph output ["Output"]
38
+ indexJson["index.json\n(48K+ lines)"]
39
+ end
40
+
41
+ specFiles --> buildScript
42
+ commonAttrs --> buildScript
43
+ commonContents --> buildScript
44
+ buildScript --> specGen
45
+
46
+ mdn --> specGen
47
+ aria --> specGen
48
+ svg --> specGen
49
+
50
+ specGen -->|"merge\n(manual takes precedence)"| indexJson
51
+ ```
52
+
53
+ ## Build Entry Point
54
+
55
+ The build is triggered via `build.mjs`:
56
+
57
+ ```javascript
58
+ import path from 'node:path';
59
+ import { main } from '@markuplint/spec-generator';
60
+
61
+ await main({
62
+ outputFilePath: path.resolve(import.meta.dirname, 'index.json'),
63
+ htmlFilePattern: path.resolve(import.meta.dirname, 'src', 'spec.*.json'),
64
+ commonAttrsFilePath: path.resolve(import.meta.dirname, 'src', 'spec-common.attributes.json'),
65
+ commonContentsFilePath: path.resolve(import.meta.dirname, 'src', 'spec-common.contents.json'),
66
+ });
67
+ ```
68
+
69
+ | Option | Description |
70
+ | ------------------------ | ------------------------------------------------ |
71
+ | `outputFilePath` | Absolute path where `index.json` will be written |
72
+ | `htmlFilePattern` | Glob pattern matching per-element spec files |
73
+ | `commonAttrsFilePath` | Path to global attribute definitions |
74
+ | `commonContentsFilePath` | Path to content model macro definitions |
75
+
76
+ ## External Data Sources
77
+
78
+ The spec-generator fetches live data from the following sources during the build:
79
+
80
+ | Source | Data Provided |
81
+ | ---------------------------------------- | --------------------------------------------------------------------------------- |
82
+ | MDN Web Docs (HTML) | Element descriptions, content categories, attribute metadata, compatibility flags |
83
+ | MDN Web Docs (SVG) | SVG element descriptions and deprecated element list |
84
+ | WAI-ARIA 1.1 (`w3.org/TR/wai-aria-1.1/`) | Role definitions, properties, states |
85
+ | WAI-ARIA 1.2 (`w3.org/TR/wai-aria-1.2/`) | Updated role definitions |
86
+ | WAI-ARIA 1.3 (`w3c.github.io/aria/`) | Latest editor's draft |
87
+ | Graphics ARIA | Graphics-specific ARIA roles |
88
+ | HTML-ARIA (`w3.org/TR/html-aria/`) | HTML attribute to ARIA property mappings |
89
+
90
+ For details on the spec-generator's internal architecture (scraping, caching, module structure), see `@markuplint/spec-generator`'s own documentation.
91
+
92
+ ## Data Precedence Rules
93
+
94
+ When manual specifications and external data overlap:
95
+
96
+ | Data | Source | Precedence |
97
+ | ------------------- | ------------------ | --------------------------- |
98
+ | `contentModel` | Manual spec only | Highest (never scraped) |
99
+ | `aria` | Manual spec only | Highest (never scraped) |
100
+ | `globalAttrs` | Manual spec only | Highest (never scraped) |
101
+ | `attributes` | Manual spec + MDN | Manual wins; MDN fills gaps |
102
+ | `description` | MDN only | MDN only |
103
+ | `categories` | MDN only | MDN only |
104
+ | `cite` | Manual spec or MDN | Manual spec if provided |
105
+ | Compatibility flags | Manual spec + MDN | Manual wins; MDN fills gaps |
106
+
107
+ Key points:
108
+
109
+ - **Manual data always takes precedence** over MDN-scraped data
110
+ - For `attributes`, MDN-scraped attributes are added only when the manual spec does not define that attribute name
111
+ - Content models and ARIA mappings are never scraped -- they come exclusively from your `src/spec.*.json` files
112
+ - The `cite` URL defaults to the MDN page but can be overridden per element
113
+
114
+ **Attribute merge behavior in detail:**
115
+
116
+ 1. **Attribute defined in spec file** -- MDN data (description, compatibility flags) is
117
+ merged in, but spec-side values take precedence. For example, if the spec file sets
118
+ `"deprecated": true` but MDN does not flag the attribute as deprecated, the spec
119
+ value wins.
120
+ 2. **Attribute exists only in MDN** -- Added to the element as-is with MDN metadata.
121
+ 3. **Attribute exists only in spec file** -- Used as-is with no MDN augmentation.
122
+
123
+ ## Generated Output Structure
124
+
125
+ The `index.json` follows the `ExtendedSpec` type from `@markuplint/ml-spec`:
126
+
127
+ ```typescript
128
+ {
129
+ cites: string[]; // Sorted list of all URLs fetched during generation
130
+ def: {
131
+ "#globalAttrs": { ... }, // 19 global attribute categories
132
+ "#aria": { // ARIA definitions per version
133
+ "1.1": { roles, props, graphicsRoles },
134
+ "1.2": { roles, props, graphicsRoles },
135
+ "1.3": { roles, props, graphicsRoles }
136
+ },
137
+ "#contentModels": { ... } // Content model category macros
138
+ },
139
+ specs: ElementSpec[] // Element specifications, sorted alphabetically (SVG after HTML)
140
+ }
141
+ ```
142
+
143
+ - `cites` -- all fetched URLs, for traceability
144
+ - `def["#globalAttrs"]` -- from `spec-common.attributes.json`
145
+ - `def["#aria"]` -- scraped from W3C ARIA specifications
146
+ - `def["#contentModels"]` -- from `spec-common.contents.json`
147
+ - `specs` -- merged element specifications array
148
+
149
+ ## Build Commands
150
+
151
+ | Command | Description |
152
+ | ------------------------------------------------------- | ------------------------------------------------- |
153
+ | `yarn workspace @markuplint/html-spec run gen` | Full generation (build + Prettier formatting) |
154
+ | `yarn workspace @markuplint/html-spec run gen:build` | Generation only |
155
+ | `yarn workspace @markuplint/html-spec run gen:prettier` | Format `index.json` with Prettier |
156
+ | `yarn up:gen` | Regenerate all spec packages from repository root |
157
+
158
+ The `gen` script runs `gen:build` then `gen:prettier` in sequence via `npm-run-all`.
159
+
160
+ ## Exports
161
+
162
+ The package exports the data in two ways:
163
+
164
+ ```json
165
+ {
166
+ ".": { "import": { "default": "./index.js", "types": "./index.d.ts" } },
167
+ "./json": "./index.json"
168
+ }
169
+ ```
170
+
171
+ Consumers can import the typed wrapper or access the raw JSON via the `./json` subpath.