@hirokisakabe/pom 8.5.1 → 8.6.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
@@ -27,6 +27,7 @@
27
27
  ## Table of Contents
28
28
 
29
29
  - [Features](#features)
30
+ - [Installation](#installation)
30
31
  - [Quick Start](#quick-start)
31
32
  - [Available Nodes](#available-nodes)
32
33
  - [Node Examples](#node-examples)
@@ -40,7 +41,7 @@
40
41
  - **Flexible Layout** — Flexbox-style layout with VStack / HStack, powered by yoga-layout. Ratio-based layouts (e.g., 2:1 columns) via the `grow` attribute (CSS `flex-grow`).
41
42
  - **Shorthand + Dot Notation** — Layout/style attributes (e.g. `padding`, `margin`, `border`, `fill`, `shadow`) can mix shorthand and dot notation on the same node. Shorthand sets defaults and dot notation overrides specific keys.
42
43
  - **Per-Side Borders** — `borderTop` / `borderRight` / `borderBottom` / `borderLeft` style each edge independently (e.g. `borderLeft.width="6"` for an accent bar, `borderBottom.width="3"` for an underlined heading), merging field-by-field with the uniform `border`. See [Nodes — Common Properties](./docs/nodes.md#common-properties).
43
- - **Rich Nodes** — 18 built-in node types: charts, flowcharts, tables, timelines, org trees, and more.
44
+ - **Rich Nodes** — 20 built-in node types: charts, flowcharts, tables, timelines, org trees, and more.
44
45
  - **Design Tokens** — Declare a color palette once with a top-level `<Theme>` element and reference tokens as `$name` from any color attribute. See [Nodes — Top-Level `<Theme>`](./docs/nodes.md#top-level-theme-design-tokens).
45
46
  - **Schema-validated** — XML input is validated with Zod schemas at runtime with clear error messages.
46
47
  - **PowerPoint Native** — Generates real editable PowerPoint shapes — not images. Recipients can modify everything. Linear gradient backgrounds (`backgroundGradient="linear-gradient(135deg, #667EEA 0%, #764BA2 100%)"`) are exported as native gradient fills.
@@ -49,7 +50,7 @@
49
50
  - **Master Slide** — Define headers, footers, and page numbers once — applied to all slides automatically.
50
51
  - **Accurate Text Measurement** — Text width measured with opentype.js and bundled Noto Sans JP fonts for consistent layout.
51
52
 
52
- ## Quick Start
53
+ ## Installation
53
54
 
54
55
  > Requires Node.js 18+
55
56
 
@@ -57,6 +58,8 @@
57
58
  npm install @hirokisakabe/pom
58
59
  ```
59
60
 
61
+ ## Quick Start
62
+
60
63
  ```typescript
61
64
  import { buildPptx } from "@hirokisakabe/pom";
62
65
 
@@ -86,28 +89,28 @@ Each slide must be wrapped in a `<Slide>` element. To produce multiple slides, l
86
89
 
87
90
  ## Available Nodes
88
91
 
89
- | Node | Description |
90
- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
- | Text | Text with font styling, decoration, rotation, letter spacing, glow / outline effects, inline bold/italic/underline/strike/highlight/color, and hyperlinks |
92
- | Ul | Unordered (bullet) list with Li items |
93
- | Ol | Ordered (numbered) list with Li items |
94
- | Image | Images from file path, URL, or base64, with optional rotation |
95
- | Table | Tables with customizable columns and rows |
96
- | Shape | PowerPoint shapes (roundRect, ellipse, etc.) with optional rotation |
97
- | Chart | Charts (bar, line, pie, area, doughnut, radar) |
98
- | Timeline | Timeline / roadmap visualizations |
99
- | Matrix | 2x2 positioning maps |
100
- | Tree | Organization charts and decision trees |
101
- | Flow | Flowcharts with nodes and edges |
102
- | ProcessArrow | Chevron-style process diagrams |
103
- | Pyramid | Pyramid diagrams for hierarchies |
104
- | Line | Horizontal / vertical lines |
105
- | Arrow | Connectors between nodes referenced by ID |
106
- | Layer | Absolute-positioned overlay container |
107
- | VStack | Vertical stack layout |
108
- | HStack | Horizontal stack layout |
109
- | Icon | Lucide icons with optional rotation |
110
- | 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, 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 |
111
114
 
112
115
  For detailed node documentation, see [Nodes](./docs/nodes.md).
113
116
 
@@ -297,6 +297,8 @@ const TEXT_STYLE_RULES = {
297
297
  italic: "boolean",
298
298
  underline: UNDERLINE_RULE,
299
299
  strike: "boolean",
300
+ subscript: "boolean",
301
+ superscript: "boolean",
300
302
  highlight: "string",
301
303
  fontFamily: "string",
302
304
  lineHeight: "number"
@@ -527,6 +529,8 @@ const CHILD_ELEMENT_COERCION_MAP = {
527
529
  italic: "boolean",
528
530
  underline: UNDERLINE_RULE,
529
531
  strike: "boolean",
532
+ subscript: "boolean",
533
+ superscript: "boolean",
530
534
  highlight: "string",
531
535
  fontFamily: "string",
532
536
  textAlign: "string",
@@ -540,6 +544,8 @@ const CHILD_ELEMENT_COERCION_MAP = {
540
544
  italic: "boolean",
541
545
  underline: UNDERLINE_RULE,
542
546
  strike: "boolean",
547
+ subscript: "boolean",
548
+ superscript: "boolean",
543
549
  highlight: "string",
544
550
  color: "string",
545
551
  fontSize: "number",
@@ -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 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 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 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 },\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 +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;AA2sC9B;;;;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;AA8sC9B;;;;AAAoD;;;;;;;;;;;;;;;;;;;;;iBAApC,QAAA,CAAS,SAAA,WAAoB,OAAO"}
@@ -176,11 +176,15 @@ function extractTextRuns(children, inherited = {}) {
176
176
  const tag = getTagName(child);
177
177
  const innerChildren = getRawChildren(child);
178
178
  const booleanFormat = INLINE_BOOLEAN_FORMATS.find((format) => format.tag === tag);
179
- if (booleanFormat) runs.push(...extractTextRuns(innerChildren, {
180
- ...inherited,
181
- [booleanFormat.property]: true
182
- }));
183
- else if (tag === "A") {
179
+ if (booleanFormat) {
180
+ const next = {
181
+ ...inherited,
182
+ [booleanFormat.property]: true
183
+ };
184
+ if (booleanFormat.property === "subscript") delete next.superscript;
185
+ if (booleanFormat.property === "superscript") delete next.subscript;
186
+ runs.push(...extractTextRuns(innerChildren, next));
187
+ } else if (tag === "A") {
184
188
  const next = { ...inherited };
185
189
  const href = getAttributes(child).href;
186
190
  if (href) next.href = href;
@@ -1 +1 @@
1
- {"version":3,"file":"parseXml.js","names":[],"sources":["../../src/parseXml/parseXml.ts"],"sourcesContent":["import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport type { z } from \"zod\";\nimport type { POMNode } from \"../types.ts\";\nimport {\n getNodeMetadata,\n getNodeMetadataByTag,\n NODE_METADATA,\n} from \"../registry/nodeMetadata.ts\";\nimport {\n INLINE_BOOLEAN_FORMATS,\n INLINE_FORMAT_TAG_LIST,\n INLINE_FORMAT_TAGS,\n INLINE_LINK_TAG,\n INLINE_MARK_TAG,\n INLINE_SPAN_TAG,\n MARK_DEFAULT_HIGHLIGHT_COLOR,\n formatExpectedTags,\n type NodeSpecificChildRule,\n type RepeatedChildRule,\n type TextRun,\n type XmlChildRule,\n} from \"../registry/xmlChildRules.ts\";\nimport {\n type CoercionRule,\n NODE_COERCION_MAP,\n CHILD_ELEMENT_COERCION_MAP,\n coerceWithRule,\n coerceFallback,\n getObjectShapeFromRule,\n resolveMixedNotationShorthand,\n} from \"./coercionRules.ts\";\n\n// ===== ParseXmlError =====\nexport class ParseXmlError extends Error {\n public readonly errors: string[];\n constructor(errors: string[]) {\n const message = `XML validation failed (${errors.length} error${errors.length > 1 ? \"s\" : \"\"}):\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`;\n super(message);\n this.name = \"ParseXmlError\";\n this.errors = errors;\n }\n}\n\n// ===== Tag name → POM node type mapping =====\nexport const TAG_TO_TYPE: Record<string, string> = Object.fromEntries(\n NODE_METADATA.map((def) => [def.tagName, def.type]),\n);\n// Attributes allowed on any node (e.g., x/y for Layer children positioning)\nconst UNIVERSAL_ATTRS = new Set([\"x\", \"y\"]);\n\n// ===== Validation helpers =====\nfunction getKnownAttributes(nodeType: string): string[] {\n const rules = NODE_COERCION_MAP[nodeType];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction levenshteinDistance(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array<number>(n + 1).fill(0),\n );\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\nfunction findClosestMatch(\n input: string,\n candidates: string[],\n): string | undefined {\n const threshold = Math.max(2, Math.floor(input.length / 2));\n let bestMatch: string | undefined;\n let bestDistance = Infinity;\n for (const candidate of candidates) {\n const dist = levenshteinDistance(\n input.toLowerCase(),\n candidate.toLowerCase(),\n );\n if (dist < bestDistance && dist <= threshold) {\n bestDistance = dist;\n bestMatch = candidate;\n }\n }\n return bestMatch;\n}\n\nfunction getKnownChildAttributes(tagName: string): string[] {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction formatZodIssue(\n issue: z.core.$ZodIssue,\n tagName: string,\n): string | null {\n const path = issue.path;\n // Skip children-related issues (validated recursively)\n if (path.length > 0 && path[0] === \"children\") return null;\n // Skip \"type\" field issues (set internally)\n if (path.length === 1 && path[0] === \"type\") return null;\n\n const attrName = path.length > 0 ? String(path[0]) : undefined;\n\n const code = issue.code;\n\n if (code === \"invalid_type\") {\n // Missing required attribute\n if (issue.input === undefined) {\n if (attrName) {\n return `<${tagName}>: Missing required attribute \"${attrName}\"`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n // Type mismatch\n if (attrName) {\n return `<${tagName}>: Invalid type for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"invalid_value\") {\n if (attrName) {\n const values = (issue as unknown as { values: string[] }).values;\n if (values) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". Expected: ${values.map((v) => `\"${v}\"`).join(\", \")}`;\n }\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"too_small\" || code === \"too_big\") {\n if (attrName) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n // Generic fallback\n if (attrName) {\n return `<${tagName}>: Attribute \"${attrName}\": ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n}\n\n// Properties that may be legitimately absent when using child element notation\n// or when the property is optional in practice (even if required in schema).\nfunction validateLeafNode(\n nodeType: string,\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n if (def.childPolicy.kind === \"pom-children\") return;\n const schema = def.schema;\n const tagName = def.tagName;\n const optionalChildProps = new Set(\n def.childPolicy.kind === \"custom\"\n ? (def.childPolicy.optionalProperties ?? [])\n : [],\n );\n const parseResult = schema.safeParse(result);\n if (!parseResult.success) {\n const seen = new Set<string>();\n for (const issue of parseResult.error.issues) {\n // Skip only top-level missing child-element properties (path.length === 1)\n // Nested issues (e.g., data.children[0].label) must still be reported\n if (\n optionalChildProps.size > 0 &&\n issue.path.length === 1 &&\n optionalChildProps.has(String(issue.path[0])) &&\n issue.code === \"invalid_type\" &&\n issue.input === undefined\n ) {\n continue;\n }\n // Skip issues for universal attributes (x, y)\n if (issue.path.length > 0 && UNIVERSAL_ATTRS.has(String(issue.path[0]))) {\n continue;\n }\n const msg = formatZodIssue(issue, tagName);\n if (msg && !seen.has(msg)) {\n seen.add(msg);\n errors.push(msg);\n }\n }\n }\n}\n\n// ===== Types for XML parser output (preserveOrder mode) =====\ntype XmlNode = XmlElement | XmlTextNode;\ntype XmlTextNode = { \"#text\": string };\ninterface XmlElement {\n [tagName: string]: XmlNode[] | Record<string, string> | undefined;\n \":@\"?: Record<string, string>;\n}\n\n// ===== Coercion rule lookup =====\n\nfunction getCoercionRule(\n nodeType: string,\n propertyName: string,\n): CoercionRule | undefined {\n return NODE_COERCION_MAP[nodeType]?.[propertyName];\n}\n\n// ===== Dot notation helpers =====\n\n// ===== Dot notation expansion =====\nfunction expandDotNotation(attrs: Record<string, string>): {\n regular: Record<string, string>;\n dotGroups: Record<string, Record<string, string>>;\n} {\n const regular: Record<string, string> = {};\n const dotGroups: Record<string, Record<string, string>> = {};\n\n for (const [key, value] of Object.entries(attrs)) {\n const dotIndex = key.indexOf(\".\");\n if (dotIndex > 0) {\n const prefix = key.substring(0, dotIndex);\n const suffix = key.substring(dotIndex + 1);\n if (!dotGroups[prefix]) dotGroups[prefix] = {};\n dotGroups[prefix][suffix] = value;\n } else {\n regular[key] = value;\n }\n }\n\n return { regular, dotGroups };\n}\n\nfunction coerceDotGroup(\n prefix: string,\n subAttrs: Record<string, string>,\n rule: CoercionRule,\n tagName: string,\n errors: string[],\n): Record<string, unknown> {\n const objectShape = getObjectShapeFromRule(rule);\n\n const obj: Record<string, unknown> = {};\n if (objectShape) {\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n if (objectShape[subKey]) {\n const coerced = coerceWithRule(subValue, objectShape[subKey]);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);\n } else {\n obj[subKey] = coerced.value;\n }\n } else {\n const knownSubKeys = Object.keys(objectShape);\n const suggestion = findClosestMatch(subKey, knownSubKeys);\n errors.push(\n `<${tagName}>: Unknown sub-attribute \"${prefix}.${subKey}\"${suggestion ? `. Did you mean \"${prefix}.${suggestion}\"?` : \"\"}`,\n );\n }\n }\n } else {\n errors.push(\n `<${tagName}>: Attribute \"${prefix}\" does not support dot notation`,\n );\n }\n return obj;\n}\n\n// ===== XML node helpers =====\nfunction isTextNode(node: XmlNode): node is XmlTextNode {\n return \"#text\" in node;\n}\n\nfunction getTagName(node: XmlElement): string {\n for (const key of Object.keys(node)) {\n if (key !== \":@\") return key;\n }\n throw new Error(\"No tag name found in XML element\");\n}\n\nfunction getAttributes(node: XmlElement): Record<string, string> {\n const attrs: Record<string, string> = {};\n const rawAttrs = node[\":@\"];\n if (rawAttrs) {\n for (const [key, value] of Object.entries(rawAttrs)) {\n const attrName = key.startsWith(\"@_\") ? key.slice(2) : key;\n attrs[attrName] = value.trim();\n }\n }\n return attrs;\n}\n\nfunction getChildElements(node: XmlElement): XmlElement[] {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return [];\n return children.filter((child): child is XmlElement => !isTextNode(child));\n}\n\nfunction getTextContent(node: XmlElement): string | undefined {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return undefined;\n const textParts: string[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n textParts.push(child[\"#text\"]);\n }\n }\n return textParts.length > 0 ? textParts.join(\"\") : undefined;\n}\n\nfunction getRawChildren(node: XmlElement): XmlNode[] {\n const tagName = getTagName(node);\n return (node[tagName] as XmlNode[] | undefined) ?? [];\n}\n\nfunction hasInlineFormatChildren(childElements: XmlElement[]): boolean {\n return (\n childElements.length > 0 &&\n childElements.every((el) => INLINE_FORMAT_TAGS.has(getTagName(el)))\n );\n}\n\nfunction extractTextRuns(\n children: XmlNode[],\n inherited: Partial<Omit<TextRun, \"text\">> = {},\n): TextRun[] {\n const runs: TextRun[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n runs.push({ text: child[\"#text\"], ...inherited });\n continue;\n }\n const tag = getTagName(child);\n const innerChildren = getRawChildren(child);\n const booleanFormat = INLINE_BOOLEAN_FORMATS.find(\n (format) => format.tag === tag,\n );\n if (booleanFormat) {\n runs.push(\n ...extractTextRuns(innerChildren, {\n ...inherited,\n [booleanFormat.property]: true,\n }),\n );\n } else if (tag === INLINE_LINK_TAG) {\n // href なしの <A> は外側の href を引き継がない(リンク解除として扱う)\n const next = { ...inherited };\n const href = getAttributes(child).href;\n if (href) {\n next.href = href;\n } else {\n delete next.href;\n }\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_MARK_TAG) {\n const rawColor = getAttributes(child).color;\n const highlight =\n rawColor && rawColor.trim() ? rawColor : MARK_DEFAULT_HIGHLIGHT_COLOR;\n runs.push(...extractTextRuns(innerChildren, { ...inherited, highlight }));\n } else if (tag === INLINE_SPAN_TAG) {\n const spanAttrs = getAttributes(child);\n const next = { ...inherited };\n if (spanAttrs.color && spanAttrs.color.trim()) {\n next.color = spanAttrs.color;\n }\n if (spanAttrs.fontFamily && spanAttrs.fontFamily.trim()) {\n next.fontFamily = spanAttrs.fontFamily;\n }\n if (spanAttrs.letterSpacing && spanAttrs.letterSpacing.trim()) {\n next.letterSpacing = Number(spanAttrs.letterSpacing);\n }\n runs.push(...extractTextRuns(innerChildren, next));\n }\n }\n return runs;\n}\n\nfunction buildRunsAndText(\n node: XmlElement,\n): { runs: TextRun[]; text: string } | null {\n const rawChildren = getRawChildren(node);\n const childElements = rawChildren.filter(\n (c): c is XmlElement => !isTextNode(c),\n );\n if (!hasInlineFormatChildren(childElements)) return null;\n const runs = extractTextRuns(rawChildren);\n const text = runs.map((r) => r.text).join(\"\");\n return { runs, text };\n}\n\nfunction coerceChildAttrs(\n parentTagName: string,\n tagName: string,\n attrs: Record<string, string>,\n errors: string[],\n): Record<string, unknown> {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n const result: Record<string, unknown> = {};\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n // Process dot-notation attributes\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (rules && rules[prefix]) {\n result[prefix] = coerceDotGroup(\n prefix,\n subAttrs,\n rules[prefix],\n `${parentTagName}.${tagName}`,\n errors,\n );\n } else if (rules) {\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${prefix}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[prefix] = {};\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n (result[prefix] as Record<string, unknown>)[subKey] =\n coerceFallback(subValue);\n }\n }\n }\n\n // Process regular attributes\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key in dotGroups) {\n if (rules && rules[key]) {\n const resolved = resolveMixedNotationShorthand(value, rules[key]);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${parentTagName}>.<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes. Use one or the other, not both`,\n );\n continue;\n }\n if (rules && rules[key]) {\n const coerced = coerceWithRule(value, rules[key]);\n if (coerced.error !== null) {\n errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (rules) {\n // Unknown attribute on child element\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(key, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${key}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[key] = coerceFallback(value);\n }\n }\n return result;\n}\n\n// ===== Child element converters =====\n\nfunction unknownChildError(\n childTag: string,\n parentTag: string,\n expectedTags: readonly string[],\n): string {\n return `Unknown child element <${childTag}> inside <${parentTag}>. Expected: ${formatExpectedTags(expectedTags)}`;\n}\n\n/** element の text content / インライン装飾を attrs の text / runs へ反映する */\nfunction applyTextAndRuns(\n element: XmlElement,\n attrs: Record<string, unknown>,\n): void {\n const runsResult = buildRunsAndText(element);\n if (runsResult) {\n attrs.runs = runsResult.runs;\n attrs.text = runsResult.text;\n } else {\n const textContent = getTextContent(element);\n if (textContent !== undefined && !(\"text\" in attrs)) {\n attrs.text = textContent;\n }\n }\n}\n\n/** RepeatedChildRule (単一種類の child tag の繰り返し → 配列 property) の汎用 converter */\nfunction convertRepeatedChildren(\n rule: RepeatedChildRule,\n parentTag: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== rule.childTag) {\n errors.push(unknownChildError(tag, parentTag, [rule.childTag]));\n continue;\n }\n const attrs = coerceChildAttrs(\n parentTag,\n tag,\n getAttributes(child),\n errors,\n );\n if (rule.allowsItemText) {\n applyTextAndRuns(child, attrs);\n }\n items.push(attrs);\n }\n result[rule.property] = items;\n}\n\n/** NodeSpecificChildRule を処理する専用 converter のシグネチャ */\ntype NodeSpecificChildConverter = (\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n) => void;\n\nfunction convertMatrixChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"MatrixAxes\":\n result.axes = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixQuadrants\":\n result.quadrants = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixItem\":\n items.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (items.length > 0) {\n result.items = items;\n }\n}\n\nfunction convertFlowChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const nodes: Record<string, unknown>[] = [];\n const connections: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"FlowNode\":\n nodes.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"FlowConnection\":\n connections.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (nodes.length > 0) {\n result.nodes = nodes;\n }\n if (connections.length > 0) {\n result.connections = connections;\n }\n}\n\nfunction convertChartChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const data: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== \"ChartSeries\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n continue;\n }\n const attrs = getAttributes(child);\n const series: Record<string, unknown> = {\n labels: [],\n values: [],\n };\n if (attrs.name !== undefined) {\n // chartDataSchema.name は z.string().optional() なのでそのまま文字列として使用\n series.name = attrs.name;\n }\n\n for (const dp of getChildElements(child)) {\n const dpTag = getTagName(dp);\n if (dpTag !== \"ChartDataPoint\") {\n errors.push(\n unknownChildError(dpTag, \"ChartSeries\", [\"ChartDataPoint\"]),\n );\n continue;\n }\n const dpAttrs = getAttributes(dp);\n if (dpAttrs.label === undefined) {\n errors.push('<ChartDataPoint> requires a \"label\" attribute');\n }\n if (dpAttrs.value === undefined) {\n errors.push('<ChartDataPoint> requires a \"value\" attribute');\n }\n if (dpAttrs.label === undefined || dpAttrs.value === undefined) {\n continue;\n }\n const numValue = Number(dpAttrs.value);\n if (isNaN(numValue)) {\n errors.push(\n `Cannot convert \"${dpAttrs.value}\" to number in <ChartDataPoint> \"value\" attribute`,\n );\n continue;\n }\n (series.labels as string[]).push(dpAttrs.label);\n (series.values as number[]).push(numValue);\n }\n data.push(series);\n }\n result.data = data;\n}\n\nfunction convertTableChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const columns: Record<string, unknown>[] = [];\n const rows: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"Col\":\n columns.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"Tr\": {\n const rowAttrs = getAttributes(child);\n const cells: Record<string, unknown>[] = [];\n for (const cellEl of getChildElements(child)) {\n const cellTag = getTagName(cellEl);\n if (cellTag !== \"Td\") {\n errors.push(unknownChildError(cellTag, \"Tr\", [\"Td\"]));\n continue;\n }\n const cellAttrs = coerceChildAttrs(\n \"Tr\",\n cellTag,\n getAttributes(cellEl),\n errors,\n );\n applyTextAndRuns(cellEl, cellAttrs);\n cells.push(cellAttrs);\n }\n const row: Record<string, unknown> = { cells };\n if (rowAttrs.height !== undefined) {\n const h = Number(rowAttrs.height);\n if (isNaN(h)) {\n errors.push(\n `Cannot convert \"${rowAttrs.height}\" to number in <Tr> \"height\" attribute`,\n );\n } else {\n row.height = h;\n }\n }\n rows.push(row);\n break;\n }\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (columns.length > 0) {\n result.columns = columns;\n } else if (rows.length > 0) {\n // Col が未指定の場合、行のセル数(colspan 考慮)からデフォルトの columns を自動生成\n const maxCells = Math.max(\n ...rows.map((row) =>\n (row.cells as Record<string, unknown>[]).reduce(\n (sum, cell) => sum + ((cell.colspan as number) ?? 1),\n 0,\n ),\n ),\n );\n result.columns = Array.from({ length: maxCells }, () => ({}));\n }\n if (rows.length > 0) {\n result.rows = rows;\n }\n}\n\nfunction convertTreeItem(\n element: XmlElement,\n errors: string[],\n): Record<string, unknown> {\n const attrs = getAttributes(element);\n if (attrs.label === undefined) {\n errors.push('<TreeItem> requires a \"label\" attribute');\n }\n const item: Record<string, unknown> = {};\n if (attrs.label !== undefined) {\n item.label = attrs.label;\n }\n if (attrs.color !== undefined) {\n item.color = attrs.color;\n }\n if (attrs.textColor !== undefined) {\n item.textColor = attrs.textColor;\n }\n const children = getChildElements(element);\n if (children.length > 0) {\n item.children = children\n .map((child) => {\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, \"TreeItem\", [\"TreeItem\"]));\n return null;\n }\n return convertTreeItem(child, errors);\n })\n .filter((item): item is Record<string, unknown> => item !== null);\n }\n return item;\n}\n\nfunction convertTreeChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Tree> must have exactly 1 <TreeItem> child element, but got ${childElements.length}`,\n );\n return;\n }\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n return;\n }\n result.data = convertTreeItem(child, errors);\n}\n\n// SVG 要素を XML 文字列に再構築する\nconst svgBuilder = new XMLBuilder({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n});\n\nfunction serializeSvgElement(svgElement: XmlElement): string {\n return String(svgBuilder.build([svgElement]));\n}\n\nfunction convertSvgChildren(\n _rule: NodeSpecificChildRule,\n _tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Svg>: Expected exactly one <svg> child element, but found ${childElements.length} child element(s)`,\n );\n return;\n }\n\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"svg\") {\n errors.push(`<Svg>: Expected <svg> child element, but found <${tag}>`);\n return;\n }\n\n result.svgContent = serializeSvgElement(child);\n}\n\nfunction convertInlineRunsChildren(\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n // インラインフォーマットタグ以外の子要素がある場合はエラー\n for (const el of childElements) {\n const tag = getTagName(el);\n if (!INLINE_FORMAT_TAGS.has(tag)) {\n const allowedTags = INLINE_FORMAT_TAG_LIST.map((t) => `<${t}>`);\n const allowedList = `${allowedTags.slice(0, -1).join(\", \")}, and ${allowedTags[allowedTags.length - 1]}`;\n errors.push(\n `<${tagName}>: Unexpected child element <${tag}>. Only ${allowedList} are allowed inside <${tagName}>`,\n );\n return;\n }\n }\n if (!node || childElements.length === 0) return;\n const runsResult = buildRunsAndText(node);\n if (runsResult) {\n result.runs = runsResult.runs;\n result.text = runsResult.text;\n }\n}\n\n/** NodeSpecificChildRule を持つノードの専用 converter テーブル */\nconst NODE_SPECIFIC_CHILD_CONVERTERS: Record<\n string,\n NodeSpecificChildConverter\n> = {\n matrix: convertMatrixChildren,\n flow: convertFlowChildren,\n chart: convertChartChildren,\n table: convertTableChildren,\n tree: convertTreeChildren,\n svg: convertSvgChildren,\n};\n\n/** NodeMetadata の xmlChildRule に従って child element を変換する */\nfunction applyXmlChildRule(\n rule: XmlChildRule,\n nodeType: string,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n if (rule.kind === \"inline-runs\") {\n convertInlineRunsChildren(tagName, childElements, result, errors, node);\n return;\n }\n if (rule.kind === \"repeated\") {\n convertRepeatedChildren(rule, tagName, childElements, result, errors);\n return;\n }\n const converter = NODE_SPECIFIC_CHILD_CONVERTERS[nodeType];\n if (!converter) {\n throw new Error(\n `No node-specific child converter registered for node type: ${nodeType}`,\n );\n }\n converter(rule, tagName, childElements, result, errors);\n}\n\n// ===== Theme tokens =====\nconst THEME_TOKEN_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst THEME_TOKEN_VALUE_PATTERN = /^[0-9A-Fa-f]{6}$/;\n// 値全体が \"$name\"(\"#\" プレフィックスは任意)のときトークン参照とみなす\nconst TOKEN_REF_PATTERN = /^(#?)\\$([A-Za-z][A-Za-z0-9_-]*)$/;\n// backgroundGradient 文字列中に現れる \"$name\" 参照\nconst TOKEN_REF_IN_GRADIENT_PATTERN = /#?\\$([A-Za-z][A-Za-z0-9_-]*)/g;\n\nfunction parseThemeElement(\n element: XmlElement,\n tokens: Record<string, string>,\n errors: string[],\n): void {\n if (getChildElements(element).length > 0) {\n errors.push(\n `<Theme>: Child elements are not supported. Declare tokens as attributes (e.g. <Theme accent=\"1D4ED8\" />)`,\n );\n }\n for (const [name, rawValue] of Object.entries(getAttributes(element))) {\n if (!THEME_TOKEN_NAME_PATTERN.test(name)) {\n errors.push(\n `<Theme>: Invalid token name \"${name}\". Token names must start with a letter and contain only letters, digits, \"_\", and \"-\"`,\n );\n continue;\n }\n const value = rawValue.replace(/^#/, \"\");\n if (!THEME_TOKEN_VALUE_PATTERN.test(value)) {\n errors.push(\n `<Theme>: Invalid color value \"${rawValue}\" for token \"${name}\". Expected 6-digit hex (e.g. \"1D4ED8\")`,\n );\n continue;\n }\n tokens[name] = value;\n }\n}\n\n// トークン参照を解決する対象のキー判定。\n// pom の色属性は \"...Color\" / \"...Colors\" / \"highlight\" に統一されているため、\n// キー名ベースで判定することでテキスト内容(text 等)の \"$...\" を誤置換しない。\nfunction isColorKey(key: string): boolean {\n return /colors?$/i.test(key) || key === \"highlight\";\n}\n\nfunction resolveThemeToken(\n name: string,\n hashPrefix: string,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): string | undefined {\n const value = tokens[name];\n if (value !== undefined) {\n return `${hashPrefix}${value}`;\n }\n if (!themeDeclared) {\n errors.push(\n `Theme token \"$${name}\" is referenced, but no <Theme> is declared. Add a top-level <Theme ${name}=\"RRGGBB\" /> element`,\n );\n } else {\n const suggestion = findClosestMatch(name, Object.keys(tokens));\n errors.push(\n `Unknown theme token \"$${name}\"${suggestion ? `. Did you mean \"$${suggestion}\"?` : \"\"}`,\n );\n }\n return undefined;\n}\n\ninterface ThemeContext {\n tokens: Record<string, string>;\n declared: boolean;\n}\n\nfunction resolveThemeTokensDeep(\n value: unknown,\n key: string | null,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): unknown {\n if (typeof value === \"string\") {\n if (key === \"backgroundGradient\") {\n return value.replace(\n TOKEN_REF_IN_GRADIENT_PATTERN,\n (matched, name: string) => {\n const resolved = resolveThemeToken(\n name,\n \"#\",\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? matched;\n },\n );\n }\n if (key !== null && isColorKey(key)) {\n const match = TOKEN_REF_PATTERN.exec(value.trim());\n if (match) {\n const resolved = resolveThemeToken(\n match[2],\n match[1],\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n // 配列はキー文脈を維持して要素ごとに解決する(chartColors 等の文字列配列に対応)\n return value.map((item) =>\n resolveThemeTokensDeep(item, key, tokens, themeDeclared, errors),\n );\n }\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n result[childKey] = resolveThemeTokensDeep(\n childValue,\n childKey,\n tokens,\n themeDeclared,\n errors,\n );\n }\n return result;\n }\n return value;\n}\n\n// ===== Node conversion =====\nfunction convertElement(\n node: XmlElement,\n errors: string[],\n theme: ThemeContext,\n): Record<string, unknown> | null {\n const tagName = getTagName(node);\n const def = getNodeMetadataByTag(tagName);\n const attrs = getAttributes(node);\n const childElements = getChildElements(node);\n const textContent = getTextContent(node);\n\n if (def) {\n return convertPomNode(\n def.type,\n tagName,\n attrs,\n childElements,\n textContent,\n errors,\n theme,\n node,\n );\n } else {\n errors.push(`Unknown tag: <${tagName}>`);\n return null;\n }\n}\n\nfunction convertPomNode(\n nodeType: string,\n tagName: string,\n attrs: Record<string, string>,\n childElements: XmlElement[],\n textContent: string | undefined,\n errors: string[],\n theme: ThemeContext,\n xmlNode?: XmlElement,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { type: nodeType };\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n\n // Expand dot-notation attributes (e.g., fill.color=\"hex\" → { fill: { color: \"hex\" } })\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (prefix === \"type\") continue;\n const rule = getCoercionRule(nodeType, prefix);\n if (rule) {\n result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);\n } else {\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${prefix}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${prefix}\"`);\n }\n }\n }\n\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key === \"type\") continue;\n // Conflict check: dot-notation and regular attribute for the same key\n if (key in dotGroups) {\n const ruleForConflict = getCoercionRule(nodeType, key);\n if (ruleForConflict) {\n const resolved = resolveMixedNotationShorthand(value, ruleForConflict);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes (e.g., \"${key}.xxx\"). Use one or the other, not both`,\n );\n continue;\n }\n const rule = getCoercionRule(nodeType, key);\n if (rule) {\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (UNIVERSAL_ATTRS.has(key)) {\n // Allow universal attributes (e.g., x/y for Layer children)\n result[key] = coerceFallback(value);\n } else {\n // Unknown attribute\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(key, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${key}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${key}\"`);\n }\n }\n }\n\n // Text content → text property for nodes that support it\n if (textContent !== undefined && def.textContentProperty) {\n if (!(def.textContentProperty in result)) {\n result[def.textContentProperty] = textContent;\n }\n }\n\n // Child element notation for complex properties\n const childRule = def.xmlChildRule;\n if (childRule && childElements.length > 0) {\n applyXmlChildRule(\n childRule,\n nodeType,\n tagName,\n childElements,\n result,\n errors,\n xmlNode,\n );\n }\n // Children for container nodes\n else if (\n def.childPolicy.kind === \"pom-children\" &&\n childElements.length > 0\n ) {\n const convertedChildren = childElements\n .map((child) => convertElement(child, errors, theme))\n .filter((child): child is Record<string, unknown> => child !== null);\n result.children = convertedChildren;\n }\n // Leaf nodes that shouldn't have child elements\n else if (\n def.childPolicy.kind !== \"pom-children\" &&\n !childRule &&\n childElements.length > 0\n ) {\n errors.push(\n `<${tagName}>: Unexpected child elements. <${tagName}> does not accept child elements`,\n );\n }\n\n // テーマトークン参照(色属性中の \"$name\")を Zod 検証より前に解決する。\n // children は各子ノードの convertPomNode で解決済みのためスキップする。\n for (const [key, value] of Object.entries(result)) {\n if (key === \"type\" || key === \"children\") continue;\n result[key] = resolveThemeTokensDeep(\n value,\n key,\n theme.tokens,\n theme.declared,\n errors,\n );\n }\n\n // Zod validation for leaf nodes\n if (def.childPolicy.kind !== \"pom-children\") {\n validateLeafNode(nodeType, result, errors);\n }\n\n // Icon: normalize color / bgColor\n if (nodeType === \"icon\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (typeof result.bgColor === \"string\" && !result.bgColor.startsWith(\"#\")) {\n result.bgColor = `#${result.bgColor}`;\n }\n }\n\n // Svg: normalize color and validate svgContent\n if (nodeType === \"svg\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (result.svgContent === undefined) {\n errors.push(\"<Svg>: A <svg> child element is required\");\n }\n }\n\n return result;\n}\n\n/**\n * XML 文字列を POMNode 配列に変換する。\n *\n * 最上位は `<Slide>` 要素と `<Theme>` 要素のみが許容される。各 `<Slide>` が\n * 1 つのスライドに対応し、その子要素がスライドのルート POMNode となる。\n * 子要素が複数ある場合は暗黙的に VStack でラップされる。\n *\n * `<Theme>` は文書全体に適用されるデザイントークン(配色)の宣言で、最大 1 つ\n * 置ける。属性名がトークン名、属性値が 6 桁 hex の色値となり、各ノードの色属性\n * から `$トークン名` で参照できる。参照は parse 時に解決されるため、返される\n * POMNode には解決済みの hex 値が入る(`<Theme>` 自体はノードにならない)。\n *\n * XML タグは POM ノードタイプにマッピングされ、属性値は Zod スキーマを参照して\n * 適切な型(number, boolean, array, object)に変換される。\n * 未知のタグ名が指定された場合はエラーがスローされる。\n *\n * @example\n * ```typescript\n * import { parseXml, buildPptx } from \"@hirokisakabe/pom\";\n *\n * const xml = `\n * <Slide>\n * <VStack gap=\"16\" padding=\"32\">\n * <Text fontSize=\"32\" bold=\"true\">売上レポート</Text>\n * </VStack>\n * </Slide>\n * `;\n *\n * const nodes = parseXml(xml);\n * const pptx = await buildPptx(nodes, { w: 1280, h: 720 });\n * ```\n */\nexport function parseXml(xmlString: string): POMNode[] {\n if (!xmlString.trim()) return [];\n\n const parser = new XMLParser({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: false,\n parseTagValue: false,\n trimValues: false,\n });\n\n const wrappedXml = `<__root__>${xmlString}</__root__>`;\n const parsed: XmlElement[] = parser.parse(wrappedXml) as XmlElement[];\n\n if (!parsed || parsed.length === 0) return [];\n\n const rootElement = parsed[0];\n const rootChildren = (rootElement[\"__root__\"] ?? []) as XmlNode[];\n\n const errors: string[] = [];\n const topLevelElements = rootChildren.filter(\n (child): child is XmlElement => !isTextNode(child),\n );\n\n // <Theme> はスライドより先に収集する(出現位置によらず文書全体に適用)\n const theme: ThemeContext = { tokens: {}, declared: false };\n for (const element of topLevelElements) {\n if (getTagName(element) !== \"Theme\") continue;\n if (theme.declared) {\n errors.push(\n `Only one <Theme> element is allowed, but multiple were found`,\n );\n continue;\n }\n theme.declared = true;\n parseThemeElement(element, theme.tokens, errors);\n }\n\n const slideElements = topLevelElements.filter(\n (element) => getTagName(element) !== \"Theme\",\n );\n\n const nodes: POMNode[] = [];\n for (const slideEl of slideElements) {\n const tagName = getTagName(slideEl);\n if (tagName !== \"Slide\") {\n errors.push(\n `Top-level element must be <Slide> or <Theme>, but got <${tagName}>. Wrap your slide content in <Slide>...</Slide>.`,\n );\n continue;\n }\n if (Object.keys(getAttributes(slideEl)).length > 0) {\n errors.push(`<Slide>: Attributes are not supported`);\n }\n const slideChildren = getChildElements(slideEl);\n if (slideChildren.length === 0) {\n errors.push(`<Slide> must contain at least one child element`);\n continue;\n }\n const converted = slideChildren\n .map((child) => convertElement(child, errors, theme))\n .filter((c): c is Record<string, unknown> => c !== null);\n if (converted.length === 0) continue;\n if (converted.length === 1) {\n nodes.push(converted[0] as POMNode);\n } else {\n nodes.push({\n type: \"vstack\",\n children: converted,\n } as POMNode);\n }\n }\n\n if (errors.length > 0) {\n throw new ParseXmlError(errors);\n }\n\n return nodes;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"parseXml.js","names":[],"sources":["../../src/parseXml/parseXml.ts"],"sourcesContent":["import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport type { z } from \"zod\";\nimport type { POMNode } from \"../types.ts\";\nimport {\n getNodeMetadata,\n getNodeMetadataByTag,\n NODE_METADATA,\n} from \"../registry/nodeMetadata.ts\";\nimport {\n INLINE_BOOLEAN_FORMATS,\n INLINE_FORMAT_TAG_LIST,\n INLINE_FORMAT_TAGS,\n INLINE_LINK_TAG,\n INLINE_MARK_TAG,\n INLINE_SPAN_TAG,\n MARK_DEFAULT_HIGHLIGHT_COLOR,\n formatExpectedTags,\n type NodeSpecificChildRule,\n type RepeatedChildRule,\n type TextRun,\n type XmlChildRule,\n} from \"../registry/xmlChildRules.ts\";\nimport {\n type CoercionRule,\n NODE_COERCION_MAP,\n CHILD_ELEMENT_COERCION_MAP,\n coerceWithRule,\n coerceFallback,\n getObjectShapeFromRule,\n resolveMixedNotationShorthand,\n} from \"./coercionRules.ts\";\n\n// ===== ParseXmlError =====\nexport class ParseXmlError extends Error {\n public readonly errors: string[];\n constructor(errors: string[]) {\n const message = `XML validation failed (${errors.length} error${errors.length > 1 ? \"s\" : \"\"}):\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`;\n super(message);\n this.name = \"ParseXmlError\";\n this.errors = errors;\n }\n}\n\n// ===== Tag name → POM node type mapping =====\nexport const TAG_TO_TYPE: Record<string, string> = Object.fromEntries(\n NODE_METADATA.map((def) => [def.tagName, def.type]),\n);\n// Attributes allowed on any node (e.g., x/y for Layer children positioning)\nconst UNIVERSAL_ATTRS = new Set([\"x\", \"y\"]);\n\n// ===== Validation helpers =====\nfunction getKnownAttributes(nodeType: string): string[] {\n const rules = NODE_COERCION_MAP[nodeType];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction levenshteinDistance(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array<number>(n + 1).fill(0),\n );\n for (let i = 0; i <= m; i++) dp[i][0] = i;\n for (let j = 0; j <= n; j++) dp[0][j] = j;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1][j - 1]\n : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n }\n }\n return dp[m][n];\n}\n\nfunction findClosestMatch(\n input: string,\n candidates: string[],\n): string | undefined {\n const threshold = Math.max(2, Math.floor(input.length / 2));\n let bestMatch: string | undefined;\n let bestDistance = Infinity;\n for (const candidate of candidates) {\n const dist = levenshteinDistance(\n input.toLowerCase(),\n candidate.toLowerCase(),\n );\n if (dist < bestDistance && dist <= threshold) {\n bestDistance = dist;\n bestMatch = candidate;\n }\n }\n return bestMatch;\n}\n\nfunction getKnownChildAttributes(tagName: string): string[] {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n if (!rules) return [];\n return Object.keys(rules);\n}\n\nfunction formatZodIssue(\n issue: z.core.$ZodIssue,\n tagName: string,\n): string | null {\n const path = issue.path;\n // Skip children-related issues (validated recursively)\n if (path.length > 0 && path[0] === \"children\") return null;\n // Skip \"type\" field issues (set internally)\n if (path.length === 1 && path[0] === \"type\") return null;\n\n const attrName = path.length > 0 ? String(path[0]) : undefined;\n\n const code = issue.code;\n\n if (code === \"invalid_type\") {\n // Missing required attribute\n if (issue.input === undefined) {\n if (attrName) {\n return `<${tagName}>: Missing required attribute \"${attrName}\"`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n // Type mismatch\n if (attrName) {\n return `<${tagName}>: Invalid type for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"invalid_value\") {\n if (attrName) {\n const values = (issue as unknown as { values: string[] }).values;\n if (values) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". Expected: ${values.map((v) => `\"${v}\"`).join(\", \")}`;\n }\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n if (code === \"too_small\" || code === \"too_big\") {\n if (attrName) {\n return `<${tagName}>: Invalid value for attribute \"${attrName}\". ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n }\n\n // Generic fallback\n if (attrName) {\n return `<${tagName}>: Attribute \"${attrName}\": ${issue.message}`;\n }\n return `<${tagName}>: ${issue.message}`;\n}\n\n// Properties that may be legitimately absent when using child element notation\n// or when the property is optional in practice (even if required in schema).\nfunction validateLeafNode(\n nodeType: string,\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n if (def.childPolicy.kind === \"pom-children\") return;\n const schema = def.schema;\n const tagName = def.tagName;\n const optionalChildProps = new Set(\n def.childPolicy.kind === \"custom\"\n ? (def.childPolicy.optionalProperties ?? [])\n : [],\n );\n const parseResult = schema.safeParse(result);\n if (!parseResult.success) {\n const seen = new Set<string>();\n for (const issue of parseResult.error.issues) {\n // Skip only top-level missing child-element properties (path.length === 1)\n // Nested issues (e.g., data.children[0].label) must still be reported\n if (\n optionalChildProps.size > 0 &&\n issue.path.length === 1 &&\n optionalChildProps.has(String(issue.path[0])) &&\n issue.code === \"invalid_type\" &&\n issue.input === undefined\n ) {\n continue;\n }\n // Skip issues for universal attributes (x, y)\n if (issue.path.length > 0 && UNIVERSAL_ATTRS.has(String(issue.path[0]))) {\n continue;\n }\n const msg = formatZodIssue(issue, tagName);\n if (msg && !seen.has(msg)) {\n seen.add(msg);\n errors.push(msg);\n }\n }\n }\n}\n\n// ===== Types for XML parser output (preserveOrder mode) =====\ntype XmlNode = XmlElement | XmlTextNode;\ntype XmlTextNode = { \"#text\": string };\ninterface XmlElement {\n [tagName: string]: XmlNode[] | Record<string, string> | undefined;\n \":@\"?: Record<string, string>;\n}\n\n// ===== Coercion rule lookup =====\n\nfunction getCoercionRule(\n nodeType: string,\n propertyName: string,\n): CoercionRule | undefined {\n return NODE_COERCION_MAP[nodeType]?.[propertyName];\n}\n\n// ===== Dot notation helpers =====\n\n// ===== Dot notation expansion =====\nfunction expandDotNotation(attrs: Record<string, string>): {\n regular: Record<string, string>;\n dotGroups: Record<string, Record<string, string>>;\n} {\n const regular: Record<string, string> = {};\n const dotGroups: Record<string, Record<string, string>> = {};\n\n for (const [key, value] of Object.entries(attrs)) {\n const dotIndex = key.indexOf(\".\");\n if (dotIndex > 0) {\n const prefix = key.substring(0, dotIndex);\n const suffix = key.substring(dotIndex + 1);\n if (!dotGroups[prefix]) dotGroups[prefix] = {};\n dotGroups[prefix][suffix] = value;\n } else {\n regular[key] = value;\n }\n }\n\n return { regular, dotGroups };\n}\n\nfunction coerceDotGroup(\n prefix: string,\n subAttrs: Record<string, string>,\n rule: CoercionRule,\n tagName: string,\n errors: string[],\n): Record<string, unknown> {\n const objectShape = getObjectShapeFromRule(rule);\n\n const obj: Record<string, unknown> = {};\n if (objectShape) {\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n if (objectShape[subKey]) {\n const coerced = coerceWithRule(subValue, objectShape[subKey]);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${prefix}.${subKey}: ${coerced.error}`);\n } else {\n obj[subKey] = coerced.value;\n }\n } else {\n const knownSubKeys = Object.keys(objectShape);\n const suggestion = findClosestMatch(subKey, knownSubKeys);\n errors.push(\n `<${tagName}>: Unknown sub-attribute \"${prefix}.${subKey}\"${suggestion ? `. Did you mean \"${prefix}.${suggestion}\"?` : \"\"}`,\n );\n }\n }\n } else {\n errors.push(\n `<${tagName}>: Attribute \"${prefix}\" does not support dot notation`,\n );\n }\n return obj;\n}\n\n// ===== XML node helpers =====\nfunction isTextNode(node: XmlNode): node is XmlTextNode {\n return \"#text\" in node;\n}\n\nfunction getTagName(node: XmlElement): string {\n for (const key of Object.keys(node)) {\n if (key !== \":@\") return key;\n }\n throw new Error(\"No tag name found in XML element\");\n}\n\nfunction getAttributes(node: XmlElement): Record<string, string> {\n const attrs: Record<string, string> = {};\n const rawAttrs = node[\":@\"];\n if (rawAttrs) {\n for (const [key, value] of Object.entries(rawAttrs)) {\n const attrName = key.startsWith(\"@_\") ? key.slice(2) : key;\n attrs[attrName] = value.trim();\n }\n }\n return attrs;\n}\n\nfunction getChildElements(node: XmlElement): XmlElement[] {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return [];\n return children.filter((child): child is XmlElement => !isTextNode(child));\n}\n\nfunction getTextContent(node: XmlElement): string | undefined {\n const tagName = getTagName(node);\n const children = node[tagName] as XmlNode[] | undefined;\n if (!children) return undefined;\n const textParts: string[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n textParts.push(child[\"#text\"]);\n }\n }\n return textParts.length > 0 ? textParts.join(\"\") : undefined;\n}\n\nfunction getRawChildren(node: XmlElement): XmlNode[] {\n const tagName = getTagName(node);\n return (node[tagName] as XmlNode[] | undefined) ?? [];\n}\n\nfunction hasInlineFormatChildren(childElements: XmlElement[]): boolean {\n return (\n childElements.length > 0 &&\n childElements.every((el) => INLINE_FORMAT_TAGS.has(getTagName(el)))\n );\n}\n\nfunction extractTextRuns(\n children: XmlNode[],\n inherited: Partial<Omit<TextRun, \"text\">> = {},\n): TextRun[] {\n const runs: TextRun[] = [];\n for (const child of children) {\n if (isTextNode(child)) {\n runs.push({ text: child[\"#text\"], ...inherited });\n continue;\n }\n const tag = getTagName(child);\n const innerChildren = getRawChildren(child);\n const booleanFormat = INLINE_BOOLEAN_FORMATS.find(\n (format) => format.tag === tag,\n );\n if (booleanFormat) {\n const next: Partial<Omit<TextRun, \"text\">> = {\n ...inherited,\n [booleanFormat.property]: true,\n };\n // subscript と superscript は OOXML の baseline 値として相互排他\n // (同時 true は描画結果が未定義になる)。後で立てた側を優先して反対側を解除する。\n if (booleanFormat.property === \"subscript\") delete next.superscript;\n if (booleanFormat.property === \"superscript\") delete next.subscript;\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_LINK_TAG) {\n // href なしの <A> は外側の href を引き継がない(リンク解除として扱う)\n const next = { ...inherited };\n const href = getAttributes(child).href;\n if (href) {\n next.href = href;\n } else {\n delete next.href;\n }\n runs.push(...extractTextRuns(innerChildren, next));\n } else if (tag === INLINE_MARK_TAG) {\n const rawColor = getAttributes(child).color;\n const highlight =\n rawColor && rawColor.trim() ? rawColor : MARK_DEFAULT_HIGHLIGHT_COLOR;\n runs.push(...extractTextRuns(innerChildren, { ...inherited, highlight }));\n } else if (tag === INLINE_SPAN_TAG) {\n const spanAttrs = getAttributes(child);\n const next = { ...inherited };\n if (spanAttrs.color && spanAttrs.color.trim()) {\n next.color = spanAttrs.color;\n }\n if (spanAttrs.fontFamily && spanAttrs.fontFamily.trim()) {\n next.fontFamily = spanAttrs.fontFamily;\n }\n if (spanAttrs.letterSpacing && spanAttrs.letterSpacing.trim()) {\n next.letterSpacing = Number(spanAttrs.letterSpacing);\n }\n runs.push(...extractTextRuns(innerChildren, next));\n }\n }\n return runs;\n}\n\nfunction buildRunsAndText(\n node: XmlElement,\n): { runs: TextRun[]; text: string } | null {\n const rawChildren = getRawChildren(node);\n const childElements = rawChildren.filter(\n (c): c is XmlElement => !isTextNode(c),\n );\n if (!hasInlineFormatChildren(childElements)) return null;\n const runs = extractTextRuns(rawChildren);\n const text = runs.map((r) => r.text).join(\"\");\n return { runs, text };\n}\n\nfunction coerceChildAttrs(\n parentTagName: string,\n tagName: string,\n attrs: Record<string, string>,\n errors: string[],\n): Record<string, unknown> {\n const rules = CHILD_ELEMENT_COERCION_MAP[tagName];\n const result: Record<string, unknown> = {};\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n // Process dot-notation attributes\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (rules && rules[prefix]) {\n result[prefix] = coerceDotGroup(\n prefix,\n subAttrs,\n rules[prefix],\n `${parentTagName}.${tagName}`,\n errors,\n );\n } else if (rules) {\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${prefix}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[prefix] = {};\n for (const [subKey, subValue] of Object.entries(subAttrs)) {\n (result[prefix] as Record<string, unknown>)[subKey] =\n coerceFallback(subValue);\n }\n }\n }\n\n // Process regular attributes\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key in dotGroups) {\n if (rules && rules[key]) {\n const resolved = resolveMixedNotationShorthand(value, rules[key]);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${parentTagName}>.<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes. Use one or the other, not both`,\n );\n continue;\n }\n if (rules && rules[key]) {\n const coerced = coerceWithRule(value, rules[key]);\n if (coerced.error !== null) {\n errors.push(`<${parentTagName}>.<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (rules) {\n // Unknown attribute on child element\n const knownAttrs = getKnownChildAttributes(tagName);\n const suggestion = findClosestMatch(key, knownAttrs);\n errors.push(\n `<${parentTagName}>.<${tagName}>: Unknown attribute \"${key}\"${suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"}`,\n );\n } else {\n result[key] = coerceFallback(value);\n }\n }\n return result;\n}\n\n// ===== Child element converters =====\n\nfunction unknownChildError(\n childTag: string,\n parentTag: string,\n expectedTags: readonly string[],\n): string {\n return `Unknown child element <${childTag}> inside <${parentTag}>. Expected: ${formatExpectedTags(expectedTags)}`;\n}\n\n/** element の text content / インライン装飾を attrs の text / runs へ反映する */\nfunction applyTextAndRuns(\n element: XmlElement,\n attrs: Record<string, unknown>,\n): void {\n const runsResult = buildRunsAndText(element);\n if (runsResult) {\n attrs.runs = runsResult.runs;\n attrs.text = runsResult.text;\n } else {\n const textContent = getTextContent(element);\n if (textContent !== undefined && !(\"text\" in attrs)) {\n attrs.text = textContent;\n }\n }\n}\n\n/** RepeatedChildRule (単一種類の child tag の繰り返し → 配列 property) の汎用 converter */\nfunction convertRepeatedChildren(\n rule: RepeatedChildRule,\n parentTag: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== rule.childTag) {\n errors.push(unknownChildError(tag, parentTag, [rule.childTag]));\n continue;\n }\n const attrs = coerceChildAttrs(\n parentTag,\n tag,\n getAttributes(child),\n errors,\n );\n if (rule.allowsItemText) {\n applyTextAndRuns(child, attrs);\n }\n items.push(attrs);\n }\n result[rule.property] = items;\n}\n\n/** NodeSpecificChildRule を処理する専用 converter のシグネチャ */\ntype NodeSpecificChildConverter = (\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n) => void;\n\nfunction convertMatrixChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const items: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"MatrixAxes\":\n result.axes = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixQuadrants\":\n result.quadrants = coerceChildAttrs(\n tagName,\n tag,\n getAttributes(child),\n errors,\n );\n break;\n case \"MatrixItem\":\n items.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (items.length > 0) {\n result.items = items;\n }\n}\n\nfunction convertFlowChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const nodes: Record<string, unknown>[] = [];\n const connections: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"FlowNode\":\n nodes.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"FlowConnection\":\n connections.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (nodes.length > 0) {\n result.nodes = nodes;\n }\n if (connections.length > 0) {\n result.connections = connections;\n }\n}\n\nfunction convertChartChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const data: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n if (tag !== \"ChartSeries\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n continue;\n }\n const attrs = getAttributes(child);\n const series: Record<string, unknown> = {\n labels: [],\n values: [],\n };\n if (attrs.name !== undefined) {\n // chartDataSchema.name は z.string().optional() なのでそのまま文字列として使用\n series.name = attrs.name;\n }\n\n for (const dp of getChildElements(child)) {\n const dpTag = getTagName(dp);\n if (dpTag !== \"ChartDataPoint\") {\n errors.push(\n unknownChildError(dpTag, \"ChartSeries\", [\"ChartDataPoint\"]),\n );\n continue;\n }\n const dpAttrs = getAttributes(dp);\n if (dpAttrs.label === undefined) {\n errors.push('<ChartDataPoint> requires a \"label\" attribute');\n }\n if (dpAttrs.value === undefined) {\n errors.push('<ChartDataPoint> requires a \"value\" attribute');\n }\n if (dpAttrs.label === undefined || dpAttrs.value === undefined) {\n continue;\n }\n const numValue = Number(dpAttrs.value);\n if (isNaN(numValue)) {\n errors.push(\n `Cannot convert \"${dpAttrs.value}\" to number in <ChartDataPoint> \"value\" attribute`,\n );\n continue;\n }\n (series.labels as string[]).push(dpAttrs.label);\n (series.values as number[]).push(numValue);\n }\n data.push(series);\n }\n result.data = data;\n}\n\nfunction convertTableChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n const columns: Record<string, unknown>[] = [];\n const rows: Record<string, unknown>[] = [];\n for (const child of childElements) {\n const tag = getTagName(child);\n switch (tag) {\n case \"Col\":\n columns.push(\n coerceChildAttrs(tagName, tag, getAttributes(child), errors),\n );\n break;\n case \"Tr\": {\n const rowAttrs = getAttributes(child);\n const cells: Record<string, unknown>[] = [];\n for (const cellEl of getChildElements(child)) {\n const cellTag = getTagName(cellEl);\n if (cellTag !== \"Td\") {\n errors.push(unknownChildError(cellTag, \"Tr\", [\"Td\"]));\n continue;\n }\n const cellAttrs = coerceChildAttrs(\n \"Tr\",\n cellTag,\n getAttributes(cellEl),\n errors,\n );\n applyTextAndRuns(cellEl, cellAttrs);\n cells.push(cellAttrs);\n }\n const row: Record<string, unknown> = { cells };\n if (rowAttrs.height !== undefined) {\n const h = Number(rowAttrs.height);\n if (isNaN(h)) {\n errors.push(\n `Cannot convert \"${rowAttrs.height}\" to number in <Tr> \"height\" attribute`,\n );\n } else {\n row.height = h;\n }\n }\n rows.push(row);\n break;\n }\n default:\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n }\n }\n if (columns.length > 0) {\n result.columns = columns;\n } else if (rows.length > 0) {\n // Col が未指定の場合、行のセル数(colspan 考慮)からデフォルトの columns を自動生成\n const maxCells = Math.max(\n ...rows.map((row) =>\n (row.cells as Record<string, unknown>[]).reduce(\n (sum, cell) => sum + ((cell.colspan as number) ?? 1),\n 0,\n ),\n ),\n );\n result.columns = Array.from({ length: maxCells }, () => ({}));\n }\n if (rows.length > 0) {\n result.rows = rows;\n }\n}\n\nfunction convertTreeItem(\n element: XmlElement,\n errors: string[],\n): Record<string, unknown> {\n const attrs = getAttributes(element);\n if (attrs.label === undefined) {\n errors.push('<TreeItem> requires a \"label\" attribute');\n }\n const item: Record<string, unknown> = {};\n if (attrs.label !== undefined) {\n item.label = attrs.label;\n }\n if (attrs.color !== undefined) {\n item.color = attrs.color;\n }\n if (attrs.textColor !== undefined) {\n item.textColor = attrs.textColor;\n }\n const children = getChildElements(element);\n if (children.length > 0) {\n item.children = children\n .map((child) => {\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, \"TreeItem\", [\"TreeItem\"]));\n return null;\n }\n return convertTreeItem(child, errors);\n })\n .filter((item): item is Record<string, unknown> => item !== null);\n }\n return item;\n}\n\nfunction convertTreeChildren(\n rule: NodeSpecificChildRule,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Tree> must have exactly 1 <TreeItem> child element, but got ${childElements.length}`,\n );\n return;\n }\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"TreeItem\") {\n errors.push(unknownChildError(tag, tagName, rule.expectedTags));\n return;\n }\n result.data = convertTreeItem(child, errors);\n}\n\n// SVG 要素を XML 文字列に再構築する\nconst svgBuilder = new XMLBuilder({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n});\n\nfunction serializeSvgElement(svgElement: XmlElement): string {\n return String(svgBuilder.build([svgElement]));\n}\n\nfunction convertSvgChildren(\n _rule: NodeSpecificChildRule,\n _tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n): void {\n if (childElements.length !== 1) {\n errors.push(\n `<Svg>: Expected exactly one <svg> child element, but found ${childElements.length} child element(s)`,\n );\n return;\n }\n\n const child = childElements[0];\n const tag = getTagName(child);\n if (tag !== \"svg\") {\n errors.push(`<Svg>: Expected <svg> child element, but found <${tag}>`);\n return;\n }\n\n result.svgContent = serializeSvgElement(child);\n}\n\nfunction convertInlineRunsChildren(\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n // インラインフォーマットタグ以外の子要素がある場合はエラー\n for (const el of childElements) {\n const tag = getTagName(el);\n if (!INLINE_FORMAT_TAGS.has(tag)) {\n const allowedTags = INLINE_FORMAT_TAG_LIST.map((t) => `<${t}>`);\n const allowedList = `${allowedTags.slice(0, -1).join(\", \")}, and ${allowedTags[allowedTags.length - 1]}`;\n errors.push(\n `<${tagName}>: Unexpected child element <${tag}>. Only ${allowedList} are allowed inside <${tagName}>`,\n );\n return;\n }\n }\n if (!node || childElements.length === 0) return;\n const runsResult = buildRunsAndText(node);\n if (runsResult) {\n result.runs = runsResult.runs;\n result.text = runsResult.text;\n }\n}\n\n/** NodeSpecificChildRule を持つノードの専用 converter テーブル */\nconst NODE_SPECIFIC_CHILD_CONVERTERS: Record<\n string,\n NodeSpecificChildConverter\n> = {\n matrix: convertMatrixChildren,\n flow: convertFlowChildren,\n chart: convertChartChildren,\n table: convertTableChildren,\n tree: convertTreeChildren,\n svg: convertSvgChildren,\n};\n\n/** NodeMetadata の xmlChildRule に従って child element を変換する */\nfunction applyXmlChildRule(\n rule: XmlChildRule,\n nodeType: string,\n tagName: string,\n childElements: XmlElement[],\n result: Record<string, unknown>,\n errors: string[],\n node?: XmlElement,\n): void {\n if (rule.kind === \"inline-runs\") {\n convertInlineRunsChildren(tagName, childElements, result, errors, node);\n return;\n }\n if (rule.kind === \"repeated\") {\n convertRepeatedChildren(rule, tagName, childElements, result, errors);\n return;\n }\n const converter = NODE_SPECIFIC_CHILD_CONVERTERS[nodeType];\n if (!converter) {\n throw new Error(\n `No node-specific child converter registered for node type: ${nodeType}`,\n );\n }\n converter(rule, tagName, childElements, result, errors);\n}\n\n// ===== Theme tokens =====\nconst THEME_TOKEN_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst THEME_TOKEN_VALUE_PATTERN = /^[0-9A-Fa-f]{6}$/;\n// 値全体が \"$name\"(\"#\" プレフィックスは任意)のときトークン参照とみなす\nconst TOKEN_REF_PATTERN = /^(#?)\\$([A-Za-z][A-Za-z0-9_-]*)$/;\n// backgroundGradient 文字列中に現れる \"$name\" 参照\nconst TOKEN_REF_IN_GRADIENT_PATTERN = /#?\\$([A-Za-z][A-Za-z0-9_-]*)/g;\n\nfunction parseThemeElement(\n element: XmlElement,\n tokens: Record<string, string>,\n errors: string[],\n): void {\n if (getChildElements(element).length > 0) {\n errors.push(\n `<Theme>: Child elements are not supported. Declare tokens as attributes (e.g. <Theme accent=\"1D4ED8\" />)`,\n );\n }\n for (const [name, rawValue] of Object.entries(getAttributes(element))) {\n if (!THEME_TOKEN_NAME_PATTERN.test(name)) {\n errors.push(\n `<Theme>: Invalid token name \"${name}\". Token names must start with a letter and contain only letters, digits, \"_\", and \"-\"`,\n );\n continue;\n }\n const value = rawValue.replace(/^#/, \"\");\n if (!THEME_TOKEN_VALUE_PATTERN.test(value)) {\n errors.push(\n `<Theme>: Invalid color value \"${rawValue}\" for token \"${name}\". Expected 6-digit hex (e.g. \"1D4ED8\")`,\n );\n continue;\n }\n tokens[name] = value;\n }\n}\n\n// トークン参照を解決する対象のキー判定。\n// pom の色属性は \"...Color\" / \"...Colors\" / \"highlight\" に統一されているため、\n// キー名ベースで判定することでテキスト内容(text 等)の \"$...\" を誤置換しない。\nfunction isColorKey(key: string): boolean {\n return /colors?$/i.test(key) || key === \"highlight\";\n}\n\nfunction resolveThemeToken(\n name: string,\n hashPrefix: string,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): string | undefined {\n const value = tokens[name];\n if (value !== undefined) {\n return `${hashPrefix}${value}`;\n }\n if (!themeDeclared) {\n errors.push(\n `Theme token \"$${name}\" is referenced, but no <Theme> is declared. Add a top-level <Theme ${name}=\"RRGGBB\" /> element`,\n );\n } else {\n const suggestion = findClosestMatch(name, Object.keys(tokens));\n errors.push(\n `Unknown theme token \"$${name}\"${suggestion ? `. Did you mean \"$${suggestion}\"?` : \"\"}`,\n );\n }\n return undefined;\n}\n\ninterface ThemeContext {\n tokens: Record<string, string>;\n declared: boolean;\n}\n\nfunction resolveThemeTokensDeep(\n value: unknown,\n key: string | null,\n tokens: Record<string, string>,\n themeDeclared: boolean,\n errors: string[],\n): unknown {\n if (typeof value === \"string\") {\n if (key === \"backgroundGradient\") {\n return value.replace(\n TOKEN_REF_IN_GRADIENT_PATTERN,\n (matched, name: string) => {\n const resolved = resolveThemeToken(\n name,\n \"#\",\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? matched;\n },\n );\n }\n if (key !== null && isColorKey(key)) {\n const match = TOKEN_REF_PATTERN.exec(value.trim());\n if (match) {\n const resolved = resolveThemeToken(\n match[2],\n match[1],\n tokens,\n themeDeclared,\n errors,\n );\n return resolved ?? value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n // 配列はキー文脈を維持して要素ごとに解決する(chartColors 等の文字列配列に対応)\n return value.map((item) =>\n resolveThemeTokensDeep(item, key, tokens, themeDeclared, errors),\n );\n }\n if (typeof value === \"object\" && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n result[childKey] = resolveThemeTokensDeep(\n childValue,\n childKey,\n tokens,\n themeDeclared,\n errors,\n );\n }\n return result;\n }\n return value;\n}\n\n// ===== Node conversion =====\nfunction convertElement(\n node: XmlElement,\n errors: string[],\n theme: ThemeContext,\n): Record<string, unknown> | null {\n const tagName = getTagName(node);\n const def = getNodeMetadataByTag(tagName);\n const attrs = getAttributes(node);\n const childElements = getChildElements(node);\n const textContent = getTextContent(node);\n\n if (def) {\n return convertPomNode(\n def.type,\n tagName,\n attrs,\n childElements,\n textContent,\n errors,\n theme,\n node,\n );\n } else {\n errors.push(`Unknown tag: <${tagName}>`);\n return null;\n }\n}\n\nfunction convertPomNode(\n nodeType: string,\n tagName: string,\n attrs: Record<string, string>,\n childElements: XmlElement[],\n textContent: string | undefined,\n errors: string[],\n theme: ThemeContext,\n xmlNode?: XmlElement,\n): Record<string, unknown> {\n const result: Record<string, unknown> = { type: nodeType };\n const def = getNodeMetadata(nodeType as POMNode[\"type\"]);\n\n // Expand dot-notation attributes (e.g., fill.color=\"hex\" → { fill: { color: \"hex\" } })\n const { regular: regularAttrs, dotGroups } = expandDotNotation(attrs);\n\n for (const [prefix, subAttrs] of Object.entries(dotGroups)) {\n if (prefix === \"type\") continue;\n const rule = getCoercionRule(nodeType, prefix);\n if (rule) {\n result[prefix] = coerceDotGroup(prefix, subAttrs, rule, tagName, errors);\n } else {\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(prefix, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${prefix}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${prefix}\"`);\n }\n }\n }\n\n for (const [key, value] of Object.entries(regularAttrs)) {\n if (key === \"type\") continue;\n // Conflict check: dot-notation and regular attribute for the same key\n if (key in dotGroups) {\n const ruleForConflict = getCoercionRule(nodeType, key);\n if (ruleForConflict) {\n const resolved = resolveMixedNotationShorthand(value, ruleForConflict);\n if (resolved.mode === \"ignore\") {\n continue;\n }\n if (resolved.mode === \"merge\") {\n result[key] = {\n ...resolved.value,\n ...(result[key] as Record<string, unknown>),\n };\n continue;\n }\n }\n errors.push(\n `<${tagName}>: Attribute \"${key}\" conflicts with dot-notation attributes (e.g., \"${key}.xxx\"). Use one or the other, not both`,\n );\n continue;\n }\n const rule = getCoercionRule(nodeType, key);\n if (rule) {\n const coerced = coerceWithRule(value, rule);\n if (coerced.error !== null) {\n errors.push(`<${tagName}>: ${coerced.error}`);\n } else {\n result[key] = coerced.value;\n }\n } else if (UNIVERSAL_ATTRS.has(key)) {\n // Allow universal attributes (e.g., x/y for Layer children)\n result[key] = coerceFallback(value);\n } else {\n // Unknown attribute\n const knownAttrs = getKnownAttributes(nodeType);\n const suggestion = findClosestMatch(key, knownAttrs);\n if (suggestion) {\n errors.push(\n `<${tagName}>: Unknown attribute \"${key}\". Did you mean \"${suggestion}\"?`,\n );\n } else {\n errors.push(`<${tagName}>: Unknown attribute \"${key}\"`);\n }\n }\n }\n\n // Text content → text property for nodes that support it\n if (textContent !== undefined && def.textContentProperty) {\n if (!(def.textContentProperty in result)) {\n result[def.textContentProperty] = textContent;\n }\n }\n\n // Child element notation for complex properties\n const childRule = def.xmlChildRule;\n if (childRule && childElements.length > 0) {\n applyXmlChildRule(\n childRule,\n nodeType,\n tagName,\n childElements,\n result,\n errors,\n xmlNode,\n );\n }\n // Children for container nodes\n else if (\n def.childPolicy.kind === \"pom-children\" &&\n childElements.length > 0\n ) {\n const convertedChildren = childElements\n .map((child) => convertElement(child, errors, theme))\n .filter((child): child is Record<string, unknown> => child !== null);\n result.children = convertedChildren;\n }\n // Leaf nodes that shouldn't have child elements\n else if (\n def.childPolicy.kind !== \"pom-children\" &&\n !childRule &&\n childElements.length > 0\n ) {\n errors.push(\n `<${tagName}>: Unexpected child elements. <${tagName}> does not accept child elements`,\n );\n }\n\n // テーマトークン参照(色属性中の \"$name\")を Zod 検証より前に解決する。\n // children は各子ノードの convertPomNode で解決済みのためスキップする。\n for (const [key, value] of Object.entries(result)) {\n if (key === \"type\" || key === \"children\") continue;\n result[key] = resolveThemeTokensDeep(\n value,\n key,\n theme.tokens,\n theme.declared,\n errors,\n );\n }\n\n // Zod validation for leaf nodes\n if (def.childPolicy.kind !== \"pom-children\") {\n validateLeafNode(nodeType, result, errors);\n }\n\n // Icon: normalize color / bgColor\n if (nodeType === \"icon\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (typeof result.bgColor === \"string\" && !result.bgColor.startsWith(\"#\")) {\n result.bgColor = `#${result.bgColor}`;\n }\n }\n\n // Svg: normalize color and validate svgContent\n if (nodeType === \"svg\") {\n if (typeof result.color === \"string\" && !result.color.startsWith(\"#\")) {\n result.color = `#${result.color}`;\n }\n if (result.svgContent === undefined) {\n errors.push(\"<Svg>: A <svg> child element is required\");\n }\n }\n\n return result;\n}\n\n/**\n * XML 文字列を POMNode 配列に変換する。\n *\n * 最上位は `<Slide>` 要素と `<Theme>` 要素のみが許容される。各 `<Slide>` が\n * 1 つのスライドに対応し、その子要素がスライドのルート POMNode となる。\n * 子要素が複数ある場合は暗黙的に VStack でラップされる。\n *\n * `<Theme>` は文書全体に適用されるデザイントークン(配色)の宣言で、最大 1 つ\n * 置ける。属性名がトークン名、属性値が 6 桁 hex の色値となり、各ノードの色属性\n * から `$トークン名` で参照できる。参照は parse 時に解決されるため、返される\n * POMNode には解決済みの hex 値が入る(`<Theme>` 自体はノードにならない)。\n *\n * XML タグは POM ノードタイプにマッピングされ、属性値は Zod スキーマを参照して\n * 適切な型(number, boolean, array, object)に変換される。\n * 未知のタグ名が指定された場合はエラーがスローされる。\n *\n * @example\n * ```typescript\n * import { parseXml, buildPptx } from \"@hirokisakabe/pom\";\n *\n * const xml = `\n * <Slide>\n * <VStack gap=\"16\" padding=\"32\">\n * <Text fontSize=\"32\" bold=\"true\">売上レポート</Text>\n * </VStack>\n * </Slide>\n * `;\n *\n * const nodes = parseXml(xml);\n * const pptx = await buildPptx(nodes, { w: 1280, h: 720 });\n * ```\n */\nexport function parseXml(xmlString: string): POMNode[] {\n if (!xmlString.trim()) return [];\n\n const parser = new XMLParser({\n preserveOrder: true,\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: false,\n parseTagValue: false,\n trimValues: false,\n });\n\n const wrappedXml = `<__root__>${xmlString}</__root__>`;\n const parsed: XmlElement[] = parser.parse(wrappedXml) as XmlElement[];\n\n if (!parsed || parsed.length === 0) return [];\n\n const rootElement = parsed[0];\n const rootChildren = (rootElement[\"__root__\"] ?? []) as XmlNode[];\n\n const errors: string[] = [];\n const topLevelElements = rootChildren.filter(\n (child): child is XmlElement => !isTextNode(child),\n );\n\n // <Theme> はスライドより先に収集する(出現位置によらず文書全体に適用)\n const theme: ThemeContext = { tokens: {}, declared: false };\n for (const element of topLevelElements) {\n if (getTagName(element) !== \"Theme\") continue;\n if (theme.declared) {\n errors.push(\n `Only one <Theme> element is allowed, but multiple were found`,\n );\n continue;\n }\n theme.declared = true;\n parseThemeElement(element, theme.tokens, errors);\n }\n\n const slideElements = topLevelElements.filter(\n (element) => getTagName(element) !== \"Theme\",\n );\n\n const nodes: POMNode[] = [];\n for (const slideEl of slideElements) {\n const tagName = getTagName(slideEl);\n if (tagName !== \"Slide\") {\n errors.push(\n `Top-level element must be <Slide> or <Theme>, but got <${tagName}>. Wrap your slide content in <Slide>...</Slide>.`,\n );\n continue;\n }\n if (Object.keys(getAttributes(slideEl)).length > 0) {\n errors.push(`<Slide>: Attributes are not supported`);\n }\n const slideChildren = getChildElements(slideEl);\n if (slideChildren.length === 0) {\n errors.push(`<Slide> must contain at least one child element`);\n continue;\n }\n const converted = slideChildren\n .map((child) => convertElement(child, errors, theme))\n .filter((c): c is Record<string, unknown> => c !== null);\n if (converted.length === 0) continue;\n if (converted.length === 1) {\n nodes.push(converted[0] as POMNode);\n } else {\n nodes.push({\n type: \"vstack\",\n children: converted,\n } as POMNode);\n }\n }\n\n if (errors.length > 0) {\n throw new ParseXmlError(errors);\n }\n\n return nodes;\n}\n"],"mappings":"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"}
@@ -4,8 +4,9 @@ import { POMNode } from "../types.js";
4
4
  /**
5
5
  * POMNode 配列を XML 文字列に変換する。
6
6
  *
7
- * parseXml の逆操作として機能する。runs(インライン装飾)は B/I/A/U/S/Mark/Span
8
- * タグとして child element に直列化されるため、テキストの装飾情報も保持される。
7
+ * parseXml の逆操作として機能する。runs(インライン装飾)は
8
+ * B/I/A/U/S/Sub/Sup/Mark/Span タグとして child element に直列化されるため、
9
+ * テキストの装飾情報も保持される。
9
10
  *
10
11
  * @example
11
12
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"serializeXml.d.ts","names":[],"sources":["../../src/parseXml/serializeXml.ts"],"mappings":";;;;;AAoJA;;;;AAA6C;;;;;;;;;iBAA7B,YAAA,CAAa,KAAgB,EAAT,OAAO"}
1
+ {"version":3,"file":"serializeXml.d.ts","names":[],"sources":["../../src/parseXml/serializeXml.ts"],"mappings":";;;;;AAqJA;;;;AAA6C;;;;;;;;;;iBAA7B,YAAA,CAAa,KAAgB,EAAT,OAAO"}