any-file to PDF (Phase 1): converters/ dispatcher, images/text/md/csv/json/xml/svg/pdf-passthrough, 112 tests green
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""XML -> PDF (pretty text dump, monospace).
|
||||
|
||||
Validation is explicit: lxml must parse the document, otherwise the job
|
||||
fails with "Invalid XML: <reason>" (never a render failure). A valid
|
||||
document is rendered as its text content — every text node and tail in
|
||||
document order, one per line, whitespace-only nodes dropped — inside
|
||||
<pre> with PRE_CSS. Attribute values are intentionally not dumped: the
|
||||
contract is that element text survives extraction.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from . import common
|
||||
from .text_converter import decode_bytes
|
||||
|
||||
|
||||
def convert(path: Path, job_id: str, progress_cb=None, output_dir=None,
|
||||
source_name=None) -> str:
|
||||
"""Render an XML file to a monospace text-dump PDF."""
|
||||
raw = path.read_bytes()
|
||||
if not raw.strip():
|
||||
raise ValueError("empty file: nothing to convert")
|
||||
text = decode_bytes(raw)
|
||||
try:
|
||||
root = etree.fromstring(text.encode("utf-8"))
|
||||
except etree.XMLSyntaxError as exc:
|
||||
raise ValueError(f"Invalid XML: {exc}") from exc
|
||||
|
||||
lines: list[str] = []
|
||||
for el in root.iter():
|
||||
for chunk in (el.text, el.tail):
|
||||
if not chunk:
|
||||
continue
|
||||
piece = " ".join(chunk.split())
|
||||
if piece:
|
||||
lines.append(piece)
|
||||
if not lines:
|
||||
raise ValueError("empty file: XML has no text content")
|
||||
body = "\n".join(lines)
|
||||
|
||||
def _build():
|
||||
return f"<html><body><pre>{common.escape(body)}</pre></body></html>", path.name
|
||||
|
||||
return common.convert_single(
|
||||
path, job_id, build_html=_build, css=common.PRE_CSS,
|
||||
progress_cb=progress_cb, output_dir=output_dir,
|
||||
name_src=source_name or path.name,
|
||||
)
|
||||
Reference in New Issue
Block a user