Repository navigation
Conversation
|
✅ DCO Check Passed Thanks @nanhanq1, all your commits are properly signed off. 🎉 |
Merge Protections🔴 1 of 2 protections blocking · waiting on 👀 reviews
🔴 Require two reviewer for test updatesWaiting for
This rule is failing.When test data is updated, we require two reviewers
Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
|
|
`_get_children_simple_text_block` guarded against a second *text* fragment but the Element branch just overwrote `result`, so `<text>2<superscript>nd</superscript></text>` returned "nd" and the leading `2` was silently discarded. Guard both branches so the element is routed to `_parse_inline_group`, which already handles mixed children. Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
… faithfully The Markdown, HTML, LaTeX and DocLang inline serializers joined runs with a hard `" "`, inventing spaces the model never asked for: `2nd` -> `2 nd`, `O2.` -> `O 2 .`, `italic text.` -> `italic text .`. Those artifacts can never be removed while the separator lives in the serializer. Serializers: - join inline parts with `""`; DocLang keeps its delimiter between the element head and the body only, where `<content>` is the whitespace channel - hoist edge whitespace around the *complete* decoration stack (formatting and hyperlink together) for Markdown, HTML and LaTeX. Decorating it verbatim emits `**bold ** tail`, which CommonMark renders as literal asterisks; hoisting inside one formatter would let the hyperlink recapture it. DocLang opts out: it keeps whitespace inside the markup, in `<content>`. DocLang deserializer: - `_get_text` stripped every fragment and joined with `""`, collapsing `Advanced <bold>Topics</bold>` into `AdvancedTopics`. It now trims the outer block boundary only, and never trims whitespace delivered by `<content>`. - bare text nodes use the standard XML heuristic: a whitespace run containing a newline is pretty-print indentation, one without it is content. This is what hand-written and VLM-emitted DocLang needs, since it will not use `<content>`. - element-head children (`<caption>`, `<description>`, `<summary>`, `<custom>`) no longer bleed into body text, where they were also double-modelled in `item.meta`. Data at rest: schema minor bumped to 1.11.0 and a `mode="before"` validator re-injects the legacy separator for documents stamped below it, preserving their previous *visible* output including its extra-space bugs (`H 2 O` stays `H 2 O`). It must run before `check_version_is_compatible`, which rewrites `version` and destroys the evidence. Versionless input is left alone. The validator works on a copy, so the caller's dict is untouched and re-validating the same raw value cannot compound separators. A separator can never land inside a delimiter. Code and formula runs are wrapped in `` ` ``/`$` by the serializers, so the space goes on the plain neighbour; when both neighbours are delimited it becomes a plain run of its own, because `` `a``b` `` and `$a$$b$` are both corrupt. Chunk text changes too, since ChunkingDocSerializer inherits the Markdown join -- anyone with a persisted vector index gets silent retrieval drift, so that needs its own line in the release notes. DocTags code is untouched. Its golden gains one empty `<text></text>` for the legacy fixture because that document now carries an extra whitespace run, which DocTags renders empty by its own pre-existing strip-per-run behaviour. Ships as a minor, not a major: `feat!:` would make python-semantic-release (7.34.6, both repos) bump to 3.0, and a 3.0 is not affordable on either package. Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
I, Christoph Auer <cau@zurich.ibm.com>, hereby add my Signed-off-by to this commit: 64404b3 I, Christoph Auer <cau@zurich.ibm.com>, hereby add my Signed-off-by to this commit: 66040cb Signed-off-by: Christoph Auer <cau@zurich.ibm.com> Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
…ct bump Integrates the 1.11.0 schema bump with the downgrade-projector framework (docling-project#703) landed upstream. 1.11 and 1.10 are structurally identical; the only difference is that 1.11 inline runs own their boundary whitespace, so the projector just re-stamps the version (a 1.10 client re-applies its own join, yielding the documented harmless double space). - add @register_projector(from_minor=11, to_minor=10) + TestProjector_1_11_to_1_10 - add the auto-generated 1.11 JSON Schema snapshot - re-format the 1.11 SCHEMA_VERSION_HISTORY entry (ruff) - update the stale dclq CLI expectation (old join produced 'public class'; faithful join now yields 'public class') Signed-off-by: Christoph Auer <cau@zurich.ibm.com> Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
typer >=0.25 vendors its own copy of click (typer._click) and raises those exceptions instead of the external click package's. The dclq CLI referenced the external click, so on typer >=0.25 bad input escaped the exit-code handlers and the context-flag callback (-C/-A/-B/--context-scope) silently no-op'd because the isinstance(param, click.Option) check no longer matched. Import the exception and Parameter types from typer._click, duck-type the option check, raise the [dclq] typer floor to >=0.25, and drop the now-unused external click dependency. Signed-off-by: Christoph Auer <cau@zurich.ibm.com> Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
…roups <content> is the explicit whitespace-preserving text wrapper, so inside an inline group it is a run, not a nested item: it must inherit the formatting accumulated while descending through <bold>/<italic>/... . Dispatching it through _dispatch_element dropped that formatting, which surfaced after the rebase as <bold><content>x </content></bold> coming back unformatted and broke the doclang round-trip for whitespace_inside_bold / _link. Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
main now lints with ruff 0.16.5 at target-version py310, where UP045 flags Optional[X] in favour of X | None. Without this the branch fails ruff check. Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
- doclang: the run following a CDATA section owns its leading space, so "<![CDATA[a & b < c]]> & d" now yields ["a & b < c", " & d"]. - doclang: drop the duplicate loop-shaped test_leading_text_before_lone_formatting_tag_is_preserved, which main already covers with the parametrized version; keeping both silently shadowed main's. - latex: give the inline-group fixture runs their own boundary whitespace, since the serializer no longer invents a separator. Signed-off-by: nanhanq1 <157583847+nanhanq1@users.noreply.github.com>
|
Rebased onto Three things had to be reconciled with upstream work:
Local gates on the rebased tree: Two things still need a maintainer:
|
|
Pinging maintainers for the two things this PR still needs. The branch is rebased onto 1. 2. Mergify still blocks on Require two reviewer for test updates — this PR refreshes ground-truth data under Recap of the rebase (details in the comment above):
@ceberam @vagenas @PeterStaar-IBM @cau-git @dolfim-ibm — would any of you have time to take a look, or point me at the right reviewers? Thanks! |
Rebases
cau/serializer-whitespace-fixes(the branch behind #693) onto the currentmain(
3e42dba), so #693 stops being 60 commits behind and can land on today's tree.This supersedes #693 rather than trying to update its branch: #693's head is
cau/serializer-whitespace-fixes, and a PR into that branch from a branch rebased ontomainwould drag all of
mainalong with it and then collide with the branch's original copies of thesesame five commits. Same content, rebased and green, offered directly against
main— close #693in favour of this one if that is easier.
Conflicts
11 conflicted paths:
docling_core/transforms/deserializer/doclang.py— kept both sides: main's_repair_unescaped_xml_textalongside this branch's_normalize_bare_textand thetrim=handling at the call site (a run inside an inline group owns its edge whitespace, a block host
does not).
docling_core/transforms/serializer/markdown.py— merged the import lines.pyproject.toml,examples/,docling_core/compat.py,tests/*— adopted upstream'stest/->tests/rename (chore: rename test folder to tests #739)..json/.yamlfiles — three-way merged against the merge base, then re-validated.Three extra commits on top
1.
fix(doclang): keep inherited formatting on <content> runs in inline groups<content>is the explicit whitespace-preserving wrapper, so inside an inline group it is a run,not a nested item, and has to inherit the formatting accumulated while descending through
<bold>/<italic>/ ... . Routing it through_dispatch_elementdropped that formatting. Thisonly surfaced after the rebase:
<bold><content>x </content></bold>came back unformatted andbroke
test_doclang_roundtrip_is_lossless[whitespace_inside_bold]and[..._link].2.
style: use PEP 604 unions instead of Optional[...] (ruff UP045)mainnow lints with ruff 0.16.5 attarget-version = "py310", where UP045 rejectsOptional[X]. Without this the branch failsruff check.3.
test: align expectations with the inline whitespace contract<![CDATA[a & b < c]]> & dyields["a & b < c", " & d"];test_leading_text_before_lone_formatting_tag_is_preserved,which silently shadowed main's parametrized test of the same name;
serializer no longer invents a separator.
Verification
ruff checkandruff format --check: clean.mainin the same environment ontest_deserializer_doclang.py,test_latex_serialization.py,test_compat.py:main11 failed / 168 passed, this branch11 failed / 172 passed, and the two failure sets are identical (diffed both ways, empty). The
11 are an artifact of the sandbox I ran in: doclang's Schematron validation writes its temp
file to
C:\WINDOWS\TEMP, which is blocked here, so Saxon reports SXXP0003. Not a regression.tests/test_inline_whitespace_contract.py(new with this branch) passes excepttest_chunk_text_follows_the_contract, which needs the optionalhuggingface_hubextra thatis not installed here.
Merge order
This has to land before docling-project/docling#3891 — new core + old backends means inline runs
lose their boundary whitespace and words get merged.
Happy to squash the three extra commits into the branch's own commits, or to re-target this at
main, if either is preferred.