Skip to content

fix(pptx): keep soft line breaks with markdown and plain link formats - #13222

Open
Rainmemery wants to merge 2 commits into
deepset-ai:mainfrom
Rainmemery:fix/pptx-soft-line-breaks
Open

Rainmemery wants to merge 2 commits into
deepset-ai:mainfrom
Rainmemery:fix/pptx-soft-line-breaks

Conversation

@Rainmemery

Copy link
Copy Markdown
Contributor

Related Issues

Proposed Changes:

With link_format="markdown" or "plain", _process_paragraph built its output from
paragraph.runs, which yields only the <a:r> children. A soft line break (<a:br/>,
Shift+Enter) standing between two runs was therefore dropped and the two sides were glued
together: a text box holding Account: Alice, a soft line break, and Balance: 100 was
converted into the single token Account: AliceBalance: 100, which retrieval cannot match.
The default link_format="none", which returns paragraph.text, already kept the break.

The link-formatting branch now walks the paragraph's children in document order instead of
just its runs, and emits each <a:br/> as the vertical tab python-pptx itself uses in
paragraph.text. All three link formats therefore return the same text, and hyperlinked
runs keep their existing formatting.

How did you test it?

Unit tests: three regressions in test/components/converters/test_pptx_to_document.py —

  • test_soft_line_break_with_link_format — the report's exact repro, for both formats;
  • test_soft_line_break_matches_link_format_none — the formatted output equals what
    link_format="none" already returns;
  • test_hyperlink_still_formatted_next_to_soft_line_break — a break next to a hyperlinked
    run still yields [example](https://example.com) / example (https://example.com).

Red/green: the new tests fail on unpatched main (6 cases; the vertical tab is missing) and
pass with the change. The whole PPTX module is green (17 passed). A before/after run of
test/components/converters goes from 133 failed / 189 passed to 127 failed / 195 passed —
the difference is exactly these 6 cases, so nothing else moved; the remaining failures are
optional dependencies missing in my environment (pypdf, pdfminer, beautifulsoup) and are
identical before and after. ruff check and ruff format --check are clean on both files.

I could not run hatch run test:types: my sandbox cannot reach PyPI to install mypy. The new
code narrows paragraph._p.iterchildren() with isinstance against the annotated
pptx.oxml.text classes rather than casting, so it should type-check cleanly.

Notes for the reviewer

  • The earlier attempt at this issue (fix(pptx): preserve soft line breaks with link formats #13073) was closed by the first-PR-limit automation, not
    on review grounds, and nothing has referenced the issue since.
  • Only <a:r> and <a:br/> children are handled, matching the previous behaviour for every
    other paragraph child (fields were already dropped in the formatted modes).
  • Transparency: this contribution was prepared with AI assistance, then reviewed, tested and
    understood by me before submitting.

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • I have updated the related issue with new insights and changes.
  • I have added unit tests and updated the docstrings.
  • I've used a conventional commit type for my PR title: fix:.
  • I have documented my code.
  • I have added a release note file, following the contributors guidelines.
  • I have run linters/formatters (ruff check, ruff format) and fixed any issue.

`_process_paragraph` built its output from `paragraph.runs`, which yields only the
`<a:r>` children. A soft line break (`<a:br/>`, Shift+Enter) standing between two runs
was therefore dropped, so with link_format="markdown" or "plain" the two sides were
glued together: a text box holding "Account: Alice", a break, and "Balance: 100"
became the single token "Account: AliceBalance: 100", which retrieval cannot match.
The default "none" mode, which returns `paragraph.text`, already kept the break.

Walk the paragraph children instead and emit each break as the vertical tab that
python-pptx itself uses in `paragraph.text`, so every link format returns the same
text, and hyperlinked runs keep their formatting.

Fixes deepset-ai#13043
@Rainmemery
Rainmemery requested a review from a team as a code owner October 12, 2026 08:16
@Rainmemery
Rainmemery requested review from bogdankostic and removed request for a team October 12, 2026 08:16
@vercel

vercel Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

@Rainmemery is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added P3 Low priority, leave it in the backlog topic:tests and removed P3 Low priority, leave it in the backlog labels Oct 12, 2026
The three new tests annotated the parametrized link_format as str, which
mypy rejects: PPTXToDocument's constructor takes
Literal['markdown', 'plain', 'none']. The pre-existing parametrized test
leaves the parameter unannotated (implicitly Any); annotating it as
Literal['markdown', 'plain'] keeps the defs complete and mypy clean.

Fixes the mypy CI failure on deepset-ai#13222.
@github-actions github-actions Bot added the type:documentation Improvements on the docs label Oct 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  haystack/components/converters
  pptx.py
  haystack/core/pipeline
  pipeline.py
Project Total  

This report was generated by python-coverage-comment-action

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low priority, leave it in the backlog topic:tests type:documentation Improvements on the docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PPTXToDocument drops soft line breaks when link_format is markdown or plain

1 participant