Relative hyperlinks are exported with backslashes on Windows (Markdown, HTML, LaTeX, DocLang, JSON)
Author: Koushik890Created Sep 11, 2026Updated Sep 12, 2026
### Bug
Relative hyperlinks are stored on `TextItem.hyperlink` as a `Path` (the field is `AnyUrl | Path`). On Windows that is a `WindowsPath`, and the serializers turn the hyperlink into text with `str(...)`, so a link written as `sub/next.html` in the source comes out as `sub\next.html`:
- Markdown: `[next page](sub\next.html)` (`MarkdownDocSerializer.serialize_hyperlink` uses `f"[{text}]({hyperlink!s})"`)
- HTML: `` (`HTMLDocSerializer.serialize_hyperlink`)
- LaTeX: `serialize_hyperlink` uses `str(hyperlink)`
- DocLang: `_text_item_hyperlink_uri` returns `str(item.hyperlink)`
- JSON: `save_as_json` stores `"sub\\next.html"`, so a document converted on Windows carries a different path than the same document converted on Linux, and loading it on Linux gives a single path component that contains a backslash.
On Linux the same document exports `sub/next.html` everywhere.
### Steps to reproduce
On Windows, with `index.html` next to `sub/next.html`:
```html
See the next page.
``` ```python from docling.document_converter import DocumentConverter doc = DocumentConverter().convert("index.html").document print(repr(doc.texts[0].hyperlink)) # WindowsPath('sub/next.html') print(doc.export_to_markdown()) # See the [next page](sub\next.html) . ``` `export_to_html()` gives ``. Expected: the same output as on Linux, a link destination with forward slashes. A possible fix: the Markdown and HTML serializers already have a helper that turns a `Path` or URL into a portable link destination (`_escape_uri_path`, added for images in docling-project/docling-core#698 and shared with the HTML serializer in docling-project/docling-core#772). Using it for `Path` hyperlinks in `serialize_hyperlink` would fix the Markdown and HTML links. LaTeX and DocLang could normalize the same way, and a field serializer on `hyperlink` would make the JSON output portable too. Output on Linux and macOS would stay the same for ordinary relative links. Related: #3617, the same Windows separator problem for exported image paths. Happy to open a PR for this if the approach sounds right. ### Docling version ``` Docling version: 2.126.0 Docling Core version: 2.96.0 Docling IBM Models version: 4.0.2 Docling Parse version: 7.19.0 Python: cpython-313 (3.13.12) Platform: Windows-11-10.0.26200-SP0 ``` ### Python version Python 3.13.12Source: docling-project/docling