Added
Table.cell_stylesandGridCell.heading_level/GridCell.style_nameexpose the paragraph
style a DOCX table cell carries. A heading styledHeading1..Heading6inside aw:tc— the
banner row forms, questionnaires and datasheets use as a section title, and what Word's
navigation pane and aTOCfield treat as the document outline — previously reached every
consumer as anonymous cell text. Cell text is deliberately unchanged: prefixing it with#
would put a markdown heading inside a table cell. The style travels beside the text instead, so
a caller can decide whether aheading 2in a banner row is a section title or a column label.
cell_stylesis sparse and omitted entirely for tables whose cells carry no style, so ordinary
tables serialise exactly as before (GH#1587).
Fixed
-
PDF text repair no longer welds two complete words into one.
repair_ligature_spacesremoves the
space in…f++i|l|f…to undo a real artefact — some PDFs decompose a ligature glyph and
leave a spurious gap, sofirstarrives asf irst— but the same character pattern is an
ordinary word boundary whenever a word ends infand the next begins withi,lorf. The
only guard was a hard-coded list of 33 short English words tested against the left token, so
everything outside it welded, English included:relief forbecamereliefforanditself infringesbecameitselfinfringes. The space is now kept when either fragment is independently
attested as a standalone word elsewhere in the same document, reusing the witness mechanism
dehyphenation already applies. A fragment appearing only as one half of a candidate pair does not
witness itself (GH#1591). -
DOCX page counting no longer collapses a table onto one page. Word writes
<w:lastRenderedPageBreak/>into every cell of a row that straddles a page boundary — one
physical break, one marker per cell — and the duplicated markers were reduced to a single break,
losing the originals with the duplicates. A seven-page document reported two. Breaks are now
identified by table depth, row and cell, so a marker echoed across the cells of one row counts
once while several breaks inside a single deep cell each still count (GH#1592). -
PDF outline (bookmark) named destinations now resolve when the
/Names->/Destsname-tree
key is UTF-16BE-with-BOM, the form Adobe Distiller writes. The lookup previously decoded the
/Destbyte string with a lossy UTF-8 conversion before searching the tree; a name-tree key is a
byte string compared by byte (ISO 32000-1 §7.9.6), not text, so the BOM was mangled into
replacement characters and every such destination silently resolved toNone, leaving the
bookmark'sdestas an unresolvedDestination::Namedwith no page (GH#1589). -
MimeDetectionPolicy::ContentOnlyno longer rejects a legacy OLE2 Office document (.doc/.xls/.ppt)
passed by path when the same bytes are accepted through the bytes API. Path-based content
detection only sniffs the first 4 KB of a file, but an MS-CFB compound document cannot be typed
from a prefix — identifying it means following the FAT sector chain to the root directory entry,
which a truncated buffer cannot do. Detection now falls back to a structure-aware read of the
file for a compound-file header that a 4 KB prefix left inconclusive, the same escape hatch a
ZIP-based Office document already had for the same class of failure (GH#1590). -
PDF table detection no longer invents a column boundary from a rule that stops short of the row
band.BAND_RULE_SPAN_TOLwas defined asSNAP_TOL, conflating two different questions:
SNAP_TOLdecides whether two coordinates are the same coordinate, while this one decides
whether a vertical rule runs through a band. At 3pt an edge could fall short at each end and
still count as spanning, so a band up to 6pt shorter than the rule beside it was cut where the
drawn rule gave it no boundary. Those phantom columns are what let a band of prose inside a
drawn frame split into cells and qualify as a table, which on the reported document cost page
text. Now 1.0 and deliberately independent ofSNAP_TOL(GH#1588). -
Tesseract
psm = 0is now rejected at configuration validation. PSM 0 is Tesseract's
PSM_OSD_ONLY— orientation and script detection with no character recognition — so it cannot
satisfy a text-extraction request, and Tesseract emits no hOCR for it at all. Setting it
previously succeeded while returning either a zero-length document or degraded, partially
dropped text, depending on the Tesseract build, in both cases with no warning and at several
times the cost of a normal run. The error now names the mode and points at 3 (auto), 6 (single
block), and 11 (sparse text). Valid values are 1-13; omittingpsmcontinues to let the
pipeline choose (GH#1586).