diff --git a/docling_core/transforms/serializer/markdown.py b/docling_core/transforms/serializer/markdown.py index 066788d23..2f6de6d70 100644 --- a/docling_core/transforms/serializer/markdown.py +++ b/docling_core/transforms/serializer/markdown.py @@ -867,6 +867,16 @@ def serialize_strikethrough(self, text: str, **kwargs: Any): """Apply Markdown-specific strikethrough serialization.""" return f"~~{text}~~" + @override + def serialize_subscript(self, text: str, **kwargs: Any): + """Apply Markdown-specific subscript serialization.""" + return f"{text}" + + @override + def serialize_superscript(self, text: str, **kwargs: Any): + """Apply Markdown-specific superscript serialization.""" + return f"{text}" + @override def serialize_hyperlink( self, diff --git a/docling_core/transforms/serializer/plain_text.py b/docling_core/transforms/serializer/plain_text.py index 488d35fab..f0a39ea68 100644 --- a/docling_core/transforms/serializer/plain_text.py +++ b/docling_core/transforms/serializer/plain_text.py @@ -43,8 +43,9 @@ class PlainTextDocSerializer(MarkdownDocSerializer): """Document serializer that produces clean plain text. Strips all Markdown decoration — heading markers, bold/italic/strikethrough - markers, and hyperlink syntax — while keeping list bullets (``-``), ordered - list numbers, and table-cell separators (``|``) intact. + markers, sub/superscript tags, and hyperlink syntax — while keeping list + bullets (``-``), ordered list numbers, and table-cell separators (``|``) + intact. """ text_serializer: BaseTextSerializer = PlainTextTextSerializer() @@ -65,6 +66,16 @@ def serialize_strikethrough(self, text: str, **kwargs: Any) -> str: """Apply plain-text strikethrough serialization.""" return text + @override + def serialize_subscript(self, text: str, **kwargs: Any) -> str: + """Apply plain-text subscript serialization.""" + return text + + @override + def serialize_superscript(self, text: str, **kwargs: Any) -> str: + """Apply plain-text superscript serialization.""" + return text + @override def serialize_hyperlink( self, diff --git a/test/data/doc/constructed_doc.embedded.md.gt b/test/data/doc/constructed_doc.embedded.md.gt index fd6468d53..9bdc8a4b7 100644 --- a/test/data/doc/constructed_doc.embedded.md.gt +++ b/test/data/doc/constructed_doc.embedded.md.gt @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_doc.placeholder.md.gt b/test/data/doc/constructed_doc.placeholder.md.gt index 9b8993271..545b4d9dd 100644 --- a/test/data/doc/constructed_doc.placeholder.md.gt +++ b/test/data/doc/constructed_doc.placeholder.md.gt @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_doc.referenced.md.gt b/test/data/doc/constructed_doc.referenced.md.gt index 6a30a5822..224dacfa5 100644 --- a/test/data/doc/constructed_doc.referenced.md.gt +++ b/test/data/doc/constructed_doc.referenced.md.gt @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_document.yaml.md b/test/data/doc/constructed_document.yaml.md index ea562f91e..b4dd33f51 100644 --- a/test/data/doc/constructed_document.yaml.md +++ b/test/data/doc/constructed_document.yaml.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_legacy_annot_mark_false.gt.md b/test/data/doc/constructed_legacy_annot_mark_false.gt.md index f0f3c4698..25e057e54 100644 --- a/test/data/doc/constructed_legacy_annot_mark_false.gt.md +++ b/test/data/doc/constructed_legacy_annot_mark_false.gt.md @@ -63,7 +63,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_legacy_annot_mark_true.gt.md b/test/data/doc/constructed_legacy_annot_mark_true.gt.md index 0382ae172..7c085f6a3 100644 --- a/test/data/doc/constructed_legacy_annot_mark_true.gt.md +++ b/test/data/doc/constructed_legacy_annot_mark_true.gt.md @@ -63,7 +63,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_mode_always_valid_false.gt.md b/test/data/doc/constructed_mode_always_valid_false.gt.md index 3121af342..34b601bdc 100644 --- a/test/data/doc/constructed_mode_always_valid_false.gt.md +++ b/test/data/doc/constructed_mode_always_valid_false.gt.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) (i) Item 1 in A (ii) Item 2 in A diff --git a/test/data/doc/constructed_mode_always_valid_true.gt.md b/test/data/doc/constructed_mode_always_valid_true.gt.md index 630d5458d..c726dcd23 100644 --- a/test/data/doc/constructed_mode_always_valid_true.gt.md +++ b/test/data/doc/constructed_mode_always_valid_true.gt.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) 1. (i) Item 1 in A 2. (ii) Item 2 in A diff --git a/test/data/doc/constructed_mode_auto_valid_false.gt.md b/test/data/doc/constructed_mode_auto_valid_false.gt.md index 585e10b86..dee12f23d 100644 --- a/test/data/doc/constructed_mode_auto_valid_false.gt.md +++ b/test/data/doc/constructed_mode_auto_valid_false.gt.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) (i) Item 1 in A (ii) Item 2 in A diff --git a/test/data/doc/constructed_mode_auto_valid_true.gt.md b/test/data/doc/constructed_mode_auto_valid_true.gt.md index ea562f91e..b4dd33f51 100644 --- a/test/data/doc/constructed_mode_auto_valid_true.gt.md +++ b/test/data/doc/constructed_mode_auto_valid_true.gt.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) - (i) Item 1 in A - (ii) Item 2 in A diff --git a/test/data/doc/constructed_mode_never_valid_false.gt.md b/test/data/doc/constructed_mode_never_valid_false.gt.md index 1a065857b..9832874a9 100644 --- a/test/data/doc/constructed_mode_never_valid_false.gt.md +++ b/test/data/doc/constructed_mode_never_valid_false.gt.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) Item 1 in A Item 2 in A diff --git a/test/data/doc/constructed_mode_never_valid_true.gt.md b/test/data/doc/constructed_mode_never_valid_true.gt.md index c42f4e83b..5c7b10f71 100644 --- a/test/data/doc/constructed_mode_never_valid_true.gt.md +++ b/test/data/doc/constructed_mode_never_valid_true.gt.md @@ -61,7 +61,7 @@ $$E=mc^2$$ -Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) +Some formatting chops: **bold** *italic* underline ~~strikethrough~~ subscript superscript [hyperlink](.) & [~~***everything at the same time.***~~](https://github.com/DS4SD/docling) 1. Item 1 in A 2. Item 2 in A diff --git a/test/test_serialization.py b/test/test_serialization.py index b6bd4b1db..7d86e4e33 100644 --- a/test/test_serialization.py +++ b/test/test_serialization.py @@ -24,7 +24,7 @@ ) from docling_core.transforms.serializer.webvtt import WebVTTDocSerializer, WebVTTParams from docling_core.transforms.visualizer.layout_visualizer import LayoutVisualizer -from docling_core.types.doc import DoclingDocument +from docling_core.types.doc import DoclingDocument, Formatting, Script from docling_core.types.doc.base import ImageRefMode from docling_core.types.doc.document import ( BaseMeta, @@ -204,6 +204,32 @@ def test_md_inline_and_formatting(): verify(exp_file=src.with_suffix(".gt.md"), actual=actual) +def test_md_subscript_formatting(): + """Subscript spans are exported as inline HTML in Markdown.""" + doc = DoclingDocument(name="test") + doc.add_text( + label=DocItemLabel.TEXT, + text="H2O", + formatting=Formatting(script=Script.SUB), + ) + + actual = MarkdownDocSerializer(doc=doc).serialize().text + assert "H2O" in actual + + +def test_md_superscript_formatting(): + """Superscript spans are exported as inline HTML in Markdown.""" + doc = DoclingDocument(name="test") + doc.add_text( + label=DocItemLabel.TEXT, + text="2", + formatting=Formatting(script=Script.SUPER), + ) + + actual = MarkdownDocSerializer(doc=doc).serialize().text + assert "2" in actual + + def test_md_pb_placeholder_and_page_filter(): src = Path("./test/data/doc/2408.09869v3_enriched.json") doc = DoclingDocument.load_from_json(src)