{"id":20828022,"url":"https://github.com/googlefonts/shaperglot","last_synced_at":"2025-05-07T21:06:41.248Z","repository":{"id":60013762,"uuid":"397294329","full_name":"googlefonts/shaperglot","owner":"googlefonts","description":"Test font files for language support","archived":false,"fork":false,"pushed_at":"2025-05-07T10:58:24.000Z","size":946,"stargazers_count":41,"open_issues_count":29,"forks_count":8,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-05-07T11:39:22.801Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/googlefonts.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.txt","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-08-17T14:51:59.000Z","updated_at":"2025-05-01T13:51:09.000Z","dependencies_parsed_at":"2024-01-10T17:44:07.928Z","dependency_job_id":"e17ca3cf-6607-46e6-8e16-08cc3e0a2963","html_url":"https://github.com/googlefonts/shaperglot","commit_stats":null,"previous_names":["simoncozens/shaperglot"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Fshaperglot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Fshaperglot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Fshaperglot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlefonts%2Fshaperglot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/googlefonts","download_url":"https://codeload.github.com/googlefonts/shaperglot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252873856,"owners_count":21817708,"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":[],"created_at":"2024-11-17T23:13:36.504Z","updated_at":"2025-05-07T21:06:41.234Z","avatar_url":"https://github.com/googlefonts.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shaperglot - Test font files for OpenType language support\n\n[![PyPI Version](https://img.shields.io/pypi/v/shaperglot.svg)](https://pypi.org/project/shaperglot)\n[![PyPI License](https://img.shields.io/pypi/l/shaperglot.svg)](https://pypi.org/project/shaperglot)\n[![Read The Docs](https://readthedocs.org/projects/shaperglot/badge/)](https://https://shaperglot.readthedocs.io/en/latest/)\n\nTry [Shaperglot on the web](https://googlefonts.github.io/shaperglot)!\n\nShaperglot is a library and a utility for testing a font's language support.\nYou give it a font, and it tells you what languages are supported and to what\ndegree.\n\nMost other libraries to check for language support (for example, Rosetta's\nwonderful [hyperglot](https://hyperglot.rosettatype.com) library) do this by\nlooking at the Unicode codepoints that the font supports. Shaperglot takes\na different approach.\n\n## What's wrong with the Unicode codepoint coverage approach?\n\nFor many common languages, it's possible to check that the language is\nsupported just by looking at the Unicode coverage. For example, to support\nEnglish, you need the 26 lowercase and uppercase letters of the Latin alphabet.\n\nHowever, for the majority of scripts around the world, covering the codepoints\nneeded is not enough to say that a font really _supports_ a particular language.\nFor correct language support, the font must also _behave_ in a particular way.\n\nTake the case of Arabic as an example. A font might contain glyphs which cover\nall the codepoints in the Arabic block (0x600-0x6FF). But the font only _supports_\nArabic if it implements joining rules for the `init`, `medi` and `fina` features.\nTo say that a font supports Devanagari, it needs to implement conjuncts (which\nset of conjuncts need to be included before we can say the font \"supports\"\nDevanagari is debated...) and half forms, as well as contain a `languagesystem`\nstatement which triggers Indic reordering.\n\nEven within the Latin script, a font only supports a language such as Turkish\nif its casing behaving respects the dotless / dotted I distinction; a font\nonly supports Navajo if its ogonek anchoring is different to the anchoring used in\nPolish; and so on.\n\nBut there's a further problem with testing language support by codepoint coverage:\nit encourages designers to \"fill in the blanks\" to get to support, rather than\nnecessarily engage with the textual requirements of particular languages.\n\n## Testing for behaviour, not coverage\n\nShaperglot therefore determines language support not just on codepoint coverage,\nbut also by examining how the font behaves when confronted with certain character\nsequences.\n\nThe trick is to do this in a way which is not prescriptive. We know that there\nare many different ways of implementing language support within a font, and that\ndesign and other considerations will factor into precisely how a font is\nconstructed. Shaperglot presents the font with different strings, and makes sure\nthat \"something interesting happened\" - without necessarily specifying what.\n\nIn the case of Arabic, we need to know that the `init` feature is present, and that\nwhen we shape some Arabic glyphs, the output with `init` turned on is different\nto the output with `init` turned off. We don't care what's different; we only\ncare that something has happened. _(Yes, this still makes it possible to trick shaperglot into reporting support for a language which is not correctly implemented, but at that point, it's probably less effort to actually implement it...)_\n\nShaperglot includes the following kinds of test:\n\n- Certain codepoints were mapped to base or mark glyphs.\n- A named feature was present.\n- A named feature changed the output glyphs.\n- A mark glyph was attached to a base glyph or composed into a precomposed glyph (but not left unattached).\n- Certain glyphs in the output were different to one another.\n- Languagesystems were defined in the font.\n- ...\n\n## Using Shaperglot\n\nShaperglot consists of multiple components:\n\n### Shaperglot Web interface\n\nThe easiest way to use Shaperglot as an end-user or font developer is through the\n[web interface](https://googlefonts.github.io/shaperglot). This allows you to drag\nand drop a font to analyze its language coverage. This is entirely client-side,\nand all fonts remain on your computer. Nothing is uploaded.\n\n### Shaperglot command line tools\n\nThe next most user-friendly way to use Shaperglot is at the command line. You can\ninstall the latest version with:\n\n    cargo install --git https://github.com/googlefonts/shaperglot\n\nThis will provide you with a new tool called `shaperglot`. It has four subcommands:\n\n- `shaperglot check \u003cfont\u003e \u003clanguage\u003e \u003clanguage\u003e...` checks whether a font supports the given language IDs.\n- `shaperglot report \u003cfont\u003e` reports all languages supported by the font.\n- `shaperglot describe \u003clanguage\u003e` explains what needs to be done for a font to supportt a given language ID.\n\n```\n$ shaperglot describe Nuer\nThe font MUST support the following Nuer bases and marks: 'a', 'A', 'ä', 'Ä', 'a̱', 'A̱', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'ë', 'Ë', 'e̱', 'E̱', 'ɛ', 'Ɛ', 'ɛ̈', 'Ɛ̈', 'ɛ̱', 'Ɛ̱', 'ɛ̱̈', 'Ɛ̱̈', 'f', 'F', 'g', 'G', 'ɣ', 'Ɣ', 'h', 'H', 'i', 'I', 'ï', 'Ï', 'i̱', 'I̱', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'ŋ', 'Ŋ', 'o', 'O', 'ö', 'Ö', 'o̱', 'O̱', 'ɔ', 'Ɔ', 'ɔ̈', 'Ɔ̈', 'ɔ̱', 'Ɔ̱', 'p', 'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U', 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z', '◌̈', '◌̱'\nThe font SHOULD support the following auxiliary orthography codepoints: 'ʈ', 'Ʈ'\nLatin letters should form small caps when the smcp feature is enabled\n```\n\n### Shaperglot Rust library\n\nSee the documentation on https://docs.rs/shaperglot/latest\n\n### Shaperglot Python library\n\nThe Python library wraps the Rust library using PyO3. This new PyO3 implementation\n_broadly_ follows the same API as the original 0.x Python implementation, but all\nimports are at the top level (`from shaperglot import Checker`, etc.) The PyO3\nversion is available as a pre-release from Pypi.\n\nPython Library Documentation: https://shaperglot.readthedocs.io/en/latest/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglefonts%2Fshaperglot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglefonts%2Fshaperglot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglefonts%2Fshaperglot/lists"}