{"id":13472089,"url":"https://github.com/zachleat/glyphhanger","last_synced_at":"2025-03-26T15:31:23.563Z","repository":{"id":44089752,"uuid":"345755429","full_name":"zachleat/glyphhanger","owner":"zachleat","description":"Your web font utility belt. It can subset web fonts. It can find unicode-ranges for you automatically. It makes julienne fries.","archived":false,"fork":true,"pushed_at":"2024-02-22T22:55:39.000Z","size":445,"stargazers_count":743,"open_issues_count":22,"forks_count":21,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-25T13:12:36.623Z","etag":null,"topics":["font","glyphs","spider","subset","subsetting","unicode","web-fonts","webfonts"],"latest_commit_sha":null,"homepage":"https://www.zachleat.com/web/glyphhanger/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"filamentgroup/glyphhanger","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zachleat.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-08T18:29:07.000Z","updated_at":"2024-10-23T22:21:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zachleat/glyphhanger","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachleat%2Fglyphhanger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachleat%2Fglyphhanger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachleat%2Fglyphhanger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachleat%2Fglyphhanger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zachleat","download_url":"https://codeload.github.com/zachleat/glyphhanger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222151628,"owners_count":16939423,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["font","glyphs","spider","subset","subsetting","unicode","web-fonts","webfonts"],"created_at":"2024-07-31T16:00:51.822Z","updated_at":"2024-10-30T02:31:25.810Z","avatar_url":"https://github.com/zachleat.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Web Typography"],"sub_categories":["Component API's"],"readme":"# glyphhanger\n\nYour 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.\n\n## Installation\n\nAvailable on [npm](https://www.npmjs.com/package/glyphhanger).\n\n```sh\nnpm install -g glyphhanger\n```\n\n### Prerequisite: `pyftsubset`\n\nSee [https://github.com/fonttools/fonttools](https://github.com/fonttools/fonttools).\n\n```sh\npip install fonttools\n```\n\n```sh\n# Additional installation for --flavor=woff2\npip install brotli\n\n# Additional installation for --flavor=woff --with-zopfli\npip install zopfli\n```\n\nIf 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](https://www.sarasoueidan.com/blog/glyphhanger/) by Sara Soueidan.\n\n## Usage\n\n_Related: operate on existing `unicode-range` values with [Unicode Range Interchange](https://www.zachleat.com/unicode-range-interchange/) ([read the blog post](https://www.zachleat.com/web/unicode-range-interchange/))._\n\n### Find the glyphs in a local file or url\n\n```sh\n# local file\nglyphhanger ./test.html\nglyphhanger ./test.txt\n\n# output characters instead of Unicode code points\nglyphhanger ./test.html --string\n\n# remote URL\nglyphhanger http://example.com\n\n# multiple URLs, optionally using HTTPS\nglyphhanger https://google.com https://www.zachleat.com\n\n# show results for each font-family on the page\nglyphhanger ./test.html --json\n\n# show results only for one or more font-family names\nglyphhanger ./test.html --family='Open Sans, Roboto'\n\n# Show version\nglyphhanger --version\n\n# See more usage\nglyphhanger --help\n```\n\n### Debug Mode\n\nReplaces `--verbose` in `v3.0.0`.\n\n```sh\n\u003e DEBUG=glyphhanger* glyphhanger http://example.com\n```\n\n### Subset font files automatically\n\nUse `--subset=*.ttf` to select some font files for subsetting. Note that you can also [subset yourself manually with `pyftsubset`](docs/manual-subset.md) (but glyphhanger is easier).\n\n_Note that the `DEBUG` output documented above will log the specific `pyftsubset` command that `glyphhanger` used. Read more [about `pyftsubset` defaults](https://github.com/filamentgroup/glyphhanger/issues/49)._\n\n#### Just make optimized TTF/WOFF/WOFF2 files\n\n```sh\n\u003e glyphhanger --subset=*.ttf\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 70.25 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 36.51 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 28.73 KB)\n```\n\n#### Subset to specific characters only (no URLs)\n\n```sh\n\u003e glyphhanger --whitelist=ABCD --subset=*.ttf\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 4.42 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 2.84 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)\n```\n\n#### Subset to the glyphs at a URL\n\n```sh\n\u003e glyphhanger ./test.html --subset=*.ttf\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 24 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 14.34 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 11.37 KB)\n```\n\n#### Subset to the glyphs at a URL only using content that matches a specific font-family\n\n```sh\n\u003e glyphhanger ./test.html --subset=*.ttf --family='Lato,sans-serif'\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.ttf (was 145.06 KB, now 24 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.zopfli.woff (was 145.06 KB, now 14.34 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 11.37 KB)\n```\n\n#### Specify the formats to output\n\nAvailable formats: `ttf,woff,woff-zopfli,woff2`.\n\n```sh\n\u003e glyphhanger --whitelist=ABCD --formats=woff2,woff --subset=*.ttf\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff (was 145.06 KB, now 2.88 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)\n```\n\n#### Output a @font-face block with `--css`\n\nBecause 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.\n\n```sh\n\u003e glyphhanger --whitelist=ABCD --formats=woff2,woff --subset=*.ttf --css\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff (was 145.06 KB, now 2.88 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)\nWriting CSS file: LatoLatin-Regular.css\n\n@font-face {\n  font-family: LatoLatin;\n  src: url(sourcesanspro-regular-subset.woff2) format(\"woff2\"), url(sourcesanspro-regular-subset.woff) format(\"woff\");\n  unicode-range: U+41-44;\n}\n```\n\n#### Specify output directory for any files created with `--output`\n\n```sh\n\u003e glyphhanger --subset=*.ttf --output=some/other/path\n\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff (was 145.06 KB, now 2.88 KB)\nSubsetting LatoLatin-Regular.ttf to LatoLatin-Regular-subset.woff2 (was 145.06 KB, now 2.24 KB)\n```\n\n### Whitelist Characters\n\n```sh\n# Add in a whitelist of specific characters\nglyphhanger https://google.com --whitelist=abcdefgh\n\n# Add in a whitelist as a unicode range\nglyphhanger https://google.com --whitelist=U+26\n\n# shortcut to add in a whitelist of all of US-ASCII (with an optional whitelist)\nglyphhanger https://google.com --US_ASCII --whitelist=™\n\n# shortcut to add in a whitelist of all Latin characters (with an optional whitelist)\nglyphhanger https://google.com --LATIN --whitelist=™\n```\n\n#### Manual subsetting\n```sh\nglyphhanger --whitelist=ABCD --subset=*.ttf\n```\n\n#### Converting unicode ranges and back again\n\n```sh\n# Convert a string to a unicode-range\nglyphhanger --whitelist=ABCD\nglyphhanger --US_ASCII\nglyphhanger --US_ASCII --whitelist=ABCD\n\n# Convert a unicode-range to a string\nglyphhanger --whitelist=U+41-44 --string\n```\n\n### Use the spider to gather URLs from links\n\nFinds all the `\u003ca href\u003e` elements on the page with *local* (not external) links and adds those to the glyphhanger URLs. If you specify `--spider-limit`, `--spider` is assumed.\n\n```sh\nglyphhanger ./test.html --spider\nglyphhanger ./test.html --spider-limit\nglyphhanger ./test.html --spider-limit=10\n\n# No limit\nglyphhanger ./test.html --spider-limit=0\n```\n\nDefault `--spider-limit` is 10. Set to `0` for no limit. This will greatly affect how long the task takes.\n\n### Only search your page for visible text\n\nMake your output even smaller by only subsetting characters that are visible on the page.\n\n```sh\nglyphhanger ./test.html --onlyVisible\n```\n\n### Only search your page for text matching a CSS selector\n\nLimit results to text inside of elements that match a CSS selector\n\n```sh\nglyphhanger ./test.html --cssSelector=\"pre, #header, .popUp\"\n```\n\nIf paired with `--onlyVisible`, it will only return elements that are both visible and match the selector\n\n### Advanced: `jsdom` Mode ⚠️\n\nJSDOM 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.\n\nJSDOM mode will also be much faster when running against files on a local filesystem rather than URL targets.\n\nRead more about [the difference between JSDOM and a full headless browser](https://github.com/jsdom/jsdom/wiki/jsdom-vs.-PhantomJS) (like the default mode that glyphhanger uses: Puppeteer/headless Chrome).\n\n```sh\n# use faster jsdom mode instead of headless Chrome\nglyphhanger ./test.html --jsdom\n\n# jsdom mode works with standard input too\necho \"this is a test\" | glyphhanger --jsdom\n```\n\n## Troubleshooting\n\n* `glyphhanger` uses Puppeteer, the headless Chrome browser. Check out the [Puppeteer Troubleshooting documentation](https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch).\n\n## Testing\n\n`npm test` will run the tests.\n\nOr, alternatively `npx mocha`.\n\n## Enhancement Queue\n\n* [Top Voted Issues 👍](https://github.com/zachleat/glyphhanger/issues?q=label%3Aneeds-votes+sort%3Areactions-%2B1-desc)\n* Archived: [Voted Issues from `filamentgroup/glyphhanger`](https://github.com/filamentgroup/glyphhanger/issues?q=label%3Aneeds-votes+sort%3Areactions-%2B1-desc)\n\n## Alternatives to GlyphHanger\n\n* [unicode-ranger from Jeremy Wagner](https://github.com/malchata/unicode-ranger)\n* [subfont from Peter Müller](https://www.npmjs.com/package/subfont)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachleat%2Fglyphhanger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzachleat%2Fglyphhanger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachleat%2Fglyphhanger/lists"}