DoclingDocument Text Formatting#
Text formatting metadata in DoclingDocument is modelled by two types defined in docling_core/types/doc/common/formatting.py:
Script— astrenum with three values:"baseline"(default),"sub"(subscript),"super"(superscript).Formatting— a PydanticBaseModelwith fourboolfields (bold,italic,underline,strikethrough, all defaulting toFalse) and oneScriptfield (script, defaulting toScript.BASELINE).
Formatting lives as an optional field on TextItem (and all its subclasses — TitleItem, SectionHeaderItem, ListItem, FormulaItem, etc.). When None, no formatting is applied. See the DoclingDocument Builder API for how to pass a Formatting instance when constructing items.
JSON Serialization#
Because Formatting is a Pydantic BaseModel, it round-trips to/from JSON automatically via model_dump(). When present, the "formatting" key appears inline in the text item object with all five fields explicitly serialized :
// subscript example
"formatting": {
"bold": false,
"italic": false,
"underline": false,
"strikethrough": false,
"script": "sub"
}
All five fields are always emitted — there is no sparse serialization. The script field takes the string literal values "baseline", "sub", or "super" matching the Script enum .
DocLang XML Serialization#
In DocLang XML, each active formatting attribute wraps the text content in a dedicated XML element. The mapping is defined by DocLangToken and implemented in DocLangDocSerializer:
Formatting field / value | DocLang XML tag |
|---|---|
bold = True | <bold>…</bold> |
italic = True | <italic>…</italic> |
underline = True | <underline>…</underline> |
strikethrough = True | <strikethrough>…</strikethrough> |
script = "sub" | <subscript>…</subscript> |
script = "super" | <superscript>…</superscript> |
Tags can be nested for combined formatting. The fixture content_all.gt.dclg.xml demonstrates this, including a case where bold, italic, underline, and strikethrough are all applied simultaneously via nested wrapping.
The serialization order and nesting are controlled by the post_process() method on the base DocSerializer. It applies wrappers in a fixed sequence — bold → italic → underline → strikethrough — and then script (subscript/superscript are mutually exclusive, handled via elif). Individual serializers override serialize_bold(), serialize_italic(), etc.; the base class stubs are no-ops that return text unchanged .
The post_process() hook runs only when the serialization params have include_formatting=True (the default). Setting include_formatting=False strips all formatting tags from output.
Key Source Files#
| File | Purpose |
|---|---|
docling_core/types/doc/common/formatting.py | Script enum and Formatting model |
docling_core/types/doc/items/text.py | TextItem.formatting field definition |
docling_core/transforms/serializer/common.py | Base post_process() and hook stubs |
docling_core/transforms/serializer/doclang.py | DocLang XML formatting overrides |
docling_core/transforms/serializer/_doclang_utils.py | DocLangToken vocabulary |
test/data/doc/constructed_doc.referenced.json.gt | JSON ground-truth with all formatting variants |
test/data/doc/content_all.gt.dclg.xml | DocLang XML ground-truth with nested formatting |