github xberg-io/xberg v1.1.3

2 hours ago

Added

  • Table.cell_styles and GridCell.heading_level / GridCell.style_name expose the paragraph
    style a DOCX table cell carries. A heading styled Heading1..Heading6 inside a w:tc — the
    banner row forms, questionnaires and datasheets use as a section title, and what Word's
    navigation pane and a TOC field 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 a heading 2 in a banner row is a section title or a column label.
    cell_styles is 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_spaces removes the
    space in …f + + i|l|f… to undo a real artefact — some PDFs decompose a ligature glyph and
    leave a spurious gap, so first arrives as f irst — but the same character pattern is an
    ordinary word boundary whenever a word ends in f and the next begins with i, l or f. 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 for became relieffor and itself infringes became itselfinfringes. 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 -> /Dests name-tree
    key is UTF-16BE-with-BOM, the form Adobe Distiller writes. The lookup previously decoded the
    /Dest byte 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 to None, leaving the
    bookmark's dest as an unresolved Destination::Named with no page (GH#1589).

  • MimeDetectionPolicy::ContentOnly no 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_TOL was defined as SNAP_TOL, conflating two different questions:
    SNAP_TOL decides 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 of SNAP_TOL (GH#1588).

  • Tesseract psm = 0 is 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; omitting psm continues to let the
    pipeline choose (GH#1586).

Don't miss a new xberg release

NewReleases is sending notifications on new releases.