JetBrains / JetBrainsMono

JetBrains Mono – the free and open-source typeface for developers
https://jetbrains.com/mono
SIL Open Font License 1.1
10.58k stars 298 forks source link

Ligature substitution rules without SPC #486

Closed ningit closed 2 years ago

ningit commented 2 years ago

Ligatures in this font are implemented by inserting a sequence of empty SPC glyphs followed by the proper ligature glyph that overflows to the left and occupies the space of the previous characters. For example, the sequence of characters := is typeset as a sequence of two glyphs SPC + colon_equal.liga, =/= is shaped as SPC + SPC + equal_slash_equal.liga, etc. Wouldn't translating the ligatures to a single glyph of the appropriate width be simpler and more convenient?

One of the disadvantages of the current approach is that text typeset with this font is not copyable nor searchable in LaTeX (see https://github.com/JetBrains/JetBrainsMono/issues/59). The drivers used by lualatex and xelatex are not able to correctly infer the translation from glyphs to Unicode characters (the ToUnicode table of the font in the PDF), since many different characters are mapped to the same SPC glyph.

The contextual alternate rules can be modified to use a single multiple substitution instead of a sequence of single substitutions. For example, the current lookup for := in sources/JetBrainsMono.glyphs is

lookup colon_equal.liga {
ignore sub equal colon' equal;
ignore sub colon colon' equal;
ignore sub colon' equal equal;
sub SPC equal' by colon_equal.liga;
sub colon' equal by SPC;
} colon_equal.liga;

and it can be transformed to the following

lookup equal_colon.liga {
ignore sub equal equal' colon';
ignore sub equal' colon' colon;
ignore sub equal' colon' equal;
sub equal' colon' by equal_colon.liga;
} equal_colon.liga;

Moreover, the equal_colon.liga glyph has to be enlarged by the size of a character and translated horizontally by the same amount.

I have written a Python script that transforms all rules and their corresponding ligatures glyphs as explained. The problem in LaTeX has disappeared, and no problem has been found when using the modified font within PyCharm and Code. I suppose there should be a reason why SPC is used in the substitution rules, but I cannot figure it out.

philippnurullin commented 2 years ago

Hi @ningit There are two reasons that we can't get rid of SPC yet.

Regarding the edited code. Why do you have two glyphs marked by '? This symbol marks the glyph that launches the sub. This should be fine.

lookup equal_colon.liga {
ignore sub equal equal' colon;
ignore sub equal' colon colon;
ignore sub equal' colon equal;
sub equal' colon by equal_colon.liga;
} equal_colon.liga;
ningit commented 2 years ago

Hi @philippnurullin,

I would say that the edited lookup code in my original post is right. The apostrophe does not mark "the glyph that launches the sub" but "the glyphs that are replaced by the sub". Symbols without apostrophe are merely context and they are not replaced by the substitution rule. Like this, the original lookup block will replace : = by SPC = and then by SPC equal_colon.liga; my edited rule will replace : = by equal_colon.liga in one step; and yours will replace : = by equal_colon.liga =, which is not desired.

Yes, compatibility was expectedly the issue. Just for fun, I have tested the SPC-free font in several editors and terminals. It works (including moving the cursor through the ligature) in PyCharm, Code, Gedit, Kate, LibreOffice Writer, Windows' Notepad (not perfectly fine), Konsole, Windows Terminal, and Kitty. It does not work in Gnome Terminal (but ligatures do no show with the original font either). It works also with XeLaTeX and LuaLaTeX (including properly copying text with ligatures), while the original font fails in the latter.

philippnurullin commented 2 years ago

Yes, you absolutely right. The line should be like this sub equal' colon' by equal_colon.liga; On the other hand ignore sub equal equal' colon; just need ' at the first ligature symbol to apply the ignore sub rule.

If you don't mind I will add a page in Wiki with a link to your script as a solution for XeLaTeX and LuaLaTeX.

We are not ready to get rid of SPC in ligature construction.