Solved. Here are the steps I took for s -> longs substitution
The rules are that s -> longs except at the end of a word. Also, u s -
> u_s, i s -> i_s, a s -> a_s only at the end of a word.
Other ligatures are longs longs -> longs_longs, etc.
The solution is to add Lookups in the GSUB section of the font info as
1. Add a Ligature Substitution lookup, with tag liga. These ligature
substitutions will be applied all the time, unless undone by a
following lookup (which is the key). The ligatures are:
u s -> u_s
i s -> i_s
a s -> a_s
longs longs -> longs_longs
other longs ligatures, but NOT s -> longs.
2. Add a Single Substitution lookup, with NO tags. Call it "Untagged
Ligature Compositions". The subtable should map s -> longs.
3. Add another Single Substitution lookup, with NO tags. Call it
"Untagged Ligature Decompositions". The subtable should map:
u_s -> u s (Base Glyph Name = u_s, Replacement Glyph Name = u s)
i_s -> i s
a_s -> a s
4. Add a Contextual Chaining Substitution lookup, with tag calt.
4a. Add a subtable using coverage classes. For match, enter: u_s i_s
a_s. This means to match any of those. For Lookahead, enter any
lowercase letter and ligature that can come after u_s, i_s, or a_s
which should force that ligature to be decomposed. Finally, for the
ordered list of sequence positions and lookup tags, enter 0 Untagged
4b. Add another subtable using coverage classes. For match, enter: s.
For lookahead, again enter any lowercase letter and ligature that can
come after s which should force s to turn into longs. Finally, for the
ordered list, enter 0 Untagged Ligature Compositions.
5. Order the lookups in GSUB as follows (very important!)
5a. The calt lookup, with subtables ordered as follows:
5a1. The subtable for u_s i_s a_s.
5a2. The subtable for s.
5c. Untagged Ligature Compositions
5d. Untagged Ligature Decompositions.
Now you can just follow the lookups in order. If you type "u s", then
when you type s, you go through calt, which does nothing, Ligatures,
which turns u s into u_s. Then, when you type another s (so you have
"u_s s"), you go through calt, which matches 5a1, triggering the
decomposition to "u s s", and then 5a2 triggers the composition to "u
If you were to type s again, you end up with "u longs_longs s". And so