@markuplint/spec-generator 4.8.0 → 4.8.2
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/ARCHITECTURE.ja.md +178 -0
- package/ARCHITECTURE.md +178 -0
- package/CHANGELOG.md +9 -5
- package/README.md +29 -41
- package/SKILL.md +134 -0
- package/docs/maintenance.ja.md +212 -0
- package/docs/maintenance.md +212 -0
- package/docs/modules.ja.md +252 -0
- package/docs/modules.md +252 -0
- package/docs/scraping.ja.md +320 -0
- package/docs/scraping.md +320 -0
- package/lib/aria.d.ts +6 -0
- package/lib/aria.js +45 -0
- package/lib/fetch.d.ts +21 -0
- package/lib/fetch.js +28 -1
- package/lib/global-attrs.d.ts +6 -0
- package/lib/global-attrs.js +6 -0
- package/lib/html-elements.d.ts +8 -0
- package/lib/html-elements.js +31 -9
- package/lib/index.d.ts +22 -0
- package/lib/index.js +15 -0
- package/lib/read-json.d.ts +18 -0
- package/lib/read-json.js +18 -0
- package/lib/scraping.d.ts +15 -0
- package/lib/scraping.js +52 -0
- package/lib/svg.d.ts +7 -0
- package/lib/svg.js +7 -0
- package/lib/utils.d.ts +59 -0
- package/lib/utils.js +56 -0
- package/package.json +7 -7
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# メンテナンスガイド
|
|
2
|
+
|
|
3
|
+
`@markuplint/spec-generator` の実践的な運用・メンテナンスガイド。
|
|
4
|
+
|
|
5
|
+
## コマンド
|
|
6
|
+
|
|
7
|
+
| コマンド | 説明 |
|
|
8
|
+
| ----------------------------------------------------- | ---------------------------------------------------------- |
|
|
9
|
+
| `yarn build --scope @markuplint/spec-generator` | TypeScript を `lib/` にコンパイル |
|
|
10
|
+
| `yarn workspace @markuplint/spec-generator run dev` | ウォッチモードでコンパイル |
|
|
11
|
+
| `yarn workspace @markuplint/spec-generator run clean` | コンパイル出力をクリーン |
|
|
12
|
+
| `yarn up:gen` | 仕様生成を実行(html-spec 経由でこのパッケージを呼び出し) |
|
|
13
|
+
|
|
14
|
+
**注意:** このパッケージは直接実行されません。`@markuplint/html-spec/build.mjs` が消費し、`main()` を呼び出します。完全な生成をトリガーするには `yarn up:gen` を使用してください。
|
|
15
|
+
|
|
16
|
+
## トラブルシューティング
|
|
17
|
+
|
|
18
|
+
### スクレイピング失敗の検出
|
|
19
|
+
|
|
20
|
+
`yarn up:gen` 実行後、必ず `index.json` の差分を確認:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git diff packages/@markuplint/html-spec/index.json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**スクレイピング失敗の兆候:**
|
|
27
|
+
|
|
28
|
+
- 差分が極端に大量のデータ消失を示す(仕様データが一括で消失)
|
|
29
|
+
- 複数の要素で突然 `description` フィールドが空になる
|
|
30
|
+
- 以前存在していた属性が削除される
|
|
31
|
+
- ARIA ロールやプロパティの定義が空、または大幅に減少
|
|
32
|
+
|
|
33
|
+
**これはほぼ確実にスクレイピングの失敗であり**、実際の仕様変更ではありません。正当な仕様変更は漸進的で、少数の要素にのみ影響します。
|
|
34
|
+
|
|
35
|
+
**根本原因:** 参照サイト(MDN または W3C)の HTML 構造、情報の記述方法、要素の ID/クラスが変更された。
|
|
36
|
+
|
|
37
|
+
**対処法:**
|
|
38
|
+
|
|
39
|
+
1. 影響を受けているデータを特定(要素メタデータ、ARIA ロール、SVG 要素など)
|
|
40
|
+
2. 該当するモジュールを特定:
|
|
41
|
+
- 要素の説明、カテゴリ、属性 -- `scraping.ts`
|
|
42
|
+
- ARIA ロールとプロパティ -- `aria.ts`
|
|
43
|
+
- SVG 非推奨要素 -- `svg.ts`
|
|
44
|
+
3. 影響を受けたウェブページをブラウザで開き、現在の HTML 構造を調査
|
|
45
|
+
4. モジュールの CSS セレクタを新しい構造に合わせて更新
|
|
46
|
+
5. ビルド: `yarn build --scope @markuplint/spec-generator`
|
|
47
|
+
6. 再生成: `yarn up:gen`
|
|
48
|
+
7. `index.json` の差分が正しくなったことを確認
|
|
49
|
+
|
|
50
|
+
### ビルドコンパイルエラー
|
|
51
|
+
|
|
52
|
+
`yarn build --scope @markuplint/spec-generator` が失敗する場合:
|
|
53
|
+
|
|
54
|
+
1. `@markuplint/ml-spec` の型が変更されていないか確認(これが主要な型プロバイダ)
|
|
55
|
+
2. 開発依存がインストールされていることを確認: `yarn install`
|
|
56
|
+
3. クリーンビルドを試行: `yarn workspace @markuplint/spec-generator run clean && yarn build --scope @markuplint/spec-generator`
|
|
57
|
+
|
|
58
|
+
### 生成時のネットワークエラー
|
|
59
|
+
|
|
60
|
+
**症状:** `yarn up:gen` が失敗またはハングする。
|
|
61
|
+
|
|
62
|
+
**原因:** MDN または W3C サーバーに到達できない。
|
|
63
|
+
|
|
64
|
+
**対処法:**
|
|
65
|
+
|
|
66
|
+
- ネットワーク接続を確認
|
|
67
|
+
- 失敗したフェッチは空文字列としてキャッシュされ、ビルドは継続
|
|
68
|
+
- プログレスバーが現在フェッチ中の URL を表示 -- どのドメインが失敗しているか特定
|
|
69
|
+
- サービスが利用可能になったら再試行
|
|
70
|
+
|
|
71
|
+
## レシピ
|
|
72
|
+
|
|
73
|
+
### 1. MDN ページ構造変更への対応
|
|
74
|
+
|
|
75
|
+
MDN が要素リファレンスページを再構築した場合、`scraping.ts` の CSS セレクタの更新が必要です。
|
|
76
|
+
|
|
77
|
+
1. 実際のページ HTML と `scraping.ts` のセレクタを比較して影響を受けたセレクタを特定
|
|
78
|
+
2. 確認すべき主要セレクタ:
|
|
79
|
+
- `MAIN_ARTICLE_SELECTOR`(`main#content`)-- メインコンテンツ領域
|
|
80
|
+
- `.reference-layout__header .content-section` -- 説明の抽出
|
|
81
|
+
- `.bc-table tbody tr:first-child th` -- 互換性テーブル
|
|
82
|
+
- `#technical_summary ~ figure.table-container > table` -- 技術サマリ
|
|
83
|
+
- `.content-section[aria-labelledby="attributes"]` -- 属性セクション
|
|
84
|
+
- アイコンクラス(`.ic-experimental`, `.ic-deprecated` など)-- ステータスフラグ
|
|
85
|
+
3. セレクタを新しい構造に合わせて更新
|
|
86
|
+
4. ビルド: `yarn build --scope @markuplint/spec-generator`
|
|
87
|
+
5. 再生成: `yarn up:gen`
|
|
88
|
+
6. 差分で正しいデータの復元を確認
|
|
89
|
+
|
|
90
|
+
### 2. 新しい ARIA バージョンの追加
|
|
91
|
+
|
|
92
|
+
新しい ARIA 仕様バージョンが公開された場合(例: 1.4):
|
|
93
|
+
|
|
94
|
+
1. `src/aria.ts` を開く
|
|
95
|
+
2. `getARIASpecURLByVersion()` に新しいケースを追加:
|
|
96
|
+
```typescript
|
|
97
|
+
case '1.4': {
|
|
98
|
+
if (!graphicsAria) {
|
|
99
|
+
return 'https://www.w3.org/TR/wai-aria-1.4/'; // またはエディターズドラフト URL
|
|
100
|
+
}
|
|
101
|
+
return 'https://w3c.github.io/graphics-aria/';
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
3. `getAria()` に新しいバージョンを追加:
|
|
105
|
+
```typescript
|
|
106
|
+
const roles14 = await getRoles('1.4');
|
|
107
|
+
// ...
|
|
108
|
+
'1.4': {
|
|
109
|
+
roles: roles14,
|
|
110
|
+
props: await getProps('1.4', roles14),
|
|
111
|
+
graphicsRoles: await getRoles('1.4', true),
|
|
112
|
+
},
|
|
113
|
+
```
|
|
114
|
+
4. **パッケージ間連携:** `@markuplint/ml-spec` の `ARIAVersion` 型も `'1.4'` を含むよう更新が必要
|
|
115
|
+
5. ビルドと再生成を実行
|
|
116
|
+
|
|
117
|
+
### 3. 非推奨リストへの要素追加
|
|
118
|
+
|
|
119
|
+
新しく非推奨になった HTML 要素を追加するには:
|
|
120
|
+
|
|
121
|
+
1. `src/html-elements.ts` を開く
|
|
122
|
+
2. `obsoleteList` 配列に要素名を追加
|
|
123
|
+
3. 要素は自動的に `obsolete: true` の最小限の仕様スタブを取得
|
|
124
|
+
4. ビルド: `yarn build --scope @markuplint/spec-generator`
|
|
125
|
+
5. 再生成: `yarn up:gen`
|
|
126
|
+
6. `index.json` で要素が `"obsolete": true` で表示されることを確認
|
|
127
|
+
|
|
128
|
+
### 4. ExtendedSpec 型変更への追従
|
|
129
|
+
|
|
130
|
+
`@markuplint/ml-spec` が `ExtendedSpec` や `ExtendedElementSpec` の型を変更した場合:
|
|
131
|
+
|
|
132
|
+
1. どのフィールドが追加、削除、変更されたか確認
|
|
133
|
+
2. `src/index.ts` のアセンブリロジック(`json` オブジェクト)を更新
|
|
134
|
+
3. 新しいフィールドを外部データから取得する必要がある場合はスクレイピングモジュールを更新
|
|
135
|
+
4. ビルドと再生成で確認
|
|
136
|
+
|
|
137
|
+
### 5. cheerio メジャーバージョン更新時の対応
|
|
138
|
+
|
|
139
|
+
`cheerio` パッケージはスクレイピングに使用される DOM API を提供します。更新時:
|
|
140
|
+
|
|
141
|
+
1. cheerio の変更履歴で破壊的 API 変更を確認
|
|
142
|
+
2. 使用されている主要 API: `.find()`, `.text()`, `.attr()`, `.toArray()`, `.each()`, `.next()`, `.prev()`, `.parent()`, `.children()`, `.before()`, `.remove()`, `.clone()`, `.append()`, `.filter()`, `.siblings()`, `.prop()`
|
|
143
|
+
3. `cheerio.load()`(`fetch.ts` で使用)も確認
|
|
144
|
+
4. HTML パース動作が変更された場合はセレクタを更新
|
|
145
|
+
5. ビルドと再生成で確認
|
|
146
|
+
|
|
147
|
+
## デバッグ
|
|
148
|
+
|
|
149
|
+
### 個別要素のスクレイピング結果確認
|
|
150
|
+
|
|
151
|
+
特定の要素についてスクレイピングされるデータをデバッグするには:
|
|
152
|
+
|
|
153
|
+
1. `scraping.ts` の `fetchHTMLElement()` 呼び出し後に一時的なログを追加:
|
|
154
|
+
```typescript
|
|
155
|
+
const mdnData = await fetchHTMLElement(cite);
|
|
156
|
+
if (localName === 'your-element') {
|
|
157
|
+
console.log(JSON.stringify(mdnData, null, 2));
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
2. ビルドして `yarn up:gen` を実行
|
|
161
|
+
3. スクレイピングデータのコンソール出力を確認
|
|
162
|
+
4. デバッグ後に一時的なログを削除
|
|
163
|
+
|
|
164
|
+
### キャッシュされたフェッチ結果の調査
|
|
165
|
+
|
|
166
|
+
`fetch.ts` の `cache` Map はすべての生の HTML レスポンスを保存しています。特定の URL のフェッチ内容を調査するには:
|
|
167
|
+
|
|
168
|
+
1. `fetchText()` に一時的なログを追加:
|
|
169
|
+
```typescript
|
|
170
|
+
if (url.includes('your-search-term')) {
|
|
171
|
+
console.log(`Fetched ${url}: ${text.length} chars`);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
2. 長さが 0 の場合はフェッチ失敗を示す(空文字列がキャッシュされた)
|
|
175
|
+
|
|
176
|
+
### ARIA ロールスクレイピングの確認
|
|
177
|
+
|
|
178
|
+
特定の ARIA バージョンから抽出されたロールを確認するには:
|
|
179
|
+
|
|
180
|
+
1. `getAria()` 内の `getRoles()` 後に一時的なログを追加:
|
|
181
|
+
```typescript
|
|
182
|
+
const roles13 = await getRoles('1.3');
|
|
183
|
+
console.log(`ARIA 1.3 roles: ${roles13.map(r => r.name).join(', ')}`);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 依存関係メモ
|
|
187
|
+
|
|
188
|
+
### cheerio
|
|
189
|
+
|
|
190
|
+
- バージョン: 1.1.2
|
|
191
|
+
- パースされた HTML に対する jQuery 風 DOM API を提供
|
|
192
|
+
- `scraping.ts`, `aria.ts`, `svg.ts`, `fetch.ts` 全体で使用
|
|
193
|
+
- `CheerioAPI` 型は `cheerio` から、`Element` は `domhandler`(cheerio の基盤 DOM ライブラリ)からインポート
|
|
194
|
+
|
|
195
|
+
### fast-xml-parser
|
|
196
|
+
|
|
197
|
+
- バージョン: 5.3.4
|
|
198
|
+
- 依存として記載されているが、現在どのソースモジュールからもインポートされていない
|
|
199
|
+
- 将来の XML パースニーズのために予約されている可能性あり
|
|
200
|
+
|
|
201
|
+
### strip-json-comments
|
|
202
|
+
|
|
203
|
+
- バージョン: 5.0.3
|
|
204
|
+
- `read-json.ts` で JSON 仕様ファイルの `//` および `/* */` コメントをサポートするために使用
|
|
205
|
+
- `html-spec` パッケージは仕様ファイルの先頭に仕様 URL の参照としてコメントを使用
|
|
206
|
+
|
|
207
|
+
### cli-progress
|
|
208
|
+
|
|
209
|
+
- バージョン: 3.12.0
|
|
210
|
+
- フェッチ操作中のターミナルプログレスバーを提供
|
|
211
|
+
- `fetch.ts` でモジュール読み込み時に初期化
|
|
212
|
+
- `shades_grey` プリセットを使用
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Maintenance Guide
|
|
2
|
+
|
|
3
|
+
Practical operations and maintenance guide for `@markuplint/spec-generator`.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description |
|
|
8
|
+
| ----------------------------------------------------- | -------------------------------------------------------- |
|
|
9
|
+
| `yarn build --scope @markuplint/spec-generator` | Compile TypeScript to `lib/` |
|
|
10
|
+
| `yarn workspace @markuplint/spec-generator run dev` | Watch mode compilation |
|
|
11
|
+
| `yarn workspace @markuplint/spec-generator run clean` | Clean compiled output |
|
|
12
|
+
| `yarn up:gen` | Run spec generation (invokes this package via html-spec) |
|
|
13
|
+
|
|
14
|
+
**Note:** This package is not run directly. It is consumed by `@markuplint/html-spec/build.mjs`, which calls `main()`. Use `yarn up:gen` to trigger a full generation.
|
|
15
|
+
|
|
16
|
+
## Troubleshooting
|
|
17
|
+
|
|
18
|
+
### Scraping Failure Detection
|
|
19
|
+
|
|
20
|
+
After running `yarn up:gen`, always check the `index.json` diff:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git diff packages/@markuplint/html-spec/index.json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Signs of scraping failure:**
|
|
27
|
+
|
|
28
|
+
- The diff shows an extremely large amount of data loss (specification data disappears in bulk)
|
|
29
|
+
- Multiple elements suddenly have empty `description` fields
|
|
30
|
+
- Attributes that were previously present are removed
|
|
31
|
+
- ARIA role or property definitions are empty or significantly reduced
|
|
32
|
+
|
|
33
|
+
**This is almost certainly a scraping failure**, not an actual specification change. Legitimate spec changes are incremental and affect small numbers of elements.
|
|
34
|
+
|
|
35
|
+
**Root cause:** The referenced site (MDN or W3C) has changed its HTML structure, information layout, or element IDs/classes.
|
|
36
|
+
|
|
37
|
+
**Resolution:**
|
|
38
|
+
|
|
39
|
+
1. Identify which data is affected (element metadata, ARIA roles, SVG elements, etc.)
|
|
40
|
+
2. Determine the responsible module:
|
|
41
|
+
- Element descriptions, categories, attributes -- `scraping.ts`
|
|
42
|
+
- ARIA roles and properties -- `aria.ts`
|
|
43
|
+
- SVG deprecated elements -- `svg.ts`
|
|
44
|
+
3. Open the affected web page in a browser and inspect its current HTML structure
|
|
45
|
+
4. Update the CSS selectors in the module to match the new structure
|
|
46
|
+
5. Rebuild: `yarn build --scope @markuplint/spec-generator`
|
|
47
|
+
6. Regenerate: `yarn up:gen`
|
|
48
|
+
7. Verify the `index.json` diff is now correct
|
|
49
|
+
|
|
50
|
+
### Build Compilation Errors
|
|
51
|
+
|
|
52
|
+
If `yarn build --scope @markuplint/spec-generator` fails:
|
|
53
|
+
|
|
54
|
+
1. Check if `@markuplint/ml-spec` types have changed (this is the primary type provider)
|
|
55
|
+
2. Verify that dev dependencies are installed: `yarn install`
|
|
56
|
+
3. Try a clean build: `yarn workspace @markuplint/spec-generator run clean && yarn build --scope @markuplint/spec-generator`
|
|
57
|
+
|
|
58
|
+
### Network Errors During Generation
|
|
59
|
+
|
|
60
|
+
**Symptom:** `yarn up:gen` fails or hangs.
|
|
61
|
+
|
|
62
|
+
**Cause:** MDN or W3C servers are unreachable.
|
|
63
|
+
|
|
64
|
+
**Resolution:**
|
|
65
|
+
|
|
66
|
+
- Check network connectivity
|
|
67
|
+
- Failed fetches are cached as empty strings and the build continues
|
|
68
|
+
- The progress bar shows the current URL being fetched -- identify which domain is failing
|
|
69
|
+
- Retry later when the service is available
|
|
70
|
+
|
|
71
|
+
## Common Recipes
|
|
72
|
+
|
|
73
|
+
### 1. Fixing MDN Page Structure Changes
|
|
74
|
+
|
|
75
|
+
When MDN restructures their element reference pages, the CSS selectors in `scraping.ts` need updating.
|
|
76
|
+
|
|
77
|
+
1. Identify affected selectors by comparing the actual page HTML with the selectors in `scraping.ts`
|
|
78
|
+
2. Key selectors to check:
|
|
79
|
+
- `MAIN_ARTICLE_SELECTOR` (`main#content`) -- main content area
|
|
80
|
+
- `.reference-layout__header .content-section` -- description extraction
|
|
81
|
+
- `.bc-table tbody tr:first-child th` -- compatibility table
|
|
82
|
+
- `#technical_summary ~ figure.table-container > table` -- technical summary
|
|
83
|
+
- `.content-section[aria-labelledby="attributes"]` -- attribute sections
|
|
84
|
+
- Icon classes (`.ic-experimental`, `.ic-deprecated`, etc.) -- status flags
|
|
85
|
+
3. Update the selectors to match the new structure
|
|
86
|
+
4. Build: `yarn build --scope @markuplint/spec-generator`
|
|
87
|
+
5. Regenerate: `yarn up:gen`
|
|
88
|
+
6. Verify the diff shows correct data restoration
|
|
89
|
+
|
|
90
|
+
### 2. Adding a New ARIA Version
|
|
91
|
+
|
|
92
|
+
When a new ARIA specification version is published (e.g., 1.4):
|
|
93
|
+
|
|
94
|
+
1. Open `src/aria.ts`
|
|
95
|
+
2. Add a new case in `getARIASpecURLByVersion()`:
|
|
96
|
+
```typescript
|
|
97
|
+
case '1.4': {
|
|
98
|
+
if (!graphicsAria) {
|
|
99
|
+
return 'https://www.w3.org/TR/wai-aria-1.4/'; // or editor's draft URL
|
|
100
|
+
}
|
|
101
|
+
return 'https://w3c.github.io/graphics-aria/';
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
3. Add the new version to `getAria()`:
|
|
105
|
+
```typescript
|
|
106
|
+
const roles14 = await getRoles('1.4');
|
|
107
|
+
// ...
|
|
108
|
+
'1.4': {
|
|
109
|
+
roles: roles14,
|
|
110
|
+
props: await getProps('1.4', roles14),
|
|
111
|
+
graphicsRoles: await getRoles('1.4', true),
|
|
112
|
+
},
|
|
113
|
+
```
|
|
114
|
+
4. **Cross-package:** The `ARIAVersion` type in `@markuplint/ml-spec` must also be updated to include `'1.4'`
|
|
115
|
+
5. Build and regenerate
|
|
116
|
+
|
|
117
|
+
### 3. Adding Elements to the Obsolete List
|
|
118
|
+
|
|
119
|
+
To add a newly obsoleted HTML element:
|
|
120
|
+
|
|
121
|
+
1. Open `src/html-elements.ts`
|
|
122
|
+
2. Add the element name to the `obsoleteList` array
|
|
123
|
+
3. The element will automatically get a minimal spec stub with `obsolete: true`
|
|
124
|
+
4. Build: `yarn build --scope @markuplint/spec-generator`
|
|
125
|
+
5. Regenerate: `yarn up:gen`
|
|
126
|
+
6. Verify the element appears in `index.json` with `"obsolete": true`
|
|
127
|
+
|
|
128
|
+
### 4. Adapting to ExtendedSpec Type Changes
|
|
129
|
+
|
|
130
|
+
When `@markuplint/ml-spec` changes the `ExtendedSpec` or `ExtendedElementSpec` types:
|
|
131
|
+
|
|
132
|
+
1. Check which fields were added, removed, or modified
|
|
133
|
+
2. Update the assembly logic in `src/index.ts` (the `json` object)
|
|
134
|
+
3. Update scraping modules if new fields need to be populated from external data
|
|
135
|
+
4. Build and regenerate to verify
|
|
136
|
+
|
|
137
|
+
### 5. Updating cheerio Major Versions
|
|
138
|
+
|
|
139
|
+
The `cheerio` package provides the DOM API used for scraping. When updating:
|
|
140
|
+
|
|
141
|
+
1. Check the cheerio changelog for breaking API changes
|
|
142
|
+
2. Key APIs used: `.find()`, `.text()`, `.attr()`, `.toArray()`, `.each()`, `.next()`, `.prev()`, `.parent()`, `.children()`, `.before()`, `.remove()`, `.clone()`, `.append()`, `.filter()`, `.siblings()`, `.prop()`
|
|
143
|
+
3. Also check `cheerio.load()` (used in `fetch.ts`)
|
|
144
|
+
4. Update selectors if the HTML parsing behavior changed
|
|
145
|
+
5. Build and regenerate to verify
|
|
146
|
+
|
|
147
|
+
## Debugging
|
|
148
|
+
|
|
149
|
+
### Checking Individual Element Scraping Results
|
|
150
|
+
|
|
151
|
+
To debug what data is being scraped for a specific element:
|
|
152
|
+
|
|
153
|
+
1. Add temporary logging in `scraping.ts` after the `fetchHTMLElement()` call:
|
|
154
|
+
```typescript
|
|
155
|
+
const mdnData = await fetchHTMLElement(cite);
|
|
156
|
+
if (localName === 'your-element') {
|
|
157
|
+
console.log(JSON.stringify(mdnData, null, 2));
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
2. Rebuild and run `yarn up:gen`
|
|
161
|
+
3. Check the console output for the scraped data
|
|
162
|
+
4. Remove the temporary logging after debugging
|
|
163
|
+
|
|
164
|
+
### Inspecting Cached Fetch Results
|
|
165
|
+
|
|
166
|
+
The `cache` Map in `fetch.ts` stores all raw HTML responses. To inspect what was fetched for a specific URL:
|
|
167
|
+
|
|
168
|
+
1. Add temporary logging in `fetchText()`:
|
|
169
|
+
```typescript
|
|
170
|
+
if (url.includes('your-search-term')) {
|
|
171
|
+
console.log(`Fetched ${url}: ${text.length} chars`);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
2. A length of 0 indicates a fetch failure (empty string cached)
|
|
175
|
+
|
|
176
|
+
### Verifying ARIA Role Scraping
|
|
177
|
+
|
|
178
|
+
To check which roles were extracted from a specific ARIA version:
|
|
179
|
+
|
|
180
|
+
1. Add temporary logging after `getRoles()` in `getAria()`:
|
|
181
|
+
```typescript
|
|
182
|
+
const roles13 = await getRoles('1.3');
|
|
183
|
+
console.log(`ARIA 1.3 roles: ${roles13.map(r => r.name).join(', ')}`);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Dependency Notes
|
|
187
|
+
|
|
188
|
+
### cheerio
|
|
189
|
+
|
|
190
|
+
- Version: 1.1.2
|
|
191
|
+
- Provides jQuery-like DOM API for parsed HTML
|
|
192
|
+
- Used throughout `scraping.ts`, `aria.ts`, `svg.ts`, and `fetch.ts`
|
|
193
|
+
- The `CheerioAPI` type is imported from `cheerio`, and `Element` from `domhandler` (cheerio's underlying DOM library)
|
|
194
|
+
|
|
195
|
+
### fast-xml-parser
|
|
196
|
+
|
|
197
|
+
- Version: 5.3.4
|
|
198
|
+
- Listed as a dependency but not currently imported by any source module
|
|
199
|
+
- May be reserved for future XML parsing needs
|
|
200
|
+
|
|
201
|
+
### strip-json-comments
|
|
202
|
+
|
|
203
|
+
- Version: 5.0.3
|
|
204
|
+
- Used in `read-json.ts` to support `//` and `/* */` comments in JSON spec files
|
|
205
|
+
- The `html-spec` package uses comments at the top of spec files for spec URL references
|
|
206
|
+
|
|
207
|
+
### cli-progress
|
|
208
|
+
|
|
209
|
+
- Version: 3.12.0
|
|
210
|
+
- Provides the terminal progress bar during fetch operations
|
|
211
|
+
- Initialized at module load time in `fetch.ts`
|
|
212
|
+
- Uses the `shades_grey` preset
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# モジュールリファレンス
|
|
2
|
+
|
|
3
|
+
`@markuplint/spec-generator` の各ソースモジュールの詳細ドキュメント。
|
|
4
|
+
|
|
5
|
+
## index.ts
|
|
6
|
+
|
|
7
|
+
メインオーケストレータ。`@markuplint/html-spec/build.mjs` が消費する公開 API をエクスポートします。
|
|
8
|
+
|
|
9
|
+
### `main(options: Options): Promise<void>`
|
|
10
|
+
|
|
11
|
+
3つの並列データ収集タスクを調整し、結果を `ExtendedSpec` オブジェクトに組み立て、JSON として書き込みます。
|
|
12
|
+
|
|
13
|
+
**フロー:**
|
|
14
|
+
|
|
15
|
+
1. `Promise.all` で3つのタスクを同時実行:
|
|
16
|
+
- `getElements(htmlFilePattern)` -- 要素仕様
|
|
17
|
+
- `getGlobalAttrs(commonAttrsFilePath)` -- グローバル属性定義
|
|
18
|
+
- `getAria()` -- ARIA 定義
|
|
19
|
+
2. `getReferences()` でフェッチした全 URL を収集
|
|
20
|
+
3. `readJson(commonContentsFilePath).models` でコンテンツモデルを読み込み
|
|
21
|
+
4. `ExtendedSpec` オブジェクトを組み立て:
|
|
22
|
+
```typescript
|
|
23
|
+
{
|
|
24
|
+
cites: string[], // ソート済み URL リスト
|
|
25
|
+
def: {
|
|
26
|
+
"#globalAttrs": { ... }, // グローバル属性カテゴリ
|
|
27
|
+
"#aria": { ... }, // バージョンごとの ARIA データ
|
|
28
|
+
"#contentModels": { ... } // コンテンツモデルカテゴリ
|
|
29
|
+
},
|
|
30
|
+
specs: ExtendedElementSpec[] // 要素仕様
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
5. JSON を `outputFilePath` に書き込み
|
|
34
|
+
|
|
35
|
+
### `Options` 型
|
|
36
|
+
|
|
37
|
+
| フィールド | 型 | 説明 |
|
|
38
|
+
| ------------------------ | -------- | -------------------------------------------- |
|
|
39
|
+
| `outputFilePath` | `string` | 生成 JSON の書き込み先の絶対パス |
|
|
40
|
+
| `htmlFilePattern` | `string` | 要素ごとの JSON ファイルの絶対 glob パターン |
|
|
41
|
+
| `commonAttrsFilePath` | `string` | グローバル属性 JSON の絶対パス |
|
|
42
|
+
| `commonContentsFilePath` | `string` | コンテンツモデル JSON の絶対パス |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## html-elements.ts
|
|
47
|
+
|
|
48
|
+
HTML および SVG 要素仕様の完全なリストを構築します。
|
|
49
|
+
|
|
50
|
+
### `getElements(filePattern: string): Promise<ExtendedElementSpec[]>`
|
|
51
|
+
|
|
52
|
+
**フロー:**
|
|
53
|
+
|
|
54
|
+
1. `readJsons()` で glob パターンにマッチする全仕様ファイルを読み込み。要素名は正規表現 `spec.([\w-]+).json` でファイル名から抽出(例: `spec.a.json` → `a`)
|
|
55
|
+
2. `getSVGElementList()` で非推奨 SVG 要素リストを取得
|
|
56
|
+
3. `fetchObsoleteElements()` で既存の仕様にない非推奨要素のスタブを生成
|
|
57
|
+
4. 各要素について MDN URL を構築し、`fetchHTMLElement()` でメタデータをスクレイピング:
|
|
58
|
+
- 見出し要素(`h1`-`h6`)は MDN パス `Heading_Elements` にマッピング
|
|
59
|
+
- SVG 要素は `/Web/SVG/Reference/Element/<name>` パスを使用
|
|
60
|
+
- HTML 要素は `/Web/HTML/Reference/Elements/<name>` パスを使用
|
|
61
|
+
5. スクレイピングデータとローカル仕様データをマージ。**ローカル仕様データが優先**:
|
|
62
|
+
- `cite` -- ローカル値があればそちらを使用、なければ MDN URL
|
|
63
|
+
- `description`, `categories`, `omission` -- MDN から
|
|
64
|
+
- `contentModel`, `aria` -- ローカル仕様のみ(スクレイピングされない)
|
|
65
|
+
- `attributes` -- 属性名ごとにマージ; ローカルエントリが MDN エントリをオーバーライド
|
|
66
|
+
6. アルファベット順にソートし、SVG 要素を HTML 要素の後に配置
|
|
67
|
+
|
|
68
|
+
### `obsoleteList`
|
|
69
|
+
|
|
70
|
+
31個の非適合 HTML 要素のハードコードリスト:
|
|
71
|
+
|
|
72
|
+
`applet`, `acronym`, `bgsound`, `dir`, `frame`, `frameset`, `noframes`, `isindex`, `keygen`, `listing`, `menuitem`, `nextid`, `noembed`, `param`, `plaintext`, `rb`, `rtc`, `strike`, `xmp`, `basefont`, `big`, `blink`, `center`, `font`, `marquee`, `multicol`, `nobr`, `spacer`, `tt`
|
|
73
|
+
|
|
74
|
+
MDN から取得した非推奨 SVG 要素と組み合わせて、完全な非推奨セットを構成します。
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## scraping.ts
|
|
79
|
+
|
|
80
|
+
MDN 要素リファレンスページからメタデータをスクレイピングします。CSS セレクタと脆弱ポイントの詳細は[スクレイピング詳細](scraping.ja.md)を参照。
|
|
81
|
+
|
|
82
|
+
### `fetchHTMLElement(link: string): Promise<ExtendedElementSpec>`
|
|
83
|
+
|
|
84
|
+
単一の MDN 要素ページをスクレイピングし、以下を含む要素仕様オブジェクトを返します:
|
|
85
|
+
|
|
86
|
+
- `description` -- `.reference-layout__header .content-section` から
|
|
87
|
+
- 互換性フラグ(`experimental`, `obsolete`, `deprecated`, `nonStandard`)-- ブラウザ互換性テーブルまたはフォールバックインジケータから
|
|
88
|
+
- `categories` -- 技術サマリテーブルの「Content categories」行をパース
|
|
89
|
+
- `attributes` -- `aria-labelledby` ID で識別されるセクションの定義リストから: `attributes`, `deprecated_attributes`, `individual_attributes`, `non-standard_attributes`, `obsolete_attributes`
|
|
90
|
+
|
|
91
|
+
### `fetchObsoleteElements(obsoleteList, specs): ExtendedElementSpec[]`
|
|
92
|
+
|
|
93
|
+
既存の仕様配列に存在しない非推奨要素の最小限のスタブを生成。各スタブは:
|
|
94
|
+
|
|
95
|
+
- `cite` は HTML 仕様の非推奨機能セクションを指す
|
|
96
|
+
- `obsolete: true`
|
|
97
|
+
- `contents: true`(任意のコンテンツ許可)
|
|
98
|
+
- `permittedRoles: true`, `implicitRole: false`
|
|
99
|
+
|
|
100
|
+
### プライベートヘルパー
|
|
101
|
+
|
|
102
|
+
- `getProperty($, prop)` -- MDN 技術サマリテーブル(`#technical_summary ~ figure.table-container > table`)から値を抽出
|
|
103
|
+
- `getAttributes($, id)` -- `.content-section[aria-labelledby="<id>"]` セクションの `<dt>`/`<dd>` ペアをパース
|
|
104
|
+
- `getItsHeading($start)` -- DOM を上方にたどって最も近い先行見出しを検索
|
|
105
|
+
- `upToPrevOrParent($start)` -- 前の兄弟要素またはに移動
|
|
106
|
+
- `isHeading($el)` -- 要素が `<h1>` から `<h6>` かどうかをテスト
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## aria.ts
|
|
111
|
+
|
|
112
|
+
W3C ARIA 仕様からロールとプロパティの定義をスクレイピングします。URL パターンとセレクタの詳細は[スクレイピング詳細](scraping.ja.md)を参照。
|
|
113
|
+
|
|
114
|
+
### `getAria(): Promise<Record<ARIAVersion, { roles, props, graphicsRoles }>>`
|
|
115
|
+
|
|
116
|
+
サポートされている3つのバージョンすべての ARIA データを返します。各バージョンについて:
|
|
117
|
+
|
|
118
|
+
1. `getRoles(version)` でロールを取得
|
|
119
|
+
2. `getProps(version, roles)` でプロパティ/ステートを取得
|
|
120
|
+
3. `getRoles(version, true)` でグラフィックス ARIA ロールを取得
|
|
121
|
+
|
|
122
|
+
**実行順序:** バージョンは順次処理されます(1.3 → 1.2 → 1.1)。各バージョン内では、プロパティの前にロールを取得する必要があります(プロパティはロールの `ownedProperties` から検出されるため)。
|
|
123
|
+
|
|
124
|
+
### URL マッピング
|
|
125
|
+
|
|
126
|
+
| バージョン | ARIA 仕様 URL | Graphics ARIA URL |
|
|
127
|
+
| ---------- | ------------------------------------- | ------------------------------------------ |
|
|
128
|
+
| 1.1 | `https://www.w3.org/TR/wai-aria-1.1/` | `https://www.w3.org/TR/graphics-aria-1.0/` |
|
|
129
|
+
| 1.2 | `https://www.w3.org/TR/wai-aria-1.2/` | `https://w3c.github.io/graphics-aria/` |
|
|
130
|
+
| 1.3 | `https://w3c.github.io/aria/` | `https://w3c.github.io/graphics-aria/` |
|
|
131
|
+
|
|
132
|
+
### プライベート関数
|
|
133
|
+
|
|
134
|
+
- `getRoles(version, graphicsAria?)` -- `#role_definitions section.role` 要素をスクレイピング。抽出内容: name, description, generalization, owned properties(required/inherited/general), required context roles, required owned elements, accessible name 設定, children presentational フラグ, prohibited properties。ロールの同義語を処理(`none`/`presentation`, `image`/`img`)
|
|
135
|
+
- `getProps(version, roles)` -- 全ロールの `ownedProperties` からプロパティリストを構築し、各プロパティのセクションをスクレイピング: type(property/state), value type, enum values, default value, global フラグ, 同等の HTML 属性。`aria-checked` と `aria-hidden` の条件付き値オーバーライドを適用
|
|
136
|
+
- `getAriaInHtml()` -- `https://www.w3.org/TR/html-aria/` から HTML 属性と ARIA プロパティのマッピングテーブルをスクレイピング。`contenteditable` はスキップ(祖先の評価が必要なため)
|
|
137
|
+
- `$$(el, selectors)` -- 複数の CSS セレクタを試し、最初の非空マッチを返す
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## fetch.ts
|
|
142
|
+
|
|
143
|
+
キャッシュとプログレス表示付きの HTTP フェッチレイヤー。
|
|
144
|
+
|
|
145
|
+
### キャッシュ
|
|
146
|
+
|
|
147
|
+
2つのインメモリ `Map` キャッシュ:
|
|
148
|
+
|
|
149
|
+
| キャッシュ | キー | 値 | 目的 |
|
|
150
|
+
| ---------- | ---- | ------------------------- | --------------------------- |
|
|
151
|
+
| `cache` | URL | 生の HTML 文字列 | 同じ URL の再フェッチを回避 |
|
|
152
|
+
| `domCache` | URL | `CheerioAPI` インスタンス | 同じ HTML の再パースを回避 |
|
|
153
|
+
|
|
154
|
+
キャッシュはプロセススコープです。ビルド間での永続化はありません。
|
|
155
|
+
|
|
156
|
+
### `fetch(url: string): Promise<CheerioAPI>`
|
|
157
|
+
|
|
158
|
+
パース済みの Cheerio DOM インスタンスを返します。まず `domCache` を確認し、なければ `fetchText()` に委譲して生の HTML を取得します。
|
|
159
|
+
|
|
160
|
+
### `fetchText(url: string): Promise<string>`
|
|
161
|
+
|
|
162
|
+
`globalThis.fetch()` を使用して URL の生テキストコンテンツを取得します。失敗時(例外発生時)は空文字列をキャッシュして返します。各呼び出しで CLI プログレスバーを更新します。
|
|
163
|
+
|
|
164
|
+
### `getReferences(): string[]`
|
|
165
|
+
|
|
166
|
+
プログレスバーを終了し、フェッチした全 URL のソート済みリストを返します。全スクレイピング完了後に一度だけ呼び出されます。
|
|
167
|
+
|
|
168
|
+
### プログレスバー
|
|
169
|
+
|
|
170
|
+
`cli-progress` の `shades_grey` プリセットを使用。モジュール読み込み時にバーが開始され、各フェッチ呼び出しで更新されます。フォーマット:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
🔎 Fetch references... ████░░░░ 45% | ETA: 30s | 90/200 🔗 https://develo...ments/div
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## read-json.ts
|
|
179
|
+
|
|
180
|
+
コメントサポート付き JSON ファイル読み込み。
|
|
181
|
+
|
|
182
|
+
### `readJson<T>(filePath: string): T`
|
|
183
|
+
|
|
184
|
+
単一の JSON ファイルを読み込みます。`strip-json-comments` を使用してパース前に `//` および `/* */` コメントを除去します。パスが絶対パスでない場合はエラーをスローします。
|
|
185
|
+
|
|
186
|
+
### `readJsons<T>(pattern: string, hook?): Promise<T[]>`
|
|
187
|
+
|
|
188
|
+
絶対 glob パターンにマッチする全 JSON ファイルを読み込みます。オプションで `hook` 関数により各結果を変換可能(ファイル名とパース済みボディを受け取る)。全ファイルを `Promise.all` で並列読み込みします。
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## global-attrs.ts
|
|
193
|
+
|
|
194
|
+
### `getGlobalAttrs(filePath: string): SpecDefs["#globalAttrs"]`
|
|
195
|
+
|
|
196
|
+
`readJson()` の薄いラッパーで、指定された JSON ファイルからグローバル属性定義を読み込んで返します。
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## svg.ts
|
|
201
|
+
|
|
202
|
+
### `getSVGElementList(): Promise<string[]>`
|
|
203
|
+
|
|
204
|
+
MDN SVG 要素インデックスページ(`https://developer.mozilla.org/en-US/docs/Web/SVG/Element`)をフェッチし、「Obsolete and deprecated elements」セクションから非推奨/廃止 SVG 要素名を抽出します。
|
|
205
|
+
|
|
206
|
+
**処理:**
|
|
207
|
+
|
|
208
|
+
1. すべての `<section>` ラッパーをアンラップ(子要素で置換)
|
|
209
|
+
2. `#obsolete_and_deprecated_elements` 見出しを検索
|
|
210
|
+
3. `getThisOutline()` で次の `<h2>` まで兄弟要素を収集
|
|
211
|
+
4. `<a>` タグから要素名を抽出し、`svg_` プレフィックスを付加
|
|
212
|
+
|
|
213
|
+
`["svg_altGlyph", "svg_altGlyphDef", ...]` のような名前を返します。
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## utils.ts
|
|
218
|
+
|
|
219
|
+
複数のモジュールで使用される共有ヘルパー関数。
|
|
220
|
+
|
|
221
|
+
### `nameCompare(a, b): number`
|
|
222
|
+
|
|
223
|
+
`name` プロパティ(または文字列値)による大文字小文字を区別しない比較。コードベース全体でソートのコンパレータとして使用。
|
|
224
|
+
|
|
225
|
+
### `sortObjectByKey<T>(o: T): T`
|
|
226
|
+
|
|
227
|
+
同じキーバリューペアを持つ新しいオブジェクトを、キーのアルファベット順(`nameCompare` 使用)でソートして返します。
|
|
228
|
+
|
|
229
|
+
### `arrayUnique<T extends { name: string }>(array: T[]): T[]`
|
|
230
|
+
|
|
231
|
+
`name` プロパティに基づいて重複項目を除去し、最初の出現のみを保持します。
|
|
232
|
+
|
|
233
|
+
### `getThisOutline($, $start): Cheerio<Element>`
|
|
234
|
+
|
|
235
|
+
`$start` の後の全兄弟要素を次の `<h2>` 見出しまで収集し、コンテナ `<div>` でラップします。`svg.ts` で見出しで定義されたセクションのコンテンツを抽出するために使用。
|
|
236
|
+
|
|
237
|
+
### `mergeAttributes<T>(fromDocs: T, fromJSON: T): T`
|
|
238
|
+
|
|
239
|
+
2つの属性オブジェクトを浅くマージし、`fromJSON` の値を優先します。
|
|
240
|
+
|
|
241
|
+
### `keys<T, K>(object: T): K[]`
|
|
242
|
+
|
|
243
|
+
カスタム型キャスト付きの `Object.keys()` を返します。
|
|
244
|
+
|
|
245
|
+
### `getName(origin: string): { localName, namespace?, ml }`
|
|
246
|
+
|
|
247
|
+
要素名文字列をパース:
|
|
248
|
+
|
|
249
|
+
| 入力 | `localName` | `namespace` | `ml` |
|
|
250
|
+
| -------------- | ----------- | ------------------------------ | -------- |
|
|
251
|
+
| `"div"` | `"div"` | `undefined` | `"HTML"` |
|
|
252
|
+
| `"svg_circle"` | `"circle"` | `"http://www.w3.org/2000/svg"` | `"SVG"` |
|