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)