@json-to-office/jto 0.3.0 → 0.3.3

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.
Files changed (64) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/client/assets/HomePage-9ryiIVJl.js +99 -0
  3. package/dist/client/assets/HomePage-9ryiIVJl.js.map +1 -0
  4. package/dist/client/assets/JsonEditorPage-BO0AtnI3.js +3 -0
  5. package/dist/client/assets/{JsonEditorPage-DKor0I6f.js.map → JsonEditorPage-BO0AtnI3.js.map} +1 -1
  6. package/dist/client/assets/MonacoPluginProvider-BE7Xjhup.js +3 -0
  7. package/dist/client/assets/{MonacoPluginProvider-BGYshg9R.js.map → MonacoPluginProvider-BE7Xjhup.js.map} +1 -1
  8. package/dist/client/assets/NotFoundPage-SV9cseZ6.js +2 -0
  9. package/dist/client/assets/{NotFoundPage-ILCklaD-.js.map → NotFoundPage-SV9cseZ6.js.map} +1 -1
  10. package/dist/client/assets/button-DghEEchK.js +2 -0
  11. package/dist/client/assets/{button-BzUKH2aN.js.map → button-DghEEchK.js.map} +1 -1
  12. package/dist/client/assets/{docx-preview-DkKCgwb-.js → docx-preview-DQa8jhzH.js} +3 -3
  13. package/dist/client/assets/{docx-preview-DkKCgwb-.js.map → docx-preview-DQa8jhzH.js.map} +1 -1
  14. package/dist/client/assets/{editor-BS2qlF-X.js → editor-BxyYhgT1.js} +2 -2
  15. package/dist/client/assets/{editor-BS2qlF-X.js.map → editor-BxyYhgT1.js.map} +1 -1
  16. package/dist/client/assets/{editor-monaco-json-DKrX3IiN.js → editor-monaco-json-PlUCgtCX.js} +3 -3
  17. package/dist/client/assets/{editor-monaco-json-DKrX3IiN.js.map → editor-monaco-json-PlUCgtCX.js.map} +1 -1
  18. package/dist/client/assets/index-DSzthtfQ.js +3 -0
  19. package/dist/client/assets/{index-D_aKAAFg.js.map → index-DSzthtfQ.js.map} +1 -1
  20. package/dist/client/assets/{monaco-editor-B-NlkJ5A.js → monaco-editor-BcgxPCqT.js} +3 -3
  21. package/dist/client/assets/{monaco-editor-B-NlkJ5A.js.map → monaco-editor-BcgxPCqT.js.map} +1 -1
  22. package/dist/client/assets/preview-BBQhSmsm.js +3 -0
  23. package/dist/client/assets/{preview-AJZwEEO9.js.map → preview-BBQhSmsm.js.map} +1 -1
  24. package/dist/client/assets/query-vendor-Df8-oete.js +7 -0
  25. package/dist/client/assets/query-vendor-Df8-oete.js.map +1 -0
  26. package/dist/client/assets/radix-ui-BZ5iKMtq.js +51 -0
  27. package/dist/client/assets/radix-ui-BZ5iKMtq.js.map +1 -0
  28. package/dist/client/assets/react-vendor-CTFDOf2G.js +61 -0
  29. package/dist/client/assets/react-vendor-CTFDOf2G.js.map +1 -0
  30. package/dist/client/assets/{state-vendor-Az8redj0.js → state-vendor-BDrPu9qj.js} +2 -2
  31. package/dist/client/assets/{state-vendor-Az8redj0.js.map → state-vendor-BDrPu9qj.js.map} +1 -1
  32. package/dist/client/assets/{ui-vendor-ChWVh3T-.js → ui-vendor-Dyg3GRT-.js} +2 -2
  33. package/dist/client/assets/{ui-vendor-ChWVh3T-.js.map → ui-vendor-Dyg3GRT-.js.map} +1 -1
  34. package/dist/client/index.html +6 -6
  35. package/dist/prompts/instructions-docx.md +46 -0
  36. package/dist/prompts/instructions-edit-document-docx.md +54 -0
  37. package/dist/prompts/instructions-edit-document-pptx-slides.md +40 -0
  38. package/dist/prompts/instructions-edit-document-pptx-templates.md +48 -0
  39. package/dist/prompts/instructions-edit-document-pptx.md +49 -0
  40. package/dist/prompts/instructions-edit-document.md +28 -0
  41. package/dist/prompts/instructions-edit-pptx.md +31 -0
  42. package/dist/prompts/instructions-edit.md +24 -0
  43. package/dist/prompts/instructions-generate-docx.md +10 -0
  44. package/dist/prompts/instructions-generate-pptx.md +24 -0
  45. package/dist/prompts/instructions-generate.md +21 -0
  46. package/dist/prompts/pptx-core.md +180 -0
  47. package/dist/prompts/pptx-design.md +209 -0
  48. package/dist/prompts/system-theme.md +28 -0
  49. package/dist/prompts/system.md +30 -0
  50. package/package.json +17 -17
  51. package/dist/client/assets/HomePage-muPAe_M2.js +0 -99
  52. package/dist/client/assets/HomePage-muPAe_M2.js.map +0 -1
  53. package/dist/client/assets/JsonEditorPage-DKor0I6f.js +0 -3
  54. package/dist/client/assets/MonacoPluginProvider-BGYshg9R.js +0 -3
  55. package/dist/client/assets/NotFoundPage-ILCklaD-.js +0 -2
  56. package/dist/client/assets/button-BzUKH2aN.js +0 -2
  57. package/dist/client/assets/index-D_aKAAFg.js +0 -3
  58. package/dist/client/assets/preview-AJZwEEO9.js +0 -3
  59. package/dist/client/assets/query-vendor-CT0SoqJh.js +0 -15
  60. package/dist/client/assets/query-vendor-CT0SoqJh.js.map +0 -1
  61. package/dist/client/assets/radix-ui-DkKm4m5M.js +0 -2
  62. package/dist/client/assets/radix-ui-DkKm4m5M.js.map +0 -1
  63. package/dist/client/assets/react-vendor-B_QXlk-T.js +0 -102
  64. package/dist/client/assets/react-vendor-B_QXlk-T.js.map +0 -1
@@ -0,0 +1,54 @@
1
+ ## Current {{contentLabel}} ({{documentName}})
2
+ The user already has this {{contentLabelLower}} open in the editor:
3
+ ```json
4
+ {{documentText}}
5
+ ```
6
+
7
+ IMPORTANT: This {{contentLabelLower}} already exists. You are EDITING it, not generating from scratch. Return the COMPLETE modified {{contentLabelLower}} with the requested changes applied — do NOT return just a fragment.
8
+
9
+ ### Rules for editing documents
10
+
11
+ - **Preserve the existing Report/Section structure** unless the user asks to reorganize.
12
+ - Place new content in the appropriate Section based on topic.
13
+ - When adding sections, maintain the existing heading hierarchy (level 1 for title, level 2 for sections).
14
+ - Keep Header/Footer intact unless explicitly asked to change them.
15
+
16
+ ### Example
17
+
18
+ **Current document:**
19
+ ```json
20
+ [
21
+ {
22
+ "name": "Report",
23
+ "props": { "title": "Status Report" },
24
+ "children": [
25
+ { "name": "Section", "props": {}, "children": [
26
+ { "name": "Heading", "props": { "text": "Status Report", "level": 1 } },
27
+ { "name": "Paragraph", "props": { "text": "Project is on track." } }
28
+ ]}
29
+ ]
30
+ }
31
+ ]
32
+ ```
33
+
34
+ **User request:** "Add a risks section"
35
+
36
+ **Correct output (full document with new section):**
37
+ ```json
38
+ [
39
+ {
40
+ "name": "Report",
41
+ "props": { "title": "Status Report" },
42
+ "children": [
43
+ { "name": "Section", "props": {}, "children": [
44
+ { "name": "Heading", "props": { "text": "Status Report", "level": 1 } },
45
+ { "name": "Paragraph", "props": { "text": "Project is on track." } }
46
+ ]},
47
+ { "name": "Section", "props": {}, "children": [
48
+ { "name": "Heading", "props": { "text": "Risks", "level": 2 } },
49
+ { "name": "List", "props": { "items": ["Timeline delay if vendor is late", "Budget overrun on infrastructure"], "type": "bullet" } }
50
+ ]}
51
+ ]
52
+ }
53
+ ]
54
+ ```
@@ -0,0 +1,40 @@
1
+ ## Presentation: {{documentName}}
2
+
3
+ ### Available Templates (reference only — do not output these)
4
+ {{templatesSummary}}
5
+
6
+ ### Current Slides
7
+ ```json
8
+ {{slidesText}}
9
+ ```
10
+
11
+ You are EDITING the slides of this presentation. Return ONLY the modified slides array:
12
+ ```json
13
+ {
14
+ "children": [ ...all slides including unmodified ones... ]
15
+ }
16
+ ```
17
+
18
+ ### Rules for slide-scoped editing
19
+
20
+ - Output the COMPLETE `children` array — include ALL slides, not just changed ones.
21
+ - Do NOT include `"name"` or `"props"` keys — templates and presentation settings are unchanged.
22
+ - Reference existing template names from the list above.
23
+ - New slides MUST reference existing templates — do not invent new templates.
24
+ - Preserve unmodified slides exactly as they appear above.
25
+ - When editing a slide, keep its `template` reference and only change `placeholders` content.
26
+ - If the presentation uses templates, new slides should also use templates for consistency.
27
+
28
+ ### Example
29
+
30
+ **User request:** "Add a slide about pricing"
31
+
32
+ **Correct output (complete children array with new slide appended):**
33
+ ```json
34
+ {
35
+ "children": [
36
+ { "name": "slide", "props": { "template": "CONTENT_TEMPLATE", "placeholders": { "heading": { "name": "text", "props": { "text": "Overview" } } } } },
37
+ { "name": "slide", "props": { "template": "CONTENT_TEMPLATE", "placeholders": { "heading": { "name": "text", "props": { "text": "Pricing" } } } } }
38
+ ]
39
+ }
40
+ ```
@@ -0,0 +1,48 @@
1
+ ## Presentation: {{documentName}}
2
+
3
+ ### Current Templates
4
+ ```json
5
+ {{templatesText}}
6
+ ```
7
+
8
+ ### Slides Using These Templates (reference only — do not output these)
9
+ {{slidesSummary}}
10
+
11
+ You are EDITING the template slides of this presentation. Output **only new or modified** templates:
12
+ ```json
13
+ {
14
+ "templates": [ ...only new/changed templates... ]
15
+ }
16
+ ```
17
+
18
+ Unchanged templates are automatically preserved — do NOT echo them back.
19
+
20
+ ### Rules for template-scoped editing
21
+
22
+ - Output ONLY templates you are adding or modifying. Omit unchanged templates entirely.
23
+ - Do NOT include `"name"`, `"children"`, or other top-level keys — only `"templates"`.
24
+ - When modifying a template, output the **complete** template object (all its placeholders, objects, background, etc.) — not just the changed fields.
25
+ - Keep template names stable — slides reference them by name. Renaming a template breaks existing slides.
26
+ - To DELETE a template, output: `{ "name": "TEMPLATE_NAME", "_delete": true }`
27
+ - When adding a new template, use SCREAMING_SNAKE_CASE naming (e.g. `FULLSCREEN_IMAGE_TEMPLATE`).
28
+ - Each template needs: `name`, `placeholders[]`, and optionally `background`, `objects[]`, `grid`.
29
+ - For page numbers, add a text component with `"text": "{PAGE_NUMBER}"` inside `objects[]` — do NOT use a `slideNumber` key.
30
+
31
+ ### Example
32
+
33
+ **User request:** "Add a divider bar to CONTENT_TEMPLATE"
34
+
35
+ **Correct output (only the modified template):**
36
+ ```json
37
+ {
38
+ "templates": [
39
+ {
40
+ "name": "CONTENT_TEMPLATE",
41
+ "placeholders": [{ "name": "heading" }, { "name": "body" }],
42
+ "objects": [
43
+ { "name": "shape", "props": { "type": "line", "x": "5%", "y": "20%", "w": "90%", "h": "0%", "line": { "color": "accent", "width": 1 } } }
44
+ ]
45
+ }
46
+ ]
47
+ }
48
+ ```
@@ -0,0 +1,49 @@
1
+ ## Current {{contentLabel}} ({{documentName}})
2
+ The user already has this {{contentLabelLower}} open in the editor:
3
+ ```json
4
+ {{documentText}}
5
+ ```
6
+
7
+ IMPORTANT: This {{contentLabelLower}} already exists. You are EDITING it, not generating from scratch. Return the COMPLETE modified {{contentLabelLower}} with the requested changes applied — do NOT return just a fragment.
8
+
9
+ ### Rules for editing presentations
10
+
11
+ - **Preserve all existing templates** in `pptx.props.templates` unless explicitly asked to modify them.
12
+ - When adding new slides, **reference existing template names** — do not invent new templates unless the user asks for a new layout.
13
+ - When editing a slide, keep its `template` reference and only change the `placeholders` content.
14
+ - If the presentation uses templates, new slides should also use templates for consistency.
15
+
16
+ ### Example
17
+
18
+ **Current presentation (abbreviated):**
19
+ ```json
20
+ {
21
+ "name": "pptx",
22
+ "props": {
23
+ "templates": [
24
+ { "name": "CONTENT_TEMPLATE", "placeholders": [{ "name": "heading", "type": "title" }, { "name": "body", "type": "body" }] }
25
+ ]
26
+ },
27
+ "children": [
28
+ { "name": "slide", "props": { "template": "CONTENT_TEMPLATE", "placeholders": { "heading": { "name": "text", "props": { "text": "Overview" } }, "body": { "name": "text", "props": { "text": "Content here." } } } } }
29
+ ]
30
+ }
31
+ ```
32
+
33
+ **User request:** "Add a slide about pricing"
34
+
35
+ **Correct output (full document with new slide appended, using existing template):**
36
+ ```json
37
+ {
38
+ "name": "pptx",
39
+ "props": {
40
+ "templates": [
41
+ { "name": "CONTENT_TEMPLATE", "placeholders": [{ "name": "heading", "type": "title" }, { "name": "body", "type": "body" }] }
42
+ ]
43
+ },
44
+ "children": [
45
+ { "name": "slide", "props": { "template": "CONTENT_TEMPLATE", "placeholders": { "heading": { "name": "text", "props": { "text": "Overview" } }, "body": { "name": "text", "props": { "text": "Content here." } } } } },
46
+ { "name": "slide", "props": { "template": "CONTENT_TEMPLATE", "placeholders": { "heading": { "name": "text", "props": { "text": "Pricing" } }, "body": { "name": "table", "props": { "rows": [["Plan", "Price"], ["Starter", "$9/mo"], ["Pro", "$29/mo"]], "grid": { "column": 0, "row": 2, "columnSpan": 12, "rowSpan": 3 } } } } } }
47
+ ]
48
+ }
49
+ ```
@@ -0,0 +1,28 @@
1
+ ## Current {{contentLabel}} ({{documentName}})
2
+ The user already has this {{contentLabelLower}} open in the editor:
3
+ ```json
4
+ {{documentText}}
5
+ ```
6
+
7
+ IMPORTANT: This {{contentLabelLower}} already exists. You are EDITING it, not generating from scratch. When the user asks to change, add, or modify content, return the COMPLETE modified {{contentLabelLower}} preserving the existing structure. Do NOT return just a fragment — return the full {{contentLabelLower}} with the requested changes applied.
8
+
9
+ ### Example
10
+
11
+ **Current document:**
12
+ ```json
13
+ [
14
+ { "name": "Heading", "props": { "text": "Old Title", "level": 1 } },
15
+ { "name": "Text", "props": { "text": "Some content here." } }
16
+ ]
17
+ ```
18
+
19
+ **User request:** "Change the title to New Title and add a second paragraph"
20
+
21
+ **Correct output (full document with changes applied):**
22
+ ```json
23
+ [
24
+ { "name": "Heading", "props": { "text": "New Title", "level": 1 } },
25
+ { "name": "Text", "props": { "text": "Some content here." } },
26
+ { "name": "Text", "props": { "text": "Additional paragraph with new content." } }
27
+ ]
28
+ ```
@@ -0,0 +1,31 @@
1
+ The user has selected a portion of their PPTX JSON document and wants you to edit it.
2
+
3
+ **Document name:** {{documentName}}
4
+ **JSON path:** {{jsonPath}}
5
+ **Selected text:**
6
+ ```json
7
+ {{selectedText}}
8
+ ```
9
+
10
+ IMPORTANT: Produce ONLY the modified fragment that replaces the selected text above. Do NOT produce the entire document. The output will be spliced back into the document at the selection point. Wrap it in a ```json code block.
11
+
12
+ ### PPTX selection editing rules
13
+
14
+ - This fragment lives inside a template-based slide. The template's placeholders already define default styling.
15
+ - **Don't add props the placeholder already defines** — `fontSize`, `fontFace`, `color`, `bold`, `italic`, `align`, `valign`, `margin`, `charSpacing`, `lineSpacing`, `style`, and position are inherited automatically.
16
+ - Grid positions are slide-relative, not placeholder-relative.
17
+ - Keep components minimal — only include props that differ from placeholder defaults.
18
+
19
+ ### Example
20
+
21
+ **Selected text:**
22
+ ```json
23
+ { "name": "text", "props": { "text": "Hello world", "fontSize": 14, "bold": false } }
24
+ ```
25
+
26
+ **User request:** "Change to Welcome and make it bold"
27
+
28
+ **Correct output** (omit fontSize if placeholder provides it):
29
+ ```json
30
+ { "name": "text", "props": { "text": "Welcome", "bold": true } }
31
+ ```
@@ -0,0 +1,24 @@
1
+ The user has selected a portion of their JSON document and wants you to edit it.
2
+
3
+ **Document name:** {{documentName}}
4
+ **JSON path:** {{jsonPath}}
5
+ **Selected text:**
6
+ ```json
7
+ {{selectedText}}
8
+ ```
9
+
10
+ IMPORTANT: Produce ONLY the modified fragment that replaces the selected text above. Do NOT produce the entire document. The output will be spliced back into the document at the selection point. Wrap it in a ```json code block.
11
+
12
+ ### Example
13
+
14
+ **Selected text:**
15
+ ```json
16
+ { "name": "Text", "props": { "text": "Hello world", "bold": false } }
17
+ ```
18
+
19
+ **User request:** "Make it bold and change to Welcome"
20
+
21
+ **Correct output:**
22
+ ```json
23
+ { "name": "Text", "props": { "text": "Welcome", "bold": true } }
24
+ ```
@@ -0,0 +1,10 @@
1
+ The user wants you to generate a complete document JSON from scratch.
2
+
3
+ Produce a full DOCX JSON wrapped in a ```json code block:
4
+
5
+ - Use a `Report` root with one or more `Section` children
6
+ - Start with a level-1 `Heading` as the document title
7
+ - Mix component types for visual interest: Headings, Paragraphs, Tables, Lists, Statistics
8
+ - Include `Header` and `Footer` if appropriate for the document type
9
+ - Use `Columns` for side-by-side comparisons or multi-column layouts
10
+ - Aim for 3–6 sections with varied content
@@ -0,0 +1,24 @@
1
+ The user wants you to generate a complete presentation JSON from scratch.
2
+
3
+ Produce a full PPTX JSON wrapped in a ```json code block:
4
+
5
+ - Define 2–3 template slides (TITLE_TEMPLATE, CONTENT_TEMPLATE, and optionally TWO_COLUMN_TEMPLATE)
6
+ - Templates should include header bars, footer bars, and branding text as `objects` (same `{ name, props }` component format as slide children)
7
+ - The presentation MUST include a `"grid"` prop on `pptx.props` (e.g. `"grid": { "columns": 12, "rows": 6, "margin": 0.5, "gutter": 0.2 }`)
8
+ - Templates with header/footer bars MUST set `"grid": { "margin": { "top": <header-height + 0.2> } }` so row 0 starts below the header
9
+ - Generate 5–8 slides that reference these templates and fill their placeholders
10
+ - Mix component types: text, shapes, tables where appropriate
11
+ - Include a title slide and a closing/thank-you slide
12
+ - Use `charSpacing` on wordmarks, uppercase labels, and section identifiers for professional typography
13
+ - For refined/elegant designs, use light font variants (e.g. `"Inter Light"`) via `fontFace` instead of relying on bold alone
14
+
15
+ Before finalizing, verify:
16
+ - [ ] No two text/shape components share the same position
17
+ - [ ] Headings fit their container (short text or reduced fontSize)
18
+ - [ ] `slideNumber` is in the bottom-right, not overlapping content
19
+ - [ ] All `ellipse` shapes intended as circles have equal `w` and `h`
20
+ - [ ] Initials and short labels inside shapes have no `\n` line breaks
21
+ - [ ] Every template with a header/footer bar sets `grid.margin` to push content clear
22
+ - [ ] Tables specify `rowH` (0.4–0.55") and `margin` ([3, 6, 3, 6])
23
+ - [ ] Tables use `borderRadius` (0.1–0.2) for polished appearance
24
+ - [ ] Cells with Unicode symbols (✓, —) use `fontFace: "Arial"`
@@ -0,0 +1,21 @@
1
+ The user wants you to generate a complete {{contentType}} JSON from scratch.
2
+
3
+ Produce a full {{contentType}} JSON wrapped in a ```json code block. Include all required fields.
4
+
5
+ ### Example
6
+
7
+ A minimal document with a heading and paragraph:
8
+ ```json
9
+ [
10
+ {
11
+ "name": "Heading",
12
+ "props": { "text": "Project Overview", "level": 1 }
13
+ },
14
+ {
15
+ "name": "Text",
16
+ "props": { "text": "This section introduces the key objectives and scope of the project." }
17
+ }
18
+ ]
19
+ ```
20
+
21
+ Use this structure as a starting point — expand with additional components appropriate to the user's request.
@@ -0,0 +1,180 @@
1
+ # PPTX Presentation Guidelines
2
+
3
+ ## Architecture
4
+
5
+ A PPTX presentation has this structure:
6
+
7
+ ```
8
+ pptx.props.templates[] → reusable slide layouts (defined once)
9
+ pptx.children[].props.template → slide references a template by name
10
+ pptx.children[].props.placeholders → slide fills template's named regions
11
+ ```
12
+
13
+ **Template slides are the foundation of every presentation.** Every slide MUST reference a template. Templates enforce visual consistency, reduce repetition, and let placeholders carry default styling so slides stay minimal. Custom (templateless) slides are an absolute last resort.
14
+
15
+ ## Template Slide Definition
16
+
17
+ Each template has:
18
+ - `name` — unique identifier (SCREAMING_SNAKE_CASE)
19
+ - `background` — optional, color or image
20
+ - `objects[]` — fixed components (shapes, text, images) that appear on every slide using this template. Uses the same `{ name, props }` format as slide children
21
+ - `placeholders[]` — named content regions that slides fill with components
22
+ - `slideNumber` — optional, position and style of auto slide numbers
23
+ - `grid` — optional grid override, merged with the presentation grid. Use this to shift the content area below header bars. Example: `"grid": { "margin": { "top": 1.1 } }` pushes row 0 below a 0.9" header.
24
+
25
+ ### Fixed objects in `objects[]`
26
+
27
+ Template objects use the **same `{ name, props }` component format** as slide children. Any content component (shape, text, image, table, chart) can be used as a template object.
28
+
29
+ **Important:** Fixed decorations (header bars, footer bars) should use absolute `x`/`y`/`w`/`h`, not grid — because the template's `grid` override shifts grid positions, and decorations shouldn't shift themselves.
30
+
31
+ ```json
32
+ { "name": "shape", "props": { "type": "rect", "x": 0, "y": 0, "w": 10, "h": 0.9, "fill": { "color": "primary" } } }
33
+ { "name": "shape", "props": { "type": "roundRect", "x": 0, "y": 0, "w": 10, "h": 0.9, "fill": { "color": "primary" }, "rectRadius": 0.15 } }
34
+ { "name": "text", "props": { "text": "COMPANY", "x": 0.6, "y": 0.15, "w": 4, "h": 0.6, "fontSize": 14, "bold": true, "color": "FFFFFF" } }
35
+ { "name": "shape", "props": { "type": "line", "x": 0.5, "y": 2, "w": 9, "h": 0, "line": { "color": "accent", "width": 1 } } }
36
+ { "name": "image", "props": { "path": "logo.png", "x": 8.5, "y": 0.15, "w": 1, "h": 0.6 } }
37
+ ```
38
+
39
+ Template objects support all component props including `rectRadius`, `shadow`, `rotate`, `fill.transparency`, `line.dashType`, rich text segments, etc.
40
+
41
+ ### Placeholder definition
42
+
43
+ ```json
44
+ {
45
+ "name": "body",
46
+ "grid": { "column": 0, "row": 2, "columnSpan": 12, "rowSpan": 3 },
47
+ "defaults": { "name": "text", "props": { "style": "body", "fontSize": 14 } }
48
+ }
49
+ ```
50
+
51
+ - `name` — key used in `slide.props.placeholders` to fill this region
52
+ - Position via `grid` (preferred) or `x`/`y`/`w`/`h`
53
+ - `defaults` — optional component stub (`{ name, props }`) whose props are inherited by the component placed in this placeholder. Supports any component type — text defaults for text placeholders, chart defaults for chart placeholders, etc.
54
+
55
+ ## Grid Positioning (preferred)
56
+
57
+ Grid is a **presentation-level** prop (on `pptx.props`), not a theme-level setting:
58
+
59
+ ```json
60
+ {
61
+ "name": "pptx",
62
+ "props": {
63
+ "theme": "corporate",
64
+ "grid": { "columns": 12, "rows": 6, "margin": { "top": 0.75, "right": 0.6, "bottom": 0.5, "left": 0.6 }, "gutter": { "column": 0.2, "row": 0.15 } }
65
+ }
66
+ }
67
+ ```
68
+
69
+ Use the 12-column × 6-row grid instead of absolute x/y/w/h:
70
+
71
+ ```json
72
+ "grid": { "column": 0, "row": 1, "columnSpan": 6, "rowSpan": 2 }
73
+ ```
74
+
75
+ - Columns: 0–11, Rows: 0–5
76
+ - Grid respects presentation-level margins (default 0.5") and gutters (default 0.2")
77
+ - Use `columnSpan`/`rowSpan` to size elements
78
+ - Explicit `x`/`y`/`w`/`h` override grid when both are present
79
+
80
+ ## Filling Placeholders (Slide Level)
81
+
82
+ Slides reference a template and fill each placeholder with a single component:
83
+
84
+ ```json
85
+ {
86
+ "name": "slide",
87
+ "props": {
88
+ "template": "CONTENT_TEMPLATE",
89
+ "placeholders": {
90
+ "heading": { "name": "text", "props": { "text": "Slide Title" } },
91
+ "body": { "name": "text", "props": { "text": "Key insight here." } }
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ Each placeholder maps to exactly one component (not an array). The component inherits the placeholder's position and `defaults` props.
98
+
99
+ ### Placeholder inheritance
100
+
101
+ Placeholders provide default props via `defaults`. The component placed in the placeholder inherits these — **do NOT re-specify a prop if `defaults` already defines it.**
102
+
103
+ Resolution order (most specific wins): `component props → defaults props → position from placeholder`
104
+
105
+ This is a simple spread: `{ ...position, ...defaults.props, ...component.props }`.
106
+
107
+ **Good** — defaults defines `fontSize: 14` and `style: "body"`, component omits them:
108
+ ```json
109
+ { "name": "text", "props": { "text": "Key insight here." } }
110
+ ```
111
+
112
+ **Bad** — redundantly re-specifying what defaults already provides:
113
+ ```json
114
+ { "name": "text", "props": { "text": "Key insight here.", "fontSize": 14, "style": "body" } }
115
+ ```
116
+
117
+ Only override a defaults prop when you genuinely need a different value for that specific component.
118
+
119
+ ## Semantic Colors
120
+
121
+ Use theme color names, not hex codes:
122
+ - `primary`, `secondary`, `accent` — brand colors
123
+ - `background`, `background2` — surface colors
124
+ - `text`, `text2` — text colors
125
+ - `accent4`, `accent5`, `accent6` — additional accents
126
+
127
+ Only use hex (e.g. `"FFFFFF"`) for absolute white/black when needed.
128
+
129
+ ## Named Styles
130
+
131
+ Themes define a `styles` map with predefined text style presets. Use `"style"` on text/shape components to apply formatting without repeating props.
132
+
133
+ **Available style names:** `title`, `subtitle`, `heading1`, `heading2`, `heading3`, `body`, `caption`
134
+
135
+ **Usage on components:**
136
+ ```json
137
+ { "name": "text", "props": { "text": "My Title", "style": "title" } }
138
+ { "name": "shape", "props": { "type": "roundRect", "text": "KPI", "style": "caption", "fill": { "color": "background2" } } }
139
+ ```
140
+
141
+ **Usage on placeholder defaults:**
142
+ ```json
143
+ { "name": "heading", "grid": { "column": 0, "row": 0, "columnSpan": 12 }, "defaults": { "name": "text", "props": { "style": "heading1" } } }
144
+ ```
145
+
146
+ **Resolution cascade (most specific wins):**
147
+ `component props → component style → defaults props → defaults style → theme defaults`
148
+
149
+ Explicit props always override style values. Example: `"style": "heading1", "fontSize": 32` → uses 32pt, not the style's fontSize.
150
+
151
+ **Built-in defaults (all themes):**
152
+
153
+ | Style | fontSize | bold | italic | fontColor | align |
154
+ |----------|----------|------|--------|-----------|--------|
155
+ | title | 36 | yes | | text | center |
156
+ | subtitle | 20 | | yes | text2 | center |
157
+ | heading1 | 28 | yes | | primary | |
158
+ | heading2 | 22 | yes | | primary | |
159
+ | heading3 | 18 | yes | | text | |
160
+ | body | 14 | | | | |
161
+ | caption | 10 | | yes | text2 | |
162
+
163
+ Heading styles (`title`, `heading1-3`) auto-use `theme.fonts.heading`; others use `theme.fonts.body`.
164
+
165
+ Themes can override styles in the `styles` key:
166
+ ```json
167
+ "styles": {
168
+ "title": { "fontSize": 40, "bold": true, "fontColor": "accent", "align": "left" }
169
+ }
170
+ ```
171
+
172
+ ## Available Components
173
+
174
+ Use these inside `placeholders`, `children`, or template `objects`:
175
+ - **text** — headings, paragraphs, bullets. Props: `text`, `fontSize`, `bold`, `italic`, `color`, `align`, `bullet`, `lineSpacing`, `charSpacing`, `paraSpaceAfter`
176
+ - **shape** — rectangles, circles, arrows, etc. Props: `type` (rect, roundRect, ellipse, triangle, etc.), `fill`, `text` (string or `[{ text, fontSize?, color?, bold?, italic?, breakLine? }]` for rich text), `fontSize`, `fontColor`, `charSpacing`
177
+ - **table** — data grids. Props: `rows` (2D array of strings or cell objects), `colW`, `rowH`, `border`, `fontSize`, `margin`, `borderRadius`
178
+ - **image** — pictures. Props: `path` or `base64`, `sizing` ({ type: "cover"|"contain" })
179
+ - **chart** — **DEFAULT for all charts.** Native PowerPoint chart — editable, no external server. Always use this unless the user explicitly asks for Highcharts. Title, legend, and axis label colors auto-default to the theme's `text` color for proper contrast on any background. Props: `type` (area, bar, bar3D, bubble, doughnut, line, pie, radar, scatter), `data` (array of `{ name?, labels?, values?, sizes? }`), `showLegend`, `showTitle`, `title`, `titleColor`, `chartColors` (hex or semantic), `legendPos`, `legendColor`, axis options (`catAxisTitle`, `valAxisTitle`, `valAxisMinVal`, `valAxisMaxVal`, `valAxisLabelFormatCode`, `catAxisLabelColor`, `valAxisLabelColor`), bar options (`barDir`, `barGrouping`, `barGapWidthPct`), line options (`lineSmooth`, `lineDataSymbol`, `lineSize`), pie/doughnut (`firstSliceAng`, `holeSize`), radar (`radarStyle`), data labels (`dataLabelColor`, `dataLabelFontSize`, `dataLabelPosition`)
180
+ - **highcharts** — **ONLY use when the user explicitly requests Highcharts.** Renders charts via Highcharts as images (not editable in PowerPoint). Props: `chartOptions` (Highcharts options object), `width`, `height`