Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions docling/backend/mspowerpoint_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ def _iter_paragraph_elements(element: etree._Element) -> Iterator[etree._Element
yield child


def _text_frame_text(text: str) -> str:
"""Return the ``.text`` of a python-pptx text frame with "\\n" line breaks.

python-pptx gives a line break inside a paragraph (``a:br``) as a vertical
tab ("\\v").
"""
return text.replace("\v", "\n").strip()


def _paragraph_fragments(element: etree._Element) -> list[tuple[DocItemLabel, str]]:
"""Coalesce adjacent text runs while keeping equations as separate fragments."""
fragments: list[tuple[DocItemLabel, str]] = []
Expand Down Expand Up @@ -1327,8 +1336,9 @@ def _handle_tables(self, shape, parent_slide, slide_ind, doc, slide_size):
else:
col_span = int(col_span)

cell_text = _text_frame_text(cell.text)
icell = TableCell(
text=cell.text.strip(),
text=cell_text,
row_span=row_span,
col_span=col_span,
start_row_offset_idx=row_idx,
Expand All @@ -1338,7 +1348,7 @@ def _handle_tables(self, shape, parent_slide, slide_ind, doc, slide_size):
column_header=row_idx == 0,
row_header=False,
)
if len(cell.text.strip()) > 0:
if len(cell_text) > 0:
tcells.append(icell)
# Initialize Docling TableData
data = TableData(num_rows=num_rows, num_cols=num_cols, table_cells=[])
Expand Down Expand Up @@ -1999,7 +2009,7 @@ def handle_groups(shape, parent_slide, slide_ind, doc, slide_size):
if slide.has_notes_slide:
notes_slide = slide.notes_slide
if notes_slide.notes_text_frame is not None:
notes_text = notes_slide.notes_text_frame.text.strip()
notes_text = _text_frame_text(notes_slide.notes_text_frame.text)
if notes_text:
bbox = BoundingBox(l=0, t=0, r=0, b=0)
prov = ProvenanceItem(
Expand Down
25 changes: 25 additions & 0 deletions tests/test_backend_pptx.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,31 @@ def test_pptx_left_flush_shape_keeps_own_bbox(tmp_path: Path):
assert bbox.r != prs.slide_width


def test_pptx_line_breaks_in_table_cells_and_notes(tmp_path: Path):
"""A line break (a:br) in a table cell or in the notes becomes "\\n".

python-pptx returns a line break inside a paragraph as a vertical tab
("\\v") in ``.text``, so this control character was in the text of table
cells and notes.
"""
from pptx import Presentation
from pptx.util import Inches

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5])
shape = slide.shapes.add_table(1, 1, Inches(1), Inches(2), Inches(4), Inches(1))
shape.table.cell(0, 0).text = "line1\vline2"
slide.notes_slide.notes_text_frame.text = "note a\vnote b"
pptx_path = tmp_path / "line_breaks.pptx"
prs.save(pptx_path)

doc = get_converter().convert(pptx_path).document

assert doc.tables[0].data.table_cells[0].text == "line1\nline2"
notes = [t.text for t in doc.texts if t.content_layer == ContentLayer.NOTES]
assert "note a\nnote b" in notes


def test_pptx_page_range():
converter = get_converter()
pptx_path = Path("./tests/data/pptx/sources/powerpoint_sample.pptx")
Expand Down
Loading