Skip to content

Extend sanitize_text with known exceptions #1127

Open

Description

@dolfim-ibm

With the new reading order module we are currently missing some text normalization which were applied by the glm component. For example in https://github.com/DS4SD/deepsearch-glm/blob/main/src/andromeda/tooling/structs/normalizers/text_normalizer.h#L52.

Currently some text normalization is done in https://github.com/DS4SD/docling/blob/main/docling/models/page_assemble_model.py#L55, however

  1. it is not complete (see complete glm tooling linked above)
  2. it does not preserve the original text in the orig field

Some extra notes:

Activity

  1. cau-git commented on Sep 1, 2026

    @cau-git
    Member

    Hi @dolfim-ibm, this issue hasn't had any activity since it was opened. Do you still consider it relevant? If we don't hear back within a week, we'll close it. Feel free to reopen if you see a need.

  2. morten-lagabote commented on Oct 4, 2026

    @morten-lagabote
    Contributor

    This is still relevant for us, for the second point (orig does not preserve the original text). We convert legal texts and compare the result with the source. #4434 made the HTML backend keep the source text in orig; in the PDF pipeline orig is still the sanitized text.

    On main (58f1f8d), TextElement only has text (sanitize_text(textlines)), and the reading-order model passes it on without orig, so docling-core sets orig = text. _merge_elements has the TODOs "we don't have the orig field of the merged element". In a Supreme Court judgment (HR-2013-2663-A), the only items with orig != text are the 76 list items whose marker is stripped from text, and the hyphen that is dropped at a line break (#4151) is dropped in orig too: § 14-12 becomes § 1412 in both.

    If you agree with the direction, I can prepare a PR:

    • TextElement gets an orig: the lines of the cluster joined with a space, before dehyphenation and character normalization. text stays as it is;
    • the reading-order model passes orig on, also in _merge_elements;
    • ListItemMarkerProcessor keeps matching the marker on orig, but strips it from text (today text is derived from orig).

    One open question: prov.charspan is computed from the length of text, while the DocLang serializer slices orig with it (item.orig[prov_.charspan[0] : prov_.charspan[1]]). Should the charspans index orig? #4217 / #4222 touch the same code, so I would wait for #4222 either way.

  3. morten-lagabote commented on Oct 12, 2026

    @morten-lagabote
    Contributor

    An update on my comment above. For PDF, some characters are already replaced in docling-parse, before Docling gets the text. Its cell sanitizer folds the quote and dash characters to ASCII, and the orig of each cell is a copy of the folded text (see the triage in docling-project/docling-parse#362).

    Two examples with docling-parse 7.22.2:

    • Page 1 of this document has 6 × ” (U+201D) in its text layer. The char, word and line cells have 6 × ", in text and in orig.
    • Page 1 of Innst. 240 S (2013–2014) has (2013–2014) in its text layer. The line cell has (2013-2014).

    So the change in my comment above can keep the text before dehyphenation in orig, but not these characters. They need a change in docling-parse first; docling-project/docling-parse#388 stops the fold for the dashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions