docling-project / docling-project/docling
Relative hyperlinks are exported with backslashes on Windows (Markdown, HTML, LaTeX, DocLang, JSON)
- Dominant language
- Python
- Stars
- 66.4k
- Forks
- 4.8k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 84
Description
### 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
```
```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.12
Contributor guide
Research direction
Start with MarkdownDocSerializer.serialize_hyperlink, HTMLDocSerializer.serialize_hyperlink, LaTeX serialize_hyperlink, DocLang _text_item_hyperlink_uri, and save_as_json. Review the existing _escape_uri_path helper used for image paths and reproduce the Windows case from the issue. Done means relative hyperlinks use forward slashes consistently in Markdown, HTML, LaTeX, DocLang, and JSON, while Linux and macOS output remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100