Created
February 5, 2018 03:07
-
-
Save reiver-dev/82da77ba3f0008c56624661a7375e0e8 to your computer and use it in GitHub Desktop.
Move ligatures for Fira Code font to private unicode area at U+e100
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
import argparse | |
from glob import glob | |
from itertools import chain | |
import fontforge | |
ADDITIONAL_LIGATURES = [ | |
'x.multiply', | |
'colon.uc', | |
'plus.lc', | |
'plus.tosf2', | |
] | |
def run(fontpath, outpath, starting_point=0xe100): | |
try: | |
font = fontforge.open(fontpath) | |
ligatures = list(filter(lambda x: x.glyphname.endswith('.liga'), | |
font.glyphs())) | |
for i, glyph in enumerate(ligatures): | |
point = starting_point + i | |
name = glyph.glyphname | |
newchar = font.createChar(point, name + '.private') | |
newchar.addReference(name) | |
# Other option is to use alternative unicode encoding | |
# fontforge recommends to use references | |
# glygh.altuni = (point, -1, 0) | |
font.generate(outpath) | |
finally: | |
font.close() | |
def main(argv): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--output-dir', '-o', type=str) | |
parser.add_argument('fonts', nargs='+', | |
help='font files to process') | |
argvals = parser.parse_args(argv) | |
output = argvals.output_dir | |
fonts = argvals.fonts | |
os.makedirs(output, exist_ok=True) | |
for f in chain.from_iterable(map(glob, fonts)): | |
run(f, os.path.join(output, os.path.basename(f))) | |
if __name__ == '__main__': | |
main(sys.argv[1:]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defconst ligatures-fira-code-start #Xe100) | |
(defconst ligatures-fira-code-list | |
'("www" "**" "***" "*>" "*/" "\\\\" "\\\\\\" "]#" "::" ":::" | |
":=" "!!" "!=" "!==" "--" "---" "-->" "->" "->>" "-<" | |
"-<<" "-~" "#{" "#[" "#!" "##" "###" "####" "#(" "#?" | |
"#_" "#_(" ".-" ".=" ".." "..<" "..." ".?" "?:" "?=" | |
"?." "??" ";;" "/*" "/=" "/==" "/>" "//" "///" "__" | |
"&&" "||" "|||>" "||=" "||>" "|=" "|>" "^=" "$>" "++" | |
"+++" "+>" "=:=" "==" "===" "==>" "=>" "=>>" "<=" "=<<" | |
"=/=" ">-" ">->" ">=" ">=>" ">>" ">>-" ">>=" ">>>" "<*" | |
"<*>" "<|" "<||" "<|||" "<|>" "<$" "<$>" "<!--" "<-" "<--" | |
"<->" "<-<" "<+" "<+>" "<=" "<==" "<=>" "<=<" "<>" "<<" | |
"<<-" "<<=" "<<<" "<~" "<~>" "<~~" "</" "</>" "~@" "~-" | |
"~=" "~>" "~~" "~~>" "%%") | |
"Ordered ligatures for Fira Code font") | |
(defun ligatures-correct-symbol-bounds (len char) | |
"Prepend up to LEN non-breaking spaces with reference points to CHAR. | |
This way `compose-region' called by function `prettify-symbols-mode' | |
will use the correct width of the symbols instead of the width | |
measured by `char-width'." | |
(let ((acc (list char))) | |
(while (> len 1) | |
(setq acc (cons #X00a0 (cons '(Br . Bl) acc))) | |
(setq len (1- len))) | |
acc)) | |
(defun ligatures-make-alist (ligatures starting-code) | |
"Construct text to ligature character. | |
For each string in LIGATURES list add replacement from STARTING-CODE | |
sequentially." | |
(mapcar (lambda (l) | |
(let ((n starting-code)) | |
(setq starting-code (1+ starting-code)) | |
(when l | |
(cons l (ligatures-correct-symbol-bounds | |
(length l) n))))) | |
ligatures)) | |
(defun ligatures-fira-code-setup () | |
"Add Fira Code ligatures to `prettify-symbols-alist'." | |
(setq prettify-symbols-alist (append (ligatures-make-alist | |
ligatures-fira-code-list | |
ligatures-fira-code-start) | |
prettify-symbols-alist))) |
def run(fontpath, outpath, starting_point=0xe100)
Here outpath is a path to file that will be used for new font. /path/output_dir/Fira Code Medium.otf
font.generate(outpath)
Output dir in arguments is a directory for new font files
Processed font files are here https://github.com/tonsky/FiraCode/files/1734878/FiraCode-private-area.zip
@reiver-dev also, where is the fontforge module from? On my system (macOS with python 2 and 3 from Homebrew) I can't import fontforge
:
>>> import fontforge
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'fontforge'
@reiver-dev: Ah, I need the fontforge complete software package. Please ignore my previous comment.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
what needs to be used as the outpath?