Skip to content
Closed
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
6 changes: 5 additions & 1 deletion docling/backend/mspowerpoint_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,11 @@ def _handle_chart(self, shape, parent_slide, slide_ind, doc, slide_size):
caption_text = self._chart_title_text(chart)
try:
table_data = self._chart_to_table_data(chart)
except (AttributeError, ValueError, KeyError) as exc:
except (AttributeError, ValueError, KeyError, NotImplementedError) as exc:
# NotImplementedError: python-pptx registers an element class and a
# plot class for c:area3DChart but no series class, so reading its
# series raises where every other 3-D plot raises earlier and is
# already caught above.
_log.warning("Could not extract chart data: %s", exc)
table_data = None

Expand Down
50 changes: 50 additions & 0 deletions tests/test_backend_pptx.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
import struct
import warnings
import zipfile
import zlib
from collections.abc import Iterable
from pathlib import Path
Expand Down Expand Up @@ -448,6 +449,55 @@ def test_chart_image_rendering(libreoffice_available):
)


def test_area_3d_chart_degrades_instead_of_failing_the_document(tmp_path: Path):
"""A ``c:area3DChart`` must lose only its data, not the whole presentation.

python-pptx has no series class for a 3-D area chart, so reading its series
raises ``NotImplementedError``. Every other 3-D plot raises earlier, where
it is already caught, so this one chart aborted the conversion of the entire
deck. It should degrade the way ``c:bar3DChart`` does: a classified picture
with no tabular data.
"""
from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])
chart_data = CategoryChartData()
chart_data.categories = ["Q1", "Q2"]
chart_data.add_series("Revenue", (10.0, 20.0))
slide.shapes.add_chart(
XL_CHART_TYPE.AREA, Inches(1), Inches(1), Inches(4), Inches(3), chart_data
)
slide.shapes.add_textbox(
Inches(0.2), Inches(0.2), Inches(3), Inches(0.5)
).text_frame.text = "text beside the chart"
flat = tmp_path / "area2d.pptx"
prs.save(flat)

# python-pptx cannot write a 3-D area chart, so retag the plot element the
# way PowerPoint writes one.
source = tmp_path / "area3d.pptx"
with (
zipfile.ZipFile(flat) as original,
zipfile.ZipFile(source, "w", zipfile.ZIP_DEFLATED) as retagged,
):
for info in original.infolist():
payload = original.read(info.filename)
if info.filename == "ppt/charts/chart1.xml":
payload = payload.replace(b"c:areaChart", b"c:area3DChart")
retagged.writestr(info, payload)

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

pictures = list(doc.pictures)
assert len(pictures) == 1
assert pictures[0].meta.tabular_chart is None
assert "text beside the chart" in doc.export_to_markdown()


def _add_bar_chart(shapes):
"""Add a small bar chart to a slide or group shape tree."""
from pptx.chart.data import CategoryChartData
Expand Down
Loading