If I type ‘e’ it’s fairly easy to make the next letter an ‘m.002’ in this case, but once the ‘m.002’ is triggered, the ‘e’ would need to turn into an ‘e.004’. I then type another ‘m’, it would need to come out as an ‘m.002’ and the previous ‘m.002’ would need to change into a ‘m.003’.
Difficult to explain but I hope the picture illustrates the type of sequences I would need this to work for. I basically want to find out if by typing a glyph it will be able to change the glyph before it. When I do simple substitutions with the calt feature I immediately run into conflicts (if I’ve subbed e m’ by m.002;, then e’ m.002 by e.004; the second command contradicts the first one) which gets more complicated with 3 character sequences. I’ve tried with classes too and keep running into similar problems. In total I have the alphabet organized into 6 classes, not all glyphs need every glyph in the alphabet.
Just curious if this is possible or if I need to stop trying to figure this out and try another solution. Only other thing I can think of is making perhaps an unrealistic amount of ligatures. I’m not a coder and have only learned the basics of contextual alternatives and ligatures, trying to teach myself something new with each font I make. Is what I want to do impossible?
Short answer: it’s not impossible, but you won’t get there with a single calt rule. You need to break the logic into multiple lookups that run in sequence, so that a later lookup can “reconsider” glyphs that were substituted earlier.
Very simplified idea (pseudocode, not copy‑pasteable yet):
First lookup: turn base sequences into your first contextual alternates
e.g. sub e m' by m.002;
Second lookup: adjust the context before or around that new glyph
e.g. sub e' m.002 by e.004 m.002;
Third lookup: handle longer chains like e m m
e.g. sub m.002' m by m.003 m.002;
The important part is that each of these is in its own named lookup, and the lookups are called in order in calt. That way the second (and third, etc.) lookup sees the already‑substituted glyphs (m.002, e.004, m.003) and can further refine them, instead of all the rules fighting each other inside one big block.
Conceptually:
Think “stages”:
Stage 1 = “rough” alternates (first level of contextual substitution)
Stage 2 = clean‑up / refinement (e.g. “if there’s an m.002 after an e, make that e into e.004”)
Stage 3+ = special cases for longer runs (mmm, different classes, etc.)
Conflicts you’re seeing (sub e m' by m.002; vs sub e' m.002 by e.004;) come from trying to do all of this in one pass. Once you separate those into different lookups, they stop contradicting each other, because they no longer apply at the same time.
You can also group things with classes instead of hard‑coding e and m, so you don’t need an insane number of ligatures. The pattern is the same: define your classes, then layer 2–3 lookups that gradually refine shapes based on context.
So: your idea is possible, but the implementation needs a little OpenType “plumbing” with multiple lookups, not just one calt block.
# Stage 1: base contextual alternates
lookup stage1_base {
# simple example: after "e", turn "m" into "m.002"
sub e m' by m.002;
} stage1_base;
# Stage 2: refine shapes based on the result of stage 1
lookup stage2_refine {
# if we now have "e m.002", change the "e" to "e.004"
sub e' m.002 by e.004 m.002;
} stage2_refine;
# Stage 3: handle longer chains / special cases
lookup stage3_chain {
# if we have "e.004 m.002 m", turn that middle m.002 into m.003
sub m.002' m by m.003 m.002;
# (you could add more rules here for other patterns)
} stage3_chain;
You are awesome, thank you so much! I’ve been struggling with this for the last week and was worried I’ve been wasting my time. I’ll have to play around with this to fully understand it but really happy to see it can be done.
I have the 6 different classes that cover every possible combination so I’m hoping I can do it that way.