Files
pdf/gateway/app/services/convert/formatters/xml_sanitize.py
T

34 lines
1.1 KiB
Python

"""Strip characters illegal in XML 1.0 / OOXML text nodes.
PDF extractors sometimes emit C0 controls (e.g. \\x02 soft-break markers)
that lxml (python-docx) and openpyxl reject on write. Also strip unpaired
UTF-16 surrogates which can appear in broken PDF ToUnicode maps.
"""
from __future__ import annotations
import re
# XML 1.0 Char production excludes C0 controls except TAB/LF/CR.
# Also drop soft hyphen (U+00AD), BOM, non-chars, and lone surrogates.
_ILLEGAL_OOXML_RE = re.compile(
r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f\u00ad\ufeff\ufffe\uffff"
r"\ud800-\udfff]"
)
def sanitize_ooxml_text(value: object | None) -> str:
"""Return text safe for OOXML / SpreadsheetML string cells."""
if value is None:
return ""
if not isinstance(value, str):
value = str(value)
if not value:
return ""
# Drop unpaired surrogates that PDF extractors may leave in strings
try:
value.encode("utf-8")
except UnicodeEncodeError:
value = value.encode("utf-8", errors="surrogatepass").decode("utf-8", errors="ignore")
return _ILLEGAL_OOXML_RE.sub("", value)