@shibayama/pdgkit 0.1.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/docs/spec.md ADDED
@@ -0,0 +1,592 @@
1
+ # PatentDSL / pdgkit 仕様書
2
+
3
+ 特許図面のための記述言語 **PatentDSL**(ファイル拡張子 `.pdg`)と、その実装エンジン **pdgkit** の仕様。`.pdg` は Patent Diagram Grammar の略である。
4
+
5
+ - 対象バージョン: pdgkit v0.1.0(DSL は PatentDSL v1.0.3 と完全互換)
6
+ - npm パッケージ: `@shibayama/pdgkit`(CLI コマンドは `pdgkit` / `pdgkit-mcp`)
7
+ - 拡張子: `.pdg`
8
+ - エンコーディング: UTF-8
9
+ - 改行: `LF` / `CRLF` のいずれも可
10
+
11
+ 本書は **言語仕様(§1–§12)** と **エンジン仕様(§13–§17)** の二部構成です。言語仕様は PatentDSL 本家と同一の挙動を、エンジン仕様は pdgkit 固有のヘッドレス描画・検証・CLI を規定します。
12
+
13
+ ---
14
+
15
+ ## 目次
16
+
17
+ **言語仕様**
18
+ 1. [設計原則](#1-設計原則)
19
+ 2. [字句](#2-字句)
20
+ 3. [文要素](#3-文要素)
21
+ 4. [ラベルと多言語](#4-ラベルと多言語)
22
+ 5. [コメント](#5-コメント)
23
+ 6. [クォート / エスケープ](#6-クォート--エスケープ)
24
+ 7. [図種の自動推論](#7-図種の自動推論)
25
+ 8. [形状の自動推論](#8-形状の自動推論)
26
+ 9. [描画・レイアウト方針](#9-描画レイアウト方針)
27
+ 10. [診断(エラー / 警告)](#10-診断エラー--警告)
28
+ 11. [BNF 風文法](#11-bnf-風文法)
29
+ 12. [仕様の境界(やらないこと)](#12-仕様の境界やらないこと)
30
+
31
+ **エンジン仕様(pdgkit 固有)**
32
+ 13. [図種アサーション・ディレクティブ](#13-図種アサーションディレクティブ)
33
+ 14. [`validate()` の診断](#14-validate-の診断)
34
+ 15. [ヘッドレス描画の寸法計算](#15-ヘッドレス描画の寸法計算)
35
+ 16. [CLI の入出力と終了コード](#16-cli-の入出力と終了コード)
36
+ 17. [出力仕様](#17-出力仕様)
37
+
38
+ ---
39
+
40
+ # 言語仕様
41
+
42
+ ## 1. 設計原則
43
+
44
+ - **1 行 = 1 文。** 改行が文の終わり。
45
+ - 文要素は **定義 / 包含 / 接続** の 3 種類のみ。
46
+ - **キーワードを持たない。** 図種は構造から自動推論される。
47
+ - 符号(reference numerals)を直接 ID として扱う。明細書本文と直接照合できる。
48
+ - 日英ラベルを 1 ソースで管理する。
49
+ - 座標指定・色指定を持たない。レイアウトは自動のみ。
50
+
51
+ ---
52
+
53
+ ## 2. 字句
54
+
55
+ ### 2.1 符号(ID)
56
+
57
+ 符号は次のパターン:
58
+
59
+ ```
60
+ ID := [A-Za-z0-9_*]+
61
+ ```
62
+
63
+ | 例 | 用途 |
64
+ |---|---|
65
+ | `10` `20` `100` | 装置クレームでよくある数値符号 |
66
+ | `S100` `S110` | 方法クレームのステップ符号 |
67
+ | `K1` `P2_3` `11a` | 英字+数字、`_` も可 |
68
+ | `*` | 状態遷移の初期/終端マーカ(黒丸で描画) |
69
+
70
+ ID に使えない記号(予約): `=` `:` `-` `>` `<` `.` `/` `#` `"` `(` `)` および空白。
71
+
72
+ ### 2.2 演算子(接続)
73
+
74
+ 接続演算子は **必ず前後を半角スペース(またはタブ)で囲む**。これは ID と演算子を曖昧さなく分離するための規則である(`11-12` は不可、`11 - 12` は可)。
75
+
76
+ 長い演算子から順にマッチする(`<->` を `<-` `->` より先に判定):
77
+
78
+ ```
79
+ OP := '<->' | '=>' | '->' | '<-' | '.>' | '..' | '-'
80
+ ```
81
+
82
+ ### 2.3 文字列リテラル
83
+
84
+ ダブルクォートで囲まれた任意の文字列。
85
+
86
+ ```
87
+ STRING := '"' (改行と '"' を除く任意の文字)* '"'
88
+ ```
89
+
90
+ 文字列内の `"` をエスケープする手段は現バージョン非対応(`\"` 等は未サポート)。
91
+
92
+ ### 2.4 空白・空行
93
+
94
+ 行内の連続する空白(スペース・タブ)は区切り。先頭/末尾の空白は無視。空行(空白のみの行を含む)は無視。
95
+
96
+ ---
97
+
98
+ ## 3. 文要素
99
+
100
+ 各行は(コメント除去後に)次の順で判定される:
101
+
102
+ 1. **定義パターン** にマッチ → 定義
103
+ 2. **接続パターン** にマッチ → 接続
104
+ 3. **包含パターン** にマッチ → 包含
105
+ 4. いずれにもマッチしない → `構文不明` エラー
106
+
107
+ > 実装注: 接続を包含より先に判定する。これにより `A -> B` は包含(`:` を含まない)ではなく接続として正しく解釈される。
108
+
109
+ ### 3.1 定義
110
+
111
+ ```
112
+ DEF := ID '=' LABEL
113
+ ```
114
+
115
+ 符号にラベルを付ける。
116
+
117
+ ```pdg
118
+ 10 = 制御装置 / control device
119
+ 11 = CPU
120
+ 13 = "I/O インターフェース" / "I/O interface"
121
+ 10 = # ラベルなし定義も可
122
+ ```
123
+
124
+ - `=` の前後の空白は任意。
125
+ - `=` の直後が `>` の場合は接続(`=>`)として扱う(否定先読み `=(?!>)`)。
126
+ - 同じ ID を 2 回定義すると **警告**(後の定義で上書き)。
127
+
128
+ ### 3.2 接続
129
+
130
+ ```
131
+ CONN := ID WS+ OP WS+ ID (WS* ':' WS* LABEL)?
132
+ ```
133
+
134
+ ノード間に線・矢印を描く。
135
+
136
+ ```pdg
137
+ 11 - 12 # 単線
138
+ 13 -> 20 # 矢印
139
+ 30 <- 40 # 逆矢印(= 40 -> 30)
140
+ 50 <-> 60 # 双方向
141
+ 70 .. 80 # 破線
142
+ 70 .> 80 # 破線矢印
143
+ 40 => 50 # 太矢印
144
+ 13 -> 20 : 信号 / signal # ラベル付き
145
+ ```
146
+
147
+ - 演算子の前後は **必ず半角スペース 1 つ以上**。
148
+ - `:` 以降がラベル(任意)。
149
+ - `<-` はパース時に from/to を入れ替えて `->` 相当に正規化される。
150
+ - 接続に登場した未定義 ID は **暗黙ノード** として自動生成される。
151
+ - **連鎖記法 `A -> B -> C` は未対応**(1 行 1 接続に分割)。
152
+
153
+ #### 演算子セマンティクス
154
+
155
+ | 演算子 | 線種 | 矢印 | 内部表現(`EdgeOp`) |
156
+ |---|---|---|---|
157
+ | `-` | 単線 | なし | `line` |
158
+ | `->` | 単線 | 終点 | `arrow` |
159
+ | `<-` | 単線 | 始点(正規化後は終点) | `arrow`(reverse) |
160
+ | `<->` | 単線 | 両端 | `bidir` |
161
+ | `..` | 破線 | なし | `dashed` |
162
+ | `.>` | 破線 | 終点 | `dashed-arrow` |
163
+ | `=>` | 太線 | 終点 | `thick` |
164
+
165
+ ### 3.3 包含
166
+
167
+ ```
168
+ CONT := ID WS* ':' WS+ ID (WS+ ID)*
169
+ ```
170
+
171
+ 親が子を内包する関係を表す。
172
+
173
+ ```pdg
174
+ 100 : 10 20
175
+ 10 : 11 12
176
+ 20 : 21 22
177
+ ```
178
+
179
+ - 子の符号は **半角スペース区切り**。子が 1 つでも可。
180
+ - ネストは別の包含文として書く(容器自身を別容器の子にする)。
181
+ - 子トークンが ID パターンに反する場合は `包含の子として不正なトークン` エラー。
182
+ - **包含文が 1 つでもあれば、図はブロック図**として描画される(§7)。
183
+
184
+ ---
185
+
186
+ ## 4. ラベルと多言語
187
+
188
+ ```
189
+ LABEL := SEGMENT (' / ' SEGMENT)?
190
+ SEGMENT := STRING | 生テキスト
191
+ ```
192
+
193
+ - ラベル中の **クォート外の空白付き ` / `**(前後に空白がある `/`)は **日英の区切り**。前=日本語、後=英語。
194
+ - `A/D`、`I/O`、`S/N` のように **語中の `/`** はラベル文字として扱う。
195
+ - クォート内の `/` `:` `=` `#` は文字として扱う。
196
+ - 片言語のみの場合、もう一方の言語モードでも同じ文字列で表示される。
197
+
198
+ | 入力 | 解釈 |
199
+ |---|---|
200
+ | `10 = 制御部 / control unit` | ja="制御部", en="control unit" |
201
+ | `11 = CPU` | ja="CPU"(両モードで CPU) |
202
+ | `13 = A/D変換部 / A/D converter` | ja="A/D変換部", en="A/D converter" |
203
+ | `14 = "I/O" / "I/O interface"` | ja="I/O", en="I/O interface" |
204
+ | `15 = "比率 1:2" / "ratio 1:2"` | ja="比率 1:2", en="ratio 1:2" |
205
+
206
+ 接続ラベル(`: ` 以降)も同じ規則に従う。
207
+
208
+ ---
209
+
210
+ ## 5. コメント
211
+
212
+ ```
213
+ COMMENT := '#' (改行以外)*
214
+ ```
215
+
216
+ - `#` から行末までは無視される。行頭・行中どこでも可。
217
+ - クォート内の `#` は文字として扱う。
218
+
219
+ ```pdg
220
+ # これはコメント行
221
+ 10 = 制御装置 # 行末コメントも可
222
+ 20 = "型番 #A100" / "Model #A100" # クォート内の # はリテラル
223
+ ```
224
+
225
+ > pdgkit はコメントの中に **図種アサーション・ディレクティブ**(§13)を置く。ディレクティブもパーサからは通常のコメントとして無視されるため、本家との互換を壊さない。
226
+
227
+ ---
228
+
229
+ ## 6. クォート / エスケープ
230
+
231
+ ラベルに予約記号(` / ` `:` `=` `#` `"`)を含めたい場合は `"..."` で囲む。語中の `/` はそのまま書ける。
232
+
233
+ | 入力 | ラベル |
234
+ |---|---|
235
+ | `13 = "I/O インターフェース"` | `I/O インターフェース` |
236
+ | `14 = "比率 1:2"` | `比率 1:2` |
237
+ | `16 = "y = ax + b"` | `y = ax + b` |
238
+
239
+ **制限**: クォート内の `"` のエスケープは未対応。
240
+
241
+ > pdgkit の SVG 出力では、ラベル中の `<` `>` `&` `"` は XML として正しくエスケープされる(§15)。DSL レベルのクォートとは別レイヤの処理である。
242
+
243
+ ---
244
+
245
+ ## 7. 図種の自動推論
246
+
247
+ ソース構造を見て **上から順に** 判定する(最初に該当した規則で確定):
248
+
249
+ ```
250
+ 1. 包含文(:)が 1 つ以上ある → ブロック図 (block)
251
+ 2. ラベル末尾が '?' の符号がある → フローチャート (flow)
252
+ 3. 符号 '*' が登場する → 状態遷移図 (state)
253
+ 4. '<->' 演算子、または往復ペア(A→B かつ B→A)がある → シーケンス図 (seq)
254
+ 5. 上記以外(片方向接続のみ) → フローチャート (flow)
255
+ ```
256
+
257
+ | ソース概略 | 判定 |
258
+ |---|---|
259
+ | `10 : 11 12` がある | block |
260
+ | `S110 = 条件?`(包含なし) | flow |
261
+ | `* -> S1`(包含・? なし) | state |
262
+ | `100 -> 200`, `200 -> 100`(往復) | seq |
263
+ | `100 <-> 200` | seq |
264
+ | `S100 -> S110`, `S110 -> S120`(片方向のみ) | flow |
265
+
266
+ > **重要(AI 向け):** 図種は宣言ではなく **構造の結果** である。意図せず `:` / `?` / `*` / `<->` を入れると図種が変わる。意図を固定したい場合は §13 の図種アサーションを使う。
267
+
268
+ ---
269
+
270
+ ## 8. 形状の自動推論
271
+
272
+ ### 8.1 フローチャート時
273
+
274
+ | 条件 | 形状 |
275
+ |---|---|
276
+ | ラベル末尾が `?` | ◆ 菱形(条件分岐) |
277
+ | 入次数 0 | ⬭ 角丸(開始) |
278
+ | 出次数 0 | ⬭ 角丸(終了) |
279
+ | それ以外 | □ 長方形(処理) |
280
+
281
+ ### 8.2 状態遷移図時
282
+
283
+ | 符号 | 形状 |
284
+ |---|---|
285
+ | `*` | ● 黒丸(初期/終端) |
286
+ | その他 | ⬭ 角丸長方形(状態) |
287
+
288
+ ### 8.3 ブロック図 / シーケンス図
289
+
290
+ - ブロック図: すべて □ 長方形(包含の親は枠付きコンテナ、子は内側の矩形)。
291
+ - シーケンス図: アクタは □ 長方形 + 下方向の破線ライフライン(自動表示)。
292
+
293
+ ---
294
+
295
+ ## 9. 描画・レイアウト方針
296
+
297
+ レイアウトは自動のみ。特許のブロック図で典型的な「機能ラベル付きの中空矩形を線で相互接続する」形式を優先する。
298
+
299
+ ### 9.1 ブロック図
300
+
301
+ - 子が 1〜2 個の包含は縦 1 列。
302
+ - 子が 3 個以上で子同士が直列の処理チェーンを作る場合は縦 1 列。
303
+ - 子が 3 個以上で分岐/並列/スター状の接続の場合は 2〜4 列グリッド寄り。
304
+ - グリッド配置では行ごとの高さを用いる(縦長要素が他行を引き伸ばさない)。
305
+ - 入れ子コンテナは外側から内側へ描画。
306
+ - 同一親コンテナ内の接続は親の外へ逃がさず、内側の余白通路を優先。
307
+ - 外部ブロックは接続先の内部ブロックに近い高さへ自動整列。
308
+ - 外部接続は可視ブロックを横切らない経路を優先。上下に明確にずれる場合は上辺/下辺への接続を優先。
309
+ - 接続ラベルはノード・コンテナのタイトル領域・外枠・既存ラベルとの重なりを避け、長い空き区間や線から少し離した位置を優先。
310
+
311
+ ### 9.2 ブロック図の配線
312
+
313
+ 接続線は **直交線による配線問題** として扱う。単純な最短経路ではなく、禁止領域とペナルティを持つ評価で経路を決定する:
314
+
315
+ - 実ノード内部を横切らない。
316
+ - 外部接続先コンテナは外枠で接続し、内部を通過しない。
317
+ - 矢印付き接続は終端直前に鏃を描ける直線区間を確保し、線本体は鏃の手前で止める。
318
+ - 既存の矢印鏃・主要線分を後続線の障害物として扱う(候補不足時も強い減点として残す)。
319
+ - 同一ノードから複数線が出る場合、接続点と短いスタブを分散する。
320
+ - 端点から大きく離れた迂回には減点。候補レーン数に上限(密な図でも探索量を抑制)。
321
+
322
+ ### 9.3 フローチャート / 状態遷移図
323
+
324
+ - 接続関係から BFS でランクを計算し、上から下へ配置。
325
+ - 循環は最初に到達したランクを優先(first-touch wins)し、接続自体は描画。
326
+ - 未接続ノードは下方へ追加配置。
327
+
328
+ ### 9.4 シーケンス図
329
+
330
+ - アクタは接続に登場した順に左から配置。
331
+ - メッセージはソースの行順に上から下へ配置。
332
+ - ライフラインは破線で描画(矢印マーカなし)。
333
+
334
+ ---
335
+
336
+ ## 10. 診断(エラー / 警告)
337
+
338
+ パーサは次の診断を発する(`Diagnostic { severity, line, col, message }`)。
339
+
340
+ | 重大度 | 例 | 意味 |
341
+ |---|---|---|
342
+ | error | `構文不明: "10 == X"` | いずれの文型にもマッチしない行 |
343
+ | error | `包含の子として不正なトークン: "1@1"` | 包含の子が ID パターンに反する |
344
+ | warning | `符号 "10" は再定義されました` | 同一 ID の重複定義(後勝ち) |
345
+
346
+ **エラーがあっても可能な範囲で描画は続行される**(堅牢性優先)。接続・包含だけに現れた未定義符号は暗黙ノードとして自動生成され、符号表では薄色で表示される。
347
+
348
+ pdgkit はこれらに加えて §13・§14 の診断を付与する。
349
+
350
+ ---
351
+
352
+ ## 11. BNF 風文法
353
+
354
+ ```ebnf
355
+ document = { line } ;
356
+ line = blank | comment | def_line | conn_line | cont_line ;
357
+
358
+ blank = WS* CR ;
359
+ comment = '#' (~CR)* CR ;
360
+
361
+ def_line = id WS* '=' (?!'>') WS* label CR ;
362
+ conn_line = id WS+ op WS+ id (WS* ':' WS* label)? CR ;
363
+ cont_line = id WS* ':' WS+ id { WS+ id } WS* CR ;
364
+
365
+ op = '<->' | '=>' | '->' | '<-' | '.>' | '..' | '-' ;
366
+
367
+ id = ID_CHAR+ ;
368
+ ID_CHAR = 'A'..'Z' | 'a'..'z' | '0'..'9' | '_' | '*' ;
369
+
370
+ label = segment (WS+ '/' WS+ segment)? ;
371
+ segment = string | raw_text ;
372
+ string = '"' (~'"' & ~CR)* '"' ;
373
+ raw_text = (~'#' & ~CR)+ ;
374
+
375
+ WS = ' ' | '\t' ;
376
+ CR = '\n' | '\r' '\n' ;
377
+ ```
378
+
379
+ > 注: `def_line` で `=` の直後が `>` の場合は否定先読みで除外する(`=>` は演算子)。判定順は §3 のとおり 定義 → 接続 → 包含。
380
+
381
+ ---
382
+
383
+ ## 12. 仕様の境界(やらないこと)
384
+
385
+ - 連鎖記法 `A -> B -> C`(各行に分ける)
386
+ - 1 ファイル複数図(1 図 1 ファイル)
387
+ - 任意 SVG の埋め込み・カスタム形状定義
388
+ - 色指定・スタイル指定(特許図面の慣習で黒線のみ)
389
+ - 自由な座標指定(レイアウトは自動のみ)
390
+ - セル / レーン(swimlane)
391
+ - alt / loop / parallel のシーケンス拡張
392
+ - カスタムフォント・配色テーマ
393
+
394
+ これらは記法を読みやすく保つため意図的に外している。
395
+
396
+ ---
397
+
398
+ # エンジン仕様(pdgkit 固有)
399
+
400
+ ## 13. 図種アサーション・ディレクティブ
401
+
402
+ 意図する図種をソース内に宣言し、`validate()`(§14)が推論結果(§7)と照合する仕組み。**コメント内に置く**ため、パーサからは通常コメントとして無視され、本家互換を壊さない。
403
+
404
+ ### 13.1 構文
405
+
406
+ コメント本文(最初の非クォート `#` 以降)が次の正規表現にマッチする最初の行を採用する:
407
+
408
+ ```
409
+ /^\s*!?\s*(?:pdgkit\s*:)?\s*kind\s*[:=]?\s*(block|flow|state|seq)\b/i
410
+ ```
411
+
412
+ 受理される表記例(いずれも同義):
413
+
414
+ ```pdg
415
+ #! kind: block # 正準形(推奨)
416
+ # pdgkit: kind = flow
417
+ # kind seq
418
+ #kind state
419
+ ```
420
+
421
+ ### 13.2 セマンティクス
422
+
423
+ - 宣言された図種が推論図種と **一致** → 問題なし(`kindMatches = true`)。
424
+ - **不一致** → `error` 重大度の診断を 1 件発する。メッセージは宣言・推論の双方と、見直すべき構造目印(`:` / 末尾 `?` / `*` / 往復・`<->`)を含む。
425
+ - 宣言が **ない** → アサーションは行わない(`declaredKind = null`, `kindMatches = null`)。
426
+
427
+ ```pdg
428
+ #! kind: block
429
+ S1 = 条件? # ← ? によりフローと推論され、宣言 block と不一致 → エラー
430
+ S2 = 次
431
+ S1 -> S2
432
+ ```
433
+
434
+ ---
435
+
436
+ ## 14. `validate()` の診断
437
+
438
+ `validate(source) → ValidateResult` は、§10 のパーサ診断に次を加えて返す。
439
+
440
+ ```ts
441
+ interface ValidateResult {
442
+ ok: boolean; // error 重大度が 0 件
443
+ kind: DiagramKind; // 推論図種
444
+ declaredKind: DiagramKind | null; // §13 の宣言
445
+ kindMatches: boolean | null;
446
+ diagnostics: Diagnostic[]; // 行・列順にソート
447
+ counts: { errors; warnings; infos };
448
+ }
449
+ ```
450
+
451
+ 付与される pdgkit 独自診断:
452
+
453
+ | 重大度 | 契機 | メッセージ要旨 |
454
+ |---|---|---|
455
+ | error | 図種アサーション不一致(§13) | 宣言と推論の図種が違う |
456
+ | info | `構文不明` 行に空白付き演算子が 2 つ以上 | 連鎖記法は未対応。1 行 1 接続に分割 |
457
+ | info | `構文不明` 行に演算子が ID に密着 | 演算子の前後に半角スペースが必要 |
458
+
459
+ `info` は助言であり `ok` を偽にしない。`ok` を偽にするのは `error` のみ(`warning` も `ok` を偽にしない)。
460
+
461
+ > 推奨運用: ホスト AI は `ok === false` の間、`diagnostics` を AI に返して `.pdg` を再生成させる。`info` も併せて渡すと修正精度が上がる。
462
+
463
+ ---
464
+
465
+ ## 15. ヘッドレス描画の寸法計算
466
+
467
+ `renderToSvg(source, options)` は `parse → layout → render → 切り出し → シリアライズ` を行う。ブラウザ版の `SVG` 書き出し(`exportSvgFile`)と同じ数値で出力する。
468
+
469
+ ### 15.1 コンテンツボックス(切り出し)
470
+
471
+ - ブラウザ版は `element.getBBox()` で実描画範囲を求めるが、これはブラウザ専用 API である。
472
+ - pdgkit は生成済み SVG モデルを走査し、各プリミティブ(`rect` / `circle` / `polygon` / `path`(M・L のみ)/ `text` / `line` / `polyline`)の範囲を **解析的に** 合算する。`text` の幅は `layout` と同一の文字幅 heuristic(`estimateTextWidth`)を用いる:
473
+
474
+ ```
475
+ 幅(文字) = 空白 → fontSize*0.35 / ASCII → fontSize*0.58 / それ以外(CJK 等) → fontSize*1.0
476
+ ```
477
+
478
+ - 合算結果に **余白 `bleed`(既定 3 単位)** を付ける(本家 `RASTER_BLEED` と一致)。
479
+
480
+ ### 15.2 表示寸法
481
+
482
+ 切り出した viewBox に対し、`width` / `height`(px)を次で定める(本家 `svgDisplayDimensionsForViewBox` と一致):
483
+
484
+ ```
485
+ scale = max(1, targetSide / max(viewBox.width, viewBox.height)) // targetSide 既定 1600
486
+ width = ceil(viewBox.width * scale)
487
+ height = ceil(viewBox.height * scale)
488
+ ```
489
+
490
+ これにより、SVG をブラウザで直接開いても極端に小さく表示されない(長辺 ≥ 1600px)。
491
+
492
+ ### 15.3 SVG 文書の属性
493
+
494
+ ルート `<svg>` に `xmlns`・`version="1.1"`・`viewBox`・`width`・`height`・`preserveAspectRatio="xMidYMid meet"` を設定し、既定で `<?xml version="1.0" encoding="UTF-8"?>` を前置する。ラベル等の `<` `>` `&`、属性値中の `"` は XML として正しくエスケープされる。
495
+
496
+ ### 15.4 オプション
497
+
498
+ | オプション | 既定 | 意味 |
499
+ |---|---|---|
500
+ | `lang` | `'ja'` | `'ja'` / `'en'` / `'both'`(日英 2 段) |
501
+ | `crop` | `true` | 実描画範囲で切り出し。`false` で全キャンバス |
502
+ | `bleed` | `3` | 切り出し余白(単位) |
503
+ | `targetSide` | `1600` | `width`/`height` の長辺 px 下限 |
504
+ | `xmlDeclaration` | `true` | `<?xml ...?>` を前置 |
505
+
506
+ ### 15.5 決定論
507
+
508
+ `Date.now()` / `Math.random()` / フォント実測に依存しない。**同じ入力・同じオプション → 同じ SVG(バイト一致)**。回帰テストとキャッシュに適する。
509
+
510
+ ---
511
+
512
+ ## 16. CLI の入出力と終了コード
513
+
514
+ ```text
515
+ pdgkit render <input> [--to svg|png|jpeg|pdf|pptx] [--lang ja|en|both] [-o file] [--no-crop]
516
+ pdgkit validate <input>
517
+ pdgkit refs <input> [--format md|csv] [-o file]
518
+ pdgkit samples
519
+ pdgkit version | help
520
+ ```
521
+
522
+ ### 16.1 入力の解決順
523
+
524
+ 1. `--sample <id>` があればその内蔵サンプル。
525
+ 2. 位置引数がファイルパス(`-` 以外)なら、そのファイル。
526
+ 3. それ以外は **標準入力**。
527
+
528
+ ### 16.2 出力
529
+
530
+ - テキスト形式(svg / md / csv)は `-o` 省略時に標準出力へ。
531
+ - バイナリ形式(png / jpeg / pdf / pptx)は `-o` 必須。
532
+ - 進捗・診断メッセージは **標準エラー出力** へ(標準出力を成果物専用に保つ)。
533
+
534
+ ### 16.3 終了コード
535
+
536
+ | コード | 意味 |
537
+ |---|---|
538
+ | `0` | 成功(`validate` は error 診断 0 件) |
539
+ | `1` | 検証エラー、または実行時エラー(未実装形式の呼び出しを含む) |
540
+ | `2` | 使い方の誤り(不明なサンプル / ファイル読込不可 / 不正なフラグ) |
541
+
542
+ ### 16.4 例
543
+
544
+ ```bash
545
+ pdgkit render fig1.pdg -o fig1.svg
546
+ pdgkit render --sample block --lang both -o block.svg
547
+ cat fig1.pdg | pdgkit validate - # 終了コードで成否判定
548
+ pdgkit refs fig1.pdg --format csv -o signs.csv
549
+ ```
550
+
551
+ ---
552
+
553
+ ## 17. 出力仕様
554
+
555
+ `.pdg` から次の形式を出力できる。いずれもブラウザ非依存(Node)で生成する。図種(block / flow / state / seq)に関わらず、どの形式でも出力可能。
556
+
557
+ | 形式 | 内容 | 生成方法 |
558
+ |---|---|---|
559
+ | SVG | 実描画範囲で切り出したベクタ画像。viewBox と表示寸法は §15 のとおり | 内蔵 SVG シリアライザ(依存なし) |
560
+ | PNG | 既定 8 倍解像度・白背景のラスタ | `@resvg/resvg-js`(IPAex 埋込) |
561
+ | JPEG | 既定 8 倍解像度・白背景のラスタ | resvg + `jpeg-js` |
562
+ | PDF | A4・IPAex 埋込。既定はベクタ(テキスト選択可)、失敗時はラスタにフォールバック | `jsPDF` + `svg2pdf.js`(jsdom) |
563
+ | PPTX | 16:9 スライドに高解像度画像を 1 枚配置 | resvg + Open XML(自前 ZIP) |
564
+ | PPTX(編集) | SVG の各要素を編集可能な PowerPoint 図形・線・文字へ変換 | SVG 走査 + Open XML |
565
+ | 符号 MD | 符号表(符号 / 日本語 / 英語)の Markdown | 純関数 |
566
+ | 符号 CSV | 符号表の CSV(`id,ja,en`) | 純関数 |
567
+
568
+ ### 17.1 共通仕様
569
+
570
+ - ラスタ倍率は既定 8。一辺 24000px・総画素 1e8 を上限に、超える場合は倍率を自動的に下げる(§15.2)。
571
+ - 画像系(SVG / PNG / JPEG / PPTX 画像)は実描画範囲で切り出し、小さな余白(`bleed`、既定 3 単位)を付ける。
572
+ - 表示言語(`ja` / `en` / `both`)はすべての描画出力に反映される。`both` は日英 2 段表示。
573
+ - ラベル中の `<` `>` `&` `"` は XML/OOXML として正しくエスケープされる。
574
+ - PNG / JPEG の背景は白。JPEG はアルファを持たないため白背景に合成される。
575
+
576
+ ### 17.2 API と CLI の対応
577
+
578
+ | 形式 | ライブラリ | CLI(§16) |
579
+ |---|---|---|
580
+ | SVG | `renderToSvg(source, opts)` → `{ svg, ... }` | `render --to svg` |
581
+ | PNG | `renderToPng(source, opts)` → `Uint8Array` | `render --to png` |
582
+ | JPEG | `renderToJpeg(source, opts)` → `Uint8Array` | `render --to jpeg` |
583
+ | PDF | `renderToPdf(source, opts)` → `Uint8Array` | `render --to pdf` |
584
+ | PPTX | `renderToPptx(source, opts)` → `Uint8Array` | `render --to pptx` |
585
+ | PPTX(編集) | `renderToPptx(source, { editable: true })` | `render --to pptx --editable` |
586
+ | 符号 MD / CSV | `refsToMarkdown(parse(s))` / `refsToCsv(parse(s))` | `refs --format md` / `refs --format csv` |
587
+
588
+ 主なオプション: `lang`(`ja` / `en` / `both`)、`scale`(ラスタ倍率、既定 8)、`bleed`(余白、既定 3)、`crop`(SVG の切り出し、既定 true)、`vector`(PDF のベクタ優先、既定 true)、`editable`(PPTX、既定 false)。
589
+
590
+ ---
591
+
592
+ Copyright (c) 2026 しばやま — MIT License。[PatentDSL](https://github.com/shibayamalicht/patent_dsl)(© 2026 しばやま, MIT)を母体とする。
@@ -0,0 +1,14 @@
1
+ # ブロック図(装置クレーム用)
2
+ # 包含(:)と接続(-, ->)だけで装置構成を表現
3
+
4
+ 10 = 制御装置 / control device
5
+ 11 = CPU
6
+ 12 = メモリ / memory
7
+ 13 = "I/O インターフェース" / "I/O interface"
8
+ 20 = 外部機器 / external device
9
+
10
+ 10 : 11 12 13
11
+
12
+ 11 - 12
13
+ 11 - 13
14
+ 13 -> 20 : 信号 / signal
@@ -0,0 +1,14 @@
1
+ # フローチャート(方法クレーム用)
2
+ # 末尾「?」が条件分岐(菱形)に自動推論される
3
+
4
+ S100 = 開始 / Start
5
+ S110 = 条件A? / "Condition A?"
6
+ S120 = 処理X / Process X
7
+ S130 = 処理Y / Process Y
8
+ S140 = 終了 / End
9
+
10
+ S100 -> S110
11
+ S110 -> S120 : Yes
12
+ S110 -> S130 : No
13
+ S120 -> S140
14
+ S130 -> S140
@@ -0,0 +1,13 @@
1
+ # 状態遷移図
2
+ # * が初期 / 終端のマーカ(黒丸で描画される)
3
+
4
+ S1 = 待機 / Idle
5
+ S2 = 動作中 / Running
6
+ S3 = エラー / Error
7
+
8
+ * -> S1
9
+ S1 -> S2 : 起動 / start
10
+ S2 -> S1 : 停止 / stop
11
+ S2 -> S3 : 異常 / fault
12
+ S3 -> S1 : リセット / reset
13
+ S3 -> *
@@ -0,0 +1,10 @@
1
+ # シーケンス図(プロトコル系)
2
+ # 包含も?も*もない → 自動的にシーケンスとして描画
3
+
4
+ 100 = クライアント / client
5
+ 200 = サーバ / server
6
+
7
+ 100 -> 200 : 認証要求 / auth request
8
+ 200 -> 100 : トークン / token
9
+ 100 -> 200 : リソース要求 / resource request
10
+ 200 -> 100 : リソース応答 / resource response
@@ -0,0 +1,19 @@
1
+ # システム全体(階層+外部接続)
2
+
3
+ 100 = システム本体 / Main system
4
+ 10 = 制御部 / Control
5
+ 20 = 通信部 / Comm
6
+ 11 = CPU
7
+ 12 = メモリ / memory
8
+ 21 = 無線部 / wireless
9
+ 22 = 有線部 / wired
10
+ 30 = 外部サーバ / external server
11
+ 40 = 外部端末 / external terminal
12
+
13
+ 100 : 10 20
14
+ 10 : 11 12
15
+ 20 : 21 22
16
+
17
+ 21 .> 40 : 無線 / wireless
18
+ 22 -> 30 : 有線 / wired
19
+ 30 <-> 40 : 通信 / comm
@@ -0,0 +1,27 @@
1
+ # IoT/クラウド構成
2
+
3
+ 100 = センサ端末 / sensor terminal
4
+ 10 = 検出部 / detector
5
+ 11 = 温度センサ / temperature sensor
6
+ 12 = 加速度センサ / acceleration sensor
7
+ 20 = 処理部 / processor
8
+ 21 = 取得部 / acquisition unit
9
+ 22 = 判定部 / determination unit
10
+ 30 = 通信部 / communication unit
11
+ 200 = ゲートウェイ / gateway
12
+ 300 = クラウドサーバ / cloud server
13
+ 310 = 受信部 / receiver
14
+ 320 = 解析部 / analyzer
15
+ 330 = 記憶部 / storage
16
+
17
+ 100 : 10 20 30
18
+ 10 : 11 12
19
+ 20 : 21 22
20
+ 300 : 310 320 330
21
+
22
+ 10 -> 20 : センサ値 / sensor value
23
+ 20 -> 30 : 送信データ / transmission data
24
+ 30 .> 200 : 無線 / wireless
25
+ 200 -> 310 : 中継 / relay
26
+ 310 -> 320 : データ / data
27
+ 320 -> 330 : 結果 / result