yanone.de
Follow yanone on Twitter

Dancing Shoes

Dancing Shoes is a Python library that provides a friendly interface to create OpenType feature code using simple instructions.

Download
Dancing Shoes here:

 

Download here
DancingShoes.zip

(16kB)

 

License:

Dancing Shoes is completely free. See LICENSE.txt for details.

Documentation

 

Main DancingShoes object

DancingShoes(glyphs, features)

This is your main code generator object. You initialize it, feed it with instructions, and it will later spit out the formatted feature code.
glyphs is a list of glyph names of your font. See Helper Functions for easy methods to pull these from your FontLab or RoboFab Font object.
features is a list of four-digit feature names, in the specific order that you want to use them in.

Example:

from dancingshoes import DancingShoes
shoes = DancingShoes(('space', 'a', 'b', 'a.sc', 'b.sc', 'one', 'two', 'one.tf', 'two.tf'), ('aalt', 'smcp', 'tnum'))

 

 

Functions

Glyph repertoire

DancingShoes.Glyphs()

Returns the previously fed list of glyph names of your font.

Example:

print shoes.Glyphs()
['space', 'a', 'b', 'a.sc', 'b.sc', 'one', 'two', 'one.tf', 'two.tf']

 

DancingShoes.HasGlyphs(glyphs)

Returns True, if all glyph names from list glyphs are present in the font (e.g. in Glyphs().)

Example:

print shoes.HasGlyphs(['one', 'one.tf'])
True

print shoes.HasGlyphs(['one', 'one.tosf'])
False

 

DancingShoes.Groups()

Return list of all glyph group endings (e.g. ['.sc', '.lf', '.tf'])

Example:

print shoes.Groups()
['.sc', '.tf']

 

DancingShoes.HasGroups(groups)

Returns True, if all group endings from list groups are present in the font (e.g. in Groups().)

Example:

print shoes.HasGroups(['.sc', '.tf'])
True

print shoes.HasGroups(['.tf', '.lf'])
False

 

DancingShoes.GlyphsInGroup(ending)

Returns list of all glyphs in glyph group by the name of ending.

Example:

print shoes.GlyphsInGroup('.sc')
['a.sc', 'b.sc']

print shoes.GlyphsInGroup('.tf)
['one.tf', 'two.tf']

 

DancingShoes.GroupHasGlyphs(ending, glyphs)

Returns True, if all glyph names from list glyphs are present in the font's glyph group by the name of ending.

Example:

print shoes.GroupHasGlyphs('.tf', ['one.tf', 'two.tf'])
True

print shoes.GroupHasGlyphs('.tf', ['one', 'two'])
False

 

DancingShoes.SourceGlyphFromTarget(target)

Chips off the ending of given target glyph name, and returns it.

Example:

print shoes.SourceGlyphFromTarget('m.medial_high_low')
m

 

DancingShoes.UsedFeatures()

Returns a list of four-digit feature names for all features that have been registered so far using the instruction functions above.
Use this to add references to all other features for the Access All Alternates (aalt) feature (See example in section Usage Examples) and for feature assigning within FontLab.

Example:

print shoes.UsedFeatures()
['smcp', 'tnum']

 

DancingShoes.UsedClasses()

Returns the names for all classes that have been registered so far using the instruction functions above.

Example:

print shoes.UsedClasses()
['@smallcaps_source', '@smallcaps_target', '@numr_source', '@numr_target']

 

DancingShoes.AddGlyphsToClass(class, glyphs)

Adds all glyph names in the list glyphs to the class by the name of class.

Example:

shoes.AddGlyphsToClass('@UpperCaseLetters', ['A', 'B', 'C'])

 

DancingShoes.AddEndingToBothClasses(class, ending)

This is a shortcut to add glyphs to both a source and a target class (whose name starts with class), chopping off the ending of the source glyph.

Example:

shoes.AddEndingToBothClasses('smallcaps', '.sc')
will create:

@smallcaps_source = [
# 2 glyph(s)
a b
];
@smallcaps_target = [
# 2 glyph(s)
a.sc b.sc
];

 

DancingShoes.DuplicateFeature(source, target)

This is a shortcut to duplicate a feature under a different name.
In case there were already lookups registered in the target feature, the lookups will be appended anyway, but a warning message will be shown.

Example:

shoes.DuplicateFeature('hist', 'ss20')

 

 

Substitution instructions (GSUB table)

DancingShoes.AddSubstitution(feature, source, target [, script, language, lookupflag, comment])

Adds a substitution feature lookup. feature is the four-digit feature name, source is a string with the source glyph sequence in FDK notation, and target the target glyph sequence in FDK notation. This is exactly the same syntax that you are used to write your features with. Both source and target may contain space-separated sequences of classes, single glyph names and the single quote used as an identifier for contextual substitution. These sequences are currently not altered, but will land directly in the resulting feature code as they are.
Optional arguments:
script is the lowercase four-digit script code (Link)
language is the uppercase three-digit language code (Link)
lookupflag is a comma-separated list of FDK lookupflags (Link)
comment is a comment to your current substition lookup, in case you want to comment on your weird afii-names.
Returns nothing.

Example:

shoes.AddSubstitution('tnum', 'one', 'one.tf')
shoes.AddSubstitution('smcp', 'a', 'a.sc')
shoes.AddSubstitution('liga', 'f i', 'fi')
shoes.AddSubstitution('dlig', 'f f i', 'uniFB03')
shoes.AddSubstitution('ordn', "[@ordn_numbers @ordn_target] s' t'", 's_t.ordn')
shoes.AddSubstitution('locl', 'i', 'i.latn_TRK', 'latn', 'TRK', '', 'Special version of Turkish "i"')
shoes.AddSubstitution('rlig', 'afii57457 afii57455', 'uniFC61', 'arab', '', 'RightToLeft,IgnoreBaseGlyphs', 'ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM')

 

DancingShoes.AddSimpleSubstitutionFeature(feature, ending)

A shortcut that adds all necessary substitutions for simple direct substitution features, where a glyph name is substituted by a glyph with the same name plus a group ending (e.g. in Small Caps: a will become a.sc).
feature is the four-digit feature name
ending is the glyph group ending, including the dot. (e.g. ".sc")
Returns nothing.

Example:

shoes.AddDirectSubstitutionFeature('smcp', '.sc')
shoes.AddDirectSubstitutionFeature('tnum', '.tf')
shoes.AddDirectSubstitutionFeature('case', '.case')

 

 

Positioning instructions (GPOS table)

DancingShoes.AddSinglePositioning(feature, glyph, adjustment [, script, language, lookupflag, comment])

Adds a positioning feature lookup for a single glyph (GPOS Lookup Type 1). feature is the four-digit feature name, glyph is a string with the source glyph sequence in FDK notation, and adjustment is the positioning value. adjustment may either be a single value for x-advance, or a four-tuple for all positioning values.
Optional arguments:
script is the lowercase four-digit script code (Link)
language is the uppercase three-digit language code (Link)
lookupflag is a comma-separated list of FDK lookupflags (Link)
comment is a comment to your current substition lookup, in case you want to comment on your weird afii-names.
Returns nothing.

Example:

shoes.AddSinglePositioning('cpsp', '@UpperCaseLetters', 10)
shoes.AddSinglePositioning('cpsp', '@UpperCaseLetters', (10, 0, 0, 0))

 

DancingShoes.AddPairPositioning(feature, pair, adjustment [, script, language, lookupflag, comment])

Adds a positioning feature lookup for a pair of glyphs (GPOS Lookup Type 2). Mostly used for kerning.
feature is the four-digit feature name, pair is a string with the space-separated pair of glyph sequence in FDK notation, and adjustment is the positioning value. adjustment may either be a single value for x-advance, or a four-tuple for all positioning values.
Optional arguments:
script is the lowercase four-digit script code (Link)
language is the uppercase three-digit language code (Link)
lookupflag is a comma-separated list of FDK lookupflags (Link)
comment is a comment to your current substition lookup, in case you want to comment on your weird afii-names.
Returns nothing.

Example:

shoes.AddSinglePositioning('kern', 'T A', -30)
shoes.AddSinglePositioning('kern', 'reh.fina heh.init', (-30, 0, -60, 0), 'arab', '', 'RightToLeft')

 

 

Get feature code

DancingShoes.GetFDKCode([version])

Returns all feature code formatted in AFDKO notation.
version is optional. Available: "2.3" and "2.5". Default: "2.5".
Use "2.3" explicitly if you’re working with FontLab Studio 5 and its built-in version of the FDK. This switch works around some bugs with the built-in FDK, especially with more complex code with different scripts, languages and lookupflags. If you’re working in FontLab, and you omit version, DancingShoes will automatically set it to "2.3".

 

DancingShoes.GetFDKFeatureCode(feature [, version])

Returns feature code formatted in AFDKO notation for specific feature.
version is optional. See above.
Use this function to assign feature code to your FontLab’s font object one by one feature.

Example:

f = fl.font
f.features.clean() # optionally clean all previous features first

for feature in shoes.UsedFeatures():
    f.features.append(Feature(feature, shoes.GetFDKFeatureCode(feature)))

 

DancingShoes.GetFDKClassesCode(feature [, version])

Returns classes code formatted in AFDKO notation.
version is optional. See above.
Use this function to assign classes code to your FontLab’s font object.

Example:

f = fl.font
f.ot_classes = shoes.GetFDKClassesCode()

 

 

Warnings, Errors

DancingShoes.Infos()
DancingShoes.Warnings()
DancingShoes.Errors()

Returns string with verbose output.
The DancingShoes object provides some verbose warning and error output, that you can consult after the operation is done.

It distinguishes three levels of occurrences:
Infos() informs you about non-critical opertions, like missing glyphs from your hard-coded instructions. You can most often opt to skip this output.
Warnings() informs you about things that should work, but somehow didn’t, like when you’re trying to add a lookup to a feature which is missing from your supplied features list.
Errors() informs you about critical failures. Not used yet, for future reference.

Example:

if shoes.Warnings():
    print shoes.Warnings()

WARNINGS:
Attempting to add pair positioning lookup to feature "kern", but the feature is not present in your supplied features list

 

 

Helper Functions

helpers.GlyphNamesFromFontLabFont(font)

Pulls a list of glyh names from your FontLab font object.

Example:

from dancingshoes import DancingShoes
from dancingshoes.helpers import GlyphNamesFromFontLabFont

glyphs = GlyphNamesFromFontLabFont(fl.font)
shoes = DancingShoes(glyphs, ('aalt', 'smcp', 'tnum'))

 

helpers.GlyphNamesFromRoboFabFont(font)

Pulls a list of glyh names from your RFont font object.

Example:

from dancingshoes import DancingShoes
from dancingshoes.helpers import GlyphNamesFromRoboFabFont
from robofab.world import CurrentFont

font = CurrentFont()
glyphs = GlyphNamesFromRoboFabFont(font)
shoes = DancingShoes(glyphs, ('aalt', 'smcp', 'tnum'))

 

helpers.SubstitutionsFromCSV(path)

Pulls your list of hard-coded simple substitutions from a CSV file at path. Its fields must be comma-delimited and quote-embraced, like this:

"locl","i","i.latn_TRK","latn","AZE",,"Turkish version of the 'i'"
"liga","f i","fi",,,,

The first three fields (feature, source, target) are required. See AddSubstitution(). The file may contain empty lines and the fields may contain comments starting with #. You can easily edit this file a spreadsheet editor like OpenOffice's Calc or Microsoft Excel.

Example:

from dancingshoes.helpers import SubstitutionsFromCSV
path = '/Users/yanone/Desktop/substitutions.csv'

for feature, source, target, script, language, lookupflag, comment in SubstitutionsFromCSV(path):
    shoes.AddSubstitution(feature, source, target, script, language, lookupflag, comment)

 

helpers.AssignFeatureCodeToFontLabFont(font, shoes)

Assigns all features and classes code from your shoes object to your FontLab’s font object.

Example:

from dancingshoes.helpers import AssignFeatureCodeToFontLabFont
AssignFeatureCodeToFontLabFont(font, shoes)

 

helpers.AssignFeatureCodeToRoboFabFont(font, shoes)

Assigns all features and classes code from your shoes object to your RFont object. Note that you would still have to save it afterwards.

Example:

from dancingshoes.helpers import AssignFeatureCodeToRoboFabFont
AssignFeatureCodeToRoboFabFont(font, shoes)
font.save()

 

 

Usage examples

A sample script to generate features and assign them to a FontLab font is here (Don’t forget to rename the text file to .py).

Version history

0.1.3 – February 7th 2011

  • Function UsedClasses added.
  • Helper function AssignFeatureCodeToGlyphsFont added.
  • Helper function GlyphNamesFromGlyphsFont added.
  • Function DuplicateFeature added.
  • Helper function AssignFeatureCodeToRoboFabFont added.
  • Bug in AddGlyphsToClass fixed.
  • Language systems dflt/dflt and latn/dflt are now added by default.
  • Multiple lookupflags now space-separated, not comma-separated.
  • Split GetFDKClassesCode into GetFDKClassesCode and GetFDKLanguageSystemCode.

0.1.2 – December 14th 2009

  • Helper function AssignFeatureCodeToFontLabFont added.

0.1.1 – December 11th 2009

  • Added work-around for a possible bug in FontLab’s FDK compiler where script latn was preceded by other scripts, including dflt. Sort order changed.
  • Added work-around for a possible bug in FontLab’s FDK compiler where language dflt was preceded by other languages. Sort order changed.

0.1 – Initial release, December 7th 2009

 

What is Dancing Shoes?

Dancing Shoes is a Python-library that provides a friendly interface to create OpenType feature code using simple instructions.
It lets you instruct it with your substitution and positioning lookups in an arbitrary order using simple functions and it will take care of outputting correct and nicely formatted feature code.

Since a lot of type designers and foundries use their own naming schemes for glyph names and the resulting feature code, Dancing Shoes cannot provide you with the perfect and professional feature code for your fonts.
You still have to come up with the features yourself. What it does is to provide you with easy means to tell it how you want your substitutions, and it will take care of the correct code output. Once you have gathered all substitutions for your glyph naming scheme, Dancing Shoes is your one-click feature code solution.

The main idea is that you can throw any amount of substitutions from your hard-coded files at it, and Dancing Shoes will only add those feature, whose participating glyphs are actually present in the font’s glyph repertoire, which you supply on each generation operation. This way you have to sit down once to harvest all the substitutions you want, including scripts to dynamically generate substitutions or positioning from the data source of your choice, and can apply this to all your fonts following your naming scheme as a recurring task.

 

This works:

  • Simple substitutions ("f" & "i" >> "fi")
  • More complex substitutions for other languages and scripts, including different lookupflags.
  • Positioning lookups
  • Shortcuts for simple direct substitution features (all lowercase glyphs will become small caps ['a' >> 'a.sc'], all figures will become table figures ['one' >> 'one.tf'])
  • Output of feature code for AFDKO, which is also built into FontLab Studio.

This doesn’t work yet, but is intended:

  • Output code for other OpenType compilers, like Microsoft’s VOLT.
  • Read previous versions of feature code to add protected lookups, or alter existing code.
  • Shortcut to write kern-feature for your FontLab and RoboFab font objects.

You like it?
Please donate a bit.

The use of this software is free of charge, even for commercial use.

However, if you use it for professional font production, please feel free to donate some ca$$$h to my PayPal account.

 

Copyright 2014 by Yanone. Impressum