Skip to content

[Bug Report] [DeckCraft] PDF text layer maps the slide-number field to a single angle quote #1153

Description

@forhadkhan

Environment

  • DeckCraft 0.9.0 (deckcraft-cli --version), Ubuntu 24.04 x86_64, .deb from ArtCraft Launcher 0.6.1
  • Driven by an MCP client over stdio: deckcraft-cli mcp --automation-read-root <dir> --automation-write-root <dir>

Steps

  1. new_presentation {}, then add_slide {"layout":"titleOnly","title":"Numbers"}
  2. run_command {"command":"design.headerFooter","params":{"slideNumber":true,"all":true}}
  3. export {"path":"d.pdf","format":"pdf"} (text layer on, the default)
  4. pdftotext -f 2 -l 2 d.pdf -

Actual

The text of page 2 is Numbers followed by ‹ (U+2039, bytes e2 80 b9). The rendered page shows the number 2.

Expected

The text layer contains the evaluated slide number ("2"), so search, copy and text extraction match what is drawn.

Near miss: #164 (closed, ToUnicode).

Activity

  1. ticket-craft commented on Oct 22, 2026

    @ticket-craft

    Possibly related: #62.

  2. MarekSpodBiedry commented on Oct 22, 2026

    @MarekSpodBiedry
    Contributor

    I'm working on this.

  3. Harrison-Booth commented on Oct 28, 2026

    @Harrison-Booth
    Contributor

    Comparison of the two open PRs for this issue: #1192 and #1197. Nothing here picks one; it is what I checked.

    #1192 #1197
    Size +108/-14, 5 files (pdf/lib.rs, pdf/tests.rs, render/lib.rs, render/placed.rs, render/tests.rs) +93/-17, 5 files (ROADMAP.md, pdf/lib.rs, pdf/tests.rs, render/placed.rs, text/lib.rs)
    Where the field value is applied In place_text: the cloned PlacedText.body gets each field run replaced by a text run holding its value, so every reader of body sees the value PlacedText.body stays as saved; a new PlacedText.shown holds each paragraph as laid out, built by a new public deckcraft_text::shown_paragraphs that shares shown_run with the layout code. The PDF code reads shown
    Line break (Break run) PDF code joins Run::content() (one \u{b}), the count the layout uses shown_run returns \u{b} for a break, the same count
    Date and time fields Also threads one RenderOpts { now } through the two rasters and the text layer (new public place_slide_with) Not touched. On main each SlideFields::new reads the clock itself (opts.now.or_else(DateTime::now_local), crates/render/src/opts.rs), so the raster and the text layer read it separately. I did not try to reproduce a mismatch
    New tests 2 in deckcraft-pdf (slide number on 3 pages, line break), 2 in deckcraft-render (field value in PlacedText, date from the given options) The same 2 in deckcraft-pdf; none in render or text
    ROADMAP.md not touched adds a row
    Behind main 518 commits 233 commits
    Merge with main conflicts in pdf/src/lib.rs, render/src/lib.rs, render/src/tests.rs conflicts in ROADMAP.md and text/src/lib.rs (the text code moved in the module split)
    Checks the 2 listed pass the 2 listed pass
    Both together conflict with each other in pdf/src/lib.rs, pdf/src/tests.rs, render/src/placed.rs and render/src/tests.rs

    What I did and did not do:

    • Read both diffs, the current placed.rs, text_layer and master_text_pieces in pdf/src/lib.rs, and ran git merge-tree of each head against origin/main and against each other. I did not build or run either branch. A reviewer on each PR reports running cargo test and clippy on the head, and the reproduction on main, which I did not repeat.
    • Real PowerPoint 16.0 (build 20527), through its COM interface, as a reference for what the text layer should hold: three slides, each with a text box containing a slide-number field and a second box with a line break (Shift+Enter), saved with Save As PDF. I decoded the page content streams' text-showing operators with a short script (Word hung when asked to open the PDF, so it was not used). Page 1, 2 and 3 hold the strings 1, 2, 3 for the field, not a placeholder; the line break gives two separate text lines (one, two) with no break character. That matches the "Page 1/2/3" and "onetwo" expectations in both PRs' tests. Date fields were not checked in PowerPoint.

    Not checked: whether a hyperlink placed after a field in the same paragraph still gets the right box (the link lookup in place_text runs on the saved body in both PRs), and the web build.

  4. added
    bugfixFixes something that is broken: wrong result, crash, data loss
    on Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions