ast: Interrogate and generate OpenType feature files
Overview:
feaLib’s ast module provides classes that represent the objects
and structures used to define OpenType feature lookups in the fea
syntax. After your code has parsed a .fea file into an abstract
syntax tree (AST), you can use these classes to modify existing
lookups or create new lookups and features.
The root of the AST representation of a parsed .fea file is a
fontTools.feaLib.ast.FeatureFile object. You can walk the
tree by examining its statements attribute. Nodes in the
tree have an asFea() method that will return a .fea
formated string representation, including correct indentation of block elements.
In the below, a glyph-containing object is an object of one of the following
classes: GlyphName, GlyphClass, GlyphClassName.
Module members
- class fontTools.feaLib.ast.Element(location=None)[source]
Bases:
objectA 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]
Bases:
BlockThe top-level element of the syntax tree, containing the whole feature file in its
statementsattribute.
- class fontTools.feaLib.ast.Comment(text, location=None)[source]
Bases:
ElementA comment in a feature file.
- text
Text of the comment
- class fontTools.feaLib.ast.GlyphName(glyph, location=None)[source]
Bases:
ExpressionA single glyph name, such as
cedilla.- glyph
The name itself as a string
- class fontTools.feaLib.ast.GlyphClass(glyphs=None, location=None)[source]
Bases:
ExpressionA glyph class, such as
[acute cedilla grave].- add_range(start, end, glyphs)[source]
Add a range (e.g.
A-Z) to the class.startandendare eitherGlyphNameobjects or strings representing the start and end glyphs in the class, andglyphsis the full list ofGlyphNameobjects in the range.
- add_cid_range(start, end, glyphs)[source]
Add a range to the class by glyph ID.
startandendare the initial and final IDs, andglyphsis the full list ofGlyphNameobjects in the range.
- add_class(gc)[source]
Add glyphs from the given
GlyphClassNameobject to the class.
- class fontTools.feaLib.ast.GlyphClassName(glyphclass, location=None)[source]
Bases:
ExpressionA glyph class name, such as
@FRENCH_MARKS. This must be instantiated with aGlyphClassDefinitionobject.
- class fontTools.feaLib.ast.MarkClassName(markClass, location=None)[source]
Bases:
ExpressionA mark class name, such as
@FRENCH_MARKSdefined withmarkClass. This must be instantiated with aMarkClassobject.
- class fontTools.feaLib.ast.AnonymousBlock(tag, content, location=None)[source]
Bases:
StatementAn anonymous data block.
- tag
string containing the block’s “tag”
- content
block data as string
- class fontTools.feaLib.ast.Block(location=None)[source]
Bases:
StatementA 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.
- class fontTools.feaLib.ast.FeatureBlock(name, use_extension=False, location=None)[source]
Bases:
BlockA named feature block.
- class fontTools.feaLib.ast.NestedBlock(tag, block_name, location=None)[source]
Bases:
BlockA block inside another block, for example when found inside a
cvParametersblock.
- class fontTools.feaLib.ast.LookupBlock(name, use_extension=False, location=None)[source]
Bases:
BlockA named lookup, containing
statements.
- class fontTools.feaLib.ast.GlyphClassDefinition(name, glyphs, location=None)[source]
Bases:
StatementExample:
@UPPERCASE = [A-Z];.- name
class name as a string, without initial
@
- glyphs
a
GlyphClassobject
- class fontTools.feaLib.ast.GlyphClassDefStatement(baseGlyphs, markGlyphs, ligatureGlyphs, componentGlyphs, location=None)[source]
Bases:
StatementExample:
GlyphClassDef @UPPERCASE, [B], [C], [D];. The parameters must be eitherGlyphClassorGlyphClassNameobjects, orNone.
- class fontTools.feaLib.ast.MarkClass(name)[source]
Bases:
objectOne or more
markClassstatements 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
MarkClassDefinitionsfor the sameMarkClass:markClass [acute grave] <anchor 350 800> @FRENCH_ACCENTS; markClass [cedilla] <anchor 350 -200> @FRENCH_ACCENTS;
The
MarkClassobject is therefore just a container for a list ofMarkClassDefinitionstatements.- addDefinition(definition)[source]
Add a
MarkClassDefinitionstatement to this mark class.
- class fontTools.feaLib.ast.MarkClassDefinition(markClass, anchor, glyphs, location=None)[source]
Bases:
StatementA single
markClassstatement. ThemarkClassshould be aMarkClassobject, theanchoranAnchorobject, and theglyphsparameter 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;
- class fontTools.feaLib.ast.AlternateSubstStatement(prefix, glyph, suffix, replacement, location=None)[source]
Bases:
StatementA
sub ... from ...statement.glyphandreplacementshould be glyph-containing objects.prefixandsuffixshould be lists of glyph-containing objects.
- class fontTools.feaLib.ast.Anchor(x, y, name=None, contourpoint=None, xDeviceTable=None, yDeviceTable=None, location=None)[source]
Bases:
ExpressionAn
Anchorelement, used inside aposrule.If a
nameis given, this will be used in preference to the coordinates. Other values should be integer.
- class fontTools.feaLib.ast.AnchorDefinition(name, x, y, contourpoint=None, location=None)[source]
Bases:
StatementA named anchor definition. (2.e.viii).
nameshould be a string.
- class fontTools.feaLib.ast.AttachStatement(glyphs, contourPoints, location=None)[source]
Bases:
StatementA
GDEFtableAttachstatement.- glyphs
- contourPoints
A list of integer contour points
- class fontTools.feaLib.ast.AxisValueLocationStatement(tag, values, location=None)[source]
Bases:
StatementA STAT table Axis Value Location
- Parameters:
tag (str) – a 4 letter axis tag
values (list) – a list of ints and/or floats
- class fontTools.feaLib.ast.BaseAxis(bases, scripts, vertical, minmax=None, location=None)[source]
Bases:
StatementAn axis definition, being either a
VertAxis.BaseTagList/BaseScriptListpair or aHorizAxis.BaseTagList/BaseScriptListpair.- 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
- minmax
A set of minmax record
- class fontTools.feaLib.ast.CVParametersNameStatement(nameID, platformID, platEncID, langID, string, block_name, location=None)[source]
Bases:
NameRecordRepresent a name statement inside a
cvParametersblock.
- class fontTools.feaLib.ast.ChainContextPosStatement(prefix, glyphs, suffix, lookups, location=None)[source]
Bases:
StatementA chained contextual positioning statement.
prefix,glyphs, andsuffixshould be lists of glyph-containing objects .lookupsshould be a list of elements representing what lookups to apply at each glyph position. Each element should be aLookupBlockto apply a single chaining lookup at the given position, a list ofLookupBlocks to apply multiple lookups, orNoneto apply no lookup. The length of the outer list should equal the length ofglyphs; the inner lists can be of variable length.
- class fontTools.feaLib.ast.ChainContextSubstStatement(prefix, glyphs, suffix, lookups, location=None)[source]
Bases:
StatementA chained contextual substitution statement.
prefix,glyphs, andsuffixshould be lists of glyph-containing objects .lookupsshould be a list of elements representing what lookups to apply at each glyph position. Each element should be aLookupBlockto apply a single chaining lookup at the given position, a list ofLookupBlocks to apply multiple lookups, orNoneto apply no lookup. The length of the outer list should equal the length ofglyphs; the inner lists can be of variable length.
- class fontTools.feaLib.ast.CharacterStatement(character, tag, location=None)[source]
Bases:
StatementStatement 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.
- class fontTools.feaLib.ast.ConditionsetStatement(name, conditions, location=None)[source]
Bases:
StatementA 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.
- class fontTools.feaLib.ast.CursivePosStatement(glyphclass, entryAnchor, exitAnchor, location=None)[source]
Bases:
StatementA cursive positioning statement. Entry and exit anchors can either be
Anchorobjects orNone.
- class fontTools.feaLib.ast.ElidedFallbackName(names, location=None)[source]
Bases:
StatementSTAT table ElidedFallbackName
- Parameters:
names – a list of
STATNameStatementobjects
- class fontTools.feaLib.ast.ElidedFallbackNameID(value, location=None)[source]
Bases:
StatementSTAT table ElidedFallbackNameID
- Parameters:
value – an int pointing to an existing name table name ID
- class fontTools.feaLib.ast.FeatureNameStatement(nameID, platformID, platEncID, langID, string, location=None)[source]
Bases:
NameRecordRepresents a
sizemenunameornamestatement.
- class fontTools.feaLib.ast.FeatureReferenceStatement(featureName, location=None)[source]
Bases:
StatementExample:
feature salt;
- class fontTools.feaLib.ast.FontRevisionStatement(revision, location=None)[source]
Bases:
StatementA
headtableFontRevisionstatement.revisionshould be a number, and will be formatted to three significant decimal places.
- class fontTools.feaLib.ast.HheaField(key, value, location=None)[source]
Bases:
StatementAn entry in the
hheatable.
- class fontTools.feaLib.ast.IgnorePosStatement(chainContexts, location=None)[source]
Bases:
StatementAn
ignore posstatement, containing one or more contexts to ignore.chainContextsshould be a list of(prefix, glyphs, suffix)tuples, with each ofprefix,glyphsandsuffixbeing glyph-containing objects .
- class fontTools.feaLib.ast.IgnoreSubstStatement(chainContexts, location=None)[source]
Bases:
StatementAn
ignore substatement, containing one or more contexts to ignore.chainContextsshould be a list of(prefix, glyphs, suffix)tuples, with each ofprefix,glyphsandsuffixbeing glyph-containing objects .
- class fontTools.feaLib.ast.IncludeStatement(filename, location=None)[source]
Bases:
StatementAn
include()statement.- filename
String containing name of file to include
- class fontTools.feaLib.ast.LanguageStatement(language, include_default=True, required=False, location=None)[source]
Bases:
StatementA
languagestatement within a feature.- language
A four-character language tag
- include_default
If false, “exclude_dflt”
- class fontTools.feaLib.ast.LanguageSystemStatement(script, language, location=None)[source]
Bases:
StatementA top-level
languagesystemstatement.
- class fontTools.feaLib.ast.LigatureCaretByIndexStatement(glyphs, carets, location=None)[source]
Bases:
StatementA
GDEFtableLigatureCaretByIndexstatement.glyphsshould be a glyph-containing object, andcaretsshould be a list of integers.
- class fontTools.feaLib.ast.LigatureCaretByPosStatement(glyphs, carets, location=None)[source]
Bases:
StatementA
GDEFtableLigatureCaretByPosstatement.glyphsshould be a glyph-containing object, andcaretsshould be a list of integers.
- class fontTools.feaLib.ast.LigatureSubstStatement(prefix, glyphs, suffix, replacement, forceChain, location=None)[source]
Bases:
StatementA chained contextual substitution statement.
prefix,glyphs, andsuffixshould be lists of glyph-containing objects;replacementshould be a single glyph-containing object.If
forceChainis True, this is expressed as a chaining rule (e.g.sub f' i' by f_i) even when no context is given.
- class fontTools.feaLib.ast.LookupFlagStatement(value=0, markAttachment=None, markFilteringSet=None, location=None)[source]
Bases:
StatementA
lookupflagstatement. Thevalueshould be an integer value representing the flags in use, but not including themarkAttachmentclass andmarkFilteringSetvalues, which must be specified as glyph-containing objects.
- class fontTools.feaLib.ast.LookupReferenceStatement(lookup, location=None)[source]
Bases:
StatementRepresents a
lookup ...;statement to include a lookup in a feature.The
lookupshould be aLookupBlockobject.
- class fontTools.feaLib.ast.MarkBasePosStatement(base, marks, location=None)[source]
Bases:
StatementA mark-to-base positioning rule. The
baseshould be a glyph-containing object. Themarksshould be a list of (Anchor,MarkClass) tuples.
- class fontTools.feaLib.ast.MarkLigPosStatement(ligatures, marks, location=None)[source]
Bases:
StatementA mark-to-ligature positioning rule. The
ligaturesmust be a glyph-containing object. Themarksshould 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;
- class fontTools.feaLib.ast.MarkMarkPosStatement(baseMarks, marks, location=None)[source]
Bases:
StatementA mark-to-mark positioning rule. The
baseMarksmust be a glyph-containing object. Themarksshould be a list of (Anchor,MarkClass) tuples.
- class fontTools.feaLib.ast.MultipleSubstStatement(prefix, glyph, suffix, replacement, forceChain=False, location=None)[source]
Bases:
StatementA 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.
- class fontTools.feaLib.ast.NameRecord(nameID, platformID, platEncID, langID, string, location=None)[source]
Bases:
StatementRepresents 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
- class fontTools.feaLib.ast.OS2Field(key, value, location=None)[source]
Bases:
StatementAn entry in the
OS/2table. Mostvaluesshould be numbers or strings, apart from when the key isUnicodeRange,CodePageRangeorPanose, in which case it should be an array of integers.
- class fontTools.feaLib.ast.PairPosStatement(glyphs1, valuerecord1, glyphs2, valuerecord2, enumerated=False, location=None)[source]
Bases:
StatementA pair positioning statement.
glyphs1andglyphs2should be glyph-containing objects.valuerecord1should be aValueRecordobject;valuerecord2should be either aValueRecordobject orNone. Ifenumeratedis true, then this is expressed as an enumerated pair.
- class fontTools.feaLib.ast.ReverseChainSingleSubstStatement(old_prefix, old_suffix, glyphs, replacements, location=None)[source]
Bases:
StatementA reverse chaining substitution statement. You don’t see those every day.
Note the unusual argument order:
suffixcomes beforeglyphs.old_prefix,old_suffix,glyphsandreplacementsshould be lists of glyph-containing objects.glyphsandreplacementsshould be one-item lists.
- class fontTools.feaLib.ast.ScriptStatement(script, location=None)[source]
Bases:
StatementA
scriptstatement.- script
the script code
- class fontTools.feaLib.ast.SinglePosStatement(pos, prefix, suffix, forceChain, location=None)[source]
Bases:
StatementA single position statement.
prefixandsuffixshould be lists of glyph-containing objects.posshould be a one-element list containing a (glyph-containing object,ValueRecord) tuple.
- class fontTools.feaLib.ast.SingleSubstStatement(glyphs, replace, prefix, suffix, forceChain, location=None)[source]
Bases:
StatementA single substitution statement.
Note the unusual argument order:
prefixand suffix come after the replacementglyphs.prefix,suffix,glyphsandreplaceshould be lists of glyph-containing objects.glyphsandreplaceshould be one-item lists.
- class fontTools.feaLib.ast.SizeParameters(DesignSize, SubfamilyID, RangeStart, RangeEnd, location=None)[source]
Bases:
StatementA
parametersstatement.
- class fontTools.feaLib.ast.STATAxisValueStatement(names, locations, flags, location=None)[source]
Bases:
StatementA STAT table Axis Value Record
- Parameters:
names (list) – a list of
STATNameStatementobjectslocations (list) – a list of
AxisValueLocationStatementobjectsflags (int) – an int
- class fontTools.feaLib.ast.STATDesignAxisStatement(tag, axisOrder, names, location=None)[source]
Bases:
StatementA STAT table Design Axis
- Parameters:
tag (str) – a 4 letter axis tag
axisOrder (int) – an int
names (list) – a list of
STATNameStatementobjects
- class fontTools.feaLib.ast.STATNameStatement(nameID, platformID, platEncID, langID, string, location=None)[source]
Bases:
NameRecordRepresents a STAT table
namestatement.
- class fontTools.feaLib.ast.SubtableStatement(location=None)[source]
Bases:
StatementRepresents a subtable break.
- class fontTools.feaLib.ast.TableBlock(name, location=None)[source]
Bases:
BlockA
table ... { }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]
Bases:
ExpressionRepresents a value record.