An open API service indexing awesome lists of open source software.

https://github.com/fontist/fontist

Install openly-licensed fonts on Windows, Linux and Mac!
https://github.com/fontist/fontist

font font-installer

Last synced: 2 months ago
JSON representation

Install openly-licensed fonts on Windows, Linux and Mac!

Awesome Lists containing this project

README

        

= Fontist

image:https://github.com/fontist/fontist/actions/workflows/test-and-release.yml/badge.svg["Build Status", link="https://github.com/fontist/fontist/actions/workflows/test-and-release.yml"]
image:https://img.shields.io/gem/v/fontist.svg["Gem Version", link="https://rubygems.org/gems/fontist"]
image:https://img.shields.io/github/issues-pr-raw/fontist/fontist.svg["Pull Requests", link="https://github.com/fontist/fontist/pulls"]

A simple library to find and download fonts for Windows, Linux and Mac.

:toc:

== Installation

Install it directly as:

[source,sh]
----
gem install fontist
----

Or use it as part of your bundle by adding this line to your application's
`Gemfile`:

[source,ruby]
----
gem "fontist"
----

And then execute:

[source,sh]
----
bundle install
----

=== Fetch formulas

After installation, please fetch formulas via the `fontist` command:

[source,sh]
----
fontist update
----

=== Dependencies

Depends on
https://github.com/fontist/ffi-libarchive-binary[ffi-libarchive-binary] which
has the following requirements:

* zlib
* Expat
* OpenSSL (for Linux only)

These dependencies are generally present on all systems.

== Using the command-line interface (CLI)

=== The `fontist` command

These commands makes possible to operate with fonts via command line.

The CLI properly supports exit status, so in a case of error it returns a status
code higher or equal than `1`.

Searches are case-insensitive for ease of use.

All commands support the following global options:

`--preferred-family`:: Search using the "`preferred family`" name of a font.
(instead of the "`default family`" name, the default prior to Fontist v1.10.)

NOTE: See <> for the differences between
"`preferred family`" and "`default family`".

`-q, --quiet`:: Print as little information as possible, mostly critical errors.

`-v, --verbose`:: Set the log level to debug. It prints formulas excluded
during installation and information for developers of fontist.

`-c, --no-cache`:: Prefer direct download even when a file is already cached in
a system.

=== Install fonts: `fontist install`

Fontist checks whether this font is already installed, and if not, then installs
the font and returns its installed paths.

The font name is the only argument to be supplied.

[source,sh]
----
$ fontist install "segoe ui"
These fonts are found or installed:
- /Users/user/.fontist/fonts/SEGOEUI.TTF
- /Users/user/.fontist/fonts/SEGOEUIB.TTF
- /Users/user/.fontist/fonts/SEGOEUII.TTF
- /Users/user/.fontist/fonts/SEGOEUIZ.TTF
----

By default, all matching styles (according to the font's "`default family`" name)
are installed.

NOTE: Prior to v1.10, the font's "`preferred family`" name is used to match
styles for search. See <> for details of that change.

To install all fonts specified in a Fontist formula, use the `-F, --formula`
option.

[source,sh]
----
$ fontist install --formula 'courier_prime'
Downloading font ...
Installing font "courier_prime".
Fonts installed at:
- /Users/user/.fontist/fonts/Courier Prime Bold Italic.ttf
- /Users/user/.fontist/fonts/Courier Prime Bold.ttf
- /Users/user/.fontist/fonts/Courier Prime Italic.ttf
- /Users/user/.fontist/fonts/Courier Prime.ttf
----

Here, `courier_prime` is the filename of the formula located at the public
Fontist Formula repository
(https://github.com/fontist/formulas/blob/v3/Formulas/courier_prime.yml[`courier_prime.yml`]).

You can also specify the human-readable name of the formula. This name is
derived from the filename, with underscores replaced by spaces. It's not
case-sensitive, meaning you can use capital letters if you prefer.

[source,sh]
----
$ fontist install --formula "Courier Prime"
$ fontist install --formula "Google/Noto Sans"
----

Installation by the formula name supports suggestions in CLI when input is
partial:

[source,sh]
----
$ fontist install --formula 'noto s'
Formula 'noto s' not found. Did you mean?
[0] Google/Noto Sans
[1] Google/Noto Serif
Please type number or press ENTER to skip installation:
----

NOTE: Specifying the font's filename is not supported yet.

If there are several formulas with a requested font, then `fontist` searches
for the newest version of the font among formulas with size below a limit
(300 MB). This behavior can be changed with options.

NOTE: If styles of a font are spread among several formulas, then all
available styles from all formulas would be installed.

NOTE: Some formulas may have the `min_fontist` attribute, which defines the
minimum version of fontist by which they can be installed. If `fontist` is of a
older version, then the formula is avoided to use. In order to see which
formulas were excluded from the search, the `-v, --verbose` option can be
specified.

Supported options:

`-f, [--force]`:: Install even if already installed in system
`-F, [--formula]`:: Install whole formula instead of a font
`-a, [--accept-all-licenses]`:: Accept all license agreements
`-h, [--hide-licenses]`:: Hide license texts
`-p, [--no-progress]`:: Hide download progress
`-V, [--version=VERSION]`:: Install particular version of a font
`-s, [--smallest]`:: Install the smallest font by file size if several
`-n, [--newest]`:: Install the newest version of a font if several
`-S, [--size-limit=N]`:: Specify upper limit for file size of a formula to be installed
(default is 300 MB)
`-u, [--update-fontconfig]`:: Update Fontconfig

NOTE: The `install` command is similar to the `Font.install` library call.

=== Uninstall fonts: `fontist uninstall`

Uninstalls any font supported by Fontist.

Returns paths of an uninstalled font, or prints an error telling that the font
isn't installed or could not be found in Fontist formulas. Aliased as `remove`.

[source,sh]
----
$ fontist uninstall "segoe ui"
These fonts are removed:
/Users/user/.fontist/fonts/SEGOEUII.TTF
/Users/user/.fontist/fonts/SEGOEUIZ.TTF
/Users/user/.fontist/fonts/SEGOEUIB.TTF
/Users/user/.fontist/fonts/SEGOEUI.TTF
----

=== Status: `fontist status`

Prints installed font paths with a corresponding formula.

[source,sh]
----
$ fontist status "segoe ui"
Fonts found at:
- /Users/user/.fontist/fonts/SEGOEUII.TTF (from segoe_ui formula)
- /Users/user/.fontist/fonts/SEGOEUIZ.TTF (from segoe_ui formula)
- /Users/user/.fontist/fonts/SEGOEUIB.TTF (from segoe_ui formula)
- /Users/user/.fontist/fonts/SEGOEUI.TTF (from segoe_ui formula)
----

=== List: `fontist list`

Lists installation status of fonts supported by Fontist.

[source,sh]
----
$ fontist list "segoe ui"
segoe_ui
Segoe UI
Regular (installed)
Bold (installed)
Italic (installed)
Bold Italic (installed)
----

[source,sh]
----
$ fontist list "roboto mono"
google/roboto_mono
Roboto Mono
Regular (not installed)
Italic (not installed)
----

=== List installed font paths: `fontist manifest-locations`

Returns locations of fonts specified in a YAML file as an input.

[source,sh]
----
$ fontist manifest-locations MANIFEST_FILE
----

`MANIFEST_FILE` is the location of a manifest file that contains specification
of one or multiple font and font styles.

A manifest file `manifest.yml` could look like:
====
[source,yml]
----
Segoe UI:
- Regular
- Bold
Roboto Mono:
- Regular
----
====

The following command will return the following YAML output:

[source,sh]
----
$ fontist manifest-locations manifest.yml
----

[source,yml]
----
---
Segoe UI:
Regular:
full_name: Segoe UI
paths:
- "/Users/user/.fontist/fonts/SEGOEUI.TTF"
Bold:
full_name: Segoe UI Bold
paths:
- "/Users/user/.fontist/fonts/SEGOEUIB.TTF"
Roboto Mono:
Regular:
full_name: Roboto Mono Regular
paths:
- "/Users/user/.fontist/fonts/RobotoMono-VariableFont_wght.ttf"
----

If one or more of requested fonts are missing, the "3" error code would be
returned, and a message printed:

[source,sh]
----
$ fontist manifest-locations manifest.yml
'Roboto Mono' 'Regular' font is missing, please run `fontist install 'Roboto Mono'` to download the font.
$ echo $?
3
----

=== Install fonts from manifest: `fontist manifest-install`

Install fonts from a YAML Fontist manifest:

[source,sh]
----
$ fontist manifest-install --confirm-license manifest.yml
----

Where `manifest.yaml` is:

[source,yml]
----
---
Segoe UI:
Regular:
full_name: Segoe UI
paths:
- "/Users/user/.fontist/fonts/SEGOEUI.TTF"
Bold:
full_name: Segoe UI Bold
paths:
- "/Users/user/.fontist/fonts/SEGOEUIB.TTF"
Roboto Mono:
Regular:
full_name: Roboto Mono Regular
paths:
- "/Users/user/.fontist/fonts/RobotoMono-VariableFont_wght.ttf"
----

=== Work with fontist config: `fontist config`

Fontist supports system-wide settings for the following parameters:

`fonts_path`:: Sets path where to install fonts (default: `~/.fontist/fonts`)

`open_timeout`:: Sets timeout for opening a connection during download
(default: `10`)

`read_timeout`:: Sets timeout for reading the opened connection during download
(default: `10`)

Show current attributes in the config:

[source,sh]
----
$ fontist config show
Current config:
read_timeout: 5
----

Assign a value to an attribute:

[source,sh]
----
$ fontist config set read_timeout 60
----

Restore a default value of an attribute:

[source,sh]
----
$ fontist config delete read_timeout
----

=== Work with Fontconfig: `fontist fontconfig`

Fontconfig is a software designed to provide fonts to other programs. It is
typically used on Linux, but also available on macOS and Windows. Fontconfig is
used by LibreOffice, GIMP, and many other programs.

It order to find fontist fonts, Fontconfig should be updated to include fontist
paths. It can be done with the `--update-fontconfig` option of the `install`
command, or by calling a special one:

[source,sh]
----
$ fontist fontconfig update
----

It would create a config in `~/.config/fontconfig/conf.d/10-fontist.conf`.

To remove it, please use:

[source,sh]
----
$ fontist fontconfig remove
----

=== Work with cache

[source,sh]
----
$ fontist cache clear
----

The command above will clear fontist's download cache

=== Help: `fontist help`

List of all commands could be seen by:

[source,sh]
----
fontist help
----

=== Configuration with environment variables

By default Fontist uses the `~/.fontist` directory to store fonts and its
files. It could be changed with the `FONTIST_PATH` environment variable.

[source,sh]
----
FONTIST_PATH=~/.fontist_new fontist update
----

== Using the Ruby library

=== `Fontist::Font`

The `Fontist::Font` is your go-to place to deal with any font using Fontist.

This interface allows you to find a font or install a font.

==== Finding a font

The `Fontist::Font.find` interface can be used a find a font in your system.

It will look into the operating system specific font directories, and also the
fontist specific `~/.fontist` directory.

[source,ruby]
----
Fontist::Font.find(name)
----

* If Fontist finds a font, then it will return the paths.

* Otherwise, it will either raise an unsupported font error, or trigger display
of installation instructions for that specific font.

==== Install a font

The `Fontist::Font.install` interface can be used to install any supported font.

This interface first checks if you already have that font installed or not and
if you do then it will return the paths.

If you don't have a font but that font is supported by Fontist, then it will
download the font and copy it to `~/.fontist` directory and also return the
paths.

[source,ruby]
----
Fontist::Font.install(name, confirmation: "no")
----

If there are issues detected with the provided font, such as the font is not
supported, those errors would be raised.

==== List all fonts

The `Fontist::Font` interface exposes an interface to list all supported fonts.

This might be useful if want to know the name of the font or the available
styles. You can do that by using:

[source,ruby]
----
Fontist::Font.all
----

The return values are `OpenStruct` objects, so you can easily do any other
operation you would do in any ruby object.

=== `Fontist::Formula`

The `fontist` gem internally usages the `Fontist::Formula` interface to find a
registered formula or fonts supported by any formula. Unless, you need to do
anything with that you shouldn't need to work with this interface directly. But
if you do then these are the public interface it offers.

==== Find a formula

The `Fontist::Formula.find` interface allows you to find any of the registered
formula. This interface takes a font name as an argument and it looks through
each of the registered formula that offers this font installation. Usages:

[source,ruby]
----
Fontist::Formula.find("Calibri")
----

This method will search and return a Fontist formula for the provided keyword
which allows for further processing, such as license checks or proceeding with
installation of the font in your system.

==== List font styles supported by a formula

Normally, each font name can be associated with multiple styles or collection,
for example the `Calibri` font might contains a `regular`, `bold` or `italic`
styles fonts and if you want a interface that can return the complete list then
this is your friend.

You can use it as following:

[source,ruby]
----
Fontist::Formula.find_fonts("Calibri")
----

==== List all formulas

The `Fontist::Formula` interface exposes an interface to list all registered
font formula. This might be useful if want to know the name of the formula or
what type fonts can be installed using that formula. Usages:

[source,ruby]
----
Fontist::Formula.all
----

The return values are `OpenStruct` objects, so you can easily do any other
operation you would do in any ruby object.

=== `Fontist::Manifest`

==== Global options

Fontist can be switched to use the preferred family names. This format was
used prior to v1.10.

[source,ruby]
----
Fontist.preferred_family = true
----

[[fontist-locations]]
==== `Fontist::Manifest::Locations`

Fontist lets you find font locations from a defined manifest Hash in the
following format:

[source,ruby]
----
{
"Segoe UI"=>["Regular", "Bold"],
"Roboto Mono"=>["Regular"]
}
----

Calling the following code returns a nested Hash with font paths and names.
Font name is useful to choose a specific font in a font collection file (TTC).

[source,ruby]
----
Fontist::Manifest::Locations.from_hash(manifest)
----

[source,ruby]
----
{
"Segoe UI"=> {
"Regular"=>{
"full_name"=>"Segoe UI",
"paths"=>["/Users/user/.fontist/fonts/SEGOEUI.TTF"]
},
"Bold"=>{
"full_name"=>"Segoe UI Bold",
"paths"=>["/Users/user/.fontist/fonts/SEGOEUIB.TTF"]
}
},
"Roboto Mono"=> {
"Regular"=>{
"full_name"=>nil,
"paths"=>[]
}
}
}
----

[[fontist-install]]
==== `Fontist::Manifest::Install`

Fontist lets you not only to obtain font locations but also to install fonts
from the manifest:

[source,ruby]
----
Fontist::Manifest::Install.from_hash(manifest, confirmation: "yes")
----

It will install fonts and return their locations:

[source,ruby]
----
{
"Segoe UI"=> {
"Regular"=>{
"full_name"=>"Segoe UI",
"paths"=>["/Users/user/.fontist/fonts/SEGOEUI.TTF"]},
"Bold"=>{
"full_name"=>"Segoe UI Bold",
"paths"=>["/Users/user/.fontist/fonts/SEGOEUIB.TTF"]
}
},
"Roboto Mono"=> {
"Regular"=>{
"full_name"=>"Roboto Mono Regular",
"paths"=>["/Users/user/.fontist/fonts/RobotoMono-VariableFont_wght.ttf"]
}
}
}
----

==== Support of YAML format

Both commands support a YAML file as an input with a `from_file` method. For
example, if there is a `manifest.yml` file containing:

[source,yaml]
----
---
Segoe UI:
- Regular
- Bold
Roboto Mono:
- Regular
----

Then the following calls would return font names and paths, as from the
`from_hash` method (see <> and <>).

[source,ruby]
----
Fontist::Manifest::Locations.from_file("manifest.yml")
Fontist::Manifest::Install.from_file("manifest.yml", confirmation: "yes")
----

=== `Fontist::Fontconfig`

Fontist supports work with Fontconfig via the Ruby interface:

[source,ruby]
----
Fontist::Fontconfig.update # let detect fontist fonts
Fontist::Fontconfig.remove # disable detection
Fontist::Fontconfig.remove(force: true) # do not fail if no config exists
----

== Platform-specific features

=== macOS-specific add-on fonts

Newer versions of macOS provide on-demand installations of a wide range of
licensed fonts. These macOS-specific add-on fonts can be installed via Fontist.

A typical use for installing macOS add-on fonts is to allow CI jobs on
macOS environments to use these specially-licensed fonts not available on other
platforms.

This blog post describes how this works:

* https://www.fontist.org/blog/2022-02-11-macos-fonts/[Fontist blog: Installing macOS-specific add-on fonts]

For example, the "Canela" font is a commercial font that comes free with macOS.

Run this command to install Canela on macOS.

[source,sh]
----
$ fontist install Canela
----

The full list of available fonts on various macOS versions can be found on the
Apple Support site:

* https://support.apple.com/en-us/HT213266[Fonts in macOS 13 Ventura]
* https://support.apple.com/en-us/HT212587[Fonts in macOS 12 Monteray]
* https://support.apple.com/en-in/HT211240[Fonts in macOS 11 Big Sur]

WARNING: Fontist does not allow installing macOS-specific fonts on non-macOS
platforms due to font license restrictions of those fonts.

=== Known problematic fonts

* NISC18030.ttf (GB18030 Bitmap) - macOS, more info in
https://github.com/fontist/fontist/issues/344[the NISC18030 issue]

The full list of known problematic fonts:

* https://github.com/fontist/fontist/blob/main/lib/fontist/exclude.yml[List of fonts excluded from usage]

== Advanced usage

=== Using proxy servers

Fontist uses Git internally for fetching formulas and fonts.

In order to use Git functionality behind a proxy, you need to update your own
Git config via the `git config` command or the `~/.gitconfig` preference file.

There are many ways to configure your local Git install to use proxies.

The simplest, global way of setting a proxy for Git is the following.

* For HTTP
+
[source,sh]
----
git config --global http.proxy http://{user}:{pass}@{proxyhost}:{port}
----

* For HTTPS, you may need to handle SSL/TLS verification errors after setting
the proxy since the encryption end is located at your HTTPS proxy endpoint:
+
[source,sh]
----
git config --global http.proxy https://{user}:{pass}@{proxyhost}:{port}
git config --global https.proxy https://{user}:{pass}@{proxyhost}:{port}
----

* For SOCKS, you will need to decide on the SOCKS protocol
+
[source,sh]
----
git config --global http.proxy '{protocol}://{user}:{pass}@{proxyhost}:{port}'
git config --global https.proxy '{protocol}://{user}:{pass}@{proxyhost}:{port}'
----
+
For example,
+
[source,sh]
----
git config --global http.proxy 'socks5h://user:[email protected]'
git config --global https.proxy 'socks5h://user:[email protected]'
----

The list of supported SOCKS protocols for the `{protocol}` field:

* `socks://`: for SOCKS below v5
* `socks5://`: for SOCKS v5
* `socks5h://`: for SOCKS below v5 + host resolution via SOCKS

You could actually set different proxy behavior for individual Git repositories
-- please see this
https://gist.github.com/evantoli/f8c23a37eb3558ab8765[great guide]
on how to use Git proxies (thanks to the GitHub user
https://github.com/evantoli[evantoli]).

== Custom Fontist repositories

=== General

A Fontist repository is a Git repo which contains YAML Formula files.
Fontist Formulas can be created manually within a Fontist repository
(see https://github.com/fontist/formulas/tree/master/Formulas[examples]),
or <>.

A Fontist repository can be accessed either through HTTPS or SSH. In case of
SSH, a corresponding SSH key should be setup with `ssh-agent` in order to access
this custom repository.

=== Registering a Fontist repository

The `fontist repo setup` command fetches a custom repository's formulas, and
stores the repository's name and URL for later use.

The `fontist repo setup` command uses the following syntax.

[source,sh]
----
fontist repo setup NAME URL
----

Internally, all custom Fontist repository information is stored at
`~/.fontist/formulas/Formulas/private`.

For example, given a Fontist repository called "acme" accessible via a
URL or an SSH address:

[source,sh]
----
fontist repo setup acme https://example.com/acme/formulas.git
# or
fontist repo setup acme [email protected]:acme/formulas.git
----

=== Listing custom Fontist repositories

[source,sh]
----
fontist repo list
----

=== Installing fonts from a Fontist repository

Once the custom Fontist repository is setup, one can install fonts from the
repo through its formulas:

[source,sh]
----
fontist install "custom font"
----

=== Updating a registered Fontist repository

If the custom Fontist formula repository is updated, the `repo update` command
is used to pull the newest changes:

[source,sh]
----
fontist repo update NAME
----

For example, given a Fontist repository called "acme", the following command
is used.

[source,sh]
----
fontist repo update acme
----

=== Removing a registered Fontist repository

If there is a need to remove a registered Fontist repository, the repo can be
removed with:

[source,sh]
----
fontist repo remove acme
----

=== Private access

Custom Fontist formulas and Fontist repositories can be made private to require
authentication.

For HTTPS and SSH Git Fontist repositories

=== Authentication for private formulas or private formula repositories

Authorization of private archives in private formulas can be implemented with
headers.

Here is an example which works with Github releases:

[source,yaml]
----
resources:
fonts.zip:
urls:
- url: https://example.com/repos/acme/formulas/releases/assets/38777461
headers:
Accept: application/octet-stream
Authorization: token ghp_1234567890abcdefghi
----

If the Fontist formula repository is a GitHub repo, a token can be obtained on
the https://github.com/settings/tokens[GitHub Settings > Tokens page].
This token should have at least the `repo` scope for access to these assets.

[[create-formula]]
=== Create Fontist formulas

==== General

Fontist formulas can be easily hand-crafted in YAML. However, the
auto-generation method is recommended for data accuracy and convenience.

==== Auto-generate a Fontist formula from a font archive

A formula could be generated from a fonts archive.

The `fontist create-formula` command allows detecting all font files from a
font archive in a multitude of formats (those supported by
https://github.com/fontist/excavate[Excavate], including zip, 7z, gzip, tar,
cab, exe).

The `fontist create-formula` command supports archives located at remote URLs or
local file paths.

For file paths, specify the file path as argument:

[source,sh]
----
wget https://www.latofonts.com/files/Lato2OFL.zip
fontist create-formula lato.zip
----

For URLs, simply specify the URL as the argument:

[source,sh]
----
fontist create-formula https://www.latofonts.com/files/Lato2OFL.zip
# > file created at lato.yml because the file downloaded is lato.zip
----

To test out the created formula, one may copy the formula into the user's
private formula repository location.

[source,sh]
----
fontist create-formula https://www.latofonts.com/files/Lato2OFL.zip
cp lato.yml ~/.fontist/formulas/Formulas/
----

==== Overriding font metadata in Fontist formulas

The `fontist create-formula` command creates font formulas using information
embedded in the OTF metadata section.

However, some fonts (such as older fonts) often contain inconsistent or
imperfect metadata information. Some fonts for example applies different OTF
`Family` values for different font styles. This will result in all font styles
not being registered in the same Family.

Fontist formula authors can rectify this situation by using the `override:` key,
which allows the formula to override metadata information obtained from the font
metadata.

NOTE: The `override` key does not cause any change in the font files, it is only
for updating information used by Fontist internally.

The `override` key exists under the definition of individual font styles:

[source,yaml]
----
resources:
...
fonts:
- name: Original font name
styles:
- family_name: Original family name
type: Original style
override:
family_name: Overridden family name
type: Overridden style
preferred_family_name: Overridden preferred family name
----

For example, the "Frutiger" fonts published by Adobe in 1994 use numbers to
represent the individual font styles, and have those names embedded in the OTF
`Family` field, such as "Frutiger 45 Light". These fonts also do not use the OTF
`Preferred Family` field, which is a more recent addition to OTF, due to their
age.

Here is how the `override` property can enforce all relevant styles to be
registered under the same family name (by overriding the `preferred_family_name`
value):

[source,yaml]
----
...
resources:
...
fonts:
- name: Frutiger 45 Light
styles:
- family_name: Frutiger 45 Light
type: Regular
full_name: Frutiger-Light
post_script_name: Frutiger-Light
override:
preferred_family_name: Frutiger
- ...
----

This fragment above will allow Fontist to generate correct indexes and allow
installation of all `Frutiger` fonts with a single command:

[source,sh]
----
$ fontist install "Frutiger" --preferred-family
----

=== Upgrading Fontist

[[preferred-family-change]]
==== To v1.10+

Fontist versions beyond v1.10 utilize a new formula format.
After the upgrade, please run `fontist update` to fetch the latest formulas.

Starting from v1.10, Fontist uses the "`default family`" instead of the
"`preferred family`" when grouping styles.

For example, a request for the "`Lato`" font prior to v1.10 will return all
styles: "`Black`", "`Black Italic`", "`Bold`", and 15 other styles.

From v1.10 onwards, Fontist will return _only_ the 4 default styles:
"`Regular`", "`Italic`", "`Bold`" and "`Bold Italic`".

In order to fetch other styles, you have to specify the exact font
"`subfamily`", such as "`Lato Black`", or "`Lato Heavy`", or use
the `--preferred-family` option with CLI and `Fontist.preferred_family = true`
with the Ruby library.

NOTE: Prior to v1.10 there was a bug with the "`Courier`" font formula, which
allowed the font to be installed when requesting the font name "`Courier`", but
its font location was only obtainable using the full "`Courier New`" font name.
From v1.10 onwards the behavior has been made consistent -- only the proper
"`Courier New`" name should be used.

[[install-font-change]]
==== To v1.16+

Fontist versions beyond v1.16 treats the `font` argument of the `install`
command differently.
After the upgrade, please ensure all required fonts are specified when using
`fontist install`, `fontist manifest-install` (and their corresponding Ruby
interface `Font.install` and `Manifest::Install`), or use the `-F, --formula`
option.

Starting from v1.16, Fontist installs only requested fonts instead of a whole
formula, unless specified explicitly.
changed now.

For example, an installation request for the "`Arial`" font prior to v1.16 will
setup all fonts found in the "`ms_truetype`" formula: "`Arial`", "`Trebuchet
MS`", "`Verdana`" and "`Times New Roman`".

From v1.16 onwards, Fontist will install _only_ the requested "`Arial`" font.

To install all fonts from a formula, the `-F, --formula` option can be used:

[source,sh]
----
$ fontist install --formula ms_truetype
----

== Maintenance (for Fontist maintainers only!)

WARNING: This section is only for Fontist maintainers.

=== Formulas versioning

To add a new attribute, change how formula is treated or completely replace the structure, there are 2 ways to change a formula format:

1. Use the `min_fontist` attribute in a formula. It sets a requirement for fontist to install the formula only if its version is equal or more than a specified version.
2. Use a new branch in the formulas repo, e.g. "v2", "v3", "v4", etc. After creating a new branch, it should be defined in https://github.com/fontist/fontist/blob/v1.16.0/lib/fontist.rb#L51[`Fontist.formulas_version`]

NOTE: Using a new branch would require all users to re-download the entire formulas repo. Since this method has a significant overhead, the former one (`min_fontist`) should be used whenever possible.

=== Dynamically importing formulas from Google Fonts

https://fonts.google.com[Google Fonts] provides probably the largest collection
of widely-used, freely and openly licensed fonts.

Fontist's https://github.com/fontist/formulas[formula library] includes support
for all openly-licensed fonts provided through Google Fonts, and maintains
Fontist formulas for all such fonts.

https://github.com/fontist/formulas/blob/v4/.github/workflows/google.yml[A GHA
workflow] checks for updated fonts on Google Fonts daily. In case an update is
found, it's added to the repo by the workflow.

=== Dynamically importing formulas from SIL

https://www.sil.org[SIL International] is an internationally recognized
faith-based nonprofit organization that serves language communities worldwide.

SIL provides a number of unique fonts that support smaller language communities
that with Unicode code often not (yet) supported by mainstream fonts.

Fontist aims to support all https://software.sil.org/fonts/[SIL fonts] and
provides their formulas in the default Fontist formula repository.

They can be updated with:

[source,sh]
----
fontist import sil
cd ~/.fontist/versions/{last_version}/formulas
git add Formulas/sil
git commit -m "SIL fonts update"
git push
----

=== Dynamically importing formulas from macOS

macOS provides https://support.apple.com/en-om/HT211240#download[fonts] which
can be manually downloaded with `Font Book.app`.

To update macOS formulas:

[source,sh]
----
fontist import macos
cd ~/.fontist/versions/{last_version}/formulas
git add Formulas/macos
git commit -m "Update macOS formulas"
git push
----

== Development

=== Setup

Clone the repository.

[source,sh]
----
git clone https://github.com/fontist/fontist
----

Setup your environment.

[source,sh]
----
bin/setup
----

Run the test suite

[source,sh]
----
bin/rspec
----

=== Formula storage

All official Fontist formulas are kept in the
https://github.com/fontist/formulas[formulas] repository.

If you'd like to add a new formula repository or change settings for an existing
one, please refer to its documentation.

=== Releasing

Releasing is done automatically with GitHub Actions. Just bump and tag with
`gem-release`.

For a patch release (0.0.x) use:

[source,sh]
----
gem bump --version patch --tag --push
----

For a minor release (0.x.0) use:

[source,sh]
----
gem bump --version minor --tag --push
----

== Contributing

First, thank you for contributing! We love pull requests from everyone. By
participating in this project, you hereby grant https://www.ribose.com[Ribose]
the right to grant or transfer an unlimited number of non exclusive licenses or
sub-licenses to third parties, under the copyright covering the contribution to
use the contribution by all means.

We are following Sandi Metz's Rules for this gem, you can read the
http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers[description of the rules here].
All new code should follow these rules. If you make changes in a pre-existing
file that violates these rules you should fix the violations as part of your
contribution.

Here are a few technical guidelines to follow:

. Open an https://github.com/fontist/fontist/issues[issue] to discuss a new feature.
. Write tests to support your new feature.
. Make sure the entire test suite passes locally and on CI.
. Open a Pull Request.
. https://github.com/thoughtbot/guides/tree/master/protocol/git#write-a-feature[Squash your commits] after receiving feedback.
. Party!

== Credit

This gem is developed, maintained and funded by https://www.ribose.com[Ribose].