Skip to content

fix(doclang): keep a single element-head layer token in merged inline runs - #779

Open
eren-YU wants to merge 1 commit into
docling-project:mainfrom
eren-YU:fix/doclang-778-duplicate-layer-token
Open

eren-YU wants to merge 1 commit into
docling-project:mainfrom
eren-YU:fix/doclang-778-duplicate-layer-token

Conversation

@eren-YU

@eren-YU eren-YU commented Sep 16, 2026

Copy link
Copy Markdown

Fixes #778.

What changed

DocLangInlineSerializer merges an inline group's children and then wraps the merged text in a single <text> element. Each child is serialized independently beforehand, and every child whose content_layer is not BODY emits its own <layer/> element-head token. The merged wrapper therefore carried one <layer/> per child, while the DocLang element_head sequence permits exactly one — so the exported document failed XSD validation:

Element '{https://www.doclang.ai/ns/v0}layer': This element is not expected.

The merged text now keeps the first leading <layer/> and drops the rest.

This is the shape produced by a Word page footer, where a group of adjacent runs is classified as furniture.

Why not the other approach

The issue lists a second option — compute one <layer/> for the group and tell children not to emit their own. That changes the child serializers' contract and touches more code. Dropping the duplicates at the merge point is the smaller change and keeps each child's output intact.

Only leading tokens are touched, so a text run that happens to contain a literal <layer value="..."/> string is left alone.

How I checked

doclang 0.7.3's bundled doclang.xsd, validating the serializer output directly:

case before after
group parent, two furniture runs 2 <layer/>, invalid 1 <layer/>, valid
furniture + BODY + furniture 2 <layer/>, invalid 1 <layer/>, valid
all BODY no <layer/> no <layer/>, unchanged

Three tests added to tests/test_serialization_doclang.py; two of them fail without the fix and all three pass with it. The third is a guard against over-correcting the all-BODY case.

uv run pytest tests/test_serialization_doclang.py -q -k "inline_runs"

ruff check and ruff format --check are clean.

Scope note

DocLangInlineSerializer also produces invalid output when the parent TextItem carries text of its own and should_wrap is False — the runs then land outside any wrapper. That is a separate defect with its own report and is deliberately not touched here.

@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

DCO Check Passed

Thanks @eren-YU, all your commits are properly signed off. 🎉

@eren-YU
eren-YU force-pushed the fix/doclang-778-duplicate-layer-token branch from c965282 to 6f52381 Compare September 16, 2026 08:53
@mergify

mergify Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 1 of 2 protections blocking · waiting on 👀 reviews

Protection Waiting on
🔴 Require two reviewer for test updates 👀 reviews
🟢 Enforce conventional commit

🔴 Require two reviewer for test updates

Waiting for

  • #approved-reviews-by >= 2
This rule is failing.

When test data is updated, we require two reviewers

  • #approved-reviews-by >= 2

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

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

Labels

None yet

Projects

None yet

1 participant