feaLib: Read/write OpenType feature files

fontTools’ feaLib allows for the creation and parsing of Adobe Font Development Kit for OpenType feature (.fea) files. The syntax of these files is described here.

The fontTools.feaLib.parser.Parser class can be used to parse files into an abstract syntax tree, and from there the fontTools.feaLib.builder.Builder class can add features to an existing font file. You can inspect the parsed syntax tree, walk the tree and do clever things with it, and also generate your own feature files programmatically, by using the classes in the fontTools.feaLib.ast module.

Parsing

class fontTools.feaLib.parser.Parser(featurefile, glyphNames=(), followIncludes=True, includeDir=None, **kwargs)[source]

Initializes a Parser object.

Example

from fontTools.feaLib.parser import Parser
parser = Parser(file, font.getReverseGlyphMap())
parsetree = parser.parse()

Note: the glyphNames iterable serves a double role to help distinguish glyph names from ranges in the presence of hyphens and to ensure that glyph names referenced in a feature file are actually part of a font’s glyph set. If the iterable is left empty, no glyph name in glyph set checking takes place, and all glyph tokens containing hyphens are treated as literal glyph names, not as ranges. (Adding a space around the hyphen can, in any case, help to disambiguate ranges from glyph names containing hyphens.)

By default, the parser will follow include() statements in the feature file. To turn this off, pass followIncludes=False. Pass a directory string as includeDir to explicitly declare a directory to search included feature files in.

parse()[source]

Parse the file, and return a fontTools.feaLib.ast.FeatureFile object representing the root of the abstract syntax tree containing the parsed contents of the file.

parse_name_()[source]

Parses a name record. See section 9.e.

parse_featureNames_(tag)[source]

Parses a featureNames statement found in stylistic set features. See section 8.c.

check_glyph_name_in_glyph_set(*names)[source]

Adds a glyph name (just start) or glyph names of a range (start and end) which are not in the glyph set to the “missing list” for future error reporting.

If no glyph set is present, does nothing.

static reverse_string_(s)[source]

‘abc’ –> ‘cba’

make_cid_range_(location, start, limit)[source]

(location, 999, 1001) –> [“cid00999”, “cid01000”, “cid01001”]

make_glyph_range_(location, start, limit)[source]

(location, “a.sc”, “d.sc”) –> [“a.sc”, “b.sc”, “c.sc”, “d.sc”]

Building

fontTools.feaLib.builder.addOpenTypeFeatures(font, featurefile, tables=None, debug=False)[source]

Add features from a file to a font. Note that this replaces any features currently present.

Parameters:
  • font (feaLib.ttLib.TTFont) – The font object.

  • featurefile – Either a path or file object (in which case we parse it into an AST), or a pre-parsed AST instance.

  • tables – If passed, restrict the set of affected tables to those in the list.

  • debug – Whether to add source debugging information to the font in the Debg table

fontTools.feaLib.builder.addOpenTypeFeaturesFromString(font, features, filename=None, tables=None, debug=False)[source]

Add features from a string to a font. Note that this replaces any features currently present.

Parameters:
  • font (feaLib.ttLib.TTFont) – The font object.

  • features – A string containing feature code.

  • filename – The directory containing filename is used as the root of relative include() paths; if None is provided, the current directory is assumed.

  • tables – If passed, restrict the set of affected tables to those in the list.

  • debug – Whether to add source debugging information to the font in the Debg table

Generation/Interrogation

In the below, a glyph-containing object is an object of one of the following classes: GlyphName, GlyphClass, GlyphClassName.

class fontTools.feaLib.ast.Element(location=None)[source]

A base class representing “something” in a feature file.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.FeatureFile[source]

The top-level element of the syntax tree, containing the whole feature file in its statements attribute.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

build(builder)

When handed a ‘builder’ object of comparable interface to fontTools.feaLib.builder, walks the statements in this block, calling the builder callbacks.

statements

Statements contained in the block

class fontTools.feaLib.ast.Comment(text, location=None)[source]

A comment in a feature file.

text

Text of the comment

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.GlyphName(glyph, location=None)[source]

A single glyph name, such as cedilla.

glyph

The name itself as a string

glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.GlyphClass(glyphs=None, location=None)[source]

A glyph class, such as [acute cedilla grave].

glyphs

The list of glyphs in this class, as GlyphName objects.

glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

extend(glyphs)[source]

Add a list of GlyphName objects to the class.

append(glyph)[source]

Add a single GlyphName object to the class.

add_range(start, end, glyphs)[source]

Add a range (e.g. A-Z) to the class. start and end are either GlyphName objects or strings representing the start and end glyphs in the class, and glyphs is the full list of GlyphName objects in the range.

add_cid_range(start, end, glyphs)[source]

Add a range to the class by glyph ID. start and end are the initial and final IDs, and glyphs is the full list of GlyphName objects in the range.

add_class(gc)[source]

Add glyphs from the given GlyphClassName object to the class.

class fontTools.feaLib.ast.GlyphClassName(glyphclass, location=None)[source]

A glyph class name, such as @FRENCH_MARKS. This must be instantiated with a GlyphClassDefinition object.

glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.MarkClassName(markClass, location=None)[source]

A mark class name, such as @FRENCH_MARKS defined with markClass. This must be instantiated with a MarkClass object.

glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.AnonymousBlock(tag, content, location=None)[source]

An anonymous data block.

tag

string containing the block’s “tag”

content

block data as string

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.Block(location=None)[source]

A block of statements: feature, lookup, etc.

statements

Statements contained in the block

build(builder)[source]

When handed a ‘builder’ object of comparable interface to fontTools.feaLib.builder, walks the statements in this block, calling the builder callbacks.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.FeatureBlock(name, use_extension=False, location=None)[source]

A named feature block.

build(builder)[source]

Call the start_feature callback on the builder object, visit all the statements in this feature, and then call end_feature.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

statements

Statements contained in the block

class fontTools.feaLib.ast.NestedBlock(tag, block_name, location=None)[source]

A block inside another block, for example when found inside a cvParameters block.

build(builder)[source]

When handed a ‘builder’ object of comparable interface to fontTools.feaLib.builder, walks the statements in this block, calling the builder callbacks.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

statements

Statements contained in the block

class fontTools.feaLib.ast.LookupBlock(name, use_extension=False, location=None)[source]

A named lookup, containing statements.

build(builder)[source]

When handed a ‘builder’ object of comparable interface to fontTools.feaLib.builder, walks the statements in this block, calling the builder callbacks.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

statements

Statements contained in the block

class fontTools.feaLib.ast.GlyphClassDefinition(name, glyphs, location=None)[source]

Example: @UPPERCASE = [A-Z];.

name

class name as a string, without initial @

glyphs

a GlyphClass object

glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.GlyphClassDefStatement(baseGlyphs, markGlyphs, ligatureGlyphs, componentGlyphs, location=None)[source]

Example: GlyphClassDef @UPPERCASE, [B], [C], [D];. The parameters must be either GlyphClass or GlyphClassName objects, or None.

build(builder)[source]

Calls the builder’s add_glyphClassDef callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.MarkClass(name)[source]

One or more markClass statements for the same mark class.

While glyph classes can be defined only once, the feature file format allows expanding mark classes with multiple definitions, each using different glyphs and anchors. The following are two MarkClassDefinitions for the same MarkClass:

markClass [acute grave] <anchor 350 800> @FRENCH_ACCENTS;
markClass [cedilla] <anchor 350 -200> @FRENCH_ACCENTS;

The MarkClass object is therefore just a container for a list of MarkClassDefinition statements.

addDefinition(definition)[source]

Add a MarkClassDefinition statement to this mark class.

glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

class fontTools.feaLib.ast.MarkClassDefinition(markClass, anchor, glyphs, location=None)[source]

A single markClass statement. The markClass should be a MarkClass object, the anchor an Anchor object, and the glyphs parameter should be a glyph-containing object .

Example

mc = MarkClass("FRENCH_ACCENTS")
mc.addDefinition( MarkClassDefinition(mc, Anchor(350, 800),
    GlyphClass([ GlyphName("acute"), GlyphName("grave") ])
) )
mc.addDefinition( MarkClassDefinition(mc, Anchor(350, -200),
    GlyphClass([ GlyphName("cedilla") ])
) )

mc.asFea()
# markClass [acute grave] <anchor 350 800> @FRENCH_ACCENTS;
# markClass [cedilla] <anchor 350 -200> @FRENCH_ACCENTS;
glyphSet()[source]

The glyphs in this class as a tuple of GlyphName objects.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.AlternateSubstStatement(prefix, glyph, suffix, replacement, location=None)[source]

A sub ... from ... statement.

prefix, glyph, suffix and replacement should be lists of glyph-containing objects. glyph should be a one element list.

build(builder)[source]

Calls the builder’s add_alternate_subst callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.Anchor(x, y, name=None, contourpoint=None, xDeviceTable=None, yDeviceTable=None, location=None)[source]

An Anchor element, used inside a pos rule.

If a name is given, this will be used in preference to the coordinates. Other values should be integer.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.AnchorDefinition(name, x, y, contourpoint=None, location=None)[source]

A named anchor definition. (2.e.viii). name should be a string.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.AttachStatement(glyphs, contourPoints, location=None)[source]

A GDEF table Attach statement.

glyphs

A glyph-containing object

contourPoints

A list of integer contour points

build(builder)[source]

Calls the builder’s add_attach_points callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.AxisValueLocationStatement(tag, values, location=None)[source]

A STAT table Axis Value Location

Parameters:
  • tag (str) – a 4 letter axis tag

  • values (list) – a list of ints and/or floats

asFea(res='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.BaseAxis(bases, scripts, vertical, location=None)[source]

An axis definition, being either a VertAxis.BaseTagList/BaseScriptList pair or a HorizAxis.BaseTagList/BaseScriptList pair.

bases

A list of baseline tag names as strings

scripts

A list of script record tuplets (script tag, default baseline tag, base coordinate)

vertical

Boolean; VertAxis if True, HorizAxis if False

build(builder)[source]

Calls the builder object’s set_base_axis callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.CVParametersNameStatement(nameID, platformID, platEncID, langID, string, block_name, location=None)[source]

Represent a name statement inside a cvParameters block.

build(builder)[source]

Calls the builder object’s add_cv_parameter callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

nameID

Name ID as integer (e.g. 9 for designer’s name)

platformID

Platform ID as integer

platEncID

Platform encoding ID as integer

langID

Language ID as integer

string

Name record value

class fontTools.feaLib.ast.ChainContextPosStatement(prefix, glyphs, suffix, lookups, location=None)[source]

A chained contextual positioning statement.

prefix, glyphs, and suffix should be lists of glyph-containing objects .

lookups should be a list of elements representing what lookups to apply at each glyph position. Each element should be a LookupBlock to apply a single chaining lookup at the given position, a list of LookupBlocks to apply multiple lookups, or None to apply no lookup. The length of the outer list should equal the length of glyphs; the inner lists can be of variable length.

build(builder)[source]

Calls the builder’s add_chain_context_pos callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ChainContextSubstStatement(prefix, glyphs, suffix, lookups, location=None)[source]

A chained contextual substitution statement.

prefix, glyphs, and suffix should be lists of glyph-containing objects .

lookups should be a list of elements representing what lookups to apply at each glyph position. Each element should be a LookupBlock to apply a single chaining lookup at the given position, a list of LookupBlocks to apply multiple lookups, or None to apply no lookup. The length of the outer list should equal the length of glyphs; the inner lists can be of variable length.

build(builder)[source]

Calls the builder’s add_chain_context_subst callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.CharacterStatement(character, tag, location=None)[source]

Statement used in cvParameters blocks of Character Variant features (cvXX). The Unicode value may be written with either decimal or hexadecimal notation. The value must be preceded by ‘0x’ if it is a hexadecimal value. The largest Unicode value allowed is 0xFFFFFF.

build(builder)[source]

Calls the builder object’s add_cv_character callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ConditionsetStatement(name, conditions, location=None)[source]

A variable layout conditionset

Parameters:
  • name (str) – the name of this conditionset

  • conditions (dict) – a dictionary mapping axis tags to a tuple of (min,max) userspace coordinates.

asFea(res='', indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.CursivePosStatement(glyphclass, entryAnchor, exitAnchor, location=None)[source]

A cursive positioning statement. Entry and exit anchors can either be Anchor objects or None.

build(builder)[source]

Calls the builder object’s add_cursive_pos callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ElidedFallbackName(names, location=None)[source]

STAT table ElidedFallbackName

Parameters:

names – a list of STATNameStatement objects

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ElidedFallbackNameID(value, location=None)[source]

STAT table ElidedFallbackNameID

Parameters:

value – an int pointing to an existing name table name ID

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.Expression(location=None)[source]
asFea(indent='')

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.FeatureNameStatement(nameID, platformID, platEncID, langID, string, location=None)[source]

Represents a sizemenuname or name statement.

build(builder)[source]

Calls the builder object’s add_featureName callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

nameID

Name ID as integer (e.g. 9 for designer’s name)

platformID

Platform ID as integer

platEncID

Platform encoding ID as integer

langID

Language ID as integer

string

Name record value

class fontTools.feaLib.ast.FeatureReferenceStatement(featureName, location=None)[source]

Example: feature salt;

build(builder)[source]

Calls the builder object’s add_feature_reference callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.FontRevisionStatement(revision, location=None)[source]

A head table FontRevision statement. revision should be a number, and will be formatted to three significant decimal places.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.HheaField(key, value, location=None)[source]

An entry in the hhea table.

build(builder)[source]

Calls the builder object’s add_hhea_field callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.IgnorePosStatement(chainContexts, location=None)[source]

An ignore pos statement, containing one or more contexts to ignore.

chainContexts should be a list of (prefix, glyphs, suffix) tuples, with each of prefix, glyphs and suffix being glyph-containing objects .

build(builder)[source]

Calls the builder object’s add_chain_context_pos callback on each rule context.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.IgnoreSubstStatement(chainContexts, location=None)[source]

An ignore sub statement, containing one or more contexts to ignore.

chainContexts should be a list of (prefix, glyphs, suffix) tuples, with each of prefix, glyphs and suffix being glyph-containing objects .

build(builder)[source]

Calls the builder object’s add_chain_context_subst callback on each rule context.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.IncludeStatement(filename, location=None)[source]

An include() statement.

filename

String containing name of file to include

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LanguageStatement(language, include_default=True, required=False, location=None)[source]

A language statement within a feature.

language

A four-character language tag

include_default

If false, “exclude_dflt”

build(builder)[source]

Call the builder object’s set_language callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LanguageSystemStatement(script, language, location=None)[source]

A top-level languagesystem statement.

build(builder)[source]

Calls the builder object’s add_language_system callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LigatureCaretByIndexStatement(glyphs, carets, location=None)[source]

A GDEF table LigatureCaretByIndex statement. glyphs should be a glyph-containing object, and carets should be a list of integers.

build(builder)[source]

Calls the builder object’s add_ligatureCaretByIndex_ callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LigatureCaretByPosStatement(glyphs, carets, location=None)[source]

A GDEF table LigatureCaretByPos statement. glyphs should be a glyph-containing object, and carets should be a list of integers.

build(builder)[source]

Calls the builder object’s add_ligatureCaretByPos_ callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LigatureSubstStatement(prefix, glyphs, suffix, replacement, forceChain, location=None)[source]

A chained contextual substitution statement.

prefix, glyphs, and suffix should be lists of glyph-containing objects; replacement should be a single glyph-containing object.

If forceChain is True, this is expressed as a chaining rule (e.g. sub f' i' by f_i) even when no context is given.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LookupFlagStatement(value=0, markAttachment=None, markFilteringSet=None, location=None)[source]

A lookupflag statement. The value should be an integer value representing the flags in use, but not including the markAttachment class and markFilteringSet values, which must be specified as glyph-containing objects.

build(builder)[source]

Calls the builder object’s set_lookup_flag callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.LookupReferenceStatement(lookup, location=None)[source]

Represents a lookup ...; statement to include a lookup in a feature.

The lookup should be a LookupBlock object.

build(builder)[source]

Calls the builder object’s add_lookup_call callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.MarkBasePosStatement(base, marks, location=None)[source]

A mark-to-base positioning rule. The base should be a glyph-containing object. The marks should be a list of (Anchor, MarkClass) tuples.

build(builder)[source]

Calls the builder object’s add_mark_base_pos callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.MarkLigPosStatement(ligatures, marks, location=None)[source]

A mark-to-ligature positioning rule. The ligatures must be a glyph-containing object. The marks should be a list of lists: each element in the top-level list represents a component glyph, and is made up of a list of (Anchor, MarkClass) tuples representing mark attachment points for that position.

Example:

m1 = MarkClass("TOP_MARKS")
m2 = MarkClass("BOTTOM_MARKS")
# ... add definitions to mark classes...

glyph = GlyphName("lam_meem_jeem")
marks = [
    [ (Anchor(625,1800), m1) ], # Attachments on 1st component (lam)
    [ (Anchor(376,-378), m2) ], # Attachments on 2nd component (meem)
    [ ]                         # No attachments on the jeem
]
mlp = MarkLigPosStatement(glyph, marks)

mlp.asFea()
# pos ligature lam_meem_jeem <anchor 625 1800> mark @TOP_MARKS
# ligComponent <anchor 376 -378> mark @BOTTOM_MARKS;
build(builder)[source]

Calls the builder object’s add_mark_lig_pos callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.MarkMarkPosStatement(baseMarks, marks, location=None)[source]

A mark-to-mark positioning rule. The baseMarks must be a glyph-containing object. The marks should be a list of (Anchor, MarkClass) tuples.

build(builder)[source]

Calls the builder object’s add_mark_mark_pos callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.MultipleSubstStatement(prefix, glyph, suffix, replacement, forceChain=False, location=None)[source]

A multiple substitution statement.

Parameters:
  • prefix – a list of glyph-containing objects.

  • glyph – a single glyph-containing object.

  • suffix – a list of glyph-containing objects.

  • replacement – a list of glyph-containing objects.

  • forceChain – If true, the statement is expressed as a chaining rule (e.g. sub f' i' by f_i) even when no context is given.

build(builder)[source]

Calls the builder object’s add_multiple_subst callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.NameRecord(nameID, platformID, platEncID, langID, string, location=None)[source]

Represents a name record. (Section 9.e.)

nameID

Name ID as integer (e.g. 9 for designer’s name)

platformID

Platform ID as integer

platEncID

Platform encoding ID as integer

langID

Language ID as integer

string

Name record value

build(builder)[source]

Calls the builder object’s add_name_record callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.OS2Field(key, value, location=None)[source]

An entry in the OS/2 table. Most values should be numbers or strings, apart from when the key is UnicodeRange, CodePageRange or Panose, in which case it should be an array of integers.

build(builder)[source]

Calls the builder object’s add_os2_field callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.PairPosStatement(glyphs1, valuerecord1, glyphs2, valuerecord2, enumerated=False, location=None)[source]

A pair positioning statement.

glyphs1 and glyphs2 should be glyph-containing objects. valuerecord1 should be a ValueRecord object; valuerecord2 should be either a ValueRecord object or None. If enumerated is true, then this is expressed as an enumerated pair.

build(builder)[source]

Calls a callback on the builder object:

  • If the rule is enumerated, calls add_specific_pair_pos on each combination of first and second glyphs.

  • If the glyphs are both single GlyphName objects, calls add_specific_pair_pos.

  • Else, calls add_class_pair_pos.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ReverseChainSingleSubstStatement(old_prefix, old_suffix, glyphs, replacements, location=None)[source]

A reverse chaining substitution statement. You don’t see those every day.

Note the unusual argument order: suffix comes before glyphs. old_prefix, old_suffix, glyphs and replacements should be lists of glyph-containing objects. glyphs and replacements should be one-item lists.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ScriptStatement(script, location=None)[source]

A script statement.

script

the script code

build(builder)[source]

Calls the builder’s set_script callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.SinglePosStatement(pos, prefix, suffix, forceChain, location=None)[source]

A single position statement. prefix and suffix should be lists of glyph-containing objects.

pos should be a one-element list containing a (glyph-containing object, ValueRecord) tuple.

build(builder)[source]

Calls the builder object’s add_single_pos callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.SingleSubstStatement(glyphs, replace, prefix, suffix, forceChain, location=None)[source]

A single substitution statement.

Note the unusual argument order: prefix and suffix come after the replacement glyphs. prefix, suffix, glyphs and replace should be lists of glyph-containing objects. glyphs and replace should be one-item lists.

build(builder)[source]

Calls the builder object’s add_single_subst callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.SizeParameters(DesignSize, SubfamilyID, RangeStart, RangeEnd, location=None)[source]

A parameters statement.

build(builder)[source]

Calls the builder object’s set_size_parameters callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.Statement(location=None)[source]
asFea(indent='')

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.STATAxisValueStatement(names, locations, flags, location=None)[source]

A STAT table Axis Value Record

Parameters:
asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.STATDesignAxisStatement(tag, axisOrder, names, location=None)[source]

A STAT table Design Axis

Parameters:
  • tag (str) – a 4 letter axis tag

  • axisOrder (int) – an int

  • names (list) – a list of STATNameStatement objects

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.STATNameStatement(nameID, platformID, platEncID, langID, string, location=None)[source]

Represents a STAT table name statement.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

build(builder)

Calls the builder object’s add_name_record callback.

nameID

Name ID as integer (e.g. 9 for designer’s name)

platformID

Platform ID as integer

platEncID

Platform encoding ID as integer

langID

Language ID as integer

string

Name record value

class fontTools.feaLib.ast.SubtableStatement(location=None)[source]

Represents a subtable break.

build(builder)[source]

Calls the builder objects’s add_subtable_break callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.TableBlock(name, location=None)[source]

A table ... { } block.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

build(builder)

When handed a ‘builder’ object of comparable interface to fontTools.feaLib.builder, walks the statements in this block, calling the builder callbacks.

statements

Statements contained in the block

class fontTools.feaLib.ast.ValueRecord(xPlacement=None, yPlacement=None, xAdvance=None, yAdvance=None, xPlaDevice=None, yPlaDevice=None, xAdvDevice=None, yAdvDevice=None, vertical=False, location=None)[source]

Represents a value record.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.ValueRecordDefinition(name, value, location=None)[source]

Represents a named value record definition.

name

Value record name as string

value

ValueRecord object

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.

class fontTools.feaLib.ast.VheaField(key, value, location=None)[source]

An entry in the vhea table.

build(builder)[source]

Calls the builder object’s add_vhea_field callback.

asFea(indent='')[source]

Returns this element as a string of feature code. For block-type elements (such as FeatureBlock), the indent string is added to the start of each line in the output.