@hirokisakabe/pom 8.6.0 → 8.7.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 CHANGED
@@ -89,28 +89,28 @@ Each slide must be wrapped in a `<Slide>` element. To produce multiple slides, l
89
89
 
90
90
  ## Available Nodes
91
91
 
92
- | Node | Description |
93
- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
- | Text | Text with font styling, decoration (incl. subscript / superscript), rotation, letter spacing, glow / outline effects, inline bold/italic/underline/strike/sub/sup/highlight/color, and hyperlinks |
95
- | Ul | Unordered (bullet) list with Li items |
96
- | Ol | Ordered (numbered) list with Li items |
97
- | Image | Images from file path, URL, or base64, with optional rotation |
98
- | Table | Tables with customizable columns and rows |
99
- | Shape | PowerPoint shapes (roundRect, ellipse, etc.) with optional rotation |
100
- | Chart | Charts (bar, line, pie, area, doughnut, radar) |
101
- | Timeline | Timeline / roadmap visualizations |
102
- | Matrix | 2x2 positioning maps |
103
- | Tree | Organization charts and decision trees |
104
- | Flow | Flowcharts with nodes and edges |
105
- | ProcessArrow | Chevron-style process diagrams |
106
- | Pyramid | Pyramid diagrams for hierarchies |
107
- | Line | Horizontal / vertical lines |
108
- | Arrow | Connectors between nodes referenced by ID |
109
- | Layer | Absolute-positioned overlay container |
110
- | VStack | Vertical stack layout |
111
- | HStack | Horizontal stack layout |
112
- | Icon | Lucide icons with optional rotation |
113
- | Svg | Inline SVG graphics |
92
+ | Node | Description |
93
+ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
+ | Text | Text with font styling, decoration (incl. subscript / superscript), rotation, letter spacing, glow / outline effects, inline bold/italic/underline/strike/sub/sup/highlight/color/fontSize, and hyperlinks |
95
+ | Ul | Unordered (bullet) list with Li items |
96
+ | Ol | Ordered (numbered) list with Li items |
97
+ | Image | Images from file path, URL, or base64, with optional rotation |
98
+ | Table | Tables with customizable columns and rows |
99
+ | Shape | PowerPoint shapes (roundRect, ellipse, etc.) with optional rotation |
100
+ | Chart | Charts (bar, line, pie, area, doughnut, radar) |
101
+ | Timeline | Timeline / roadmap visualizations |
102
+ | Matrix | 2x2 positioning maps |
103
+ | Tree | Organization charts and decision trees |
104
+ | Flow | Flowcharts with nodes and edges |
105
+ | ProcessArrow | Chevron-style process diagrams |
106
+ | Pyramid | Pyramid diagrams for hierarchies |
107
+ | Line | Horizontal / vertical lines |
108
+ | Arrow | Connectors between nodes referenced by ID |
109
+ | Layer | Absolute-positioned overlay container |
110
+ | VStack | Vertical stack layout |
111
+ | HStack | Horizontal stack layout |
112
+ | Icon | Lucide icons with optional rotation |
113
+ | Svg | Inline SVG graphics |
114
114
 
115
115
  For detailed node documentation, see [Nodes](./docs/nodes.md).
116
116
 
@@ -125,6 +125,16 @@ For detailed node documentation, see [Nodes](./docs/nodes.md).
125
125
  <ChartDataPoint label="Feb" value="45" />
126
126
  </ChartSeries>
127
127
  </Chart>
128
+
129
+ <!-- Sparkline mode: hides legend / axes / margins for compact h=40 inline charts (bar / line / area) -->
130
+ <Chart chartType="bar" w="200" h="40" sparkline="true" chartColors='["0088CC"]'>
131
+ <ChartSeries name="Sales">
132
+ <ChartDataPoint label="Q1" value="100" />
133
+ <ChartDataPoint label="Q2" value="200" />
134
+ <ChartDataPoint label="Q3" value="150" />
135
+ <ChartDataPoint label="Q4" value="300" />
136
+ </ChartSeries>
137
+ </Chart>
128
138
  ```
129
139
 
130
140
  <img src="./docs/images/chart.png" alt="Chart example" width="600">
@@ -11,36 +11,52 @@ function reduceFontSize(node, targetRatio) {
11
11
  const ratio = Math.max(targetRatio, MIN_SCALE);
12
12
  let changed = false;
13
13
  let sawTarget = false;
14
+ const scale = (current) => Math.max(MIN_FONT_SIZE, Math.round(current * ratio));
15
+ const scaleRuns = (runs) => {
16
+ if (!runs) return;
17
+ for (const run of runs) {
18
+ if (run.fontSize === void 0) continue;
19
+ sawTarget = true;
20
+ const newSize = scale(run.fontSize);
21
+ if (newSize !== run.fontSize) {
22
+ run.fontSize = newSize;
23
+ changed = true;
24
+ }
25
+ }
26
+ };
14
27
  walkPOMTree(node, (n) => {
15
28
  if (n.type === "text" || n.type === "shape" || n.type === "ul" || n.type === "ol") {
16
29
  if (n.fontSize !== void 0) {
17
30
  sawTarget = true;
18
- const newSize = Math.max(MIN_FONT_SIZE, Math.round(n.fontSize * ratio));
31
+ const newSize = scale(n.fontSize);
19
32
  if (newSize !== n.fontSize) {
20
33
  n.fontSize = newSize;
21
34
  changed = true;
22
35
  }
23
36
  }
24
37
  }
25
- if (n.type === "ul" || n.type === "ol") {
26
- for (const item of n.items) if (item.fontSize !== void 0) {
38
+ if (n.type === "text") scaleRuns(n.runs);
39
+ if (n.type === "ul" || n.type === "ol") for (const item of n.items) {
40
+ if (item.fontSize !== void 0) {
27
41
  sawTarget = true;
28
- const newSize = Math.max(MIN_FONT_SIZE, Math.round(item.fontSize * ratio));
42
+ const newSize = scale(item.fontSize);
29
43
  if (newSize !== item.fontSize) {
30
44
  item.fontSize = newSize;
31
45
  changed = true;
32
46
  }
33
47
  }
48
+ scaleRuns(item.runs);
34
49
  }
35
- if (n.type === "table") {
36
- for (const row of n.rows) for (const cell of row.cells) if (cell.fontSize !== void 0) {
50
+ if (n.type === "table") for (const row of n.rows) for (const cell of row.cells) {
51
+ if (cell.fontSize !== void 0) {
37
52
  sawTarget = true;
38
- const newSize = Math.max(MIN_FONT_SIZE, Math.round(cell.fontSize * ratio));
53
+ const newSize = scale(cell.fontSize);
39
54
  if (newSize !== cell.fontSize) {
40
55
  cell.fontSize = newSize;
41
56
  changed = true;
42
57
  }
43
58
  }
59
+ scaleRuns(cell.runs);
44
60
  }
45
61
  });
46
62
  return toStrategyResult({
@@ -1 +1 @@
1
- {"version":3,"file":"reduceFontSize.js","names":[],"sources":["../../../src/autoFit/strategies/reduceFontSize.ts"],"sourcesContent":["import type { POMNode } from \"../../types.ts\";\nimport { walkPOMTree } from \"../../shared/walkTree.ts\";\nimport type { AutoFitStrategyResult } from \"../strategyResult.ts\";\nimport { toStrategyResult } from \"../strategyResult.ts\";\n\nconst MIN_FONT_SIZE = 10;\nconst MIN_SCALE = 0.6;\n\n/**\n * テキスト系ノードの fontSize を縮小する。\n * 対象: text, ul, ol, shape\n */\nexport function reduceFontSize(\n node: POMNode,\n targetRatio: number,\n): AutoFitStrategyResult {\n const ratio = Math.max(targetRatio, MIN_SCALE);\n let changed = false;\n let sawTarget = false;\n\n walkPOMTree(node, (n) => {\n if (\n n.type === \"text\" ||\n n.type === \"shape\" ||\n n.type === \"ul\" ||\n n.type === \"ol\"\n ) {\n if (n.fontSize !== undefined) {\n sawTarget = true;\n const newSize = Math.max(MIN_FONT_SIZE, Math.round(n.fontSize * ratio));\n if (newSize !== n.fontSize) {\n n.fontSize = newSize;\n changed = true;\n }\n }\n }\n\n // ul/ol の li 要素の fontSize も縮小\n if (n.type === \"ul\" || n.type === \"ol\") {\n for (const item of n.items) {\n if (item.fontSize !== undefined) {\n sawTarget = true;\n const newSize = Math.max(\n MIN_FONT_SIZE,\n Math.round(item.fontSize * ratio),\n );\n if (newSize !== item.fontSize) {\n item.fontSize = newSize;\n changed = true;\n }\n }\n }\n }\n\n // table セルの fontSize も縮小\n if (n.type === \"table\") {\n for (const row of n.rows) {\n for (const cell of row.cells) {\n if (cell.fontSize !== undefined) {\n sawTarget = true;\n const newSize = Math.max(\n MIN_FONT_SIZE,\n Math.round(cell.fontSize * ratio),\n );\n if (newSize !== cell.fontSize) {\n cell.fontSize = newSize;\n changed = true;\n }\n }\n }\n }\n }\n });\n\n return toStrategyResult({ changed, sawTarget });\n}\n"],"mappings":";;;AAKA,MAAM,gBAAgB;AACtB,MAAM,YAAY;;;;;AAMlB,SAAgB,eACd,MACA,aACuB;CACvB,MAAM,QAAQ,KAAK,IAAI,aAAa,SAAS;CAC7C,IAAI,UAAU;CACd,IAAI,YAAY;CAEhB,YAAY,OAAO,MAAM;EACvB,IACE,EAAE,SAAS,UACX,EAAE,SAAS,WACX,EAAE,SAAS,QACX,EAAE,SAAS;OAEP,EAAE,aAAa,KAAA,GAAW;IAC5B,YAAY;IACZ,MAAM,UAAU,KAAK,IAAI,eAAe,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;IACtE,IAAI,YAAY,EAAE,UAAU;KAC1B,EAAE,WAAW;KACb,UAAU;IACZ;GACF;;EAIF,IAAI,EAAE,SAAS,QAAQ,EAAE,SAAS;QAC3B,MAAM,QAAQ,EAAE,OACnB,IAAI,KAAK,aAAa,KAAA,GAAW;IAC/B,YAAY;IACZ,MAAM,UAAU,KAAK,IACnB,eACA,KAAK,MAAM,KAAK,WAAW,KAAK,CAClC;IACA,IAAI,YAAY,KAAK,UAAU;KAC7B,KAAK,WAAW;KAChB,UAAU;IACZ;GACF;;EAKJ,IAAI,EAAE,SAAS;QACR,MAAM,OAAO,EAAE,MAClB,KAAK,MAAM,QAAQ,IAAI,OACrB,IAAI,KAAK,aAAa,KAAA,GAAW;IAC/B,YAAY;IACZ,MAAM,UAAU,KAAK,IACnB,eACA,KAAK,MAAM,KAAK,WAAW,KAAK,CAClC;IACA,IAAI,YAAY,KAAK,UAAU;KAC7B,KAAK,WAAW;KAChB,UAAU;IACZ;GACF;;CAIR,CAAC;CAED,OAAO,iBAAiB;EAAE;EAAS;CAAU,CAAC;AAChD"}
1
+ {"version":3,"file":"reduceFontSize.js","names":[],"sources":["../../../src/autoFit/strategies/reduceFontSize.ts"],"sourcesContent":["import type { POMNode } from \"../../types.ts\";\nimport { walkPOMTree } from \"../../shared/walkTree.ts\";\nimport type { AutoFitStrategyResult } from \"../strategyResult.ts\";\nimport { toStrategyResult } from \"../strategyResult.ts\";\n\nconst MIN_FONT_SIZE = 10;\nconst MIN_SCALE = 0.6;\n\n/**\n * テキスト系ノードの fontSize を縮小する。\n * 対象: text, ul, ol, shape\n */\nexport function reduceFontSize(\n node: POMNode,\n targetRatio: number,\n): AutoFitStrategyResult {\n const ratio = Math.max(targetRatio, MIN_SCALE);\n let changed = false;\n let sawTarget = false;\n\n const scale = (current: number) =>\n Math.max(MIN_FONT_SIZE, Math.round(current * ratio));\n\n const scaleRuns = (runs: { fontSize?: number }[] | undefined) => {\n if (!runs) return;\n for (const run of runs) {\n if (run.fontSize === undefined) continue;\n sawTarget = true;\n const newSize = scale(run.fontSize);\n if (newSize !== run.fontSize) {\n run.fontSize = newSize;\n changed = true;\n }\n }\n };\n\n walkPOMTree(node, (n) => {\n if (\n n.type === \"text\" ||\n n.type === \"shape\" ||\n n.type === \"ul\" ||\n n.type === \"ol\"\n ) {\n if (n.fontSize !== undefined) {\n sawTarget = true;\n const newSize = scale(n.fontSize);\n if (newSize !== n.fontSize) {\n n.fontSize = newSize;\n changed = true;\n }\n }\n }\n\n // text の <Span fontSize> による run 単位上書きも一緒に縮小する\n // (shape は runs フィールドを持たない)\n if (n.type === \"text\") {\n scaleRuns(n.runs);\n }\n\n // ul/ol の li 要素の fontSize と <Span fontSize> による run 単位上書きも縮小\n if (n.type === \"ul\" || n.type === \"ol\") {\n for (const item of n.items) {\n if (item.fontSize !== undefined) {\n sawTarget = true;\n const newSize = scale(item.fontSize);\n if (newSize !== item.fontSize) {\n item.fontSize = newSize;\n changed = true;\n }\n }\n scaleRuns(item.runs);\n }\n }\n\n // table セルの fontSize と <Span fontSize> による run 単位上書きも縮小\n if (n.type === \"table\") {\n for (const row of n.rows) {\n for (const cell of row.cells) {\n if (cell.fontSize !== undefined) {\n sawTarget = true;\n const newSize = scale(cell.fontSize);\n if (newSize !== cell.fontSize) {\n cell.fontSize = newSize;\n changed = true;\n }\n }\n scaleRuns(cell.runs);\n }\n }\n }\n });\n\n return toStrategyResult({ changed, sawTarget });\n}\n"],"mappings":";;;AAKA,MAAM,gBAAgB;AACtB,MAAM,YAAY;;;;;AAMlB,SAAgB,eACd,MACA,aACuB;CACvB,MAAM,QAAQ,KAAK,IAAI,aAAa,SAAS;CAC7C,IAAI,UAAU;CACd,IAAI,YAAY;CAEhB,MAAM,SAAS,YACb,KAAK,IAAI,eAAe,KAAK,MAAM,UAAU,KAAK,CAAC;CAErD,MAAM,aAAa,SAA8C;EAC/D,IAAI,CAAC,MAAM;EACX,KAAK,MAAM,OAAO,MAAM;GACtB,IAAI,IAAI,aAAa,KAAA,GAAW;GAChC,YAAY;GACZ,MAAM,UAAU,MAAM,IAAI,QAAQ;GAClC,IAAI,YAAY,IAAI,UAAU;IAC5B,IAAI,WAAW;IACf,UAAU;GACZ;EACF;CACF;CAEA,YAAY,OAAO,MAAM;EACvB,IACE,EAAE,SAAS,UACX,EAAE,SAAS,WACX,EAAE,SAAS,QACX,EAAE,SAAS;OAEP,EAAE,aAAa,KAAA,GAAW;IAC5B,YAAY;IACZ,MAAM,UAAU,MAAM,EAAE,QAAQ;IAChC,IAAI,YAAY,EAAE,UAAU;KAC1B,EAAE,WAAW;KACb,UAAU;IACZ;GACF;;EAKF,IAAI,EAAE,SAAS,QACb,UAAU,EAAE,IAAI;EAIlB,IAAI,EAAE,SAAS,QAAQ,EAAE,SAAS,MAChC,KAAK,MAAM,QAAQ,EAAE,OAAO;GAC1B,IAAI,KAAK,aAAa,KAAA,GAAW;IAC/B,YAAY;IACZ,MAAM,UAAU,MAAM,KAAK,QAAQ;IACnC,IAAI,YAAY,KAAK,UAAU;KAC7B,KAAK,WAAW;KAChB,UAAU;IACZ;GACF;GACA,UAAU,KAAK,IAAI;EACrB;EAIF,IAAI,EAAE,SAAS,SACb,KAAK,MAAM,OAAO,EAAE,MAClB,KAAK,MAAM,QAAQ,IAAI,OAAO;GAC5B,IAAI,KAAK,aAAa,KAAA,GAAW;IAC/B,YAAY;IACZ,MAAM,UAAU,MAAM,KAAK,QAAQ;IACnC,IAAI,YAAY,KAAK,UAAU;KAC7B,KAAK,WAAW;KAChB,UAAU;IACZ;GACF;GACA,UAAU,KAAK,IAAI;EACrB;CAGN,CAAC;CAED,OAAO,iBAAiB;EAAE;EAAS;CAAU,CAAC;AAChD"}
@@ -13,6 +13,18 @@ function uniformScale(node, targetRatio) {
13
13
  const ratio = Math.max(targetRatio, MIN_SCALE);
14
14
  let changed = false;
15
15
  let sawTarget = false;
16
+ const scaleRunFontSizes = (runs) => {
17
+ if (!runs) return;
18
+ for (const run of runs) {
19
+ if (run.fontSize === void 0) continue;
20
+ sawTarget = true;
21
+ const newVal = scaleNumber(run.fontSize, ratio, 8);
22
+ if (newVal !== run.fontSize) {
23
+ run.fontSize = newVal;
24
+ changed = true;
25
+ }
26
+ }
27
+ };
16
28
  walkPOMTree(node, (n) => {
17
29
  if ("fontSize" in n && typeof n.fontSize === "number") {
18
30
  sawTarget = true;
@@ -22,6 +34,7 @@ function uniformScale(node, targetRatio) {
22
34
  changed = true;
23
35
  }
24
36
  }
37
+ if (n.type === "text") scaleRunFontSizes(n.runs);
25
38
  if ((n.type === "vstack" || n.type === "hstack") && n.gap !== void 0) {
26
39
  sawTarget = true;
27
40
  const newVal = scaleNumber(n.gap, ratio, 1);
@@ -56,8 +69,8 @@ function uniformScale(node, targetRatio) {
56
69
  }
57
70
  }
58
71
  }
59
- if (n.type === "ul" || n.type === "ol") {
60
- for (const item of n.items) if (item.fontSize !== void 0) {
72
+ if (n.type === "ul" || n.type === "ol") for (const item of n.items) {
73
+ if (item.fontSize !== void 0) {
61
74
  sawTarget = true;
62
75
  const newVal = scaleNumber(item.fontSize, ratio, 8);
63
76
  if (newVal !== item.fontSize) {
@@ -65,6 +78,7 @@ function uniformScale(node, targetRatio) {
65
78
  changed = true;
66
79
  }
67
80
  }
81
+ scaleRunFontSizes(item.runs);
68
82
  }
69
83
  if (n.type === "icon" && n.size !== void 0) {
70
84
  sawTarget = true;
@@ -74,8 +88,8 @@ function uniformScale(node, targetRatio) {
74
88
  changed = true;
75
89
  }
76
90
  }
77
- if (n.type === "table") {
78
- for (const row of n.rows) for (const cell of row.cells) if (cell.fontSize !== void 0) {
91
+ if (n.type === "table") for (const row of n.rows) for (const cell of row.cells) {
92
+ if (cell.fontSize !== void 0) {
79
93
  sawTarget = true;
80
94
  const newVal = scaleNumber(cell.fontSize, ratio, 8);
81
95
  if (newVal !== cell.fontSize) {
@@ -83,6 +97,7 @@ function uniformScale(node, targetRatio) {
83
97
  changed = true;
84
98
  }
85
99
  }
100
+ scaleRunFontSizes(cell.runs);
86
101
  }
87
102
  });
88
103
  return toStrategyResult({
@@ -1 +1 @@
1
- {"version":3,"file":"uniformScale.js","names":[],"sources":["../../../src/autoFit/strategies/uniformScale.ts"],"sourcesContent":["import type { POMNode } from \"../../types.ts\";\nimport { walkPOMTree } from \"../../shared/walkTree.ts\";\nimport { mapBoxSpacing } from \"../../shared/boxSpacing.ts\";\nimport type { AutoFitStrategyResult } from \"../strategyResult.ts\";\nimport { toStrategyResult } from \"../strategyResult.ts\";\n\nconst MIN_SCALE = 0.5;\n\nfunction scaleNumber(value: number, ratio: number, min: number): number {\n return Math.max(min, Math.round(value * ratio));\n}\n\n/**\n * 全サイズ関連プロパティを一律スケーリングする(フォールバック)。\n */\nexport function uniformScale(\n node: POMNode,\n targetRatio: number,\n): AutoFitStrategyResult {\n const ratio = Math.max(targetRatio, MIN_SCALE);\n let changed = false;\n let sawTarget = false;\n\n walkPOMTree(node, (n) => {\n // fontSize\n if (\"fontSize\" in n && typeof n.fontSize === \"number\") {\n sawTarget = true;\n const newVal = scaleNumber(n.fontSize, ratio, 8);\n if (newVal !== n.fontSize) {\n (n as { fontSize: number }).fontSize = newVal;\n changed = true;\n }\n }\n\n // gap (vstack/hstack)\n if ((n.type === \"vstack\" || n.type === \"hstack\") && n.gap !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(n.gap, ratio, 1);\n if (newVal !== n.gap) {\n n.gap = newVal;\n changed = true;\n }\n }\n\n // padding\n if (n.padding !== undefined) {\n sawTarget = true;\n const result = mapBoxSpacing(n.padding, (v) => scaleNumber(v, ratio, 1));\n if (result.changed) {\n n.padding = result.value;\n changed = true;\n }\n }\n\n // table: defaultRowHeight, row.height\n if (n.type === \"table\") {\n if (n.defaultRowHeight !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(n.defaultRowHeight, ratio, 16);\n if (newVal !== n.defaultRowHeight) {\n n.defaultRowHeight = newVal;\n changed = true;\n }\n }\n for (const row of n.rows) {\n if (row.height !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(row.height, ratio, 16);\n if (newVal !== row.height) {\n row.height = newVal;\n changed = true;\n }\n }\n }\n }\n\n // ul/ol items fontSize\n if (n.type === \"ul\" || n.type === \"ol\") {\n for (const item of n.items) {\n if (item.fontSize !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(item.fontSize, ratio, 8);\n if (newVal !== item.fontSize) {\n item.fontSize = newVal;\n changed = true;\n }\n }\n }\n }\n\n // icon size\n if (n.type === \"icon\" && n.size !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(n.size, ratio, 8);\n if (newVal !== n.size) {\n n.size = newVal;\n changed = true;\n }\n }\n\n // table cells fontSize\n if (n.type === \"table\") {\n for (const row of n.rows) {\n for (const cell of row.cells) {\n if (cell.fontSize !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(cell.fontSize, ratio, 8);\n if (newVal !== cell.fontSize) {\n cell.fontSize = newVal;\n changed = true;\n }\n }\n }\n }\n }\n });\n\n return toStrategyResult({ changed, sawTarget });\n}\n"],"mappings":";;;;AAMA,MAAM,YAAY;AAElB,SAAS,YAAY,OAAe,OAAe,KAAqB;CACtE,OAAO,KAAK,IAAI,KAAK,KAAK,MAAM,QAAQ,KAAK,CAAC;AAChD;;;;AAKA,SAAgB,aACd,MACA,aACuB;CACvB,MAAM,QAAQ,KAAK,IAAI,aAAa,SAAS;CAC7C,IAAI,UAAU;CACd,IAAI,YAAY;CAEhB,YAAY,OAAO,MAAM;EAEvB,IAAI,cAAc,KAAK,OAAO,EAAE,aAAa,UAAU;GACrD,YAAY;GACZ,MAAM,SAAS,YAAY,EAAE,UAAU,OAAO,CAAC;GAC/C,IAAI,WAAW,EAAE,UAAU;IACzB,EAA4B,WAAW;IACvC,UAAU;GACZ;EACF;EAGA,KAAK,EAAE,SAAS,YAAY,EAAE,SAAS,aAAa,EAAE,QAAQ,KAAA,GAAW;GACvE,YAAY;GACZ,MAAM,SAAS,YAAY,EAAE,KAAK,OAAO,CAAC;GAC1C,IAAI,WAAW,EAAE,KAAK;IACpB,EAAE,MAAM;IACR,UAAU;GACZ;EACF;EAGA,IAAI,EAAE,YAAY,KAAA,GAAW;GAC3B,YAAY;GACZ,MAAM,SAAS,cAAc,EAAE,UAAU,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC;GACvE,IAAI,OAAO,SAAS;IAClB,EAAE,UAAU,OAAO;IACnB,UAAU;GACZ;EACF;EAGA,IAAI,EAAE,SAAS,SAAS;GACtB,IAAI,EAAE,qBAAqB,KAAA,GAAW;IACpC,YAAY;IACZ,MAAM,SAAS,YAAY,EAAE,kBAAkB,OAAO,EAAE;IACxD,IAAI,WAAW,EAAE,kBAAkB;KACjC,EAAE,mBAAmB;KACrB,UAAU;IACZ;GACF;GACA,KAAK,MAAM,OAAO,EAAE,MAClB,IAAI,IAAI,WAAW,KAAA,GAAW;IAC5B,YAAY;IACZ,MAAM,SAAS,YAAY,IAAI,QAAQ,OAAO,EAAE;IAChD,IAAI,WAAW,IAAI,QAAQ;KACzB,IAAI,SAAS;KACb,UAAU;IACZ;GACF;EAEJ;EAGA,IAAI,EAAE,SAAS,QAAQ,EAAE,SAAS;QAC3B,MAAM,QAAQ,EAAE,OACnB,IAAI,KAAK,aAAa,KAAA,GAAW;IAC/B,YAAY;IACZ,MAAM,SAAS,YAAY,KAAK,UAAU,OAAO,CAAC;IAClD,IAAI,WAAW,KAAK,UAAU;KAC5B,KAAK,WAAW;KAChB,UAAU;IACZ;GACF;;EAKJ,IAAI,EAAE,SAAS,UAAU,EAAE,SAAS,KAAA,GAAW;GAC7C,YAAY;GACZ,MAAM,SAAS,YAAY,EAAE,MAAM,OAAO,CAAC;GAC3C,IAAI,WAAW,EAAE,MAAM;IACrB,EAAE,OAAO;IACT,UAAU;GACZ;EACF;EAGA,IAAI,EAAE,SAAS;QACR,MAAM,OAAO,EAAE,MAClB,KAAK,MAAM,QAAQ,IAAI,OACrB,IAAI,KAAK,aAAa,KAAA,GAAW;IAC/B,YAAY;IACZ,MAAM,SAAS,YAAY,KAAK,UAAU,OAAO,CAAC;IAClD,IAAI,WAAW,KAAK,UAAU;KAC5B,KAAK,WAAW;KAChB,UAAU;IACZ;GACF;;CAIR,CAAC;CAED,OAAO,iBAAiB;EAAE;EAAS;CAAU,CAAC;AAChD"}
1
+ {"version":3,"file":"uniformScale.js","names":[],"sources":["../../../src/autoFit/strategies/uniformScale.ts"],"sourcesContent":["import type { POMNode } from \"../../types.ts\";\nimport { walkPOMTree } from \"../../shared/walkTree.ts\";\nimport { mapBoxSpacing } from \"../../shared/boxSpacing.ts\";\nimport type { AutoFitStrategyResult } from \"../strategyResult.ts\";\nimport { toStrategyResult } from \"../strategyResult.ts\";\n\nconst MIN_SCALE = 0.5;\n\nfunction scaleNumber(value: number, ratio: number, min: number): number {\n return Math.max(min, Math.round(value * ratio));\n}\n\n/**\n * 全サイズ関連プロパティを一律スケーリングする(フォールバック)。\n */\nexport function uniformScale(\n node: POMNode,\n targetRatio: number,\n): AutoFitStrategyResult {\n const ratio = Math.max(targetRatio, MIN_SCALE);\n let changed = false;\n let sawTarget = false;\n\n const scaleRunFontSizes = (runs: { fontSize?: number }[] | undefined) => {\n if (!runs) return;\n for (const run of runs) {\n if (run.fontSize === undefined) continue;\n sawTarget = true;\n const newVal = scaleNumber(run.fontSize, ratio, 8);\n if (newVal !== run.fontSize) {\n run.fontSize = newVal;\n changed = true;\n }\n }\n };\n\n walkPOMTree(node, (n) => {\n // fontSize\n if (\"fontSize\" in n && typeof n.fontSize === \"number\") {\n sawTarget = true;\n const newVal = scaleNumber(n.fontSize, ratio, 8);\n if (newVal !== n.fontSize) {\n (n as { fontSize: number }).fontSize = newVal;\n changed = true;\n }\n }\n\n // text の <Span fontSize> による run 単位上書きも一緒にスケーリング\n // (shape は runs フィールドを持たない)\n if (n.type === \"text\") {\n scaleRunFontSizes(n.runs);\n }\n\n // gap (vstack/hstack)\n if ((n.type === \"vstack\" || n.type === \"hstack\") && n.gap !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(n.gap, ratio, 1);\n if (newVal !== n.gap) {\n n.gap = newVal;\n changed = true;\n }\n }\n\n // padding\n if (n.padding !== undefined) {\n sawTarget = true;\n const result = mapBoxSpacing(n.padding, (v) => scaleNumber(v, ratio, 1));\n if (result.changed) {\n n.padding = result.value;\n changed = true;\n }\n }\n\n // table: defaultRowHeight, row.height\n if (n.type === \"table\") {\n if (n.defaultRowHeight !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(n.defaultRowHeight, ratio, 16);\n if (newVal !== n.defaultRowHeight) {\n n.defaultRowHeight = newVal;\n changed = true;\n }\n }\n for (const row of n.rows) {\n if (row.height !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(row.height, ratio, 16);\n if (newVal !== row.height) {\n row.height = newVal;\n changed = true;\n }\n }\n }\n }\n\n // ul/ol items fontSize と Li 内 <Span fontSize> も一緒にスケーリング\n if (n.type === \"ul\" || n.type === \"ol\") {\n for (const item of n.items) {\n if (item.fontSize !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(item.fontSize, ratio, 8);\n if (newVal !== item.fontSize) {\n item.fontSize = newVal;\n changed = true;\n }\n }\n scaleRunFontSizes(item.runs);\n }\n }\n\n // icon size\n if (n.type === \"icon\" && n.size !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(n.size, ratio, 8);\n if (newVal !== n.size) {\n n.size = newVal;\n changed = true;\n }\n }\n\n // table cells fontSize と Td 内 <Span fontSize> も一緒にスケーリング\n if (n.type === \"table\") {\n for (const row of n.rows) {\n for (const cell of row.cells) {\n if (cell.fontSize !== undefined) {\n sawTarget = true;\n const newVal = scaleNumber(cell.fontSize, ratio, 8);\n if (newVal !== cell.fontSize) {\n cell.fontSize = newVal;\n changed = true;\n }\n }\n scaleRunFontSizes(cell.runs);\n }\n }\n }\n });\n\n return toStrategyResult({ changed, sawTarget });\n}\n"],"mappings":"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"}
@@ -368,7 +368,8 @@ const NODE_COERCION_MAP = {
368
368
  showTitle: "boolean",
369
369
  title: "string",
370
370
  chartColors: "json",
371
- radarStyle: "string"
371
+ radarStyle: "string",
372
+ sparkline: "boolean"
372
373
  },
373
374
  timeline: {
374
375
  ...BASE_RULES,
@@ -556,6 +557,7 @@ const CHILD_ELEMENT_COERCION_MAP = {
556
557
  Span: {
557
558
  color: "string",
558
559
  fontFamily: "string",
560
+ fontSize: "number",
559
561
  letterSpacing: "number"
560
562
  }
561
563
  };
@@ -1 +1 @@
1
- {"version":3,"file":"coercionRules.js","names":[],"sources":["../../src/parseXml/coercionRules.ts"],"sourcesContent":["/**\n * 明示的な型変換ルール定義\n *\n * Zod の内部構造(_def)に依存せず、XML 属性値の文字列→適切な型への変換ルールを\n * 静的に定義する。各ノードタイプ・子要素タイプごとに変換テーブルを持つ。\n */\n\n// ===== CoercionRule 型定義 =====\nexport type CoercionRule =\n | \"number\"\n | \"boolean\"\n | \"string\" // string, enum を含む\n | \"json\" // array, object, record, tuple → JSON.parse\n | { type: \"literal\"; value: string | number | boolean }\n | { type: \"union\"; options: CoercionRule[] }\n | { type: \"object\"; shape: Record<string, CoercionRule> };\n\n// ===== 変換関数 =====\n\nexport function coerceWithRule(\n value: string,\n rule: CoercionRule,\n): { value: unknown; error: string | null } {\n if (rule === \"number\") {\n if (value === \"\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n const num = Number(value);\n if (isNaN(num)) {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n return { value: num, error: null };\n }\n if (rule === \"boolean\") {\n if (value !== \"true\" && value !== \"false\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to boolean (expected \"true\" or \"false\")`,\n };\n }\n return { value: value === \"true\", error: null };\n }\n if (rule === \"string\") {\n return { value, error: null };\n }\n if (rule === \"json\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n // オブジェクト型のルール\n if (rule.type === \"literal\") {\n return { value: rule.value, error: null };\n }\n if (rule.type === \"union\") {\n return { value: coerceUnionWithRules(value, rule.options), error: null };\n }\n if (rule.type === \"object\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n return { value: coerceFallback(value), error: null };\n}\n\nexport function coerceUnionWithRules(\n value: string,\n options: CoercionRule[],\n): unknown {\n // boolean を試行\n if ((value === \"true\" || value === \"false\") && options.includes(\"boolean\")) {\n return value === \"true\";\n }\n\n // number を試行\n if (options.includes(\"number\")) {\n const num = Number(value);\n if (!isNaN(num) && value !== \"\") {\n return num;\n }\n }\n\n // literal を試行\n for (const opt of options) {\n if (typeof opt === \"object\" && opt.type === \"literal\") {\n if (`${opt.value as string | number}` === value) return opt.value;\n }\n }\n\n // object/json を試行(JSON パース)\n if (\n options.some(\n (opt) =>\n opt === \"json\" || (typeof opt === \"object\" && opt.type === \"object\"),\n )\n ) {\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n }\n\n // string にフォールバック\n return value;\n}\n\nexport function coerceFallback(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n const num = Number(value);\n if (value !== \"\" && !isNaN(num)) return num;\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n return value;\n}\n\n/**\n * CoercionRule からオブジェクト型の shape を取得する。\n * dot notation の展開で使用。\n */\nexport function getObjectShapeFromRule(\n rule: CoercionRule,\n): Record<string, CoercionRule> | undefined {\n if (typeof rule === \"object\" && rule.type === \"object\") {\n return rule.shape;\n }\n if (typeof rule === \"object\" && rule.type === \"union\") {\n const objectOpt = rule.options.find(\n (opt): opt is { type: \"object\"; shape: Record<string, CoercionRule> } =>\n typeof opt === \"object\" && opt.type === \"object\",\n );\n return objectOpt?.shape;\n }\n return undefined;\n}\n\n/**\n * boolean と object の union かどうかを判定する。\n * endArrow=\"true\" と endArrow.type=\"triangle\" の共存を許可するために使用。\n */\nexport function isBooleanObjectUnionRule(rule: CoercionRule): boolean {\n if (typeof rule === \"string\") return false;\n if (rule.type !== \"union\") return false;\n const hasBoolean = rule.options.includes(\"boolean\");\n const hasObject = rule.options.some(\n (opt) => typeof opt === \"object\" && opt.type === \"object\",\n );\n return hasBoolean && hasObject;\n}\n\ntype ResolvedMixedNotationShorthand =\n | { mode: \"merge\"; value: Record<string, unknown> }\n | { mode: \"ignore\" }\n | { mode: \"conflict\" };\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isDirectionalBoxShape(shape: Record<string, CoercionRule>): boolean {\n const keys = Object.keys(shape).sort();\n return (\n keys.length === 4 &&\n keys[0] === \"bottom\" &&\n keys[1] === \"left\" &&\n keys[2] === \"right\" &&\n keys[3] === \"top\"\n );\n}\n\n/**\n * 同一属性で shorthand と dot notation を併用したときに、\n * shorthand 側をどのように扱うかを解決する。\n *\n * - merge: shorthand をオブジェクト化して dot notation 側で上書き\n * - ignore: boolean shorthand を無視して dot notation を優先\n * - conflict: 併用不可(従来どおりエラー)\n */\nexport function resolveMixedNotationShorthand(\n value: string,\n rule: CoercionRule,\n): ResolvedMixedNotationShorthand {\n const objectShape = getObjectShapeFromRule(rule);\n if (!objectShape) return { mode: \"conflict\" };\n\n if (\n isBooleanObjectUnionRule(rule) &&\n (value === \"true\" || value === \"false\")\n ) {\n return { mode: \"ignore\" };\n }\n\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) return { mode: \"conflict\" };\n\n if (isPlainObject(coerced.value)) {\n return { mode: \"merge\", value: coerced.value };\n }\n\n if (typeof coerced.value === \"number\" && isDirectionalBoxShape(objectShape)) {\n return {\n mode: \"merge\",\n value: {\n top: coerced.value,\n right: coerced.value,\n bottom: coerced.value,\n left: coerced.value,\n },\n };\n }\n\n return { mode: \"conflict\" };\n}\n\n// ===== 共通変換ルール =====\n\nconst LENGTH_RULE: CoercionRule = {\n type: \"union\",\n options: [\"number\", { type: \"literal\", value: \"max\" }, \"string\"],\n};\n\nconst PADDING_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"number\",\n {\n type: \"object\",\n shape: {\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n },\n },\n ],\n};\n\nconst BORDER_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", dashType: \"string\" },\n};\n\nconst FILL_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", transparency: \"number\" },\n};\n\nconst SHADOW_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n opacity: \"number\",\n blur: \"number\",\n angle: \"number\",\n offset: \"number\",\n color: \"string\",\n },\n};\n\nconst UNDERLINE_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"boolean\",\n { type: \"object\", shape: { style: \"string\", color: \"string\" } },\n ],\n};\n\nconst TEXT_GLOW_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", opacity: \"number\", color: \"string\" },\n};\n\nconst TEXT_OUTLINE_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", color: \"string\" },\n};\n\nconst LINE_ARROW_RULE: CoercionRule = {\n type: \"union\",\n options: [\"boolean\", { type: \"object\", shape: { type: \"string\" } }],\n};\n\nconst BACKGROUND_IMAGE_RULE: CoercionRule = {\n type: \"object\",\n shape: { src: \"string\", sizing: \"string\" },\n};\n\nconst TREE_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\" },\n};\n\nconst FLOW_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n color: \"string\",\n width: \"number\",\n arrowType: \"string\",\n labelColor: \"string\",\n },\n};\n\nconst IMAGE_SIZING_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n w: \"number\",\n h: \"number\",\n x: \"number\",\n y: \"number\",\n },\n};\n\n// ===== Base node 属性 =====\nconst BASE_RULES: Record<string, CoercionRule> = {\n id: \"string\",\n w: LENGTH_RULE,\n h: LENGTH_RULE,\n grow: \"number\",\n minW: \"number\",\n maxW: \"number\",\n minH: \"number\",\n maxH: \"number\",\n padding: PADDING_RULE,\n margin: PADDING_RULE,\n backgroundColor: \"string\",\n backgroundGradient: \"string\",\n backgroundImage: BACKGROUND_IMAGE_RULE,\n border: BORDER_STYLE_RULE,\n borderTop: BORDER_STYLE_RULE,\n borderRight: BORDER_STYLE_RULE,\n borderBottom: BORDER_STYLE_RULE,\n borderLeft: BORDER_STYLE_RULE,\n borderRadius: \"number\",\n opacity: \"number\",\n zIndex: \"number\",\n position: \"string\",\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n alignSelf: \"string\",\n shadow: SHADOW_STYLE_RULE,\n};\n\n// テキスト系の共通属性\nconst TEXT_STYLE_RULES: Record<string, CoercionRule> = {\n fontSize: \"number\",\n color: \"string\",\n textAlign: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n lineHeight: \"number\",\n};\n\n// ===== ノードタイプ別の変換ルールマップ =====\nexport const NODE_COERCION_MAP: Record<string, Record<string, CoercionRule>> = {\n text: {\n ...BASE_RULES,\n text: \"string\",\n rotate: \"number\",\n ...TEXT_STYLE_RULES,\n letterSpacing: \"number\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n },\n ul: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n },\n ol: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n numberType: \"string\",\n numberStartAt: \"number\",\n },\n image: {\n ...BASE_RULES,\n src: \"string\",\n sizing: IMAGE_SIZING_RULE,\n rotate: \"number\",\n },\n icon: {\n ...BASE_RULES,\n name: \"string\",\n size: \"number\",\n color: \"string\",\n variant: \"string\",\n bgColor: \"string\",\n rotate: \"number\",\n },\n svg: {\n ...BASE_RULES,\n color: \"string\",\n },\n table: {\n ...BASE_RULES,\n columns: \"json\",\n rows: \"json\",\n defaultRowHeight: \"number\",\n cellBorder: BORDER_STYLE_RULE,\n },\n shape: {\n ...BASE_RULES,\n shapeType: \"string\",\n text: \"string\",\n rotate: \"number\",\n fill: FILL_STYLE_RULE,\n line: BORDER_STYLE_RULE,\n ...TEXT_STYLE_RULES,\n },\n chart: {\n ...BASE_RULES,\n chartType: \"string\",\n data: \"json\",\n showLegend: \"boolean\",\n showTitle: \"boolean\",\n title: \"string\",\n chartColors: \"json\",\n radarStyle: \"string\",\n },\n timeline: {\n ...BASE_RULES,\n direction: \"string\",\n items: \"json\",\n dateColor: \"string\",\n titleColor: \"string\",\n descriptionColor: \"string\",\n },\n matrix: {\n ...BASE_RULES,\n axes: \"json\",\n quadrants: \"json\",\n items: \"json\",\n axisLabelColor: \"string\",\n quadrantLabelColor: \"string\",\n itemLabelColor: \"string\",\n },\n tree: {\n ...BASE_RULES,\n layout: \"string\",\n nodeShape: \"string\",\n data: \"json\",\n textColor: \"string\",\n connectorStyle: TREE_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n levelGap: \"number\",\n siblingGap: \"number\",\n },\n flow: {\n ...BASE_RULES,\n direction: \"string\",\n nodes: \"json\",\n connections: \"json\",\n connectorStyle: FLOW_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n nodeGap: \"number\",\n },\n processArrow: {\n ...BASE_RULES,\n direction: \"string\",\n steps: \"json\",\n itemWidth: \"number\",\n itemHeight: \"number\",\n gap: \"number\",\n fontSize: \"number\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n },\n pyramid: {\n ...BASE_RULES,\n direction: \"string\",\n levels: \"json\",\n fontSize: \"number\",\n bold: \"boolean\",\n fontFamily: \"string\",\n },\n line: {\n ...BASE_RULES,\n x1: \"number\",\n y1: \"number\",\n x2: \"number\",\n y2: \"number\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n arrow: {\n ...BASE_RULES,\n from: \"string\",\n to: \"string\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n // コンテナノード\n vstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n hstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n layer: {\n ...BASE_RULES,\n },\n};\n\n// ===== 子要素の変換ルールマップ =====\nexport const CHILD_ELEMENT_COERCION_MAP: Record<\n string,\n Record<string, CoercionRule>\n> = {\n ProcessArrowStep: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n PyramidLevel: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n TimelineItem: {\n date: \"string\",\n title: \"string\",\n description: \"string\",\n color: \"string\",\n },\n MatrixAxes: {\n x: \"string\",\n y: \"string\",\n },\n MatrixQuadrants: {\n topLeft: \"string\",\n topRight: \"string\",\n bottomLeft: \"string\",\n bottomRight: \"string\",\n },\n MatrixItem: {\n label: \"string\",\n x: \"number\",\n y: \"number\",\n color: \"string\",\n textColor: \"string\",\n },\n FlowNode: {\n id: \"string\",\n shape: \"string\",\n text: \"string\",\n color: \"string\",\n textColor: \"string\",\n width: \"number\",\n height: \"number\",\n },\n FlowConnection: {\n from: \"string\",\n to: \"string\",\n label: \"string\",\n color: \"string\",\n labelColor: \"string\",\n },\n Col: {\n width: \"number\",\n },\n Td: {\n text: \"string\",\n fontSize: \"number\",\n color: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n textAlign: \"string\",\n backgroundColor: \"string\",\n colspan: \"number\",\n rowspan: \"number\",\n },\n Li: {\n text: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n color: \"string\",\n fontSize: \"number\",\n fontFamily: \"string\",\n },\n B: {},\n I: {},\n Span: { color: \"string\", fontFamily: \"string\", letterSpacing: \"number\" },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"coercionRules.js","names":[],"sources":["../../src/parseXml/coercionRules.ts"],"sourcesContent":["/**\n * 明示的な型変換ルール定義\n *\n * Zod の内部構造(_def)に依存せず、XML 属性値の文字列→適切な型への変換ルールを\n * 静的に定義する。各ノードタイプ・子要素タイプごとに変換テーブルを持つ。\n */\n\n// ===== CoercionRule 型定義 =====\nexport type CoercionRule =\n | \"number\"\n | \"boolean\"\n | \"string\" // string, enum を含む\n | \"json\" // array, object, record, tuple → JSON.parse\n | { type: \"literal\"; value: string | number | boolean }\n | { type: \"union\"; options: CoercionRule[] }\n | { type: \"object\"; shape: Record<string, CoercionRule> };\n\n// ===== 変換関数 =====\n\nexport function coerceWithRule(\n value: string,\n rule: CoercionRule,\n): { value: unknown; error: string | null } {\n if (rule === \"number\") {\n if (value === \"\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n const num = Number(value);\n if (isNaN(num)) {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to number`,\n };\n }\n return { value: num, error: null };\n }\n if (rule === \"boolean\") {\n if (value !== \"true\" && value !== \"false\") {\n return {\n value: undefined,\n error: `Cannot convert \"${value}\" to boolean (expected \"true\" or \"false\")`,\n };\n }\n return { value: value === \"true\", error: null };\n }\n if (rule === \"string\") {\n return { value, error: null };\n }\n if (rule === \"json\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n // オブジェクト型のルール\n if (rule.type === \"literal\") {\n return { value: rule.value, error: null };\n }\n if (rule.type === \"union\") {\n return { value: coerceUnionWithRules(value, rule.options), error: null };\n }\n if (rule.type === \"object\") {\n try {\n return { value: JSON.parse(value), error: null };\n } catch {\n return {\n value: undefined,\n error: `Cannot parse JSON value: \"${value}\"`,\n };\n }\n }\n return { value: coerceFallback(value), error: null };\n}\n\nexport function coerceUnionWithRules(\n value: string,\n options: CoercionRule[],\n): unknown {\n // boolean を試行\n if ((value === \"true\" || value === \"false\") && options.includes(\"boolean\")) {\n return value === \"true\";\n }\n\n // number を試行\n if (options.includes(\"number\")) {\n const num = Number(value);\n if (!isNaN(num) && value !== \"\") {\n return num;\n }\n }\n\n // literal を試行\n for (const opt of options) {\n if (typeof opt === \"object\" && opt.type === \"literal\") {\n if (`${opt.value as string | number}` === value) return opt.value;\n }\n }\n\n // object/json を試行(JSON パース)\n if (\n options.some(\n (opt) =>\n opt === \"json\" || (typeof opt === \"object\" && opt.type === \"object\"),\n )\n ) {\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n }\n\n // string にフォールバック\n return value;\n}\n\nexport function coerceFallback(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n const num = Number(value);\n if (value !== \"\" && !isNaN(num)) return num;\n if (value.startsWith(\"{\") || value.startsWith(\"[\")) {\n try {\n return JSON.parse(value);\n } catch {\n /* ignore */\n }\n }\n return value;\n}\n\n/**\n * CoercionRule からオブジェクト型の shape を取得する。\n * dot notation の展開で使用。\n */\nexport function getObjectShapeFromRule(\n rule: CoercionRule,\n): Record<string, CoercionRule> | undefined {\n if (typeof rule === \"object\" && rule.type === \"object\") {\n return rule.shape;\n }\n if (typeof rule === \"object\" && rule.type === \"union\") {\n const objectOpt = rule.options.find(\n (opt): opt is { type: \"object\"; shape: Record<string, CoercionRule> } =>\n typeof opt === \"object\" && opt.type === \"object\",\n );\n return objectOpt?.shape;\n }\n return undefined;\n}\n\n/**\n * boolean と object の union かどうかを判定する。\n * endArrow=\"true\" と endArrow.type=\"triangle\" の共存を許可するために使用。\n */\nexport function isBooleanObjectUnionRule(rule: CoercionRule): boolean {\n if (typeof rule === \"string\") return false;\n if (rule.type !== \"union\") return false;\n const hasBoolean = rule.options.includes(\"boolean\");\n const hasObject = rule.options.some(\n (opt) => typeof opt === \"object\" && opt.type === \"object\",\n );\n return hasBoolean && hasObject;\n}\n\ntype ResolvedMixedNotationShorthand =\n | { mode: \"merge\"; value: Record<string, unknown> }\n | { mode: \"ignore\" }\n | { mode: \"conflict\" };\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isDirectionalBoxShape(shape: Record<string, CoercionRule>): boolean {\n const keys = Object.keys(shape).sort();\n return (\n keys.length === 4 &&\n keys[0] === \"bottom\" &&\n keys[1] === \"left\" &&\n keys[2] === \"right\" &&\n keys[3] === \"top\"\n );\n}\n\n/**\n * 同一属性で shorthand と dot notation を併用したときに、\n * shorthand 側をどのように扱うかを解決する。\n *\n * - merge: shorthand をオブジェクト化して dot notation 側で上書き\n * - ignore: boolean shorthand を無視して dot notation を優先\n * - conflict: 併用不可(従来どおりエラー)\n */\nexport function resolveMixedNotationShorthand(\n value: string,\n rule: CoercionRule,\n): ResolvedMixedNotationShorthand {\n const objectShape = getObjectShapeFromRule(rule);\n if (!objectShape) return { mode: \"conflict\" };\n\n if (\n isBooleanObjectUnionRule(rule) &&\n (value === \"true\" || value === \"false\")\n ) {\n return { mode: \"ignore\" };\n }\n\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) return { mode: \"conflict\" };\n\n if (isPlainObject(coerced.value)) {\n return { mode: \"merge\", value: coerced.value };\n }\n\n if (typeof coerced.value === \"number\" && isDirectionalBoxShape(objectShape)) {\n return {\n mode: \"merge\",\n value: {\n top: coerced.value,\n right: coerced.value,\n bottom: coerced.value,\n left: coerced.value,\n },\n };\n }\n\n return { mode: \"conflict\" };\n}\n\n// ===== 共通変換ルール =====\n\nconst LENGTH_RULE: CoercionRule = {\n type: \"union\",\n options: [\"number\", { type: \"literal\", value: \"max\" }, \"string\"],\n};\n\nconst PADDING_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"number\",\n {\n type: \"object\",\n shape: {\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n },\n },\n ],\n};\n\nconst BORDER_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\", dashType: \"string\" },\n};\n\nconst FILL_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", transparency: \"number\" },\n};\n\nconst SHADOW_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n opacity: \"number\",\n blur: \"number\",\n angle: \"number\",\n offset: \"number\",\n color: \"string\",\n },\n};\n\nconst UNDERLINE_RULE: CoercionRule = {\n type: \"union\",\n options: [\n \"boolean\",\n { type: \"object\", shape: { style: \"string\", color: \"string\" } },\n ],\n};\n\nconst TEXT_GLOW_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", opacity: \"number\", color: \"string\" },\n};\n\nconst TEXT_OUTLINE_RULE: CoercionRule = {\n type: \"object\",\n shape: { size: \"number\", color: \"string\" },\n};\n\nconst LINE_ARROW_RULE: CoercionRule = {\n type: \"union\",\n options: [\"boolean\", { type: \"object\", shape: { type: \"string\" } }],\n};\n\nconst BACKGROUND_IMAGE_RULE: CoercionRule = {\n type: \"object\",\n shape: { src: \"string\", sizing: \"string\" },\n};\n\nconst TREE_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: { color: \"string\", width: \"number\" },\n};\n\nconst FLOW_CONNECTOR_STYLE_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n color: \"string\",\n width: \"number\",\n arrowType: \"string\",\n labelColor: \"string\",\n },\n};\n\nconst IMAGE_SIZING_RULE: CoercionRule = {\n type: \"object\",\n shape: {\n type: \"string\",\n w: \"number\",\n h: \"number\",\n x: \"number\",\n y: \"number\",\n },\n};\n\n// ===== Base node 属性 =====\nconst BASE_RULES: Record<string, CoercionRule> = {\n id: \"string\",\n w: LENGTH_RULE,\n h: LENGTH_RULE,\n grow: \"number\",\n minW: \"number\",\n maxW: \"number\",\n minH: \"number\",\n maxH: \"number\",\n padding: PADDING_RULE,\n margin: PADDING_RULE,\n backgroundColor: \"string\",\n backgroundGradient: \"string\",\n backgroundImage: BACKGROUND_IMAGE_RULE,\n border: BORDER_STYLE_RULE,\n borderTop: BORDER_STYLE_RULE,\n borderRight: BORDER_STYLE_RULE,\n borderBottom: BORDER_STYLE_RULE,\n borderLeft: BORDER_STYLE_RULE,\n borderRadius: \"number\",\n opacity: \"number\",\n zIndex: \"number\",\n position: \"string\",\n top: \"number\",\n right: \"number\",\n bottom: \"number\",\n left: \"number\",\n alignSelf: \"string\",\n shadow: SHADOW_STYLE_RULE,\n};\n\n// テキスト系の共通属性\nconst TEXT_STYLE_RULES: Record<string, CoercionRule> = {\n fontSize: \"number\",\n color: \"string\",\n textAlign: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n lineHeight: \"number\",\n};\n\n// ===== ノードタイプ別の変換ルールマップ =====\nexport const NODE_COERCION_MAP: Record<string, Record<string, CoercionRule>> = {\n text: {\n ...BASE_RULES,\n text: \"string\",\n rotate: \"number\",\n ...TEXT_STYLE_RULES,\n letterSpacing: \"number\",\n glow: TEXT_GLOW_RULE,\n outline: TEXT_OUTLINE_RULE,\n },\n ul: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n },\n ol: {\n ...BASE_RULES,\n items: \"json\",\n ...TEXT_STYLE_RULES,\n numberType: \"string\",\n numberStartAt: \"number\",\n },\n image: {\n ...BASE_RULES,\n src: \"string\",\n sizing: IMAGE_SIZING_RULE,\n rotate: \"number\",\n },\n icon: {\n ...BASE_RULES,\n name: \"string\",\n size: \"number\",\n color: \"string\",\n variant: \"string\",\n bgColor: \"string\",\n rotate: \"number\",\n },\n svg: {\n ...BASE_RULES,\n color: \"string\",\n },\n table: {\n ...BASE_RULES,\n columns: \"json\",\n rows: \"json\",\n defaultRowHeight: \"number\",\n cellBorder: BORDER_STYLE_RULE,\n },\n shape: {\n ...BASE_RULES,\n shapeType: \"string\",\n text: \"string\",\n rotate: \"number\",\n fill: FILL_STYLE_RULE,\n line: BORDER_STYLE_RULE,\n ...TEXT_STYLE_RULES,\n },\n chart: {\n ...BASE_RULES,\n chartType: \"string\",\n data: \"json\",\n showLegend: \"boolean\",\n showTitle: \"boolean\",\n title: \"string\",\n chartColors: \"json\",\n radarStyle: \"string\",\n sparkline: \"boolean\",\n },\n timeline: {\n ...BASE_RULES,\n direction: \"string\",\n items: \"json\",\n dateColor: \"string\",\n titleColor: \"string\",\n descriptionColor: \"string\",\n },\n matrix: {\n ...BASE_RULES,\n axes: \"json\",\n quadrants: \"json\",\n items: \"json\",\n axisLabelColor: \"string\",\n quadrantLabelColor: \"string\",\n itemLabelColor: \"string\",\n },\n tree: {\n ...BASE_RULES,\n layout: \"string\",\n nodeShape: \"string\",\n data: \"json\",\n textColor: \"string\",\n connectorStyle: TREE_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n levelGap: \"number\",\n siblingGap: \"number\",\n },\n flow: {\n ...BASE_RULES,\n direction: \"string\",\n nodes: \"json\",\n connections: \"json\",\n connectorStyle: FLOW_CONNECTOR_STYLE_RULE,\n nodeWidth: \"number\",\n nodeHeight: \"number\",\n nodeGap: \"number\",\n },\n processArrow: {\n ...BASE_RULES,\n direction: \"string\",\n steps: \"json\",\n itemWidth: \"number\",\n itemHeight: \"number\",\n gap: \"number\",\n fontSize: \"number\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n },\n pyramid: {\n ...BASE_RULES,\n direction: \"string\",\n levels: \"json\",\n fontSize: \"number\",\n bold: \"boolean\",\n fontFamily: \"string\",\n },\n line: {\n ...BASE_RULES,\n x1: \"number\",\n y1: \"number\",\n x2: \"number\",\n y2: \"number\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n arrow: {\n ...BASE_RULES,\n from: \"string\",\n to: \"string\",\n color: \"string\",\n lineWidth: \"number\",\n dashType: \"string\",\n beginArrow: LINE_ARROW_RULE,\n endArrow: LINE_ARROW_RULE,\n },\n // コンテナノード\n vstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n hstack: {\n ...BASE_RULES,\n gap: \"number\",\n alignItems: \"string\",\n justifyContent: \"string\",\n flexWrap: \"string\",\n },\n layer: {\n ...BASE_RULES,\n },\n};\n\n// ===== 子要素の変換ルールマップ =====\nexport const CHILD_ELEMENT_COERCION_MAP: Record<\n string,\n Record<string, CoercionRule>\n> = {\n ProcessArrowStep: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n PyramidLevel: {\n label: \"string\",\n color: \"string\",\n textColor: \"string\",\n },\n TimelineItem: {\n date: \"string\",\n title: \"string\",\n description: \"string\",\n color: \"string\",\n },\n MatrixAxes: {\n x: \"string\",\n y: \"string\",\n },\n MatrixQuadrants: {\n topLeft: \"string\",\n topRight: \"string\",\n bottomLeft: \"string\",\n bottomRight: \"string\",\n },\n MatrixItem: {\n label: \"string\",\n x: \"number\",\n y: \"number\",\n color: \"string\",\n textColor: \"string\",\n },\n FlowNode: {\n id: \"string\",\n shape: \"string\",\n text: \"string\",\n color: \"string\",\n textColor: \"string\",\n width: \"number\",\n height: \"number\",\n },\n FlowConnection: {\n from: \"string\",\n to: \"string\",\n label: \"string\",\n color: \"string\",\n labelColor: \"string\",\n },\n Col: {\n width: \"number\",\n },\n Td: {\n text: \"string\",\n fontSize: \"number\",\n color: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n fontFamily: \"string\",\n textAlign: \"string\",\n backgroundColor: \"string\",\n colspan: \"number\",\n rowspan: \"number\",\n },\n Li: {\n text: \"string\",\n bold: \"boolean\",\n italic: \"boolean\",\n underline: UNDERLINE_RULE,\n strike: \"boolean\",\n subscript: \"boolean\",\n superscript: \"boolean\",\n highlight: \"string\",\n color: \"string\",\n fontSize: \"number\",\n fontFamily: \"string\",\n },\n B: {},\n I: {},\n Span: {\n color: \"string\",\n fontFamily: \"string\",\n fontSize: \"number\",\n letterSpacing: \"number\",\n },\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseXml.d.ts","names":[],"sources":["../../src/parseXml/parseXml.ts"],"mappings":";;;cAiCa,aAAA,SAAsB,KAAK;EAAA,SACtB,MAAA;cACJ,MAAA;AAAA;;;;;;;AAAgB;AA8sC9B;;;;AAAoD;;;;;;;;;;;;;;;;;;;;;iBAApC,QAAA,CAAS,SAAA,WAAoB,OAAO"}
1
+ {"version":3,"file":"parseXml.d.ts","names":[],"sources":["../../src/parseXml/parseXml.ts"],"mappings":";;;cAiCa,aAAA,SAAsB,KAAK;EAAA,SACtB,MAAA;cACJ,MAAA;AAAA;;;;;;;AAAgB;AAitC9B;;;;AAAoD;;;;;;;;;;;;;;;;;;;;;iBAApC,QAAA,CAAS,SAAA,WAAoB,OAAO"}
@@ -202,6 +202,7 @@ function extractTextRuns(children, inherited = {}) {
202
202
  const next = { ...inherited };
203
203
  if (spanAttrs.color && spanAttrs.color.trim()) next.color = spanAttrs.color;
204
204
  if (spanAttrs.fontFamily && spanAttrs.fontFamily.trim()) next.fontFamily = spanAttrs.fontFamily;
205
+ if (spanAttrs.fontSize && spanAttrs.fontSize.trim()) next.fontSize = Number(spanAttrs.fontSize);
205
206
  if (spanAttrs.letterSpacing && spanAttrs.letterSpacing.trim()) next.letterSpacing = Number(spanAttrs.letterSpacing);
206
207
  runs.push(...extractTextRuns(innerChildren, next));
207
208
  }