Release PPT workflow 0.7.3 with fixed spacing, paragraphs and native math
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Text blocks and container layout
|
||||
|
||||
Apply C16–C19 in [production rules](production-rules.md) to page authoring, reconstruction, reusable components and collaboration. These are required constraints. A page-library example is a design reference, not an exemption from current rules. Keep fonts, sizes, colors, grid and spacing tied to the selected external template.
|
||||
Apply C16–C23 in [production rules](production-rules.md) to page authoring, reconstruction, reusable components and collaboration. These are required constraints. A page-library example is a design reference, not an exemption from current rules. Keep fonts, sizes, colors, grid and spacing tied to the selected external template.
|
||||
|
||||
## One paragraph, one logical text block
|
||||
|
||||
@@ -23,6 +23,32 @@ The bundled compiler's default `preserve` text flow retains eligible stacked row
|
||||
|
||||
For an object check, find the text-bearing `p:sp` objects and their `p:txBody` in the current slide XML. A normal paragraph should occupy one text-bearing shape; multiple `a:r` runs, `a:br` breaks or `a:p` elements inside the same `p:txBody` are internal text structure. Distinct semantic labels remain independent. If the fallback is used, check the whole-block source and fragment mapping as well as native counts. Group/native XML checks do not establish actual application editing or appearance.
|
||||
|
||||
## Paragraph line-breaking rules
|
||||
|
||||
Apply punctuation prohibitions at **every line start and end**. Closing punctuation, such as Chinese commas/full stops, closing brackets and closing quotation marks, stays with preceding text; opening brackets and opening quotation marks stay with following text. Do not split paired ellipses (`……`), paired dashes (`——`) or an unbreakable Western word/number merely to fill a line. Use the appropriate punctuation convention for the language and the selected template.
|
||||
|
||||
No paragraph line may consist of only one substantive character after ignoring surrounding punctuation and whitespace. Examples of prohibited lines include `果`, `果。`, `(果)` and `“果”。`. Adding more punctuation or spaces does not make a singleton acceptable. Check **all lines, including the final line**, rather than checking only the paragraph's tail. Punctuation-only lines are also invalid.
|
||||
|
||||
Independent short labels, standalone table values and separate mathematical symbols are not automatically paragraphs. Determine their actual function; do not relabel a sentence fragment as a label to evade this rule.
|
||||
|
||||
Recompute the complete paragraph's break positions. Prefer intact phrases/clauses where they fit; move enough content between neighboring lines to satisfy both punctuation and singleton rules. If the existing bounds cannot support compliant lines, use the template's normal rewrite/layout/capacity policy. Preserve the complete content and logical text block. Do not delete punctuation, silently add words, compress glyphs, invent a smaller font size or independently position the last line.
|
||||
|
||||
For supported plain horizontal text, `scripts/paragraph_layout.py` provides `wrap_paragraph(text, max_width, measure, *, max_lines=None)` and `validate_lines(lines)`. The caller supplies a width-measurement function using the actual selected font and size. The wrapper returns derived rows whose concatenation preserves the input; render them as internal lines of one text frame. Unsupported or impossible input raises an error instead of returning a known-invalid layout. Keep the helper with the shared renderer in the portable project's inputs.
|
||||
|
||||
This helper is not a complete Unicode line-breaking or typesetting engine, and does not automatically run on arbitrary SVG, rich-text runs or PowerPoint objects. Mixed run sizes need measurements for those actual runs; application reflow must be checked in the current render even when the source rows passed validation. The punctuation/widow descriptions in the [W3C Chinese Layout Requirements working draft](https://www.w3.org/TR/clreq/#prohibition_rules_for_line_start_end) and [orphan discussion](https://www.w3.org/TR/clreq/#handling_of_widows_and_orphans) inform the implementation; the user's requirement here explicitly covers every line.
|
||||
|
||||
## Spacing and paragraph separation
|
||||
|
||||
Check more than overlap. Text must not crowd a border, a preceding explanation, a following module or a connector. Check heading/body spacing, four-sided container padding, column/group gaps, and the clearance around separators and formulas. Judge actual glyphs and visible edges at normal viewing scale; a text frame's nominal box may contain extra space or fail to describe its ink.
|
||||
|
||||
Spacing is **fixed per relationship by the selected template and shared recipe**. Content callers cannot supply numeric gaps, minima, arbitrary padding or alternate spacing variants. The template owner provides moderate values and the recipe applies them; callers do not decide how wide a particular instance should look. See the [fixed spacing contract](spacing.md). Resolve crowding by reflow, shorter content or a different supported whole layout/capacity choice, not by changing spacing or shrinking text. Intentionally cropped watermarks, attached arrows and other decorative/semantic contacts retain their own fixed rules.
|
||||
|
||||
Preserve separate paragraphs as separate complete strings or explicit paragraph nodes. Use the fixed positive paragraph gap beyond the normal line-height slots, consistently within the same text role/variant. A line wrap inside one paragraph is not a new paragraph. Prefer native paragraph before/after spacing when multiple paragraphs share a frame; one native frame per paragraph is also supported, with the shared layout deriving all positions. Avoid empty paragraphs, repeated hard breaks and blank text boxes used only as spacers.
|
||||
|
||||
`scripts/text_block.py` provides `render_text_block(data, style, theme, bounds, component_id, measure)`. Data carries `schema_version: 1`, `paragraphs: [complete string, ...]` and optional declared `text_role`/`palette_index`. The renderer reads `components.text_group.padding_px` and `paragraph_gap_px`, resolves the role's line height and uses the measured paragraph helper. It emits one SVG text per paragraph with derived internal rows, rejects height overflow, and retains the full content and layout records in metadata. Paragraph bounds describe line-height slots, not exact font ink. Supply actual-font width measurements; check native frame counts and actual rendered spacing separately.
|
||||
|
||||
`scripts/layout_spacing.py` provides `resolve_spacing(style, role)` and `check_spacing(boxes, checks, *, style)`. Boxes map stable IDs to `[x,y,width,height]`; shared recipes declare directional gaps or padding using template role names. Numeric `minimum`/`expected`/override fields are rejected. Checks compare the exact fixed value, reporting `too_narrow`, `too_wide`, `overlap` or `outside`. Padding compares the outer frame with its complete usable inner area; actual text need not fill that area. Only declared meaningful relationships are checked. Floating-point tolerance is not layout allowance. This geometric check supplements actual visual review.
|
||||
|
||||
## Keep substantive explanations visible
|
||||
|
||||
Determine importance before assigning `caption`, `detail` or muted styles. Small muted text is for supplementary background, provenance and nonessential definitions. Key conditions, timing, dependencies, conclusions and interpretation-changing limitations belong in readable body, node, callout or heading roles. A qualifying statement is not supplementary merely because it sounds cautious.
|
||||
@@ -61,5 +87,9 @@ Keep the recipe, parameters, content and assets in the portable project's declar
|
||||
2. Review every small muted note for meaning. Move essential statements into the main hierarchy and verify no qualification disappeared in the move.
|
||||
3. Compare subheading/body and other distinct roles within each container at normal viewing scale. Font family alone cannot pass.
|
||||
4. Compare all instances of each type/variant and inspect their creation calls/source. Confirm one shared implementation, no child-coordinate overrides and no post-generation nudges. Equal-looking screenshots alone cannot prove this.
|
||||
5. Read the actual line starts, line ends and last line of each paragraph. Reject forbidden punctuation positions, split unbreakable marks/words, punctuation-only rows and every singleton row, including a character surrounded by punctuation. Reflow and regenerate the whole logical paragraph when changing content, width or typography.
|
||||
6. Check the template's exact fixed values for text padding, heading/body, adjacent-group and formula/connector spacing. Verify no numeric spacing overrides or instance variants entered the caller input. Check actual glyph/edge clearance separately; non-overlap alone is insufficient.
|
||||
7. Locate semantic paragraph boundaries in the content source and render. Confirm visible extra separation between paragraphs while maintaining normal line spacing within each paragraph; no dummy empty paragraphs or manually positioned spacer objects.
|
||||
8. For mathematics, inspect [font and equation structure](mathematics.md), then the actual render. Confirm scripts/fractions/limits have not become ordinary unformatted text or a picture.
|
||||
|
||||
The compiler cannot reliably infer these semantic properties from arbitrary SVG. Combine source review, native object checks and current rendered-page review; mark unavailable application checks explicitly.
|
||||
|
||||
Reference in New Issue
Block a user