Skip to content

feat(jats/inline-formula): Support emphasis elements and Inline formulas#3726

Open
taru-garg-2000 wants to merge 6 commits into
docling-project:mainfrom
taru-garg-2000:feat/jats-inline-formula-emphasis
Open

feat(jats/inline-formula): Support emphasis elements and Inline formulas#3726
taru-garg-2000 wants to merge 6 commits into
docling-project:mainfrom
taru-garg-2000:feat/jats-inline-formula-emphasis

Conversation

@taru-garg-2000

@taru-garg-2000 taru-garg-2000 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

#3696 landed inline tex-math rendering for JATS as the first step. This continues that work by handling the styling that can sit alongside the formula inside an <inline-formula>.

When we walk an <inline-formula>, we now break it into ordered inline pieces instead of one flat string: the tex-math becomes the formula, and emphasis around it (italic, bold, underline, strike, sub, sup) is kept as styled text. MathML <mml:math> or other alternatives are skipped — as MathML isn't parsed yet, so we rely on the tex-math sibling instead. The pieces go into an inline group so everything still reads as one continuous line.

A couple of examples:

<p>We use <inline-formula><italic>x</italic> <tex-math>$$a^2$$</tex-math></inline-formula> here.</p>

The x stays italic right next to the a^2 formula.

<p>Index <inline-formula>x<sub>i</sub> <tex-math>$$x_i$$</tex-math></inline-formula> shown.</p>

One thing I noticed with things like Superscript or Subscript, there is a space in between the element which carry that super/sub-script and the actual element in the sub/super-script. To explain, when parsing something like

<p><inline-formula>x<sup>2</sup></inline-formula></p>

We would expect to be rendered as x2 but it actually renders as x 2 (notice the space), it seems this is because how the elements are serialized, but I haven't looked into it that much.

Signed-off-by: Taru Garg <taru.garg@hashicorp.com>
@github-actions

Copy link
Copy Markdown
Contributor

DCO Check Passed

Thanks @taru-garg-2000, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Jun 30, 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)(?:\(.+\))?(!)?:

@PeterStaar-IBM PeterStaar-IBM requested a review from ceberam July 1, 2026 03:47
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 26.31579% with 56 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
docling/backend/xml/jats_backend.py 26.31% 56 Missing ⚠️

📢 Thoughts on this report? Let us know!

@ceberam

ceberam commented Jul 2, 2026

Copy link
Copy Markdown
Member

One thing I noticed with things like Superscript or Subscript, there is a space in between the element which carry that super/sub-script and the actual element in the sub/super-script.

This is correct and it affects all parsers. Just accept it as the normal behavior for now. There is another PR in docling-core that will fix it.

@ceberam ceberam left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @taru-garg-2000 for your PR. Please, see my comments below.
I was also wondering if you could extend the styling of text beyond the inline formulas, since it is still missing. I guess it would be pretty simple to reuse the static methods you created to add the formatting of text.

Comment thread docling/backend/xml/jats_backend.py Outdated
math_parts = tex_math.text.split("$$")
return math_parts[1] if len(math_parts) == 3 else tex_math.text.strip()
math_parts = node.text.split("$$")
return math_parts[1] if len(math_parts) == 3 else None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove the explicit fallback for tex-math content that is not wrapped in $$...$$?
Real JATS files from publishers frequently emit bare tex-math without $$ delimiters. Those formulas now silently disappear.

@taru-garg-2000 taru-garg-2000 Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I saw that in the previous PR the behaviour diverged for how tex-math is handled in inline-formula and how it is handled in _add_equation with this PR I wanted to reduce the duplication and since _add_equation existed before, I adapted my implementation considering that as the base, will add back the fallback if that is more favourable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good point to align the implementation for both cases. Actually the best approach would have been to use a utility function to avoid the risk of divergence (or we could just reuse _extract_tex_math).

Instead of regressing the code above, we should improve _extract_tex_math by adding the fallback. Actually, according to JATS, the formula inside <tex-math> should not be surrounded by $$ or $ symbols.

Also please note that the original code was treating <tex-math> regardless of the container and creating a Docling document item of type DocItemLabel.FORMULA . The issue we want to resolve here is to enable inline formulas through a Docling document inline group. Therefore it is not enough to add a block elif child.tag == "inline-formula" in _walk_linear to capture the container of the inline formula. We should also consider the container of the block-level formula, which is <disp-formula> to distinguish both cases and then be able to reuse the handing of <tex-math>.

It would also help having a real JATS document in the test suite that includes both inline and block-level formulas. Let me know if you need any help here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the real JATS document I was wondering if the 2nd document from here would be acceptable ? It seems to contain good number of samples of inline-formula, disp-formula and emphasis tags.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like a nice sample document with all kind of formulas. Unfortunately, I don't see an explicit open license in the document. We should only include CC0 or CC-BY documents.

@taru-garg-2000 taru-garg-2000 Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh okay no worries, I will test on it for now, and see how the changes perform, and find another doc for adding hopefully I find one with an open license. Apologies for the delay on this, I hope to rework it within this week.

Comment thread docling/backend/xml/jats_backend.py Outdated
Comment thread docling/backend/xml/jats_backend.py Outdated
Comment thread docling/backend/xml/jats_backend.py Outdated
Comment thread tests/test_backend_jats.py Outdated
Comment thread docling/backend/xml/jats_backend.py Outdated
Comment thread tests/test_backend_jats.py
@taru-garg-2000

Copy link
Copy Markdown
Contributor Author

Hi @ceberam , Thanks a lot for the review! Happy to extend it for generalised implementation on formatting tags, I was wondering though if it would be better to keep it as a separate PR ?

@ceberam

ceberam commented Jul 2, 2026

Copy link
Copy Markdown
Member

Hi @ceberam , Thanks a lot for the review! Happy to extend it for generalised implementation on formatting tags, I was wondering though if it would be better to keep it as a separate PR ?

Let's do it in this PR since it will help us better design the formatting in a reusable manner.

@taru-garg-2000 taru-garg-2000 changed the title feat(jats/inline-formula): Support emphasis elements for Inline formulas WIP: feat(jats/inline-formula): Support emphasis elements for Inline formulas Jul 2, 2026
@taru-garg-2000 taru-garg-2000 marked this pull request as draft July 2, 2026 18:26
Signed-off-by: Taru Garg <taru.garg@hashicorp.com>
@taru-garg-2000 taru-garg-2000 changed the title WIP: feat(jats/inline-formula): Support emphasis elements for Inline formulas feat(jats/inline-formula): Support emphasis elements for Inline formulas Jul 2, 2026
Signed-off-by: Taru Garg <taru.garg@hashicorp.com>
Generalize the inline walker to accumulate styled InlineSegments so bold, italic, underline, strike, sub, and sup formatting is preserved for all paragraph text, not only inside inline formulas. Regenerate JATS groundtruth to include the recovered body emphasis.

Signed-off-by: Taru Garg <taru.garg@hashicorp.com>
@taru-garg-2000 taru-garg-2000 marked this pull request as ready for review July 8, 2026 16:04
@taru-garg-2000

taru-garg-2000 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Hi @ceberam, There's some polishing still left I feel, however was looking to get an early review if the approach looks good ?

For tex-math items I tested on a bunch of real JATS files, and they seems to have this whole blob around them

\documentclass[12pt]{minimal} \usepackage{wasysym} \usepackage[substack]{amsmath} \usepackage{amsfonts} \usepackage{amssymb} \usepackage{amsbsy} \usepackage[mathscr]{eucal} \usepackage{mathrsfs} \DeclareFontFamily{T1}{linotext}{} \DeclareFontShape{T1}{linotext}{m}{n} { <-> linotext }{} \DeclareSymbolFont{linotext}{T1}{linotext}{m}{n} \DeclareSymbolFontAlphabet{\mathLINOTEXT}{linotext} \begin{document} $$ \frac{dA(t)}{dt}={\gamma}_{i,j,B} \left( { \,\substack{ ^{3} \\ {\sum} \\ _{i=1} }\, }I_{i,F,B}(t)+I_{i,M,B}(t) \right) -{\mu}_{A}A(t)-{\delta}A(t), $$ \end{document}

Which kind of corrupts the render of actual formula

\frac{dA(t)}{dt}={\gamma}_{i,j,B} \left( { \,\substack{ ^{3} \\ {\sum} \\ _{i=1} }\, }I_{i,F,B}(t)+I_{i,M,B}(t) \right) -{\mu}_{A}A(t)-{\delta}A(t)

Although it is latex, we don't really render it correctly when the conversion to markdown happens.

Condense the multi-line docstring/comments added for the inline emphasis walker, and remove the markdown-rendering test that duplicated the italic-inside-formula structural case.

Signed-off-by: Taru Garg <taru.garg@hashicorp.com>
…ula-emphasis

Signed-off-by: Taru Garg <taru.garg@hashicorp.com>
@taru-garg-2000 taru-garg-2000 requested a review from ceberam July 14, 2026 16:04
@taru-garg-2000

taru-garg-2000 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Polished up the remaining bit, so for the current implementation we check if the text in a tex-math element is surrounded with $$ or $ if so extract the text within them, else just fallback to the text available in the element (this will not work if there is a lot of latex other than the formula like above), happy to find more samples on real documents and test it out against those.

@taru-garg-2000 taru-garg-2000 changed the title feat(jats/inline-formula): Support emphasis elements for Inline formulas feat(jats/inline-formula): Support emphasis elements and Inline formulas Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants