Your web font utility belt. It can subset web fonts. It can show you what unicode-ranges are used on a web site (optionally per font-family). It can also subset web fonts automatically using the unicode-ranges it found. It makes julienne fries.
Available on npm.
npm install -g glyphhanger
See https://github.com/fonttools/fonttools.
pip install fonttools
# Additional installation for --flavor=woff2
pip install brotli
# Additional installation for --flavor=woff --with-zopfli
pip install zopfli
If you want to read an in-depth tutorial on the installation steps above, please read How I set up Glyphhanger on macOS for optimizing and converting font files for the Web by Sara Soueidan.
Related: operate on existing unicode-range
values with Unicode Range Interchange (read the blog post).
# local file
glyphhanger ./test.html
glyphhanger ./test.txt
# output characters instead of Unicode code points
glyphhanger ./test.html --string
# remote URL
glyphhanger http://example.com
# multiple URLs, optionally using HTTPS
glyphhanger https://google.com https://www.zachleat.com
# show results for each font-family on the page
glyphhanger ./test.html --json
# show results only for one or more font-family names
glyphhanger ./test.html --family='Open Sans, Roboto'
# Show version
glyphhanger --version
# See more usage
glyphhanger --help
Replaces --verbose
in v3.0.0
.
> DEBUG=glyphhanger* glyphhanger http://example.com
Use --subset=*.ttf
to select some font files for subsetting. Note that you can also subset yourself manually with pyftsubset
(but glyphhanger is easier).
Note that the DEBUG
output documented above will log the specific pyftsubset
command that glyphhanger
used. Read more about pyftsubset
defaults.
> glyphhanger --subset=*.ttf
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 70.25 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 36.51 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 28.73 KB)
> glyphhanger --whitelist=ABCD --subset=*.ttf
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 4.42 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 2.84 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)
> glyphhanger ./test.html --subset=*.ttf
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 24 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 14.34 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 11.37 KB)
> glyphhanger ./test.html --subset=*.ttf --family='Lato,sans-serif'
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 24 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 14.34 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 11.37 KB)
Available formats: ttf,woff,woff-zopfli,woff2
.
> glyphhanger --whitelist=ABCD --formats=woff2,woff --subset=*.ttf
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff (was 145.06 KB, now 2.88 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)
Because we’re not parsing URLs for glyphs, we can optionally use --family='My Family Name'
to set the name used in the @font-face
block. Normally --family
would tell GlyphHanger to only parse text data from nodes using one of the fonts listed in --family
. Using --subset
and --css
together will write a CSS file, too.
> glyphhanger --whitelist=ABCD --formats=woff2,woff --subset=*.ttf --css
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff (was 145.06 KB, now 2.88 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)
Writing CSS file: LatoLatin-Regular.css
@font-face {
font-family: LatoLatin;
src: url(sourcesanspro-regular-subset.woff2) format("woff2"), url(sourcesanspro-regular-subset.woff) format("woff");
unicode-range: U+41-44;
}
> glyphhanger --subset=*.ttf --output=some/other/path
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff (was 145.06 KB, now 2.88 KB)
Subsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)
# Add in a whitelist of specific characters
glyphhanger https://google.com --whitelist=abcdefgh
# Add in a whitelist as a unicode range
glyphhanger https://google.com --whitelist=U+26
# shortcut to add in a whitelist of all of US-ASCII (with an optional whitelist)
glyphhanger https://google.com --US_ASCII --whitelist=™
# shortcut to add in a whitelist of all Latin characters (with an optional whitelist)
glyphhanger https://google.com --LATIN --whitelist=™
glyphhanger --whitelist=ABCD --subset=*.ttf
# Convert a string to a unicode-range
glyphhanger --whitelist=ABCD
glyphhanger --US_ASCII
glyphhanger --US_ASCII --whitelist=ABCD
# Convert a unicode-range to a string
glyphhanger --whitelist=U+41-44 --string
Finds all the <a href>
elements on the page with local (not external) links and adds those to the glyphhanger URLs. If you specify --spider-limit
, --spider
is assumed.
glyphhanger ./test.html --spider
glyphhanger ./test.html --spider-limit
glyphhanger ./test.html --spider-limit=10
# No limit
glyphhanger ./test.html --spider-limit=0
Default --spider-limit
is 10. Set to 0
for no limit. This will greatly affect how long the task takes.
Make your output even smaller by only subsetting characters that are visible on the page.
glyphhanger ./test.html --onlyVisible
Limit results to text inside of elements that match a CSS selector
glyphhanger ./test.html --cssSelector="pre, #header, .popUp"
If paired with --onlyVisible
, it will only return elements that are both visible and match the selector
JSDOM mode can be useful running against static pages that don’t use a lot of JavaScript generated content. While JSDOM mode can handle some JavaScript generated content, Puppeteer mode should be the safest method for most use cases.
JSDOM mode will also be much faster when running against files on a local filesystem rather than URL targets.
Read more about the difference between JSDOM and a full headless browser (like the default mode that glyphhanger uses: Puppeteer/headless Chrome).
# use faster jsdom mode instead of headless Chrome
glyphhanger ./test.html --jsdom
# jsdom mode works with standard input too
echo "this is a test" | glyphhanger --jsdom
glyphhanger
uses Puppeteer, the headless Chrome browser. Check out the Puppeteer Troubleshooting documentation.
npm test
will run the tests.
Or, alternatively npx mocha
.