fix(presentations): separate slides with a thematic break - #32
Open
Ready22Race wants to merge 1 commit into
Open
fix(presentations): separate slides with a thematic break#32Ready22Race wants to merge 1 commit into
Ready22Race wants to merge 1 commit into
Conversation
The three presentation parsers concatenate every slide's blocks into one list with nothing between them. A slide's title becomes a heading, so decks that title every slide read correctly by accident — but a slide with no title placeholder contributes no structural block at all, and its content becomes indistinguishable from the previous slide's. Two title-less slides in a row produce two adjacent paragraphs, exactly as if they were two paragraphs of one slide. Bullet lists from different slides merge into one list. This is not the pagination that "Markdown has no pages" rightly refuses. A slide is a container in the source model, not a layout artifact, and losing its boundary loses document structure. Block::Rule is the separator the model already has (emitted for <hr>, rendered as ---), so no new concept is introduced and no page number is implied. Emitted BETWEEN slides only: never leading, and a slide that produces no blocks never yields a doubled or dangling break. Applies to pptx, ppt and odp, which all had the same shape. Core-only: every binding already maps model::Block::Rule (node/src/ document.rs:88, python/src/document.rs:83, wasm/src/document.rs:96) and already declares the `rule` kind (node/index.d.ts:60, python/anydoc/_anydoc.pyi:84, wasm/src/typescript.rs:47), so no binding source or type surface changes.
|
Independent verification, for whatever it's worth — we hit #31 on a Pandoc-authored deck while evaluating anydoc as the conversion engine for our ingestion pipeline, before finding the issue already filed. Checked out
One note for anyone reading along, orthogonal to this PR: on that same deck the remaining structure loss is bullet formatting inherited from the layout ( |
H0rowitz
added a commit
to H0rowitz/anydoc
that referenced
this pull request
Aug 6, 2026
…(independently verified) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #31.
What
Emits
Block::Rulebetween slides in the three presentation parsers (pptx,ppt,odp), which previously concatenated every slide's blocks with nothing in between.A slide's title becomes a
Heading, so decks that title every slide read correctly by accident. A slide with no title placeholder contributes no structural block, so its content is indistinguishable from a continuation of the previous slide — two untitled slides in a row produce two adjacent paragraphs, and bullet lists from different slides merge into one list.Why a thematic break
No new concept and no page number:
Block::Rulealready exists, is already emitted for<hr>(src/shared/html.rs:432), and already renders as---(src/render/markdown/mod.rs:201).This is deliberately not the pagination #26 declined. That issue settled that a
w:type="page"break is layout and dropping it is correct. A slide is a container in the source model rather than a layout artifact, so its boundary is document structure.Shape of the change
Each parser now accumulates one slide into a local
Vec<Block>and appends it only if non-empty, pushing aRulefirst when output already exists. That gives two guarantees worth stating:---before the first slidepptalready accumulated per slide, so it only needed the guard.Scope: core only, no binding changes
Block::Rulealready exists and every binding already handles it, so nothing outsidesrc/formats/needs to move:model::Block::Rulerulekindnode/src/document.rs:88node/index.d.ts:60python/src/document.rs:83python/anydoc/_anydoc.pyi:84wasm/src/document.rs:96wasm/src/typescript.rs:47No new
Blockvariant, no public API change, no type-surface change. Confirmed end to end through the Python binding on the deck from the issue:Tests
Three unit tests in
src/formats/pptx/mod.rs, building minimal packages in memory in the style of thesheetmodule's tests — they pin the behaviour rather than just the output:untitled_slides_are_separated— the defect itself: two title-less slides must not read as oneseparator_never_leads— a deck must not open with---, and a single slide yields only its own contentempty_slides_leave_no_dangling_separator— a slide contributing no blocks must not add a break, neither doubled between two real slides nor trailingVerification
Snapshot delta is 6 added
---lines and 6 added blank lines across 6 snapshots, with zero removals — no content changed, only separators appeared:Also checked by hand against a deck whose slides 2 and 3 have no title placeholder (the case in the issue) and against
tests/fixtures/ppt/pres.ppt.Note
Happy to take this in a different direction if you would rather the boundary be expressed some other way, or scope it to a subset of the three parsers. The behaviour change is visible in output, so it is your call whether it belongs in a minor bump.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.