Repository navigation
Unable to disable font ligatures in insert_htmlbox method #4981
Description
Activity
Parsing the HTML and CSS syntax in the text and the css parameters is done by our base library MuPDF. As documented, not the full respective syntaxes are covered by this parsing. So you will always find unsupported language expressions.
PyMuPDF has no way of influencing this. All you can do is contacting the MuPDF team in this Discord channel.
However: Even when your request would be implemented, it would not solve your problem, because "ti" is no official ligature. There exists no Unicode definition for it.
The problem is caused by the font itself.Text searching in PyMuPDF has no problem with ligatures: they will be automatically decomposed, letting you successfully find e.g. "fi" - whether present as separate characters or as ligature "fi".
I reproduced your observation with this snippet:import pymupdf from pathlib import Path calibri = Path("calibri.ttf").read_bytes() arch = pymupdf.Archive(calibri, "calibri") css = "@font-face {font-family: sans-serif; src: url(calibri);}" css += "* {font-family: sans-serif}" doc = pymupdf.open() page = doc.new_page() rect = (200, 200, 400, 400) text = "Introduction" page.insert_htmlbox(rect, text, archive=arch, css=css) print(page.get_text()) # extract with auto-replacing unknown Unicodes print(page.get_text(flags=0)) # extract suppressing replacement # doc.ez_save("test.pdf")
The output:
IAW: the font contains no backtranslation information for this pseudo-ligature.
My recommendation: Use a different font!
Reacted by Kishan B- addednot a bugnot a bug / user error / unable to reproducenot a bug / user error / unable to reproducewontfixno intention to resolveno intention to resolve
on May 3, 2026 You can of course use
page.insert_textbox()- this is a character-based output method and thus avoids the use of Harfbuzz. The result will be as you expect it.@JorjMcKie My usecase is the following
I have a page (table of contents page) created using the
insert_htmlboxmethod and the rest of the contents of the pdf come from merging several other PDFsI would like to create links (preferably with
<a>tag) to other pages.. I tried the followingfor toc_entry in chunk: title = toc_entry[1].strip() page_no = toc_entry[2] rl = page.search_for(title) print(f"toc_entry: {toc_entry}") if rl: link = { "kind": pymupdf.LINK_GOTO, "from": rl[0], "to": toc_entry[3]["to"], "page": page_no, } page.insert_link(link)
but the above did not works as expected because
search_forwas not detecting the strings like "Introduction"Any pointers would be much appreciated.
You could give up using
.insert_htmlbox()altogether and use theStoryobject directly. The HTMLBOX method also makes use of it under the hood.If you use
Storythen you can let it create TOCs automatically. It also takes care of fitting content to page rectangles and much more. This would free you from above pesky problems.Using Story basically means that you prepare the complete content in one string, including require HTML / CSS styling, tables, and potential images to be embedded. Then use one of the Story methods to create the PDF output.
Reacted by Kishan BBTW - You are aware of Calibri license restrictions that may apply to you? This is not a free font.
@JorjMcKie How to solve the linking problem using the Story object? Could not get that working. Any pointers to examples would be great..
Use a method like this one to get a a PDF Document object in which the links contained in your source text have been correctly resolved.
Reacted by Kishan BLet me know how you get on with this!
Reacted by Kishan BDefinitely @JorjMcKie I am currently thinking, if there is a way i can define the internal address in the
hrefattribute of the<a>tag. Thehrefattribute should specify both the "page number" and the "y" location in the page so that when the user clicks the link in the first page it goes to the "exact" location.Let's move this to the Discussions tab first.
- locked and limited conversation to collaborators
on May 5, 2026
Description of the bug
I would like to disable font ligatures when creating a page using
insert_htmlboxmethod.I tried creating the following css to disable the same but it had no effect
Image
If you notice the image below in the word "Introduction" the letters "ti" as compressed into one
Impact
search_for()function, when i pass "Introduction" as the parameter i.e.page.search_for("Introduction")it is unable to find the sameHow to reproduce the bug
insert_htmlboxmethod with Calibri font with content as "Introduction"PyMuPDF version
1.27.2.3
Operating system
MacOS
Python version
3.14