* Custom fonts
  :PROPERTIES:
  :header-args: :results output
  :END:

  Orgro offers the following fonts:

  - [[https://github.com/tonsky/FiraCode][Fira Code]] (bundled with the app)
  - All monospace fonts offered for dynamic download by the [[https://pub.dev/packages/google_fonts][google_fonts]] package
  - Additional fonts manually made available for dynamic download via the
    [[https://pub.dev/packages/dynamic_fonts][dynamic_fonts]] package
    - [[https://pub.dev/packages/dynamic_fonts][FiraGO]]
    - [[https://rubjo.github.io/victor-mono/][Victor Mono]]
    - [[https://typeof.net/Iosevka/][Iosevka]]

  This file documents how the last category is prepared in literate-programming
  style.

** Font variants

   Org documents in general require four font variants:

   - regular
   - *bold*
   - /italic/
   - /bold italic/ :: You can't /*just*/ */combine/* ~*~ and ~/~, you have to
     italicize something that is naturally bold for some other reason,
     apparently

** FiraGO

   Download

   #+begin_src bash :dir ../..
     git clone --depth 1 https://github.com/bBoxType/FiraGO.git
   #+end_src

   Update

   #+begin_src bash :dir ../../FiraGO
     git pull
   #+end_src

   Checksum

   #+name: firago-csums
   #+begin_src bash :dir ../../FiraGO/Fonts :results table drawer replace
     for ttf in FiraGO_TTF_*/*/*.ttf; do
         echo $(basename $ttf) $(stat -f '%z' $ttf) $(openssl sha256 $ttf | cut -d '=' -f 2)
     done
   #+end_src

   #+RESULTS: firago-csums
   :results:
   | FiraGO-BoldItalic.ttf       | 813028 | 51ad0da400568385e038ccb962a692f145dfbd9071d7fe5cb0903fd2a8912ccd |
   | FiraGO-BookItalic.ttf       | 811792 | d1acf0bfba04de8a35888f402bbe029b3c412b2a52ea4da27bf498bc5973fc05 |
   | FiraGO-EightItalic.ttf      | 768336 | ef2d9f3c9caf711d9aab4839abf63d50e658db802555364f8bbec0fd594fb41a |
   | FiraGO-ExtraBoldItalic.ttf  | 812624 | fa332efd69db43a3dc3ea9cc9efbec938f5cb7d74331b653b5e5f5a0aab6f6cb |
   | FiraGO-ExtraLightItalic.ttf | 813732 | 17b25b0acc856d25a84066acb84de10adc0adc0057cfde52b45e453daec25825 |
   | FiraGO-FourItalic.ttf       | 765044 | e93d9f2e95f7ea40770583c41acaad4678ed90d5ef2cb0beeae073691805c8e4 |
   | FiraGO-HairItalic.ttf       | 778444 | 719d4c484d24961a1d34df543654e9483a59be136f11efbb9a94522c5feb7cf7 |
   | FiraGO-HeavyItalic.ttf      | 730912 | f7ee3438edc6d14046c0175eab3bc6edfccb72b7bda5f73e65509b5e1108573e |
   | FiraGO-Italic.ttf           | 813116 | 36713ecac376845daa58738d2c2ba797cf6f6477b8c5bb4fa79721dc970e8081 |
   | FiraGO-LightItalic.ttf      | 812940 | 0b686cb6edbb457ef3442f4c500a53bb964b96b939a7603949ee7ed812f5105d |
   | FiraGO-MediumItalic.ttf     | 813936 | 949698ddae3a568f1ada6eed12d5226d448b0b4a6600a44f096cfd9a1aabb555 |
   | FiraGO-SemiBoldItalic.ttf   | 813732 | 0dda9d907ec201586736814689a387a36fd05ebb87ac6faebdf4f8e4299d3020 |
   | FiraGO-ThinItalic.ttf       | 802064 | c3bb05f7ec7715a9f2e733e11b23e2a564ad0fafbdb81e097f0f006d5288850f |
   | FiraGO-TwoItalic.ttf        | 720640 | cebcd6f719b48196e0b23d70515ce9154f2c97edfaf954e2b6e97aa4b79420f1 |
   | FiraGO-UltraLightItalic.ttf | 814244 | 71b11d76754a0d43c412a8af5ce6a69c0c32c4d2e6d8a23e0e747cf4dc62cd10 |
   | FiraGO-Bold.ttf             | 807140 | ab720753c39073556260ebbaee7e7af89f9ca202a7c7abc257d935db590a1e35 |
   | FiraGO-Book.ttf             | 805308 | 4c132d5290477709da7fee51f2494d9d13157024e5011d665ebe73489416f894 |
   | FiraGO-Eight.ttf            | 757808 | ad5c1faab9d627aa69dcf3544530622d6c8281571e603d61879a5885b403b946 |
   | FiraGO-ExtraBold.ttf        | 805876 | 4cc3a0294144d7194e1ab9be8603690d2059b2b66b9106896e1b1bf0ac542347 |
   | FiraGO-ExtraLight.ttf       | 805744 | b1eca47daf25d0f975fedce2a7c18161d5b12f4ccef49bd15c9a55b6e65299d0 |
   | FiraGO-Four.ttf             | 754716 | 57bd7bad431f02d578e2edd7f2e8864aae5420bbe309ee782bd0ab5fafb69aeb |
   | FiraGO-Hair.ttf             | 768432 | 6516767cb6003138ab53f63c07f07d8c8236c3bb9214837dab056395d1e6349a |
   | FiraGO-Heavy.ttf            | 719748 | ac93a492bd88d0bca88bcacb8c169101c013013b9d92bb06d757717e6a5af8a5 |
   | FiraGO-Light.ttf            | 805292 | a8145c545e448cc3c51b1417422bc16ff84c5098907827dbfc13f8109ab3507b |
   | FiraGO-Medium.ttf           | 806400 | 5f753a48c7dff5b7af294e76624febb28c41071a5a65c0fd8a024ea9d1491e8a |
   | FiraGO-Regular.ttf          | 804888 | 495901c0c608ea265f4c31aa2a4c7a313e5cc2a3dd610da78a447fe8e07454a2 |
   | FiraGO-SemiBold.ttf         | 806684 | b47f1eaf02deaf16051a897f84f275326476306eb198f1cbceb5b1f5882021b1 |
   | FiraGO-Thin.ttf             | 793404 | a86be3f3ecf807e363347297bff4db79951394d7b024fe83b8ebb1cd2ddf1152 |
   | FiraGO-Two.ttf              | 708572 | f5691843d026b52c1d40505ebf04fdea67b0eb50ca945642dfa033abf70d5c3c |
   | FiraGO-UltraLight.ttf       | 804924 | a3f15783dc7b783e07518560992f038409eea500729cf2b2cfaef7cc17bd2cf7 |
   :end:

   #+call: update-checksums(replacements=firago-csums)

   Deploy to S3

   #+begin_src bash :dir ../../FiraGO :var dryrun="--dryrun"
     aws s3 $dryrun sync --no-progress --exclude '*' --include 'FiraGO_TTF_*' --acl public-read Fonts 's3://orgro/assets/fonts/'
   #+end_src

** Victor Mono

   Download

   #+begin_src bash :dir ../tmp :mkdirp t :var version="1.5.4"
     curl -LO https://github.com/rubjo/victor-mono/raw/v$version/public/VictorMonoAll.zip
     rm -r VictorMono
     mkdir VictorMono
     unzip VictorMonoAll.zip -d VictorMono/$version
   #+end_src

   Checksum

   #+name: victormono-csums
   #+begin_src bash :dir ../tmp/VictorMono :results table drawer replace
     for ttf in */TTF/*.ttf; do
         echo $(basename $ttf) $(stat -f '%z' $ttf) $(openssl sha256 $ttf | cut -d '=' -f 2)
     done
   #+end_src

   #+RESULTS: victormono-csums
   :results:
   | VictorMono-Bold.ttf              | 192920 | ed641d97b729c179a00a1f84b5c33006e1e592a48090191dae3181781ac008d9 |
   | VictorMono-BoldItalic.ttf        | 241804 | f2382a8cd453838784464b768918b34fff81ff1110a969af87089af2b37cf9cd |
   | VictorMono-BoldOblique.ttf       | 203188 | d0c26239c0337e879276d17a4e610d2ba2d424067fabe6e848b8bb4c7687a9f2 |
   | VictorMono-ExtraLight.ttf        | 183080 | 1b0c14f78e3d195fe31479521401bf9fd431af04f1fdd18cacefd40275efa85c |
   | VictorMono-ExtraLightItalic.ttf  | 229500 | 8f1823c91fc395b17c4893f8de5a52a8e9f2b4d0e9071ad120b52c341431f65a |
   | VictorMono-ExtraLightOblique.ttf | 194812 | b3a5d11eebf8e77d48ab1e2a5e3c6dcccc283f2327fed2832cce955d38b92567 |
   | VictorMono-Italic.ttf            | 231304 | 9193aea602749f757723cd3bf59bfb532c3bbd3ff7a4bc7ecb50b88ea8f6d6ac |
   | VictorMono-Light.ttf             | 184216 | 40ed2dd9d2cdcfee34783561d9acfee6a29bbd286a8e9cdcdbfd8624984f7c3c |
   | VictorMono-LightItalic.ttf       | 231480 | e59d785747c2066f4b702a3c205ecdd507a4779c694ec1eb684825dd244914f7 |
   | VictorMono-LightOblique.ttf      | 195512 | e2ab30d34e5da8f20d10dbae7cbac0fbc477d5061f52bf46747ea56a6e0d9157 |
   | VictorMono-Medium.ttf            | 186800 | 4de25934faa0b33b8d6f807c4b91e4114f5397790c61b448b20d02a57d6dc8a9 |
   | VictorMono-MediumItalic.ttf      | 238456 | 3af8c39481de2cdb9a4a79045840e7ef8ec1c7b43d6b122c065d848a087b3cf5 |
   | VictorMono-MediumOblique.ttf     | 199700 | b443a3eab2492bebc44504b83461d62055348f3637b22490bd3cc0ee9c207a16 |
   | VictorMono-Oblique.ttf           | 196136 | 1dc4cc2cc7bb5a78c04421740625132b22521eb753c672f1af4b6b35e07b34b6 |
   | VictorMono-Regular.ttf           | 184692 | f9ad2fdc82aaf8e05dc6b7f46923ba4f0c35200067d8974671c13fb898b39ce3 |
   | VictorMono-SemiBold.ttf          | 187904 | 59e2ee38083e1a658ed79d2ca5091dfd70083dc52b8a241a1f7305fd4a4a43a1 |
   | VictorMono-SemiBoldItalic.ttf    | 236792 | fff0b4c095cbd3beefe7335694f177a6fe90ae76b212dca745d7d5581e9fb920 |
   | VictorMono-SemiBoldOblique.ttf   | 198888 | a13ab6a78ee1e3dfe243daac0ca5e317c7666009a1cda55bbbc9acc1c388359c |
   | VictorMono-Thin.ttf              | 183592 | 0aaeea4c048c801ea14431fdf6f491f3fde29f7779bc200ce604165781b80fa3 |
   | VictorMono-ThinItalic.ttf        | 231036 | 0ecd6bc8f50ebc9208d49a7b03aa6f7b4fdac9a5b840941d5fd02e16c3f578ab |
   | VictorMono-ThinOblique.ttf       | 195624 | d940af2907afaffd31964f7988d6293404fb1834a91cf229442d57abcaa8f5ce |
   :end:

   #+call: update-checksums(replacements=victormono-csums)

   Deploy to S3

   #+begin_src bash :dir ../tmp :var dryrun="--dryrun"
     aws s3 $dryrun sync --no-progress --exclude '*' --include 'VictorMono/*.ttf' --acl public-read . 's3://orgro/assets/fonts/'
   #+end_src

** Custom Iosevka

   Download

   #+begin_src bash :dir ../..
     git clone --depth 1 https://github.com/be5invis/Iosevka.git
   #+end_src

   System prerequisites: Install with MacPorts

   #+begin_src bash :dir /sudo::
     port install npm8 ttfautohint
   #+end_src

   Additional preparation and updating

   #+begin_src bash :dir ../../Iosevka
     set -e
     # Check out newest tag; see
     # https://stackoverflow.com/a/22857288/448068
     git fetch --tags
     tag=$(git describe --tags $(git rev-list --tags --max-count=1))
     git checkout $tag
     echo $tag
   #+end_src

   #+RESULTS:
   : v17.0.4

   Configuration: Tangle the following

   #+begin_src yaml :tangle ../../Iosevka/private-build-plans.toml
     [buildPlans.iosevka-orgro]      # <iosevka-custom> is your plan name
     family = "Iosevka Orgro"        # Font menu family name
     # spacing = "normal"               # Optional; Values: `normal`, `term`, `fontconfig-mono`, or `fixed`
     # serifs = "sans"                  # Optional; Values: `sans` or `slab`

     ###################################################################################################
     # Configure variants

     # Optional; Whether to inherit a `ss##` variant
     # [buildPlans.iosevka-custom.variants]
     # inherits = "ss01"

     # Optional; Configure single character's variant
     [buildPlans.iosevka-orgro.variants.design]
     # g = 'single-storey'
     asterisk = 'penta-low'

     # Optional; Configure single character's variant for Upright and Oblique; Overrides [design]
     # [buildPlans.iosevka-custom.variants.upright]
     # i = 'zshaped'
     # l = 'zshaped'

     # Optional; Configure single character's variant for Italic only; Overrides [design]
     # [buildPlans.iosevka-custom.variants.italic]
     # i = 'tailed-serifed'
     # l = 'tailed-serifed'

     # End variant section
     ###################################################################################################

     ###################################################################################################
     # Configure ligations

     # [buildPlans.iosevka-custom.ligations]
     # inherits = "default-calt"   # Optional; inherits an existing ligation set
     # disables = []               # Optional; disable specific ligation groups, overrides inherited ligation set
     # enables  = []               # Optional; enable specific ligation groups, overrides inherited ligation set

     # End ligation section
     ###################################################################################################


     ###################################################################################################
     # Override default building weights
     # When buildPlans.<plan name>.weights is absent, all weights would built and mapped to
     # default values.
     # IMPORTANT : Currently "menu" and "css" property only support numbers between 0 and 1000.
     #             and "shape" properly only supports number between 100 and 900 (inclusive).
     #             If you decide to use custom weights you have to define all the weights you
     #             plan to use otherwise they will not be built.
     [buildPlans.iosevka-orgro.weights.regular]
     shape = 400  # Weight for glyph shapes.
     menu  = 400  # Weight for the font's names.
     css   = 400  # Weight for webfont CSS.

     # [buildPlans.iosevka-custom.weights.book]
     # shape = 450
     # menu  = 450  # Use 450 here to name the font's weight "Book"
     # css   = 450

     [buildPlans.iosevka-orgro.weights.bold]
     shape = 700
     menu  = 700
     css   = 700

     # End weight section
     ###################################################################################################

     ###################################################################################################
     # Override default building slope sets
     # When this section is absent, all slopes would be built.

     [buildPlans.iosevka-orgro.slopes.upright]
     angle = 0             # Angle in degrees. Valid range [0, 15]
     shape = "upright"     # Slope grade used for shape selection.  `upright` | `oblique` | `italic`
     menu  = "upright"     # Slope grade used for naming.           `upright` | `oblique` | `italic`
     css   = "normal"      # Slope grade used for webfont CSS.      `normal`  | `oblique` | `italic`

     # [buildPlans.iosevka-custom.slopes.oblique]
     # angle = 9.4
     # shape = "oblique"
     # menu  = "oblique"
     # css   = "oblique"

     [buildPlans.iosevka-orgro.slopes.italic]
     angle = 9.4
     shape = "italic"
     menu  = "italic"
     css   = "italic"
     # End slope section
     ###################################################################################################

     ###################################################################################################
     # Override default building widths
     # When buildPlans.<plan name>.widths is absent, all widths would built and mapped to
     # default values.
     # IMPORTANT : Currently "shape" property only supports numbers between 434 and 664 (inclusive),
     #             while "menu" only supports integers between 1 and 9 (inclusive).
     #             The "shape" parameter specifies the unit width, measured in 1/1000 em. The glyphs'
     #             width are equal to, or a simple multiple of the unit width.
     #             If you decide to use custom widths you have to define all the widths you plan to use,
     #             otherwise they will not be built.

     [buildPlans.iosevka-orgro.widths.normal]
     shape = 500        # Unit Width, measured in 1/1000 em.
     menu  = 5          # Width grade for the font's names.
     css   = "normal"   # "font-stretch' property of webfont CSS.

     # [buildPlans.iosevka-custom.widths.extended]
     # shape = 600
     # menu  = 7
     # css   = "expanded"

     # End width section
     ###################################################################################################

     ###################################################################################################
     # Character Exclusion
     # Specify character ranges in the section below to exclude certain characters from the font being
     # built. Remove this section when this feature is not needed.

     # [buildPlans.iosevka-custom.exclude-chars]
     # ranges = [[10003, 10008]]

     # End character exclusion
     ###################################################################################################

     ###################################################################################################
     # Compatibility Ligatures
     # Certain applications like Emacs does not support proper programming liagtures provided by
     # OpenType, but can support ligatures provided by PUA codepoints. Therefore you can edit the
     # following section to build PUA characters that are generated from the OpenType ligatures.
     # Remove this section when compatibility ligatures are not needed.

     # [[buildPlans.iosevka-custom.compatibility-ligatures]]
     # unicode = 57600 # 0xE100
     # featureTag = 'calt'
     # sequence = '<*>'

     # End compatibility ligatures section
     ###################################################################################################

     ###################################################################################################
     # Metric overrides
     # Certain metrics like line height (leading) could be overridden in your build plan file.
     # Edit the values to change the metrics. Remove this section when overriding is not needed.

     # [buildPlans.iosevka-custom.metric-override]
     # leading = 1250
     # winMetricAscenderPad = 0
     # winMetricDescenderPad = 0
     # powerlineScaleY = 1
     # powerlineScaleX = 1
     # powerlineShiftY = 0
     # powerlineShiftX = 0

     # End metric override section
     ###################################################################################################
   #+end_src

   Build

   #+begin_src bash :dir ../../Iosevka :async
     npm install
     npm run clean
     npm run build -- ttf::iosevka-orgro
   #+end_src

   Checksum

   #+name: iosevka-csums
   #+begin_src bash :dir ../../Iosevka/dist/iosevka-orgro/ttf :results table replace
     for ttf in *.ttf; do
         echo $ttf $(stat -f '%z' $ttf) $(openssl sha256 $ttf | cut -d '=' -f 2)
     done
   #+end_src

   #+RESULTS: iosevka-csums
   | iosevka-orgro-bold.ttf       | 6005168 | 7b56a94572c2557e6c0db37867f98d5d69eacc873d5328be8ee978a2c10eb5bb |
   | iosevka-orgro-bolditalic.ttf | 6215328 | f6a77ef8616af206d9826cd57cc8c484b8666eef4d8f45ce8ce6a0903e74bad8 |
   | iosevka-orgro-italic.ttf     | 6203064 | a4ec0349e2638912b011f14aca42f70ff1fdb6ef99e584c0fe5df376578cd69c |
   | iosevka-orgro-regular.ttf    | 5979432 | 42c0c00879761260ffe56e1ad4f949796699f77b3ed3b374ae77893c0d8d18a9 |

   #+call: update-checksums(replacements=iosevka-csums)

   Deploy to S3

   #+begin_src bash :dir ../../Iosevka :var dryrun="--dryrun"
     ver=$(git describe --tags)
     aws s3 $dryrun sync --no-progress --exclude '*' --include 'ttf/*' --acl public-read \
         dist/iosevka-orgro "s3://orgro/assets/fonts/iosevka-orgro-$ver/"
   #+end_src

** Updating sizes and checksums

   #+name: old-csums
   #+begin_src bash :results output table
     git show HEAD:./custom-fonts.org | grep "^ *|.*|.*| *$" | tr -d '|'
   #+end_src

   #+name: update-checksums
   #+header: :var target="../lib/src/fonts.dart" needles=old-csums
   #+header: :var replacements=()
   #+begin_src ruby :results output
     File.open(target, 'r+') do |out|
       text = out.read
       replacements.each do |filename, size, csum|
         _, old_size, old_csum = needles.assoc(filename)
         next unless old_size && old_csum

         unless size == old_size
           puts "#{filename}: #{old_size} -> #{size}"
           text.gsub!(old_size.to_s) { |_| size.to_s }
         end
         unless csum == old_csum
           puts "#{filename}: #{old_csum} -> #{csum}"
           text.gsub!(old_csum) { |_| csum }
         end
       end

       out.rewind
       out.write(text)
       out.truncate(out.pos)
     end
   #+end_src
