Hey all, so I’m trying to write an Ordinal feature that will substitute sequences of letters like TH, RD, and ND with the corresponding modifier glyphs when placed after a number.

I’ve tried all sorts of different things so far but the closest I’ve got to getting it to work is the following:

sub [zero one two three four five six seven eight nine] [A a]’ by ordfeminine;
sub [zero one two three four five six seven eight nine] [O o]’ by ordmasculine;
sub [zero one two three four five six seven eight nine] [T H]’ by [tmod hmod];
sub [zero one two three four five six seven eight nine] [R D]’ by [rmod dmod];
sub [zero one two three four five six seven eight nine] [N D]’ by [nmod dmod];

The problem is that this code doesn’t successfully substitute the second letter.

You are trying to do a contextual many to many substitution. That is not supported by OpenType or more precisely the Adobe Feature file syntax.
Something like this might work:

sub [zero one two three four five six seven eight nine] [N]' [D] by nmod;
sub [zero one two three four five six seven eight nine] [nmod] [D]' by dmod;

I know a few years late but after looking for the best way to do ordinals this thread helped me but I was a little confused. This may help someone or someone could tell me a better way. I made these characters
s.ordn
t.ordn
n.ordn
d.ordn
r.ordn
h.ordn
And this code in Features-ordn is working for me.

sub [zero one two three four five six seven eight nine] [s]' [t] by s.ordn;
sub [zero one two three four five six seven eight nine] [s.ordn] [t]' by t.ordn;
sub [zero one two three four five six seven eight nine] [S]' [T] by s.ordn;
sub [zero one two three four five six seven eight nine] [s.ordn] [T]' by t.ordn;
sub [zero one two three four five six seven eight nine] [N]' [D] by n.ordn;
sub [zero one two three four five six seven eight nine] [n.ordn] [D]' by d.ordn;
sub [zero one two three four five six seven eight nine] [n]' [d] by n.ordn;
sub [zero one two three four five six seven eight nine] [n.ordn] [d]' by d.ordn;
sub [zero one two three four five six seven eight nine] [r]' [d] by r.ordn;
sub [zero one two three four five six seven eight nine] [r.ordn] [d]' by d.ordn;
sub [zero one two three four five six seven eight nine] [R]' [D] by r.ordn;
sub [zero one two three four five six seven eight nine] [r.ordn] [D]' by d.ordn;
sub [zero one two three four five six seven eight nine] [t]' [h] by t.ordn;
sub [zero one two three four five six seven eight nine] [t.ordn] [h]' by h.ordn;
sub [zero one two three four five six seven eight nine] [T]' [H] by t.ordn;
sub [zero one two three four five six seven eight nine] [t.ordn] [H]' by h.ordn;

You could somewhat shorten your code by adding a class (for example) “Numbers” on the Features panel. Write one two three ... in there and substitute your lines [one two three ...] in your feature code by @Numbers.

@NUMBERS = [zero one two three four five six seven eight nine];
sub @NUMBERS [s S]' [t T] by s.ordn;
sub @NUMBERS [n N]' [d D] by n.ordn;
sub @NUMBERS [r R]' [d D] by r.ordn;
sub @NUMBERS [t T]' [h H] by t.ordn;
sub @NUMBERS [s.ordn S.ordn] [t T]' by t.ordn;
sub @NUMBERS [r.ordn R.ordn n.ordn N.ordn] [d D]' by d.ordn;
sub @NUMBERS [t.ordn T.ordn] [h H]' by h.ordn;