diff --git a/src/parse_bench/inference/pipelines/parse.py b/src/parse_bench/inference/pipelines/parse.py
index 1599bc8..19c70a2 100644
--- a/src/parse_bench/inference/pipelines/parse.py
+++ b/src/parse_bench/inference/pipelines/parse.py
@@ -526,6 +526,15 @@ def register_parse_pipelines(register_fn) -> None: # type: ignore[no-untyped-de
)
)
+ register_fn(
+ PipelineSpec(
+ pipeline_name="pymupdf4llm_html_tables",
+ provider_name="pymupdf4llm",
+ product_type=ProductType.PARSE,
+ config={"table_output": "html"},
+ )
+ )
+
register_fn(
PipelineSpec(
pipeline_name="markitdown",
diff --git a/src/parse_bench/inference/providers/parse/pymupdf4llm.py b/src/parse_bench/inference/providers/parse/pymupdf4llm.py
index 70cd85b..a24710c 100644
--- a/src/parse_bench/inference/providers/parse/pymupdf4llm.py
+++ b/src/parse_bench/inference/providers/parse/pymupdf4llm.py
@@ -89,6 +89,19 @@ def _markdown_options(self, pymupdf: Any) -> dict[str, Any]:
raise ProviderConfigError("PyMuPDF4LLM 'ocr_language' must be a non-empty string")
options["ocr_language"] = ocr_language
+ table_output = self.base_config.get("table_output")
+ if table_output is not None:
+ if not isinstance(table_output, str):
+ raise ProviderConfigError("PyMuPDF4LLM 'table_output' must be a string")
+ normalized_table_output = table_output.strip().lower()
+ if normalized_table_output not in ("markdown", "html"):
+ raise ProviderConfigError("PyMuPDF4LLM 'table_output' must be 'markdown' or 'html'")
+ # Opt-in HTML table rendering. pymupdf4llm builds that ship the native
+ # HTML table engine emit structured
markup for table_output="html";
+ # builds without it ignore the extra keyword, so the default markdown
+ # pipelines above are unaffected.
+ options["table_output"] = normalized_table_output
+
raw_backend = self.base_config.get("ocr_backend")
if raw_backend is None:
return options
diff --git a/tests/parse_bench/inference/providers/parse/test_pymupdf4llm.py b/tests/parse_bench/inference/providers/parse/test_pymupdf4llm.py
index 2973c91..6d176b2 100644
--- a/tests/parse_bench/inference/providers/parse/test_pymupdf4llm.py
+++ b/tests/parse_bench/inference/providers/parse/test_pymupdf4llm.py
@@ -1,5 +1,8 @@
"""Tests for PyMuPDF4LLM layout normalization helpers."""
+import pytest
+
+from parse_bench.inference.providers.base import ProviderConfigError
from parse_bench.inference.providers.parse.pymupdf4llm import (
_PYMUPDF_CLASS_TO_CANONICAL,
PyMuPDF4LLMProvider,
@@ -29,3 +32,21 @@ def test_build_layout_page_maps_all_pymupdf_classes() -> None:
assert page is not None
assert [item.layout_segments[0].label for item in page.items] == list(_PYMUPDF_CLASS_TO_CANONICAL.values())
+
+
+def test_markdown_options_threads_table_output() -> None:
+ provider = PyMuPDF4LLMProvider("pymupdf4llm", {"table_output": "html"})
+ options = provider._markdown_options(None)
+ assert options["table_output"] == "html"
+
+
+def test_markdown_options_omits_table_output_by_default() -> None:
+ provider = PyMuPDF4LLMProvider("pymupdf4llm", {})
+ options = provider._markdown_options(None)
+ assert "table_output" not in options
+
+
+def test_markdown_options_rejects_unknown_table_output() -> None:
+ provider = PyMuPDF4LLMProvider("pymupdf4llm", {"table_output": "xml"})
+ with pytest.raises(ProviderConfigError):
+ provider._markdown_options(None)