Skip to content

feat(markdown): add footnote serialization support#569

Open
ShrillHarrier wants to merge 2 commits intodocling-project:mainfrom
ShrillHarrier:dev/md-footnote-serializer
Open

feat(markdown): add footnote serialization support#569
ShrillHarrier wants to merge 2 commits intodocling-project:mainfrom
ShrillHarrier:dev/md-footnote-serializer

Conversation

@ShrillHarrier
Copy link
Copy Markdown

@ShrillHarrier ShrillHarrier commented Mar 26, 2026

This PR is related to the Improved Footnote Serialization in MarkdownDocSerializer.

It is a Feature Request submitted by simonschoe in docling-project.

The features added include serializing a footnote in the form [^{Identifier}]: {Description}. This is done for Table and Picture items, as footnotes are linked to those.

In general, footnotes in .md files should look like:

[^5]: https://github.com/tesseract-ocr/tesseract
[^6]: https://github.com/VikParuchuri/surya
[^7]: https://github.com/lukas-blecher/LaTeX-OCR

Resolves docling-project/docling#3128

Tests Added:

  • test_table_with_footnotes_markdown()
  • test_picture_with_footnotes_markdown()
  • test_table_export_to_markdown_with_footnotes()

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

DCO Check Passed

Thanks @ShrillHarrier, all your commits are properly signed off. 🎉

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 26, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 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

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

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)(?:\(.+\))?(!)?:

@dosubot
Copy link
Copy Markdown

dosubot bot commented Mar 26, 2026

Related Documentation

1 document(s) may need updating based on files changed in this PR:

Docling

What are the differences between vlm_pipeline_model_local and picture_description_local in Docling, and how do image descriptions, OCR, and table extraction work together? Also, how do the include_annotations and mark_annotations properties affect exported output?
View Suggested Changes
@@ -67,6 +67,9 @@
 - `compact_tables` (bool): Whether to use compact table format without column padding (default: `False`, Markdown only)
 - `traverse_pictures` (bool): Whether to traverse into picture items and serialize their text children (default: `False`)
 
+**Footnote Serialization in Markdown:**
+When tables or pictures have associated footnotes in the document, these footnotes are automatically serialized in the markdown output using standard markdown footnote syntax: `[^{Identifier}]: {Description}`. The identifier is extracted from the first part of the footnote text, and the remaining text becomes the footnote description. This formatting ensures that footnotes attached to Table and Picture items appear correctly in the exported markdown.
+
 **Handling OCR Text in Scanned/Image-Based PDFs:**
 When processing scanned or image-based PDFs with `force_full_page_ocr=True`, the layout model classifies full-page scans as `PictureItem` nodes. OCR text items are added as children of that picture node in the document tree.
 

[Accept] [Decline]

Note: You must be authenticated to accept/decline updates.

How did I do? Any feedback?  Join Discord

@ShrillHarrier ShrillHarrier changed the title Improved Footnote Serialization in MarkdownDocSerializer #3128 feat(markdown-serializer): add footnote serialization support for markdown Mar 26, 2026
@ShrillHarrier ShrillHarrier changed the title feat(markdown-serializer): add footnote serialization support for markdown feat(markdown): add footnote serialization support Mar 26, 2026
I, Matthew Panizza <shrillharrier1@gmail.com>, hereby add my Signed-off-by to this commit: 73a9a40
I, Matthew Panizza <shrillharrier1@gmail.com>, hereby add my Signed-off-by to this commit: 929c11f

Signed-off-by: Matthew Panizza <shrillharrier1@gmail.com>
@ShrillHarrier ShrillHarrier force-pushed the dev/md-footnote-serializer branch from b849797 to 27e8b28 Compare March 30, 2026 19:41
@ShrillHarrier
Copy link
Copy Markdown
Author

Signing off with personal email.

Signed-off-by: Matthew Panizza <username@users.noreply.github.com>
@ShrillHarrier ShrillHarrier force-pushed the dev/md-footnote-serializer branch from 483d902 to f3f0876 Compare April 5, 2026 19:36
@ceberam ceberam self-requested a review April 11, 2026 07:08
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 11, 2026

Codecov Report

❌ Patch coverage is 95.45455% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
docling_core/transforms/serializer/markdown.py 95.45% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Member

@ceberam ceberam left a comment

Choose a reason for hiding this comment

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

Thanks @ShrillHarrier for suggesting this PR. Please, see my comments.
In general:

  • Adding new tests with a programmatic example is fine but it is much more illustrative to show the impact of the new feature in a serialization with a ground truth data file. This allows us to check how the output markdown file gets rendered in applications like Github or VSC. Please, check how this is done in other test modules.
  • To keep the repository consistent, I would suggest that you add the tests in the module test/test_serialization.py, together with the other tests of the markdown serialization, instead of creating a separate module.
  • There are some DoclingDocument files (.json) that do not serialize as expected. Please, check some of them and ensure that the markdown serialization generates the right footnotes hook and text. For instance, test/data/doc/2408.09869v3_enriched.json has a footnote. If you regenerate the ground truth files (by running the tests with env variable DOCLING_GEN_TEST_DATA=1 ), I would expect that the markdown serialization gets updated with the new footnote serialization.

params: MarkdownParams = self.params.merge_with_patch(patch=kwargs)
results: list[SerializationResult] = []
if DocItemLabel.FOOTNOTE in params.labels:
results = []
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.

This line is redundant

Suggested change
results = []

results = []
for footnote in item.footnotes:
if isinstance(ftn := footnote.resolve(self.doc), TextItem):
parts = ftn.text.split(" ", 1)
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.

The footnote parsing logic assumes a specific format (the identifier and the footnote text). This format is not clearly represented or documented. It would be good that the format is explicit, validated, and clearly documented. We should keep in mind that for the markdown footnote to work, identifiers can be numbers or words, but they can’t contain spaces or tabs..
In addition, I don't think that we keep the footnote references with the correct formatting (a caret and an identifier inside brackets, e.g., [^1]).

If I try to serialize a DoclingDocument from the test dataset, you'll see that the footnote 1 see huggingface.co/ds4sd/docling-models/ (doc item with reference #/texts/29) is not properly serialized as in the markdown specification.

from docling_core.types.doc import DoclingDocument
from docling_core.types.doc.base import ImageRefMode

with open("test/data/doc/2408.09869v3_enriched.json") as handler:
  content = handler.read()
doc = DoclingDocument.model_validate_json(content)
doc.export_to_markdown(image_mode=ImageRefMode.PLACEHOLDER)

Comment on lines +4 to +11
CodeItem,
FieldHeadingItem,
FieldValueItem,
FormulaItem,
ListItem,
SectionHeaderItem,
TextItem,
TitleItem,
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.

Many of these imports are never used. Please, remove unused imports.

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.

Improved Footnote Serialization in MarkdownDocSerializer

2 participants