diff --git a/README.md b/README.md index 0b94226..9c5320a 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ В основе лежит моноширинный шрифт [Iosevka](https://github.com/be5invis/Iosevka/) и встраиваемый в шрифт набор иконок [Nerd Fonts](https://www.nerdfonts.com/). -Для сборки требуется установка [Docker](https://www.docker.com/): +Для сборки требуется установка [Docker](https://www.docker.com/) и библиотека +для работы со шрифтами [fonttools](https://pypi.org/project/fonttools/): ```sh -sudo apt-get install docker.io +sudo apt-get install docker.io python3-fonttools ``` Сборка шрифта выполняется командой `make`, результат сохраняется в каталог `dist`. -Готовый шрифт версии [22.1.2](../../../releases/download/22.1.2/iosevka-prog-22.1.2.tar.xz). +Готовый шрифт версии [25.1.1](../../../releases/download/25.1.1/iosevka-prog-25.1.1.tar.xz). diff --git a/build-iosevka-prog-font.sh b/build-iosevka-prog-font.sh index 712e90a..8f6dc76 100755 --- a/build-iosevka-prog-font.sh +++ b/build-iosevka-prog-font.sh @@ -2,7 +2,7 @@ set -e -IOSEVKA_VERSION=22.1.2 +IOSEVKA_VERSION=25.1.1 FONT_NAME=iosevka-prog FILE=$( readlink -f "${BASH_SOURCE[0]}" ) DIR=$( dirname "${FILE}" ) @@ -20,14 +20,21 @@ if [ -r "${CONFIG}" ]; then sudo chown -R "$(id -u)":"$(id -g)" "${DIST}" mkdir -p "${OBLIQUE}" cp -af "${OUT_DIR}/${FONT_NAME}-oblique.ttf" "${OBLIQUE}" - docker run -v "${OBLIQUE}":/in -v "${OUT_DIR}":/out nerdfonts/patcher --complete --careful --adjust-line-height --makegroups || true + docker run --rm -v "${OBLIQUE}":/in -v "${OUT_DIR}":/out nerdfonts/patcher --complete --adjust-line-height --makegroups 1 mkdir -p "${REGULAR}" cp -af "${OUT_DIR}/${FONT_NAME}-regular.ttf" "${REGULAR}" - docker run -v "${REGULAR}":/in -v "${OUT_DIR}":/out nerdfonts/patcher --complete --careful --adjust-line-height --makegroups --mono --removeligatures || true + docker run --rm -v "${REGULAR}":/in -v "${OUT_DIR}":/out nerdfonts/patcher --complete --adjust-line-height --makegroups 1 --mono --removeligatures + sudo chown -R "$(id -u)":"$(id -g)" "${DIST}" cd "${OUT_DIR}" - tar acf "${DIST}/fonts-iosevka-prog-nerd_${IOSEVKA_VERSION}.orig.tar.xz" Iosevka*Nerd*ttf - tar acf "${DIST}/fonts-iosevka-prog_${IOSEVKA_VERSION}.orig.tar.xz" iosevka*ttf + python3 "${DIR}/fontname.py" "Iosevka Prog Nerd Font" IosevkaProgNerdFont-Oblique.ttf + python3 "${DIR}/fontname.py" "Iosevka Prog Nerd Font Mono" IosevkaProgNerdFontMono-Regular.ttf tar acf "${DIST}/iosevka-prog-${IOSEVKA_VERSION}.tar.xz" *ttf + mkdir -p "iosevka-prog-nerd-$IOSEVKA_VERSION" + mv Iosevka*Nerd*ttf "iosevka-prog-nerd-$IOSEVKA_VERSION" + tar acf "${DIST}/fonts-iosevka-prog-nerd_${IOSEVKA_VERSION}.orig.tar.xz" "iosevka-prog-nerd-$IOSEVKA_VERSION" + mkdir -p "iosevka-prog-$IOSEVKA_VERSION" + mv iosevka*ttf "iosevka-prog-$IOSEVKA_VERSION" + tar acf "${DIST}/fonts-iosevka-prog_${IOSEVKA_VERSION}.orig.tar.xz" "iosevka-prog-$IOSEVKA_VERSION" else echo "Docker executable not found" fi diff --git a/fontname.py b/fontname.py new file mode 100644 index 0000000..26f0294 --- /dev/null +++ b/fontname.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +# ========================================================================== +# fontname.py +# Copyright 2019 Christopher Simpkins +# MIT License +# +# Dependencies: +# 1) Python 3.6+ interpreter +# 2) fonttools Python library (https://github.com/fonttools/fonttools) +# - install with `pip3 install fonttools` +# +# Usage: +# python3 fontname.py [FONT FAMILY NAME] [FONT PATH 1] +# +# Notes: +# Use quotes around font family name arguments that include spaces +# =========================================================================== + +import os +import sys + +from fontTools import ttLib + + +def main(argv): + # command argument tests + print(" ") + if len(argv) < 2: + sys.stderr.write( + f"[fontname.py] ERROR: you did not include enough arguments to the script.{os.linesep}" + ) + sys.stderr.write( + f"Usage: python3 fontname.py [FONT FAMILY NAME] [FONT PATH 1] {os.linesep}" + ) + sys.exit(1) + + # begin parsing command line arguments + try: + font_name = str(argv[0]) # the first argument is the new typeface name + except Exception as e: + sys.stderr.write( + f"[fontname.py] ERROR: Unable to convert argument to string. {e}{os.linesep}" + ) + sys.exit(1) + + # all remaining arguments on command line are file paths to fonts + font_path_list = argv[1:] + + # iterate through all paths provided on command line and rename to `font_name` defined by user + for font_path in font_path_list: + # test for existence of font file on requested file path + if not file_exists(font_path): + sys.stderr.write( + f"[fontname.py] ERROR: the path '{font_path}' does not appear to be a valid file path.{os.linesep}" + ) + sys.exit(1) + + tt = ttLib.TTFont(font_path) + namerecord_list = tt["name"].names + + style = "" + + # determine font style for this file path from name record nameID 2 + for record in namerecord_list: + if record.nameID == 2: + style = str(record) + break + + # test that a style name was found in the OpenType tables of the font + if len(style) == 0: + sys.stderr.write( + f"[fontname.py] Unable to detect the font style from the OpenType name table in '{font_path}'. {os.linesep}" + ) + sys.stderr.write("Unable to complete execution of the script.") + sys.exit(1) + else: + # used for the Postscript name in the name table (no spaces allowed) + postscript_font_name = font_name.replace(" ", "") + # font family name + nameID1_string = font_name + nameID16_string = font_name + # full font name + nameID4_string = f"{font_name} {style}" + # Postscript name + # - no spaces allowed in family name or the PostScript suffix. should be dash delimited + nameID6_string = f"{postscript_font_name}-{style.replace(' ', '')}" + # nameID6_string = postscript_font_name + "-" + style.replace(" ", "") + + # modify the opentype table data in memory with updated values + for record in namerecord_list: + if record.nameID == 1: + record.string = nameID1_string + elif record.nameID == 4: + record.string = nameID4_string + elif record.nameID == 6: + record.string = nameID6_string + elif record.nameID == 16: + record.string = nameID16_string + + # CFF table naming for CFF fonts (only) + if "CFF " in tt: + try: + cff = tt["CFF "] + cff.cff[0].FamilyName = nameID1_string + cff.cff[0].FullName = nameID4_string + cff.cff.fontNames = [nameID6_string] + except Exception as e: + sys.stderr.write( + f"[fontname.py] ERROR: unable to write new names to CFF table: {e}" + ) + + # write changes to the font file + try: + tt.save(font_path) + print(f"[OK] Updated '{font_path}' with the name '{nameID4_string}'") + except Exception as e: + sys.stderr.write( + f"[fontname.py] ERROR: unable to write new name to OpenType name table for '{font_path}'. {os.linesep}" + ) + sys.stderr.write(f"{e}{os.linesep}") + sys.exit(1) + + +# Utilities + + +def file_exists(filepath): + """Tests for existence of a file on the string filepath""" + return os.path.exists(filepath) and os.path.isfile(filepath) + + +if __name__ == "__main__": + main(sys.argv[1:])