Release PPT workflow 0.7.1 with portable installation and production components

This commit is contained in:
2026-10-12 18:45:54 +08:00
parent 4e3271ff62
commit f932b1970d
40 changed files with 2166 additions and 28 deletions
+43
View File
@@ -0,0 +1,43 @@
# Data-bound basic components
`scripts/basic_component.py` provides native tables, text metrics, timelines and explicit linear flows. Use [charts](charts.md) for seven native Chart types. All helpers read the selected external template's style/theme and return a component SVG group; they add no organization, page UI, Master or Layout. Compose groups inside existing declared slots. SVG images inserted through `image href` are not a substitute for this native-object composition.
| Kind and source example | Native result | Input and capacity |
|---|---|---|
| [table](../assets/components/basic/table.json) | PowerPoint Table with actual cells, widths, padding and header rows | `columns`, equal-length `rows`, optional `column_widths` summing to bounds width, zero-based `numeric_columns`; strings or finite numbers, empty cells allowed |
| [table / grouped](../assets/components/basic/table-grouped.json) | Native Table with merged group headers, separate native data bars and explicit status shapes | `variant: grouped`; object columns, explicit groups/widths and original row values; optional focus, row headers, per-column bars and status mapping |
| [metric](../assets/components/basic/metric.json) | Text objects, including number/unit | `label`, `value`, optional `unit` and `detail`; at least160px high |
| [timeline](../assets/components/basic/timeline.json) | Native line, circles and text | 2–6 `items` with `date` and `label`; at least208px high; ordinal milestones spaced equally, not a quantitative elapsed-time axis |
| [flow](../assets/components/basic/flow.json) | Native boxes, arrows and text | 2–6 `nodes` with unique `id`/`label`, explicit `edges: [[from,to], …]`; at least160px high; supports only forward adjacent links, not inferred causality or branches |
Each JSON uses `schema_version: 1` and `kind`. Examples are marked `data_kind: synthetic-demo`; preserve this declaration and source metadata when demonstrating. Real reports retain observations, definitions, missing-value policy and sources under [production rules](production-rules.md). Metadata remains in SVG; save original JSON with the page. The table payload is canonical native metadata, with original data in `data-component-source`; other groups carry original JSON in metadata. Native PPTX does not retain arbitrary SVG metadata, so retain project sources separately.
The table uses `style.components.table`, including theme-indexed header colors and padding. Text uses `typography.roles.label`, `caption` and `number`, their declared font families and `canvas.pt_to_px`. Other component colors use `dk1`, `dk2`, `accent1`, `line` and `lt1` from the palette. Internal spacing uses fixed 8px modules; derived equal columns/centers do not introduce new page alignment guides. Width checks are conservative estimates, not a font renderer. The tool rejects excess capacity instead of shrinking text. Rephrase, enlarge a slot, change layout or split content; inspect actual application output.
## Grouped table
The default table remains unchanged. Select `kind: table, variant: grouped` for a denser comparison with two header levels. Each column is `{id, label, unit?, format?}` with a unique stable ID. `format` is `text` (default), `integer` (integral numbers only, with thousands separators), or `one-decimal`. Formatting changes display text, never original `rows`. `numeric_columns` contains zero-based indices and right-aligns those headers and values. Numeric columns require actual finite numbers rather than formatted strings.
`column_widths` is mandatory and must fill the bounds width. `column_groups: [{label,start,span}, …]` must cover all columns once in order, with no gaps or overlap; spans become merged native cells. `row_header_columns` optionally gives zero-based columns a persistent pale background. `focus_row` optionally emphasizes one explicit zero-based data row; this does not infer a recommendation. Preserve a `focus_meaning` when its interpretation matters.
Optional `bars: {columns: […]}` adds 4px tracks and bars to explicitly declared numeric columns. Values must be finite and nonnegative. Each column has its own domain `[0, maximum]`, with `[0,1]` for an all-zero column. A zero value leaves an empty track. Bars permit comparison only within a column; they do not normalize different units into a score. Save the source, units and `bar_meaning` alongside the page. The outer group's JSON metadata includes `derived_marks` with raw values, domains, row/column indices and geometry so these mappings can be checked.
Optional `status: {column, values: {"label": {palette_index, shape}}}` binds an explicit textual status to `circle` or `diamond` and a palette index. Unknown values, shapes and palette indices fail; the helper does not infer success, caution or failure semantics. Text remains visible alongside the shape. Stable shape IDs derive from the component ID and row/column. These simple semantic marks are native UI shapes; custom illustrative icons still follow [icon production](icon-production.md).
The grouped style reads `typography.roles.label` and `caption`, including each role's declared family, and uses `accent1`, `accent2`, `surface_tint`, `lt1`, `lt2`, `dk1`, `dk2` and `line`. Optional `style.components.table_grouped` keys are `group_height_px`, `header_height_px`, `row_height_px` and `cell_padding_px: [top,side]`. Heights and padding use 8px modules and must meet text capacity. Defaults derive from the external typography; 20pt label / 18pt caption at 96dpi produces 40px group, 80px header and 56px data rows with bars. No font or organization is fixed in the component. Accent group headers, pale column headers, light alternating rows, group separators and a 4px focus edge provide hierarchy without a full grid.
The returned outer `g` contains a separate native-table marker with a fresh fallback fingerprint, followed by native bar/status shapes outside that marker. Insert the **whole outer group** into the page, not just the table marker. Retain its original data and regenerate after changes; never edit only the payload or only the fallback. Use the same `basic_component.py` CLI/API shown below with the grouped JSON and sufficiently large bounds. The bundled example needs 1152px width and 400px height under the stated 20pt/18pt typography.
```sh
python /path/to/skill/scripts/basic_component.py \
--manifest /absolute/template/manifest.json --theme selected-theme \
--data /absolute/project/data/table.json \
--bounds 64 156 564 464 --id results-table \
--output /absolute/project/sources/new-component.svg
```
The CLI protects existing files and symlinked output paths. The output canvas follows the template but contains only the component. It cannot be compiled as a complete template page by itself.
For Python composition, add the Skill's `scripts` directory to `sys.path`, import `render_component` from `basic_component`, and call `render_component(data, style, theme_data, (x,y,width,height), component_id)`. Take `style` and `theme_data` from `template_ref.py export-style`. Insert the returned `g` into the current template page's slot while retaining its existing Master/Layout/placeholder attributes and full roster. A slot label or example content must be removed as part of filling that slot, without removing inherited UI.
After composition, validate native marker payloads using [native objects](native-objects.md). Compile with `native_export.py`, check `a:tbl` for the table and text/shapes/connectors for the other components, then inspect current renders. Keep separate evidence for native structure, application appearance, editing and projection. General architectures, branched flows and custom comparisons can be composed from the same native primitives; this limited helper is not a requirement to fit every diagram into a linear chain.