@cardenelabs/dragon 0.30.0 → 0.32.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/README.md +314 -12
- package/dist/index.cjs +6966 -1438
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2150 -118
- package/dist/index.d.ts +2150 -118
- package/dist/index.js +6950 -1440
- package/dist/index.js.map +1 -1
- package/package.json +12 -13
- package/src/compile/actor-ids.ts +6 -15
- package/src/compile/actor-option-notice.ts +379 -0
- package/src/compile/actors.ts +32 -3
- package/src/compile/c4.ts +0 -3
- package/src/compile/chain.ts +43 -4
- package/src/compile/chart-fields.ts +16 -1
- package/src/compile/direction.ts +50 -11
- package/src/compile/edge-option-notice.ts +112 -0
- package/src/compile/flowchart.ts +344 -0
- package/src/compile/funnel.ts +14 -2
- package/src/compile/gantt.ts +141 -36
- package/src/compile/generic.ts +473 -61
- package/src/compile/journey.ts +14 -5
- package/src/compile/kinds.ts +5 -13
- package/src/compile/lanes.ts +95 -13
- package/src/compile/metro.ts +271 -0
- package/src/compile/mind.ts +55 -5
- package/src/compile/notice.ts +51 -4
- package/src/compile/order.ts +62 -0
- package/src/compile/parts.ts +107 -33
- package/src/compile/placement-apply.ts +27 -11
- package/src/compile/quadrant.ts +171 -16
- package/src/compile/record.ts +75 -0
- package/src/compile/row-marks.ts +128 -0
- package/src/compile/sequence.ts +105 -26
- package/src/compile/slug.ts +9 -1
- package/src/compile/stages.ts +247 -0
- package/src/compile/subtitle.ts +15 -2
- package/src/compile/swimlane-marks.ts +87 -0
- package/src/compile/swimlane.ts +13 -14
- package/src/compile/timeline.ts +213 -0
- package/src/compile/topology.ts +3 -9
- package/src/compile/tree.ts +13 -4
- package/src/compile/value-chart.ts +179 -25
- package/src/compile.ts +1550 -370
- package/src/focus.ts +2 -2
- package/src/index.ts +34 -2
- package/src/json-parser.ts +1407 -48
- package/src/keywords.ts +251 -17
- package/src/notation-lint.ts +41 -64
- package/src/schemas/diagram.json +643 -20
- package/src/types.ts +336 -35
- package/src/v05/parser.ts +2451 -271
- package/src/compile/class.ts +0 -100
- package/src/compile/er.ts +0 -44
- package/src/compile/solidity.ts +0 -39
- package/src/compile/state.ts +0 -71
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardenelabs/dragon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Dragon — Mermaid 感覚で animated SVG を生成する Text DSL。 cdl engine を内部利用。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "cardene777",
|
|
@@ -46,18 +46,8 @@
|
|
|
46
46
|
"node": ">=18"
|
|
47
47
|
},
|
|
48
48
|
"sideEffects": false,
|
|
49
|
-
"scripts": {
|
|
50
|
-
"build": "tsup",
|
|
51
|
-
"dev": "tsup --watch",
|
|
52
|
-
"typecheck": "tsc --noEmit",
|
|
53
|
-
"typecheck:test": "tsc --noEmit -p tsconfig.test.json",
|
|
54
|
-
"test": "cd ../.. && vitest run packages/dragon",
|
|
55
|
-
"test:watch": "cd ../.. && vitest packages/dragon",
|
|
56
|
-
"lint": "tsc --noEmit",
|
|
57
|
-
"prepublishOnly": "pnpm run typecheck && pnpm run test && pnpm run build"
|
|
58
|
-
},
|
|
59
49
|
"dependencies": {
|
|
60
|
-
"@cardenelabs/cdl": "^0.
|
|
50
|
+
"@cardenelabs/cdl": "^0.139.0"
|
|
61
51
|
},
|
|
62
52
|
"peerDependencies": {
|
|
63
53
|
"react": "^19.0.0",
|
|
@@ -76,5 +66,14 @@
|
|
|
76
66
|
"react": "^19.1.0",
|
|
77
67
|
"tsup": "^8.5.1",
|
|
78
68
|
"typescript": "^5.8.0"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsup",
|
|
72
|
+
"dev": "tsup --watch",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"typecheck:test": "tsc --noEmit -p tsconfig.test.json",
|
|
75
|
+
"test": "cd ../.. && vitest run packages/dragon",
|
|
76
|
+
"test:watch": "cd ../.. && vitest packages/dragon",
|
|
77
|
+
"lint": "tsc --noEmit"
|
|
79
78
|
}
|
|
80
|
-
}
|
|
79
|
+
}
|
package/src/compile/actor-ids.ts
CHANGED
|
@@ -79,7 +79,7 @@ function cdl側のslug(s: string): string {
|
|
|
79
79
|
* |---|---|
|
|
80
80
|
* | `sequence` / `solidity` | 枠 `actor-0` (cdl の `sequence()`) |
|
|
81
81
|
* | `swimlane` | 枠 `lane-0` (cdl の `swimlane()`) |
|
|
82
|
-
* | 残る
|
|
82
|
+
* | 残る 5 図種 | 箱 `n` (dragon 側の逃げ先。 cdl の逃げ道を通らない) |
|
|
83
83
|
*
|
|
84
84
|
* 空配列は「cdl の逃げ道を通らない」 を表す。 1 箱で描く図種はここに来ない (作り替え自体を
|
|
85
85
|
* しない) が、 図種を足した時に決め忘れないよう全種を並べる。
|
|
@@ -89,25 +89,16 @@ function cdl側のslug(s: string): string {
|
|
|
89
89
|
*/
|
|
90
90
|
const 空の形の逃げ先: Record<PresetType, string[]> = {
|
|
91
91
|
sequence: ["actor-"],
|
|
92
|
-
solidity: ["actor-"],
|
|
93
92
|
swimlane: ["lane-"],
|
|
93
|
+
// 分かれ道の図も縦列を持ち、 描画側は縦列の名前から箱を作る (`swimlane` と同じ逃げ先)
|
|
94
|
+
flowchart: ["lane-"],
|
|
94
95
|
flow: [],
|
|
95
|
-
|
|
96
|
-
state: [],
|
|
96
|
+
record: [],
|
|
97
97
|
topology: [],
|
|
98
|
-
class: [],
|
|
99
98
|
c4: [],
|
|
100
99
|
// 図全体を 1 箱で描く群 (作り替えないのでここは使わない)
|
|
101
100
|
gantt: [],
|
|
102
|
-
|
|
103
|
-
bar: [],
|
|
104
|
-
line: [],
|
|
105
|
-
gauge: [],
|
|
106
|
-
radial: [],
|
|
107
|
-
stat: [],
|
|
108
|
-
waffle: [],
|
|
109
|
-
stacked: [],
|
|
110
|
-
slope: [],
|
|
101
|
+
chart: [],
|
|
111
102
|
funnel: [],
|
|
112
103
|
tree: [],
|
|
113
104
|
journey: [],
|
|
@@ -241,7 +232,7 @@ export function disambiguateActorIds(
|
|
|
241
232
|
: { ...event, target: { ...target, from, to } };
|
|
242
233
|
}
|
|
243
234
|
// sequence 系の縦列は登場人物から作るため、同じ名前の読み替えが必要。
|
|
244
|
-
if (target.kind === "lane" &&
|
|
235
|
+
if (target.kind === "lane" && doc.type === "sequence") {
|
|
245
236
|
const name = 直す(target.name);
|
|
246
237
|
return name === target.name ? event : { ...event, target: { ...target, name } };
|
|
247
238
|
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 箱に書いた指定が効かない時の、伝える欄の割り出しと呼び名 (#2368 で 1 箇所にまとめた)。
|
|
3
|
+
*
|
|
4
|
+
* 同じ判定を図種の族ごとの経路が使う (経路の数は下の表ではなく実装が SSOT)。
|
|
5
|
+
*
|
|
6
|
+
* | 経路 | 図種 | 起点 |
|
|
7
|
+
* |---|---|---|
|
|
8
|
+
* | 板の面 | `sequence` / `solidity` | #2358 |
|
|
9
|
+
* | 木の図 | `tree` | #2360 |
|
|
10
|
+
* | 値の図とじょうご | `pie` ほか 9 図種 + `funnel` | #2368 |
|
|
11
|
+
* | ガントチャートと体験の地図と四象限 | `gantt` / `journey` / `quadrant` | #2370 |
|
|
12
|
+
* | 骨組みの図 | `flow` / `flowchart` / `swimlane` / `topology` / `c4` / `record` | #2376 / #2382 / #2782 |
|
|
13
|
+
*
|
|
14
|
+
* 矢印の側は `edge-option-notice.ts` が同じ形を持つ (#2366)。
|
|
15
|
+
*/
|
|
16
|
+
import type { DslActor } from "../types";
|
|
17
|
+
import type { DslDiagramShape } from "../keywords";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 効かない箱の欄の呼び名 (#2358)。 **並べた順に知らせへ出す**。
|
|
21
|
+
*
|
|
22
|
+
* 呼び名を持たない欄は名前をそのまま出すので、ここに足し忘れても知らせは消えない。
|
|
23
|
+
* 複数の欄が 1 つの呼び名を持つ形 (位置が 4 欄) は、1 度だけ出す。
|
|
24
|
+
*
|
|
25
|
+
* **図種をまたいで 1 つの表にする** (#2360)。 同じ欄を図種ごとに別の文言で呼ぶと、
|
|
26
|
+
* 図種を変えた読み手が同じ指定だと気付けない。 どの欄を伝えるかは図種ごとの除外が決める。
|
|
27
|
+
*
|
|
28
|
+
* **箱に無い欄名を書けないようにする** (#2384)。 表と除外は箱の欄と文字で突き合わせるので、
|
|
29
|
+
* 綴りが箱と違う行は静かに何とも一致しない。 実測 = 記法の `色:` に引きずられて書いた
|
|
30
|
+
* `color` が、箱に生まれない欄名のまま残っていた (箱に入るのは `colorHex` か `tone`)。
|
|
31
|
+
*/
|
|
32
|
+
export const 効かない箱の欄の呼び名 = [
|
|
33
|
+
["kind", "種類"],
|
|
34
|
+
// 呼び名 (#2390)。 板 / 木 / 骨組みの図は箱に描くので、伝えるのは値として読む図だけ
|
|
35
|
+
["subtitle", "呼び名"],
|
|
36
|
+
["posW", "大きさ"],
|
|
37
|
+
["posH", "大きさ"],
|
|
38
|
+
["posX", "位置"],
|
|
39
|
+
["posY", "位置"],
|
|
40
|
+
["posRel", "位置"],
|
|
41
|
+
// 位置のずらし (#1971)。 板は面ごとの箱を持たないので動かす相手が無い
|
|
42
|
+
["layoutPos", "位置"],
|
|
43
|
+
["rows", "行"],
|
|
44
|
+
["tone", "色"],
|
|
45
|
+
["colorHex", "色"],
|
|
46
|
+
["eyebrow", "小見出し"],
|
|
47
|
+
["value", "値"],
|
|
48
|
+
["shape", "図形"],
|
|
49
|
+
["previous", "前の値"],
|
|
50
|
+
["marks", "印"],
|
|
51
|
+
["stack", "段"],
|
|
52
|
+
["initial", "始まりの印"],
|
|
53
|
+
["final", "終わりの印"],
|
|
54
|
+
["visibleIf", "出す条件"],
|
|
55
|
+
["opacity", "透け具合"],
|
|
56
|
+
["wBind", "値への追随"],
|
|
57
|
+
["hBind", "値への追随"],
|
|
58
|
+
["renderOffsetX", "値への追随"],
|
|
59
|
+
["renderOffsetY", "値への追随"],
|
|
60
|
+
["owner", "担当"],
|
|
61
|
+
["stage", "段階"],
|
|
62
|
+
["end", "終わる時期"],
|
|
63
|
+
["startLabel", "始まりの札"],
|
|
64
|
+
["milestone", "節目"],
|
|
65
|
+
["emphasis", "主役"],
|
|
66
|
+
["at", "点の位置"],
|
|
67
|
+
["atPos", "点の位置"],
|
|
68
|
+
["touchpoint", "接点"],
|
|
69
|
+
["opportunity", "伸びしろ"],
|
|
70
|
+
["opportunityPosition", "伸びしろの位置"],
|
|
71
|
+
] as const satisfies readonly (readonly [keyof DslActor, string])[];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 体験と工程の欄 (#2380)。 **どの族の除外にも入る**。
|
|
75
|
+
*
|
|
76
|
+
* 担当 (`owner`) と終わる時期 (`end`) はガントチャートが、接点 (`touchpoint`) と伸びしろ
|
|
77
|
+
* (`opportunity`) と伸びしろの位置 (`opportunityPosition`) は体験の地図が描く。 描けない図種で書いた時は
|
|
78
|
+
* `reportChartFieldsNotHonored` が図種ごとの行き先を添えて伝える。
|
|
79
|
+
*
|
|
80
|
+
* 箱の知らせが同じ欄を重ねて伝えると、1 つの欄が 2 つの名前で呼ばれる (「担当」 と `owner`)
|
|
81
|
+
* うえ、案内が食い違う = 箱の知らせは「箱を持つ図種へ」 と言うが、担当は箱を持つ図種でも
|
|
82
|
+
* 効かない。
|
|
83
|
+
*
|
|
84
|
+
* **1 か所に置いて各族が読む**。 欄を族ごとに書き並べると、新しい欄を足した日に
|
|
85
|
+
* 直し忘れた族だけが 2 件並べるようになる (実測 = 板の族だけが 4 欄を持たず、
|
|
86
|
+
* `sequence` / `solidity` の 8 通りで知らせが 2 件並んでいた)。
|
|
87
|
+
*/
|
|
88
|
+
export const 体験と工程の欄: ReadonlySet<string> = new Set([
|
|
89
|
+
"owner",
|
|
90
|
+
"end",
|
|
91
|
+
"startLabel",
|
|
92
|
+
"milestone",
|
|
93
|
+
"emphasis",
|
|
94
|
+
"touchpoint",
|
|
95
|
+
"opportunity",
|
|
96
|
+
"opportunityPosition",
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 板の面で、効かないと伝えない箱の欄 (#2358)。
|
|
101
|
+
*
|
|
102
|
+
* **除外側を書く**。 効かない欄を並べる形にすると、箱に欄を足した日にその欄だけが
|
|
103
|
+
* 一覧から漏れ、書いた人には「書いたのに何も起きない」 としか見えない。
|
|
104
|
+
*
|
|
105
|
+
* | 区分 | 欄 |
|
|
106
|
+
* |---|---|
|
|
107
|
+
* | 板が描く | 名前 / 題 / 呼び名 と、書いた場所と種類を書いたかの印 |
|
|
108
|
+
* | 別の知らせが受け持つ | 縦列 (`reportLaneNotHonored`) / 体験と工程の 4 欄 (#2380) |
|
|
109
|
+
*
|
|
110
|
+
* 種類 (`kind`) は図種で分かれるので、判定の側で足す。
|
|
111
|
+
*/
|
|
112
|
+
export const 板が伝えない箱の欄: ReadonlySet<string> = new Set([
|
|
113
|
+
"name",
|
|
114
|
+
"title",
|
|
115
|
+
"subtitle",
|
|
116
|
+
"pos",
|
|
117
|
+
"kindWritten",
|
|
118
|
+
"lane",
|
|
119
|
+
...体験と工程の欄,
|
|
120
|
+
]);
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 木の図で、効かないと伝えない箱の欄 (#2360)。
|
|
124
|
+
*
|
|
125
|
+
* | 区分 | 欄 |
|
|
126
|
+
* |---|---|
|
|
127
|
+
* | 木の図が描く | 名前 / 題 / 呼び名 / 値 と、書いた場所と種類を書いたかの印 |
|
|
128
|
+
* | 別の知らせが受け持つ | 縦列 / 位置のずらし / 体験と工程の 4 欄 |
|
|
129
|
+
*
|
|
130
|
+
* 別の知らせは順に `lane-not-honored` / `position-offset-ignored` / `chart-value-unreadable`。
|
|
131
|
+
* 除かないと同じ箱に 2 件並ぶ。 体験と工程の 4 欄は `体験と工程の欄` から読む (#2380)。
|
|
132
|
+
*/
|
|
133
|
+
export const 木の図が伝えない箱の欄: ReadonlySet<string> = new Set([
|
|
134
|
+
"name",
|
|
135
|
+
"title",
|
|
136
|
+
"subtitle",
|
|
137
|
+
"value",
|
|
138
|
+
"pos",
|
|
139
|
+
"kindWritten",
|
|
140
|
+
"lane",
|
|
141
|
+
"layoutPos",
|
|
142
|
+
...体験と工程の欄,
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 箱を名前と値の組として読む図で、どの図種でも効かないと伝えない箱の欄 (#2368 / #2370)。
|
|
147
|
+
*
|
|
148
|
+
* | 区分 | 欄 |
|
|
149
|
+
* |---|---|
|
|
150
|
+
* | どの図種も読む | 名前 / 題 / 値 と、書いた場所と種類を書いたかの印 |
|
|
151
|
+
* | 別の知らせが受け持つ | 縦列 / 位置のずらし / 体験と工程の 4 欄 |
|
|
152
|
+
*
|
|
153
|
+
* 呼び名 (`subtitle`) は除かない (#2390)。 値を書いていない箱で **値として読まれる**
|
|
154
|
+
* (`a.value ?? a.subtitle`) ので除いていたが、**値を書いた箱では読む先が無い**。
|
|
155
|
+
* 除いた結果、値と呼び名を両方書いた箱では誰も伝えず、13 図種で黙って消えていた。
|
|
156
|
+
* 値を書いていない箱で鳴らさない判定は呼び元が持つ = 箱 1 つごとに決まる条件なので、
|
|
157
|
+
* 図種ごとの除外では表せない (#2384 の色番号と同じ形)。
|
|
158
|
+
*
|
|
159
|
+
* 位置 (`posX` / `posY`) は除かない = この図種では両方書いても効かないため、
|
|
160
|
+
* 片方だけの知らせ (#2362) ではなくこちらが伝える。
|
|
161
|
+
*
|
|
162
|
+
* 記法の `offsetX` / `offsetY` は `layoutPos` に入る (`position-offset-ignored` が受け持つ)。
|
|
163
|
+
* 欄の名前で判定するので、記法の項目名ではなく入った先の欄を書く。
|
|
164
|
+
*
|
|
165
|
+
* 体験と工程の欄 (`体験と工程の欄`) は、読む図種と別の知らせが受け持つ図種に分かれる。
|
|
166
|
+
* どちらも伝えないので 1 つにまとめて除く。
|
|
167
|
+
*/
|
|
168
|
+
const 値として読む図に共通の除外: ReadonlySet<string> = new Set([
|
|
169
|
+
"name",
|
|
170
|
+
"title",
|
|
171
|
+
"value",
|
|
172
|
+
"pos",
|
|
173
|
+
"kindWritten",
|
|
174
|
+
"lane",
|
|
175
|
+
"layoutPos",
|
|
176
|
+
...体験と工程の欄,
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 箱を名前と値の組として読む図種と、共通に加えて読む欄 (#2368 / #2370)。
|
|
181
|
+
*
|
|
182
|
+
* **表で持つ**。 図種ごとに除外の集合を丸ごと書くと、共通部分が図種の数だけ写され、
|
|
183
|
+
* 1 つ直した日に他が古いまま残る (実測 = 値の図とじょうごで 2 つに分かれていた)。
|
|
184
|
+
*
|
|
185
|
+
* | 図種 | 共通に加えて読む欄 |
|
|
186
|
+
* |---|---|
|
|
187
|
+
* | 数を描く図 (`chart`) | 色味 (`tone`) / 前の値 (`previous`) |
|
|
188
|
+
* | じょうご | 色味 (`tone`) |
|
|
189
|
+
* | 体験の地図 / 四象限 | 無し (名前と値だけを読む) |
|
|
190
|
+
* | ガントチャート | 色味 (`tone`)。 担当と終わる時期は共通の除外に入っている |
|
|
191
|
+
*/
|
|
192
|
+
export const 値として読む図種: ReadonlyMap<string, readonly string[]> = new Map([
|
|
193
|
+
["chart", ["tone", "previous"]],
|
|
194
|
+
["funnel", ["tone"]],
|
|
195
|
+
["gantt", ["tone"]],
|
|
196
|
+
["journey", []],
|
|
197
|
+
["quadrant", ["at", "atPos"]],
|
|
198
|
+
]);
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 件ごとの主役 (`emphasis`) を実際に描く値の図。
|
|
202
|
+
*
|
|
203
|
+
* `chart` という node の種類だけでは円・折れ線なども混ざるため、`chart/stacked` まで
|
|
204
|
+
* 形を含めて区別する。じょうごは形を持たず、段の `emphasis` を読む。
|
|
205
|
+
*/
|
|
206
|
+
const 主役を読む値の図: ReadonlySet<string> = new Set(["chart/stacked", "funnel"]);
|
|
207
|
+
|
|
208
|
+
/** 件ごとの `emphasis` がその図で描かれるか */
|
|
209
|
+
export function 値として読む図が主役を読む(図種: string, 形?: DslDiagramShape): boolean {
|
|
210
|
+
return 主役を読む値の図.has(形 === undefined ? 図種 : `${図種}/${形}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* その図種で、効かないと伝えない箱の欄を返す (#2370)。
|
|
215
|
+
*
|
|
216
|
+
* @param 図種 `値として読む図種` に載っている図種
|
|
217
|
+
* @returns 共通の除外に、その図種が読む欄を足した集合
|
|
218
|
+
*/
|
|
219
|
+
export function 値として読む図が伝えない箱の欄(図種: string): ReadonlySet<string> {
|
|
220
|
+
const 読む欄 = 値として読む図種.get(図種) ?? [];
|
|
221
|
+
if (読む欄.length === 0) return 値として読む図に共通の除外;
|
|
222
|
+
return new Set([...値として読む図に共通の除外, ...読む欄]);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 箱を並べて線で繋ぐ図 (骨組みの図) で、どの図種でも効かないと伝えない箱の欄 (#2376)。
|
|
227
|
+
*
|
|
228
|
+
* | 区分 | 欄 |
|
|
229
|
+
* |---|---|
|
|
230
|
+
* | 骨組みの図が描く | 名前 / 題 / 呼び名 / 小見出し / 値 / 行 / 色味 / 図形 / 種類 / 段 / 透け具合 / 出す条件 |
|
|
231
|
+
* | 位置と大きさ | `posX` / `posY` / `posW` / `posH` / `posRel` / `layoutPos` |
|
|
232
|
+
* | 値への追随 | `wBind` / `hBind` / `renderOffsetX` / `renderOffsetY` |
|
|
233
|
+
* | 別の知らせが受け持つ | 縦列 / 体験と工程の 4 欄 |
|
|
234
|
+
*
|
|
235
|
+
* 色番号 (`colorHex`) は除かない (#2384)。 部品を置いた箱でだけ効く欄なので
|
|
236
|
+
* 「部品の側が伝えるから重ねない」 として除いていたが、**呼び元が部品を置いた箱を
|
|
237
|
+
* 判定の入口で飛ばす** (`a.partId !== undefined`) ため重なりようがなかった。
|
|
238
|
+
* 除いた結果、部品でない箱では誰も伝えず、7 図種で黙って消えていた。
|
|
239
|
+
*
|
|
240
|
+
* 記法の `色:` は 16 進数なら `colorHex` に、色の名前なら `tone` に入る。
|
|
241
|
+
* 名前で書いた形は箱の色として効くので、伝えるのは 16 進数で書いた形だけになる。
|
|
242
|
+
*
|
|
243
|
+
* 印 (`marks`) は除かない (#2377)。 行頭の記号に読み替えるのは ER 図と状態遷移図だけ
|
|
244
|
+
* (`行頭の印にする`) で、骨組みの残りの図種では行と組にしても効かない。
|
|
245
|
+
* 効く図種で鳴らさない判定は呼び元が持つ = 図種の一覧をここに写すと、印を読む図種を
|
|
246
|
+
* 足した日に古くなる。
|
|
247
|
+
*
|
|
248
|
+
* 残るのは始まりの印 / 終わりの印 / 印 / 前の値の 4 つ。
|
|
249
|
+
* 実測 = フロー 447 枚 ・ 泳路の図 35 枚 ・ 配置の図 8 枚の見本すべてで、この 4 件が
|
|
250
|
+
* 図も変えず知らせも出さなかった。
|
|
251
|
+
*
|
|
252
|
+
* **図種ごとの違いは `骨組みの図種` が持つ** (#2382)。 状態遷移図は始まりの印と終わりの印を
|
|
253
|
+
* 読むので、その 2 欄だけ除外に足す。
|
|
254
|
+
*/
|
|
255
|
+
const 骨組みの図に共通の除外: ReadonlySet<string> = new Set([
|
|
256
|
+
"name",
|
|
257
|
+
"title",
|
|
258
|
+
"subtitle",
|
|
259
|
+
"pos",
|
|
260
|
+
"kindWritten",
|
|
261
|
+
"value",
|
|
262
|
+
"eyebrow",
|
|
263
|
+
"tone",
|
|
264
|
+
"rows",
|
|
265
|
+
// cdl 0.129.0-0.136.0 の表箱・部品箱の欄。 applyV05Extensions が node へ渡し、
|
|
266
|
+
// 描き手が箱の種類に応じて題・罫線・印・入れ子・線画・足として読む (#2854)。
|
|
267
|
+
"kindForm",
|
|
268
|
+
"icon",
|
|
269
|
+
"emptyRowsNote",
|
|
270
|
+
"titleAlign",
|
|
271
|
+
"rowRules",
|
|
272
|
+
"rowStripe",
|
|
273
|
+
"rowLayout",
|
|
274
|
+
"rowDividerForm",
|
|
275
|
+
"rowWell",
|
|
276
|
+
"rowMarkForm",
|
|
277
|
+
"nestIn",
|
|
278
|
+
"figureCard",
|
|
279
|
+
"shape",
|
|
280
|
+
"kind",
|
|
281
|
+
"stack",
|
|
282
|
+
"opacity",
|
|
283
|
+
"visibleIf",
|
|
284
|
+
"posX",
|
|
285
|
+
"posY",
|
|
286
|
+
"posW",
|
|
287
|
+
"posH",
|
|
288
|
+
"posRel",
|
|
289
|
+
"layoutPos",
|
|
290
|
+
"wBind",
|
|
291
|
+
"hBind",
|
|
292
|
+
"renderOffsetX",
|
|
293
|
+
"renderOffsetY",
|
|
294
|
+
"lane",
|
|
295
|
+
...体験と工程の欄,
|
|
296
|
+
]);
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* 図種ごとの、共通の除外との違い (#2382)。
|
|
300
|
+
*
|
|
301
|
+
* **両方向に持つ**。 共通の除外は「どの骨組みの図も読む欄」 を集めたものなので、
|
|
302
|
+
* 図種ごとの違いは 2 通り出る。 外す側だけだと、1 つの図種だけが読む欄を持つ図種を
|
|
303
|
+
* 族に入れられない (実測 = 状態遷移図が始まりの印を読むため、族の外に置かれていた)。
|
|
304
|
+
*/
|
|
305
|
+
export type 骨組みの図の違い = {
|
|
306
|
+
/** その図種だけが読まない欄。 共通の除外から外して、伝える側へ回す */
|
|
307
|
+
readonly 読まない?: readonly string[];
|
|
308
|
+
/** その図種だけが読む欄。 共通の除外に足して、伝えない側へ回す */
|
|
309
|
+
readonly 読む?: readonly string[];
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* 箱を並べて線で繋ぐ図種と、共通の除外との違い (#2376 / #2382)。
|
|
314
|
+
*
|
|
315
|
+
* | 図種 | 違い | 理由 |
|
|
316
|
+
* |---|---|---|
|
|
317
|
+
* | フロー / 泳路の図 / 配置の図 | 無し | `compile/generic.ts` が共通の経路で箱を作る |
|
|
318
|
+
* | 分かれ道の図 (`flowchart`) | 無し | 種類は専用の形または箱の見た目として読む |
|
|
319
|
+
* | 構成の図 (`c4`) | 段 (`stack`) を読まない | `compile/c4.ts` が `a.stack` を読まない |
|
|
320
|
+
* | 行を持つ図 (`record`) | 始まりの印と終わりの印を読む | `compile/generic.ts` の札がこの図種でだけ出る |
|
|
321
|
+
*/
|
|
322
|
+
export const 骨組みの図種: ReadonlyMap<string, 骨組みの図の違い> = new Map([
|
|
323
|
+
["flow", {}],
|
|
324
|
+
["flowchart", {}],
|
|
325
|
+
["swimlane", {}],
|
|
326
|
+
["topology", {}],
|
|
327
|
+
["c4", { 読まない: ["stack"] }],
|
|
328
|
+
["record", { 読む: ["initial", "final"] }],
|
|
329
|
+
]);
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* その図種で、効かないと伝えない箱の欄を返す (#2376 / #2382)。
|
|
333
|
+
*
|
|
334
|
+
* @param 図種 `骨組みの図種` に載っている図種
|
|
335
|
+
* @returns 共通の除外から読まない欄を抜き、読む欄を足した集合
|
|
336
|
+
*/
|
|
337
|
+
export function 骨組みの図が伝えない箱の欄(図種: string): ReadonlySet<string> {
|
|
338
|
+
const 違い = 骨組みの図種.get(図種) ?? {};
|
|
339
|
+
const 読まない欄 = 違い.読まない ?? [];
|
|
340
|
+
const 読む欄 = 違い.読む ?? [];
|
|
341
|
+
if (読まない欄.length === 0 && 読む欄.length === 0) return 骨組みの図に共通の除外;
|
|
342
|
+
const 残り = new Set(骨組みの図に共通の除外);
|
|
343
|
+
for (const 欄 of 読まない欄) 残り.delete(欄);
|
|
344
|
+
for (const 欄 of 読む欄) 残り.add(欄);
|
|
345
|
+
return 残り;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* 箱に書いた欄のうち、効かないものの呼び名を並べる (#2368)。
|
|
350
|
+
*
|
|
351
|
+
* **伝える欄を並べず、読む欄を除いた残り全部を返す**。 効かない欄を並べる形にすると、
|
|
352
|
+
* 箱に欄を足した日にその欄だけが一覧から漏れ、書いた人には「書いたのに何も起きない」
|
|
353
|
+
* としか見えない。 除外側を書けば、足し忘れは「余計に知らせる」 側へ倒れる。
|
|
354
|
+
*
|
|
355
|
+
* @param 箱 記法から読んだ箱 1 つ
|
|
356
|
+
* @param 伝えない欄 その図種が読む欄と、別の知らせが受け持つ欄
|
|
357
|
+
* @param 判定で外す欄 図種の中でさらに外す欄 (種類が図種で分かれる形、#2358)
|
|
358
|
+
* @returns 知らせに出す呼び名。 空なら伝えるものが無い
|
|
359
|
+
*/
|
|
360
|
+
export function 効かない箱の欄を並べる(
|
|
361
|
+
箱: object,
|
|
362
|
+
伝えない欄: ReadonlySet<string>,
|
|
363
|
+
判定で外す欄: readonly string[] = [],
|
|
364
|
+
): string[] {
|
|
365
|
+
const 残り = new Set(
|
|
366
|
+
Object.entries(箱 as Record<string, unknown>)
|
|
367
|
+
.filter(([欄, 値]) => 値 !== undefined && !伝えない欄.has(欄))
|
|
368
|
+
.map(([欄]) => 欄),
|
|
369
|
+
);
|
|
370
|
+
for (const 欄 of 判定で外す欄) 残り.delete(欄);
|
|
371
|
+
const 効かない: string[] = [];
|
|
372
|
+
for (const [欄, 呼び名] of 効かない箱の欄の呼び名) {
|
|
373
|
+
if (!残り.delete(欄)) continue;
|
|
374
|
+
if (!効かない.includes(呼び名)) 効かない.push(呼び名);
|
|
375
|
+
}
|
|
376
|
+
// 呼び名を持たない欄は名前をそのまま出す = 読みにくい名前でも、黙って落とすよりは伝わる
|
|
377
|
+
効かない.push(...[...残り].sort());
|
|
378
|
+
return 効かない;
|
|
379
|
+
}
|
package/src/compile/actors.ts
CHANGED
|
@@ -59,16 +59,45 @@ export function canonicalizeFlowActors(doc: DslDocument): DslDocument {
|
|
|
59
59
|
*
|
|
60
60
|
* 1 つも書いていなければ従来どおり位置で決める = 書かない記法の図は変わらない。
|
|
61
61
|
* 片方だけ書いた形も、書いた側だけが切り替わる。
|
|
62
|
+
*
|
|
63
|
+
* ## 打ち消し (`initial: false`) は書いた箱にだけ効く (#2418)
|
|
64
|
+
*
|
|
65
|
+
* 書いたかどうかを `true` だけで数えていた間、`false` しか書かれていない図は
|
|
66
|
+
* 「1 つも書いていない」 扱いになって位置で決める既定へ落ちていた。 その既定は
|
|
67
|
+
* 「1 番目の箱が始まり」 なので、**打ち消しを書いた当の箱に札が出ていた** (知らせも 0 件)。
|
|
68
|
+
*
|
|
69
|
+
* 位置で決める既定から、打ち消しを書いた箱だけを外す。
|
|
70
|
+
*
|
|
71
|
+
* **「どれか 1 つでも書いたら既定を捨てる」 形にはしない** = 途中の箱に書いた
|
|
72
|
+
* `initial: false` が 1 番目の箱の札まで消す。 書き手は途中の箱のことしか言っていない。
|
|
62
73
|
*/
|
|
63
|
-
export function 始まりと終わりの決め方(
|
|
74
|
+
export function 始まりと終わりの決め方(
|
|
75
|
+
doc: DslDocument,
|
|
76
|
+
/**
|
|
77
|
+
* 並びで決める既定を使うか (#2349)。
|
|
78
|
+
*
|
|
79
|
+
* **格子に置く形では並びが始まりと終わりを意味しない**。 縦列と段を書いた図は
|
|
80
|
+
* 書いた順に左から並ぶわけではないので、「最初に書いた箱」 を初期とみなす既定は
|
|
81
|
+
* 図の見た目と合わない (実測 = 印の箱を持つ見本で、既に形が始点を示している箱へ
|
|
82
|
+
* 「初期」 の字が重ねて出た)。 書いた値はどの並べ方でも効く。
|
|
83
|
+
*/
|
|
84
|
+
opts: { 並びで決める?: boolean } = {},
|
|
85
|
+
): {
|
|
64
86
|
始まり: (a: DslActor, idx: number) => boolean;
|
|
65
87
|
終わり: (a: DslActor, idx: number) => boolean;
|
|
66
88
|
} {
|
|
89
|
+
const 並びで決める = opts.並びで決める ?? true;
|
|
67
90
|
const 書いた始まり = doc.actors.some((a) => a.initial === true);
|
|
68
91
|
const 書いた終わり = doc.actors.some((a) => a.final === true);
|
|
69
92
|
return {
|
|
70
|
-
始まり: (a, idx) =>
|
|
93
|
+
始まり: (a, idx) =>
|
|
94
|
+
書いた始まり ? a.initial === true : 並びで決める && idx === 0 && a.initial !== false,
|
|
71
95
|
終わり: (a, idx) =>
|
|
72
|
-
書いた終わり
|
|
96
|
+
書いた終わり
|
|
97
|
+
? a.final === true
|
|
98
|
+
: 並びで決める &&
|
|
99
|
+
idx === doc.actors.length - 1 &&
|
|
100
|
+
doc.actors.length > 1 &&
|
|
101
|
+
a.final !== false,
|
|
73
102
|
};
|
|
74
103
|
}
|
package/src/compile/c4.ts
CHANGED
package/src/compile/chain.ts
CHANGED
|
@@ -19,13 +19,52 @@ import { lookupPartRaw } from "./parts-lookup";
|
|
|
19
19
|
*/
|
|
20
20
|
export function 鎖でつなぐ形か(doc: DslDocument): boolean {
|
|
21
21
|
if (doc.type !== "flow") return false;
|
|
22
|
-
|
|
23
|
-
if (doc.direction !== undefined) return false;
|
|
24
|
-
return !書いた縦列に置く("flow", doc);
|
|
22
|
+
return !鎖にしない書き方.some((x) => x.あてはまる(doc));
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
/**
|
|
28
|
-
*
|
|
26
|
+
* 鎖をやめて、書いた端どおりに繋ぐ書き方 (#2374)。
|
|
27
|
+
*
|
|
28
|
+
* **判定と案内を組にして持つ**。 以前は判定が 3 つの条件を見るのに、知らせの案内は
|
|
29
|
+
* 手で並べた 2 つだった (実測 = 動きを書く経路が案内に無く、読み手はその道を知れなかった)。
|
|
30
|
+
*
|
|
31
|
+
* 表から判定を導き、案内も同じ表から作る。 条件を足した日に案内が自動で追随する。
|
|
32
|
+
*
|
|
33
|
+
* どれも図の見た目を変えるので、**優先順位は付けない**。 向きを書けば並びが変わり、
|
|
34
|
+
* 縦列を書けば列ができ、動きを書けば段が付く。 どれを選ぶかは書き手が決める。
|
|
35
|
+
*/
|
|
36
|
+
export const 鎖にしない書き方: readonly {
|
|
37
|
+
/** 検査と読み手のための短い呼び名 */
|
|
38
|
+
名: string;
|
|
39
|
+
/** その書き方をしているか */
|
|
40
|
+
あてはまる: (doc: DslDocument) => boolean;
|
|
41
|
+
/** 知らせの案内に出す文 */
|
|
42
|
+
案内: string;
|
|
43
|
+
}[] = [
|
|
44
|
+
{
|
|
45
|
+
名: "動き",
|
|
46
|
+
あてはまる: (doc) => doc.animate !== undefined && doc.animate.phases.length > 0,
|
|
47
|
+
案内: "動き (animation:) を書く",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
名: "向き",
|
|
51
|
+
あてはまる: (doc) => doc.direction !== undefined,
|
|
52
|
+
案内: "向き (direction: 縦) を書く",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
名: "縦列",
|
|
56
|
+
あてはまる: (doc) => 書いた縦列に置く("flow", doc),
|
|
57
|
+
案内: "箱に縦列 (lane:) を書く",
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/** 知らせの案内に出す、鎖をやめる書き方の並び (#2374) */
|
|
62
|
+
export function 鎖にしない書き方の案内(): string {
|
|
63
|
+
return 鎖にしない書き方.map((x) => x.案内).join(" / ");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 静止したフローの鎖に並べる登場人物 (#1987)。
|
|
29
68
|
*
|
|
30
69
|
* **どの行にも書かれていない部品は鎖に並べない**。 並べると、部品の前後の並び順の矢印は書き手が
|
|
31
70
|
* 部品へ引いたものではないため部品へ繋がずに外され (#1979)、部品を途中に置いた図から矢印が全て
|
|
@@ -78,12 +78,27 @@ export function 参照する名前(value: number | string | null): string | null
|
|
|
78
78
|
*/
|
|
79
79
|
export const 図表の大きさ = {
|
|
80
80
|
funnel: { w: 560, h: 480 },
|
|
81
|
-
|
|
81
|
+
// 木は幅を持たない (cdl#970)。 必要な幅は葉の数で変わるので、描画側の `木の札の幅` が出す。
|
|
82
|
+
// 値を残すと、描画側が割付を変えた時にここだけが古い幅を持つ
|
|
83
|
+
tree: { h: 480 },
|
|
82
84
|
mind: { w: 720, h: 480 },
|
|
83
85
|
journey: { w: 720, h: 480 },
|
|
84
86
|
quadrant: { w: 640, h: 480 },
|
|
85
87
|
} as const;
|
|
86
88
|
|
|
89
|
+
/**
|
|
90
|
+
* 記法に札の寸法があればそれを使い、無ければ図種ごとの既定をそのまま返す (#2854 C13)。
|
|
91
|
+
* `図表の大きさ` 自体は変更しない。欄を書かない既存の図が byte-level で同じ寸法を保つため。
|
|
92
|
+
*/
|
|
93
|
+
export function 図表の大きさを読む(
|
|
94
|
+
doc: DslDocument,
|
|
95
|
+
fallback: { w: number; h: number },
|
|
96
|
+
): { w: number; h: number } {
|
|
97
|
+
return doc.figureSize === undefined
|
|
98
|
+
? fallback
|
|
99
|
+
: { w: doc.figureSize.width, h: doc.figureSize.height };
|
|
100
|
+
}
|
|
101
|
+
|
|
87
102
|
/**
|
|
88
103
|
* 図表の欄が `{名前}` で読む値を、**1 か所で** 確かめる (#1200)。
|
|
89
104
|
*
|