@cardenelabs/dragon 0.27.0 → 0.30.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 +119 -12
- package/dist/index.cjs +9619 -8023
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +407 -175
- package/dist/index.d.ts +407 -175
- package/dist/index.js +9617 -8024
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/compile/actor-ids.ts +306 -0
- package/src/compile/actors.ts +74 -0
- package/src/compile/c4.ts +77 -0
- package/src/compile/chain.ts +54 -0
- package/src/compile/chart-fields.ts +178 -0
- package/src/compile/class.ts +100 -0
- package/src/compile/deep-rewrite.ts +30 -0
- package/src/compile/derived-source.ts +18 -0
- package/src/compile/direction.ts +63 -0
- package/src/compile/er-relation.ts +200 -0
- package/src/compile/er.ts +44 -0
- package/src/compile/flow.ts +54 -0
- package/src/compile/funnel.ts +75 -0
- package/src/compile/gantt.ts +232 -0
- package/src/compile/generic.ts +284 -0
- package/src/compile/hierarchy.ts +92 -0
- package/src/compile/journey.ts +84 -0
- package/src/compile/kinds.ts +156 -0
- package/src/compile/lanes.ts +56 -0
- package/src/compile/mind.ts +343 -0
- package/src/compile/node-title.ts +24 -0
- package/src/compile/notice.ts +94 -0
- package/src/compile/parts-lookup.ts +17 -0
- package/src/compile/parts.ts +2635 -0
- package/src/compile/placement-apply.ts +673 -0
- package/src/compile/placement.ts +15 -0
- package/src/compile/quadrant.ts +110 -0
- package/src/compile/rows.ts +40 -0
- package/src/compile/sequence.ts +226 -0
- package/src/compile/slug.ts +29 -0
- package/src/compile/solidity.ts +39 -0
- package/src/compile/state.ts +71 -0
- package/src/compile/subtitle.ts +22 -0
- package/src/compile/swimlane.ts +83 -0
- package/src/compile/topology.ts +50 -0
- package/src/compile/tree.ts +60 -0
- package/src/compile/value-chart.ts +183 -0
- package/src/compile/values.ts +432 -0
- package/src/compile/word-state.ts +82 -0
- package/src/compile.ts +596 -5672
- package/src/index.ts +13 -10
- package/src/json-line-map.ts +30 -0
- package/src/json-parser.ts +509 -176
- package/src/near-name.ts +42 -0
- package/src/notation-lint.ts +112 -74
- package/src/relative-pos.ts +71 -2
- package/src/schema.ts +1 -1
- package/src/schemas/diagram.json +130 -34
- package/src/types.ts +60 -41
- package/src/v05/input-table.generated.ts +6 -4
- package/src/v05/parser-types.ts +12 -1
- package/src/v05/parser.ts +503 -149
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { diagram } from "@cardenelabs/cdl";
|
|
2
|
+
import type { CdlDiagram } from "@cardenelabs/cdl";
|
|
3
|
+
import type { DslActor, DslDocument } from "../types";
|
|
4
|
+
import { 図表の大きさ } from "./chart-fields";
|
|
5
|
+
import { 矢印から親を決める, 放射に出す文字 } from "./hierarchy";
|
|
6
|
+
import type { CompileNotice } from "./notice";
|
|
7
|
+
import { slugify } from "./slug";
|
|
8
|
+
import { truncateForMessage, 図の小見出し } from "./subtitle";
|
|
9
|
+
/**
|
|
10
|
+
* 記法の `type: mind` を放射の図に直す (#2031 で `compile.ts` から移した)。
|
|
11
|
+
*
|
|
12
|
+
* 中心 1 つと枝の並びを 1 つの箱 (`mind-map`) に載せる。 枝の親は矢印で決まり、
|
|
13
|
+
* 規則は `type: tree` と共有する (`矢印から親を決める`)。
|
|
14
|
+
*
|
|
15
|
+
* 放射だけが使う小道具もここへ一緒に移した。 `compile.ts` に残していた間、
|
|
16
|
+
* 「放射で描けるか描けないか」 の割り当てが `compileMind` から 250 行離れており、
|
|
17
|
+
* 欄を足す人が両方を見つけにくかった。
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 1 箱で描く放射が **描ける欄**。 これ以外は書いても出ない (#1177 Round 3)。
|
|
22
|
+
*
|
|
23
|
+
* 数え上げは 3 度直した。 副題 / 値 / 行 → 位置 / 大きさ → 種類 / 枠 / 積む順 …と、 見落とした
|
|
24
|
+
* 欄が review のたびに出た。 数え漏らしても検査は通ってしまう = 「書いたのに出ない」 が黙って
|
|
25
|
+
* 残る形が繰り返し発生した。
|
|
26
|
+
*
|
|
27
|
+
* そこで **`DslActor` の全ての欄を、 描ける側か描けない側のどちらかに必ず割り当てる**。
|
|
28
|
+
* 欄が増えた時に両方へ入れ忘れると型検査が落ちるので、 「描けるのか描けないのか」 を必ず
|
|
29
|
+
* 判断することになる (`rules/quality.md § 多層 SSOT 経路の全 registration 保証` と同じ形)。
|
|
30
|
+
*/
|
|
31
|
+
type 放射で描ける欄 =
|
|
32
|
+
/** 中心の名前 / 枝の名前になる */
|
|
33
|
+
| "name"
|
|
34
|
+
/** 名前と分けて中心 / 枝に出す題。 書かなければ名前を出す */
|
|
35
|
+
| "title"
|
|
36
|
+
/**
|
|
37
|
+
* 名前とは分けて補足に出す 2 欄。
|
|
38
|
+
*
|
|
39
|
+
* `- 描く量を減らす: "{draw} ms"` の形は副題として解析されるため、 値の欄だけを見ると
|
|
40
|
+
* 記法で最も普通な書き方が届かない (#1230 で実測)。 明示的に書いた値の欄も同じ場所へ出す。
|
|
41
|
+
*
|
|
42
|
+
* 描画側は枝の `subtitle` と中心の `rootSubtitle` を名前とは別の行に描く。 2 欄を
|
|
43
|
+
* `放射に出す文字` で 1 つの補足にまとめ、 名前とは分けて渡す。
|
|
44
|
+
*/
|
|
45
|
+
| "subtitle"
|
|
46
|
+
| "value"
|
|
47
|
+
/** 枝の色 (`MindBranchNode.tone`)。 中心は持てないので `描けない欄` が別に見る */
|
|
48
|
+
| "tone"
|
|
49
|
+
/** 見本は放射に載せず、 見本の中身だけを描く (別経路で伝える) */
|
|
50
|
+
| "partId"
|
|
51
|
+
/** 種類を書いたかどうかの印。 `kind` と対で見るので単独では扱わない */
|
|
52
|
+
| "kindWritten"
|
|
53
|
+
/** 本文の行番号。 知らせに載せるために使う */
|
|
54
|
+
| "pos";
|
|
55
|
+
|
|
56
|
+
/** 放射では描けない欄。 書かれていたら伝える */
|
|
57
|
+
type 放射で描けない欄 =
|
|
58
|
+
| "kind"
|
|
59
|
+
| "eyebrow"
|
|
60
|
+
| "touchpoint"
|
|
61
|
+
| "opportunity"
|
|
62
|
+
| "owner"
|
|
63
|
+
| "end"
|
|
64
|
+
| "rows"
|
|
65
|
+
| "marks"
|
|
66
|
+
| "lane"
|
|
67
|
+
| "stack"
|
|
68
|
+
| "initial"
|
|
69
|
+
| "final"
|
|
70
|
+
// 前の時点の値 (#1450)。 放射の枝は 1 時点しか描かない = 2 本目の帯に当たるものが無い
|
|
71
|
+
| "previous"
|
|
72
|
+
| "colorHex"
|
|
73
|
+
// 部品に書いた色の名前 (#1973)。 色番号と同じく部品にしか残らない
|
|
74
|
+
| "partColorName"
|
|
75
|
+
| "stateOverride"
|
|
76
|
+
| "posX"
|
|
77
|
+
| "posY"
|
|
78
|
+
| "posW"
|
|
79
|
+
| "posH"
|
|
80
|
+
| "scale"
|
|
81
|
+
| "scaleKeys"
|
|
82
|
+
| "posRel"
|
|
83
|
+
| "layoutPos"
|
|
84
|
+
// 箱の中に描く図形 (#1374)。 放射の枝は箱の中に図形を持たない
|
|
85
|
+
| "shape"
|
|
86
|
+
// 出す条件 (#1381)。 放射の枝は個別に出し分けられない
|
|
87
|
+
| "visibleIf"
|
|
88
|
+
// 値に追随する 5 欄 (#1392)。 放射の枝は大きさも位置も中心からの配置で決まる
|
|
89
|
+
| "wBind"
|
|
90
|
+
| "hBind"
|
|
91
|
+
| "opacity"
|
|
92
|
+
| "renderOffsetX"
|
|
93
|
+
| "renderOffsetY";
|
|
94
|
+
|
|
95
|
+
/** 引数が `never` でなければ型検査が落ちる */
|
|
96
|
+
type 空であること<T extends never> = T;
|
|
97
|
+
|
|
98
|
+
/** `DslActor` に割り当て漏れの欄があると落ちる */
|
|
99
|
+
export type _放射の欄を覆えている = 空であること<
|
|
100
|
+
Exclude<keyof DslActor, 放射で描ける欄 | 放射で描けない欄>
|
|
101
|
+
>;
|
|
102
|
+
|
|
103
|
+
/** `DslActor` に無い欄を割り当てていると落ちる */
|
|
104
|
+
export type _放射の欄に余りがない = 空であること<
|
|
105
|
+
Exclude<放射で描ける欄 | 放射で描けない欄, keyof DslActor>
|
|
106
|
+
>;
|
|
107
|
+
|
|
108
|
+
/** 描ける側と描けない側が重なっていると落ちる */
|
|
109
|
+
export type _放射の欄が重なっていない = 空であること<Extract<放射で描ける欄, 放射で描けない欄>>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 描けない欄と、 知らせに出す名前。
|
|
113
|
+
*
|
|
114
|
+
* **欄ごとに式を持たせない** (Round 5 の指摘)。 `{ 説明, 書いたか }` の形にすると、 項目名と式が
|
|
115
|
+
* 型で結ばれず `scale: { 書いたか: () => false }` のように **判定を骨抜きにしても型検査が通る**。
|
|
116
|
+
* 名前だけを持ち、 書かれていたかは下の 1 つの式で見る。
|
|
117
|
+
*
|
|
118
|
+
* `Record<放射で描けない欄, string>` なので、 欄を足すと項目も要る。 判定の側は欄ごとに書く所が
|
|
119
|
+
* 無いため、 書き忘れも骨抜きも起きない。
|
|
120
|
+
*
|
|
121
|
+
* 表示の名前は複数の欄で同じでよい (`posX` と `posY` はどちらも「位置 (座標)」)。 出す時に
|
|
122
|
+
* 重複を除く。
|
|
123
|
+
*/
|
|
124
|
+
const 放射で描けない欄の名前: Record<放射で描けない欄, string> = {
|
|
125
|
+
kind: "種類",
|
|
126
|
+
eyebrow: "上の小見出し",
|
|
127
|
+
touchpoint: "場所 (体験の道筋の欄)",
|
|
128
|
+
opportunity: "改善の余地 (体験の道筋の欄)",
|
|
129
|
+
owner: "担当 (工程の並びの欄)",
|
|
130
|
+
end: "終わる時期 (工程の並びの欄)",
|
|
131
|
+
rows: "行",
|
|
132
|
+
marks: "印",
|
|
133
|
+
lane: "枠の指定",
|
|
134
|
+
stack: "積む順",
|
|
135
|
+
initial: "始まり / 終わり の印",
|
|
136
|
+
final: "始まり / 終わり の印",
|
|
137
|
+
previous: "前の時点の値",
|
|
138
|
+
colorHex: "色番号",
|
|
139
|
+
partColorName: "色の名前",
|
|
140
|
+
stateOverride: "状態の上書き",
|
|
141
|
+
// 位置は「登場人物ごとの箱をどこに置くか」 の指定で、 箱が 1 つの図では置く先が無い
|
|
142
|
+
posX: "位置 (座標)",
|
|
143
|
+
posY: "位置 (座標)",
|
|
144
|
+
posW: "大きさ",
|
|
145
|
+
posH: "大きさ",
|
|
146
|
+
scale: "倍率",
|
|
147
|
+
scaleKeys: "倍率",
|
|
148
|
+
posRel: "位置 (相対)",
|
|
149
|
+
layoutPos: "配置のずらし",
|
|
150
|
+
shape: "箱の中の図形",
|
|
151
|
+
visibleIf: "出す条件",
|
|
152
|
+
wBind: "値に追随する大きさ",
|
|
153
|
+
hBind: "値に追随する大きさ",
|
|
154
|
+
opacity: "濃さ",
|
|
155
|
+
renderOffsetX: "描く時のずらし",
|
|
156
|
+
renderOffsetY: "描く時のずらし",
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* その欄が書かれていたか。 **全ての欄をこの 1 つの式で見る**。
|
|
161
|
+
*
|
|
162
|
+
* 欄ごとに式を持たせると、 1 つだけ骨抜きにしても型検査が通る (Round 5 の指摘)。 1 つにすれば
|
|
163
|
+
* 骨抜きにした時点で全ての欄の検査が落ちる。
|
|
164
|
+
*
|
|
165
|
+
* 例外は種類だけ。 既定値 (`actor`) が必ず入るので、 書いたかどうかの印 (`kindWritten`) で見る。
|
|
166
|
+
* 真偽を持つ欄 (`initial` / `final`) は `false` を「書いていない」 として扱う = 既定と同じ意味で、
|
|
167
|
+
* 伝えると書いていない人にも出る。
|
|
168
|
+
*/
|
|
169
|
+
function 放射で描けない欄を書いたか(a: DslActor, 欄: 放射で描けない欄): boolean {
|
|
170
|
+
if (欄 === "kind") return a.kindWritten === true;
|
|
171
|
+
const v = a[欄];
|
|
172
|
+
if (typeof v === "boolean") return v;
|
|
173
|
+
return v !== undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 記法の `type: mind` を engine の `mind-map` 種別の 1 箱に組む (#1177)。
|
|
178
|
+
*
|
|
179
|
+
* 以前は `card` を 3 列 (`mind-left` / `mind-center` / `mind-right`) に並べる別実装で、
|
|
180
|
+
* engine の `mind-map` を使っていなかった。 絵は 3 列の箱から中心の放射に変わり、 破壊的変更
|
|
181
|
+
* として `CHANGELOG` に記録している。
|
|
182
|
+
*
|
|
183
|
+
* 記法の `actors` は「1 つ目が中心、 残りが枝」 の並び。 枝の親は矢印で決まり (#1251)、
|
|
184
|
+
* 書かなければ全ての枝を中心の直下に置く。 描けない欄と、 親にできなかった矢印は黙って
|
|
185
|
+
* 捨てず、 書いた人に伝える。
|
|
186
|
+
*/
|
|
187
|
+
export function compileMind(
|
|
188
|
+
doc: DslDocument,
|
|
189
|
+
onNotice?: (n: CompileNotice) => void,
|
|
190
|
+
): CdlDiagram {
|
|
191
|
+
// 図の型は描画側の組み立て関数 `mindMap()` と同じ綴り (cdl 0.63.0 で `mindmap` から `mind` に揃った)
|
|
192
|
+
const b = diagram(slugify(doc.title), { topic: doc.title, type: "mind" });
|
|
193
|
+
const { w: W, h: H } = 図表の大きさ.mind;
|
|
194
|
+
|
|
195
|
+
const 伝える = (kind: CompileNotice["kind"], 名: string, message: string, line = 0): void => {
|
|
196
|
+
onNotice?.({ kind, actor: 名, line, message });
|
|
197
|
+
if (typeof console !== "undefined" && console.warn) console.warn(`[dragon] ${message}`);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// **見本 (`parts`) を重ねた登場人物は中心にも枝にもしない** (review 指摘)。 後段の
|
|
201
|
+
// `mergePartsFromActors` が見本の中身を別の箱として足すため、 こちらにも載せると同じ
|
|
202
|
+
// 登場人物が 2 箇所に描かれる。 中心だけ外し忘れると、 中心が見本の記法で二重になる
|
|
203
|
+
const 見本でない: DslActor[] = [];
|
|
204
|
+
for (const a of doc.actors) {
|
|
205
|
+
if (a.partId !== undefined) {
|
|
206
|
+
伝える(
|
|
207
|
+
"part-not-drawn",
|
|
208
|
+
a.name,
|
|
209
|
+
`type: mind では見本 (${a.partId}) を中心にも枝にもできません。 見本はそのまま描き、 放射には載せません`,
|
|
210
|
+
a.pos?.line ?? 0,
|
|
211
|
+
);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
見本でない.push(a);
|
|
215
|
+
}
|
|
216
|
+
// 枝の親は矢印で決まる (#1251)。 書かなければ全て中心の直下 = 従来と同じ図になる。
|
|
217
|
+
// 規則は `type: tree` と共有する = 同じ本文で図種だけ変えた時に親子の解釈が割れない。
|
|
218
|
+
//
|
|
219
|
+
// **早期 return より前に置く** = 見本しか居ない記法で矢印を書いた時、 枝が 1 本も無いため
|
|
220
|
+
// どの矢印も親にできない。 後ろに置くと、その形で矢印が黙って消える (Round 3 の指摘と同じ理由)
|
|
221
|
+
const 枝の名前 = new Set(見本でない.map((a) => slugify(a.name)));
|
|
222
|
+
const 親 = 矢印から親を決める(doc, "mind", 枝の名前, (名, message, line) =>
|
|
223
|
+
// 親にできなかった矢印は描かれない。 知らせの種別も「矢印を落とした」 にする
|
|
224
|
+
伝える("chart-edge-dropped", 名, message, line ?? 0),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// 放射に載る登場人物が 0 人なら枠も作らない。 中身の無い枠が 1 つ残るのを避ける (#1096)。
|
|
228
|
+
// **枠を作る前に見る** = 見本しか居ない記法で作ると、 見本だけが描かれた図に空の枠が残る
|
|
229
|
+
if (見本でない.length === 0) return b.build();
|
|
230
|
+
|
|
231
|
+
b.lane("chart", { width: W + 64 });
|
|
232
|
+
|
|
233
|
+
// **同じ slug になる名前を先に見る** (`type: tree` と同じ理由)。 違う名前が同じ id に潰れると、
|
|
234
|
+
// 枝が 1 本消えたり、 枝の親を見る規則が別の枝を指したりする
|
|
235
|
+
const slug別 = new Map<string, string[]>();
|
|
236
|
+
for (const a of 見本でない) {
|
|
237
|
+
const k = slugify(a.name);
|
|
238
|
+
slug別.set(k, [...(slug別.get(k) ?? []), a.name]);
|
|
239
|
+
}
|
|
240
|
+
for (const [k, 群] of slug別) {
|
|
241
|
+
if (群.length > 1) {
|
|
242
|
+
伝える(
|
|
243
|
+
"chart-value-unreadable",
|
|
244
|
+
群[0]!,
|
|
245
|
+
`type: mind で ${群.join(" / ")} が同じ id (${k}) になります。 名前を変えてください`,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const root = 見本でない[0]!;
|
|
251
|
+
const rootId = slugify(root.name) || "root";
|
|
252
|
+
|
|
253
|
+
// **中心を子にする矢印は表せない** (#1251 Round 1 の指摘)。 中心は枝の並びに居ないため
|
|
254
|
+
// 親を持てず、 解決はできても誰にも読まれずに消える。 黙って捨てると「書いたのに
|
|
255
|
+
// 図が変わらない」 が手掛かりなしで起きるので、 行番号付きで伝える
|
|
256
|
+
for (const f of doc.flow) {
|
|
257
|
+
if (slugify(f.to) !== rootId) continue;
|
|
258
|
+
伝える(
|
|
259
|
+
"chart-edge-dropped",
|
|
260
|
+
f.to,
|
|
261
|
+
`type: mind で中心 (${truncateForMessage(f.to)}) を子にはできません (${truncateForMessage(f.from)} -> ${truncateForMessage(f.to)} を使いません)。 中心は放射の真ん中に置く 1 つだけです`,
|
|
262
|
+
f.pos?.line ?? 0,
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// **1 箱で描く種別が持てる欄は限られる**。 枝は名前と色、 中心は名前だけ。 書いても描けない
|
|
267
|
+
// 欄は伝える = 箱ごとに描いていた頃は載っていた欄で、 黙って消すと「書いたのに出ない」 が残る
|
|
268
|
+
const 描けない欄 = (a: DslActor): string[] => {
|
|
269
|
+
const out: string[] = [];
|
|
270
|
+
for (const 欄 of Object.keys(放射で描けない欄の名前) as 放射で描けない欄[]) {
|
|
271
|
+
if (!放射で描けない欄を書いたか(a, 欄)) continue;
|
|
272
|
+
const 名前 = 放射で描けない欄の名前[欄];
|
|
273
|
+
// 同じ名前を持つ欄 (`posX` と `posY`) は 1 度だけ出す
|
|
274
|
+
if (!out.includes(名前)) out.push(名前);
|
|
275
|
+
}
|
|
276
|
+
return out;
|
|
277
|
+
};
|
|
278
|
+
const 消えた欄 = new Map<string, string[]>();
|
|
279
|
+
const 記録する = (a: DslActor): void => {
|
|
280
|
+
const 欄 = 描けない欄(a);
|
|
281
|
+
if (欄.length > 0) 消えた欄.set(a.name, 欄);
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const branches: NonNullable<CdlDiagram["nodes"][number]["mindData"]>["branches"] = [];
|
|
285
|
+
const 使った = new Set<string>([rootId]);
|
|
286
|
+
記録する(root);
|
|
287
|
+
// 中心は色の欄を持たない (`MindBranchPayload` に `tone` が無い)
|
|
288
|
+
if (root.tone)
|
|
289
|
+
消えた欄.set(root.name, [...(消えた欄.get(root.name) ?? []), "色 (中心は持てない)"]);
|
|
290
|
+
|
|
291
|
+
見本でない.slice(1).forEach((a, i) => {
|
|
292
|
+
const id = slugify(a.name) || `leaf-${i}`;
|
|
293
|
+
if (使った.has(id)) {
|
|
294
|
+
伝える(
|
|
295
|
+
"chart-value-unreadable",
|
|
296
|
+
a.name,
|
|
297
|
+
`type: mind で ${a.name} が既にある id (${id}) と重なります (枝に載せません)`,
|
|
298
|
+
a.pos?.line ?? 0,
|
|
299
|
+
);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
使った.add(id);
|
|
303
|
+
記録する(a);
|
|
304
|
+
// 矢印を書かなかった枝は中心の直下。 中心を親に指した矢印も同じ値になる
|
|
305
|
+
// (中心は `見本でない` の先頭なので、 その名前の slug が `rootId` そのもの)
|
|
306
|
+
// 枝は色を持てる (`MindBranchNode.tone`)
|
|
307
|
+
branches.push({
|
|
308
|
+
id,
|
|
309
|
+
...放射に出す文字(a),
|
|
310
|
+
parent: 親.get(id) ?? rootId,
|
|
311
|
+
...(a.tone ? { tone: a.tone } : {}),
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
if (消えた欄.size > 0) {
|
|
316
|
+
const 一覧 = [...消えた欄].map(([名, 欄]) => `${名} の${欄.join(" / ")}`).join("、 ");
|
|
317
|
+
伝える(
|
|
318
|
+
"chart-value-unreadable",
|
|
319
|
+
[...消えた欄.keys()][0]!,
|
|
320
|
+
`type: mind は名前と副題 / 値、 枝の色しか描けません (描かない欄: ${一覧})。 これらを描くなら type: tree か type: flow を使ってください`,
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
b.node(`${slugify(doc.title) || "mind"}-chart`, {
|
|
325
|
+
lane: "chart",
|
|
326
|
+
stack: 0,
|
|
327
|
+
kind: "mind-map",
|
|
328
|
+
title: doc.title,
|
|
329
|
+
...図の小見出し(doc),
|
|
330
|
+
w: W,
|
|
331
|
+
h: H,
|
|
332
|
+
mindData: (() => {
|
|
333
|
+
const 中心 = 放射に出す文字(root);
|
|
334
|
+
return {
|
|
335
|
+
rootId,
|
|
336
|
+
rootTitle: 中心.title,
|
|
337
|
+
...(中心.subtitle === undefined ? {} : { rootSubtitle: 中心.subtitle }),
|
|
338
|
+
branches,
|
|
339
|
+
};
|
|
340
|
+
})(),
|
|
341
|
+
});
|
|
342
|
+
return b.build();
|
|
343
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DslActor } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* 箱に出す題を決める (#2030 で `compile.ts` から移した)。
|
|
4
|
+
*
|
|
5
|
+
* 15 図種の組み立て器が使う。 `compileC4` だけは自前で題を組む。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** 題を出さない種類。 始まりと終わりの印は丸だけを描き、中に字を入れない */
|
|
9
|
+
const 題を持たない種類: ReadonlySet<string> = new Set(["mark-start", "mark-end"]);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 箱に出す題 (#1381)。 書いていなければ名前をそのまま使う。
|
|
13
|
+
*
|
|
14
|
+
* 名前は図の中で 1 つに決まる必要がある (`focus:` と `flow:` が名前で指す) 一方、題は
|
|
15
|
+
* 重なってよい。 同じ題の箱を並べる図と、題を持たない箱は、名前と切り離さないと書けない。
|
|
16
|
+
*
|
|
17
|
+
* **始まりと終わりの印は題を持たない** (#1466)。 塗った丸と輪で描くもので、名前を出す場所が
|
|
18
|
+
* 無い。 名前は矢印の端として指すために要るので、名前をそのまま題にすると `begin` の字が
|
|
19
|
+
* 丸の上に乗る (組み立て API 側の `.mark()` は題を空で作る)。 書いた題があればそれを使う。
|
|
20
|
+
*/
|
|
21
|
+
export function 箱の題(a: DslActor): string {
|
|
22
|
+
if (a.title === undefined && a.kind !== undefined && 題を持たない種類.has(a.kind)) return "";
|
|
23
|
+
return a.title ?? a.name;
|
|
24
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 組み立てが出す知らせの形 (#2030 で `compile.ts` から移した)。
|
|
3
|
+
*
|
|
4
|
+
* 図種ごとの file が受け取り口の型として使い、`compile.ts` が再輸出して外へ出す。
|
|
5
|
+
*
|
|
6
|
+
* **葉に置く** = 型そのものは消えるが、TypeScript の取り込みの輪は残る。 輪があると
|
|
7
|
+
* 読む順で解決が変わるため、型でも輪を作らない。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** 図は出せるが書いた通りにならなかった、 という知らせ。 */
|
|
11
|
+
export type CompileNotice = {
|
|
12
|
+
kind:
|
|
13
|
+
| "relative-position-ignored"
|
|
14
|
+
| "focus-target-missing"
|
|
15
|
+
| "state-override-rejected"
|
|
16
|
+
| "external-paint-dropped"
|
|
17
|
+
// 図の中に描く部品を持たない見本を重ねた (#1017)
|
|
18
|
+
| "part-not-drawn"
|
|
19
|
+
// 向きが効かない形で `向き:` を書いた (#1494)
|
|
20
|
+
| "direction-not-honored"
|
|
21
|
+
// `倍率:` を書いた見本が、同じ名前の状態も持っていた (#1026)
|
|
22
|
+
| "scale-reserved"
|
|
23
|
+
// 部品に書いた色が効かない (#1973)。 色番号を入れる状態を 1 つも持たない部品に色番号を
|
|
24
|
+
// 書いた時と、色番号でなく色の名前を書いた時
|
|
25
|
+
| "part-color-ignored"
|
|
26
|
+
// 部品に、部品が持たない状態の名前で値を書いた (#1976)。 綴り違いと、外した欄 (`nodes`) を書いた時
|
|
27
|
+
| "part-state-missing"
|
|
28
|
+
// 部品へ引いた矢印を、部品の中のどの要素にも繋げず外した (#1979)。 要素が 2 つ以上あり名指しが無い時、
|
|
29
|
+
// 名指しした要素が部品に無い時、部品を取り込まなかった時
|
|
30
|
+
| "part-edge-dropped"
|
|
31
|
+
// 種類 (`kind`) に書いた名前が、箱の種類にも渡された部品の一覧にも無い (#2113)。 箱の種類の綴り違いも
|
|
32
|
+
// 部品の名前とみなされてここに来る。 部品の一覧を渡さない組み立てでは出さない
|
|
33
|
+
| "part-not-found"
|
|
34
|
+
// 矢印に部品の要素の名指し (`fromPartNode` / `toPartNode`) を書いたが、その端が部品でない (#1979)
|
|
35
|
+
| "part-node-ignored"
|
|
36
|
+
// 縦列に置くはずの部品が他の箱の位置の基準になっていて、縦列に置けなかった (#1980)
|
|
37
|
+
| "part-lane-ignored"
|
|
38
|
+
// 箱ごとの値や時期を読んで 1 つの図に描く図種で、読めない項目があった (#1154)。 使う図種は
|
|
39
|
+
// 各図種の組み立て (`compile/*.ts`) が決める
|
|
40
|
+
| "chart-value-unreadable"
|
|
41
|
+
// 同じ図種で、書いた矢印を描かなかった (#1154)。 関係を描かない図種と、端を描けない矢印 (工程表で
|
|
42
|
+
// 時期の無い項目を指す等、#2111)
|
|
43
|
+
| "chart-edge-dropped"
|
|
44
|
+
// 同じ名前を `states` と `values` の両方に書いた (#1162)
|
|
45
|
+
| "value-shadows-state"
|
|
46
|
+
// 式を解けず、その値を止めた (輪 / 無い名前 / 読めない式 / 数として読めない値、 #1162)
|
|
47
|
+
| "value-unresolved"
|
|
48
|
+
// 同じ名前を `values` に 2 度書いた。 先に書いた式を使う (#1162)
|
|
49
|
+
| "value-duplicate"
|
|
50
|
+
// 矢印が `actors` に無い名前を指した (#1209)
|
|
51
|
+
| "flow-actor-missing"
|
|
52
|
+
// きっかけ形の値を段に畳めなかった (段が無い / 相手が境目を通らない / 段からはみ出す、 #1161)
|
|
53
|
+
| "value-trigger-unresolved"
|
|
54
|
+
// 箱に `lane:` を書いたが、 縦列は図種が決めるため効かなかった (#1246)
|
|
55
|
+
| "lane-not-honored"
|
|
56
|
+
// `lanes:` に書いた縦列に箱が 1 つも入らなかった (#1241)
|
|
57
|
+
| "lane-declared-empty"
|
|
58
|
+
// 最上位に `eyebrow:` を書いたが、 箱ごとに分かれる図種で相手が決まらなかった (#1247)
|
|
59
|
+
| "eyebrow-not-honored"
|
|
60
|
+
// 静止した `type: flow` で、書いた矢印の端が使われなかった (#1269)
|
|
61
|
+
| "flow-endpoint-not-honored"
|
|
62
|
+
// 起点から描く動きを持たない図種で段に `draw:` を書いた (#1312)
|
|
63
|
+
| "draw-not-honored"
|
|
64
|
+
// `draw:` の語がその図種と食い違う (`type: bar` に `draw: pie`、 #1314)
|
|
65
|
+
| "draw-target-mismatch"
|
|
66
|
+
// 式が、どこにも書かれていない名前を読んだ (#1391)
|
|
67
|
+
| "formula-unresolved"
|
|
68
|
+
// 出来事が指す相手が図に無い (#1393)
|
|
69
|
+
| "event-target-missing"
|
|
70
|
+
// 順序図で面に種類を書いたが、板は名前と呼び名しか描かない (#1466)
|
|
71
|
+
| "actor-kind-not-honored"
|
|
72
|
+
// 順序図の言づてに、板が描かない飾りを書いた (#1466)。 数える飾りは `reportMessageOptionNotHonored` の一覧が持つ
|
|
73
|
+
| "message-option-not-honored"
|
|
74
|
+
// 位置のずらし (`pos` / `offsetX` / `offsetY`) を載せる相手が無いか、書いた量だけ動かせなかった (#1971)
|
|
75
|
+
| "position-offset-ignored"
|
|
76
|
+
// 組 (`groups:`) が束ねる縦列が図に無い (#1972)
|
|
77
|
+
| "group-lane-missing"
|
|
78
|
+
// 組が束ねる縦列の間に、束ねない縦列を挟んでいる (#1972)
|
|
79
|
+
| "group-lanes-apart"
|
|
80
|
+
// 矢印に書いた多重度 (`cardinality`) から端の形を描けない (#2107)。 `er` で端の形が決まる 6 語以外を
|
|
81
|
+
// 書き、端を両方は書いていない時と、`er` 以外の図種に書いた時
|
|
82
|
+
| "cardinality-not-honored"
|
|
83
|
+
// 矢印に、その図種が描かない飾り (文字 / 色 / 線種 / 多重度) を書いた (#2111)。 工程表の矢印は
|
|
84
|
+
// 前後の関係だけを使う
|
|
85
|
+
| "edge-option-not-honored"
|
|
86
|
+
// 工程表の項目の終わりが始まりより前か、状態で決まる終わりが始まりより前の値を取る (#2111)
|
|
87
|
+
| "gantt-end-before-start";
|
|
88
|
+
/** 対象の名前。 光らせる相手なら書かれた指定そのまま */
|
|
89
|
+
actor: string;
|
|
90
|
+
/** 書かれていた行 */
|
|
91
|
+
line: number;
|
|
92
|
+
message: string;
|
|
93
|
+
hint?: string;
|
|
94
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CdlDiagram } from "@cardenelabs/cdl";
|
|
2
|
+
/**
|
|
3
|
+
* 見本帳から部品を引く (#2030 で `compile.ts` から移した)。
|
|
4
|
+
*
|
|
5
|
+
* `parts-` の前置きは付けても付けなくても引ける。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** catalog を引くところだけ。 測れるかは見ない。 */
|
|
9
|
+
export function lookupPartRaw(
|
|
10
|
+
partsCatalog: Record<string, CdlDiagram>,
|
|
11
|
+
partId: string | undefined,
|
|
12
|
+
): CdlDiagram | undefined {
|
|
13
|
+
if (typeof partId !== "string" || partId.length === 0) return undefined;
|
|
14
|
+
if (Object.hasOwn(partsCatalog, partId)) return partsCatalog[partId];
|
|
15
|
+
if (Object.hasOwn(partsCatalog, `parts-${partId}`)) return partsCatalog[`parts-${partId}`];
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|