This module provides utilities for defining and managing OpenType font features. It includes tools for creating stylistic sets, character variants, ligatures, and more.
The feature/
module is designed to simplify the creation of OpenType font features. It uses an abstract syntax tree (AST) approach to define and manage features programmatically.
ast.py
: Core utilities for defining OpenType features.regular.py
: Entry file for regular style.italic.py
: Entry file for italic style.base/
: Contains foundational classes and features like numbers, cases, and localized forms.calt/
: Default ligatures.cv/
: Character variants.ss/
: Stylistic sets.
The calt/tag.py
file provides utilities for creating custom tags.
There are many built-in tags with full-round border in the font, you can use subst_liga
function to custom trigger text. Following example shows how to convert TODO:
to (TODO)
(Cons: the first letter before the tag will be overlapped)
subst_liga(
source="TODO:",
target="tag_todo.liga",
lookup_name="todo_colon"
)
If you want to get more tags, use tag_custom
function:
tag_custom(
[
(":attention:", "[attention]"),
("_noqa_", "(noqa)"),
# ("_alter_", "<alter>"),
],
bg_cls_dict,
)
This will convert
:attention: _noqa_
to:
- The built-in tags are optimized for glyph spacing, but the custom tags not.
- The tag will be splited if letter spacing > 0, see in #381
- The tag's color follows the original text color, see in #381
The ast.py
file provides classes and functions to define OpenType features. Below are some key utilities:
Represents a class of glyphs.
from source.py.feature.ast import Clazz, subst
cls_digit = Clazz("Digit", ["zero", "one", "two", "three"])
cls_digit.state()
subst(cls_digit.use(), "a", "b", "c")
Generated fea string:
@Digit = [zero, one, two, three];
sub @Digit a' b by c;
Defines a lookup block for substitutions.
from source.py.feature.ast import Lookup, subst
lookup_example = Lookup(
name="example_lookup",
desc="Example substitution",
content=[
subst("a", "b", None, "c"),
],
)
Generated fea string:
# Example substitution
lookup example_lookup {
sub a b' by c;
} example_lookup;
Represents an OpenType feature.
from source.py.feature.ast import Feature
feature_example = Feature(
tag="calt",
content=[
lookup_example,
],
)
Generated fea string:
feature calt {
# Example substitution
lookup example_lookup {
sub a b' by c;
} example_lookup;
}
Generates the final OpenType feature file content.
from source.py.feature.ast import create
fea_content = create([feature_example])
print(fea_content)
In most of time, you don't need to update the fea files. The generated fea string will be automatically applied at build time without using --apply-fea-file
flag.
You can use uv run task.py fea
to update exists fea files.
Here is an example to show how to use the generate_fea_string
function to generate feature files
from source.py.feature import generate_fea_string
fea_string = generate_fea_string(italic=False, cn=True)
print(fea_string)