Contextual ligatures?

Hi!

I’m working on a font that has ligatures of prepositions and common words in English. There are two versions of each word/ligature – upright and slanted. At the moment I have them set up as a dlig (upright) with a stylistic set for the dlig in slanted versions.

I have two questions, I guess:

  1. Is the liga + ss the best way to go to achieve this, from a user perspective?

  2. Is there a way to only apply these ligatures if there aren’t any characters before or after (not counting space) so the ligatures only kicks in if it’s the actual word by itself and not characters within another word? From a user perspective this would be a nice feature.

Maybe this has been answered before, but I searched this forum and didn’t find the answer I was looking for. I am a Glyphs noob. I’ve been working with Fontself in Adobe Illustrator for years but I finally got tired of the lack of features. I got Glyphs less than 24 hours ago and I’ve already solved several issues I’ve had for years. :partying_face:

Ok, so I think I managed to get it right using the AllLetters class and the following code in the Discretionary Ligature feature:

lookup NiceLigas {
script latn;
ignore sub @AllLetters a' n' d', a' n' d' @AllLetters;
ignore sub @AllLetters A' n' d', A' n' d' @AllLetters;
ignore sub @AllLetters A' N' D', A' N' D' @AllLetters;

ignore sub @AllLetters a' r' e', a' r' e' @AllLetters;
ignore sub @AllLetters A' r' e', A' r' e' @AllLetters;
ignore sub @AllLetters A' R' E', A' R' E' @AllLetters;

ignore sub @AllLetters a' t', a' t' @AllLetters;
ignore sub @AllLetters A' t', A' t' @AllLetters;
ignore sub @AllLetters A' T', A' T' @AllLetters;

ignore sub @AllLetters b' y', b' y' @AllLetters;
ignore sub @AllLetters B' y', B' y' @AllLetters;
ignore sub @AllLetters B' Y', B' Y' @AllLetters;

ignore sub @AllLetters c' o', c' o' @AllLetters;
ignore sub @AllLetters C' o', C' o' @AllLetters;
ignore sub @AllLetters C' O', C' O' @AllLetters;

ignore sub @AllLetters e' s' t', e' s' t' @AllLetters;
ignore sub @AllLetters E' s' t', E' s' t' @AllLetters;
ignore sub @AllLetters E' S' T', E' S' T' @AllLetters;

ignore sub @AllLetters f' e' a' t', f' e' a' t' @AllLetters;
ignore sub @AllLetters F' e' a' t', F' e' a' t' @AllLetters;
ignore sub @AllLetters F' E' A' T', F' E' A' T' @AllLetters;

ignore sub @AllLetters f' o' r', f' o' r' @AllLetters;
ignore sub @AllLetters F' o' r', F' o' r' @AllLetters;
ignore sub @AllLetters F' O' R', F' O' R' @AllLetters;

ignore sub @AllLetters f' r' o' m', f' r' o' m' @AllLetters;
ignore sub @AllLetters F' r' o' m', F' r' o' m' @AllLetters;
ignore sub @AllLetters F' R' O' M', F' R' O' M' @AllLetters;

ignore sub @AllLetters i' n', i' n' @AllLetters;
ignore sub @AllLetters I' n', I' n' @AllLetters;
ignore sub @AllLetters I' N', I' N' @AllLetters;

ignore sub @AllLetters i' s', i' s' @AllLetters;
ignore sub @AllLetters I' s', I' s' @AllLetters;
ignore sub @AllLetters I' S', I' S' @AllLetters;

ignore sub @AllLetters o' f', o' f' @AllLetters;
ignore sub @AllLetters O' f', O' f' @AllLetters;
ignore sub @AllLetters O' F', O' F' @AllLetters;

ignore sub @AllLetters o' n', o' n' @AllLetters;
ignore sub @AllLetters O' n', O' n' @AllLetters;
ignore sub @AllLetters O' N', O' N' @AllLetters;

ignore sub @AllLetters o' r', o' r' @AllLetters;
ignore sub @AllLetters O' r', O' r' @AllLetters;
ignore sub @AllLetters O' R', O' R' @AllLetters;

ignore sub @AllLetters o' u' r', o' u' r' @AllLetters;
ignore sub @AllLetters O' u' r', O' u' r' @AllLetters;
ignore sub @AllLetters O' U' R', O' U' R' @AllLetters;

ignore sub @AllLetters t' h' a' n', t' h' a' n' @AllLetters;
ignore sub @AllLetters T' h' a' n', T' h' a' n' @AllLetters;
ignore sub @AllLetters T' H' A' N', T' H' A' N' @AllLetters;

ignore sub @AllLetters t' h' a' t', t' h' a' t' @AllLetters;
ignore sub @AllLetters T' h' a' t', T' h' a' t' @AllLetters;
ignore sub @AllLetters T' H' A' T', T' H' A' T' @AllLetters;

ignore sub @AllLetters t' h' e', t' h' e' @AllLetters;
ignore sub @AllLetters T' h' e', T' h' e' @AllLetters;
ignore sub @AllLetters T' H' E', T' H' E' @AllLetters;

ignore sub @AllLetters t' o', t' o' @AllLetters;
ignore sub @AllLetters T' o', T' o' @AllLetters;
ignore sub @AllLetters T' O', T' O' @AllLetters;

ignore sub @AllLetters w' i' t' h', w' i' t' h' @AllLetters;
ignore sub @AllLetters W' i' t' h', W' i' t' h' @AllLetters;
ignore sub @AllLetters W' I' T' H', W' I' T' H' @AllLetters;

ignore sub @AllLetters y' o' u' r', y' o' u' r' @AllLetters;
ignore sub @AllLetters Y' o' u' r', Y' o' u' r' @AllLetters;
ignore sub @AllLetters Y' O' U' R', Y' O' U' R' @AllLetters;

sub a' n' d' by A_N_D.dlig;
sub A' n' d' by A_N_D.dlig;
sub A' N' D' by A_N_D.dlig;

sub a' r' e' by A_R_E.dlig;
sub A' r' e' by A_R_E.dlig;
sub A' R' E' by A_R_E.dlig;

sub a' t' by A_T.dlig;
sub A' t' by A_T.dlig;
sub A' T' by A_T.dlig;

sub b' y' by B_Y.dlig;
sub B' y' by B_Y.dlig;
sub B' Y' by B_Y.dlig;

sub c' o' by C_O.dlig;
sub C' o' by C_O.dlig;
sub C' O' by C_O.dlig;

sub e' s' t' by E_S_T.dlig;
sub E' s' t' by E_S_T.dlig;
sub E' S' T' by E_S_T.dlig;

sub f' e' a' t' by F_E_A_T.dlig;
sub F' e' a' t' by F_E_A_T.dlig;
sub F' E' A' T' by F_E_A_T.dlig;

sub f' o' r' by F_O_R.dlig;
sub F' o' r' by F_O_R.dlig;
sub F' O' R' by F_O_R.dlig;

sub f' r' o' m' by F_R_O_M.dlig;
sub F' r' o' m' by F_R_O_M.dlig;
sub F' R' O' M' by F_R_O_M.dlig;

sub i' n' by I_N.dlig;
sub I' n' by I_N.dlig;
sub I' N' by I_N.dlig;

sub i' s' by I_S.dlig;
sub I' s' by I_S.dlig;
sub I' S' by I_S.dlig;

sub o' f' by O_F.dlig;
sub O' f' by O_F.dlig;
sub O' F' by O_F.dlig;

sub o' n' by O_N.dlig;
sub O' n' by O_N.dlig;
sub O' N' by O_N.dlig;

sub o' r' by O_R.dlig;
sub O' r' by O_R.dlig;
sub O' R' by O_R.dlig;

sub o' u' r' by O_U_R.dlig;
sub O' u' r' by O_U_R.dlig;
sub O' U' R' by O_U_R.dlig;

sub t' h' a' n' by T_H_A_N.dlig;
sub T' h' a' n' by T_H_A_N.dlig;
sub T' H' A' N' by T_H_A_N.dlig;

sub t' h' a' t' by T_H_A_T.dlig;
sub T' h' a' t' by T_H_A_T.dlig;
sub T' H' A' T' by T_H_A_T.dlig;

sub t' h' e' by T_H_E.dlig;
sub T' h' e' by T_H_E.dlig;
sub T' H' E' by T_H_E.dlig;

sub t' o' by T_O.dlig;
sub T' o' by T_O.dlig;
sub T' O' by T_O.dlig;

sub w' i' t' h' by W_I_T_H.dlig;
sub W' i' t' h' by W_I_T_H.dlig;
sub W' I' T' H' by W_I_T_H.dlig;

sub y' o' u' r' by Y_O_U_R.dlig;
sub Y' o' u' r' by Y_O_U_R.dlig;
sub Y' O' U' R' by Y_O_U_R.dlig;
} NiceLigas;

It seems to be working just fine.
But is this a good approach or are there better/smarter ways of writing this code?

You can simplify it a bit like this:

ignore sub @AllLetters [A a]' [N n]' [D d]', [A a]' [N n]' [D d]' @AllLetters;
sub [A a]' [N n]' [D d]' by A_N_D;

And for manually feature code, you don’t need the “.dlig” suffix.

Ah, thank you!

But if I don’t use the “.dlig” suffix I get an error in the code. I am entering this code in the dlig feature, is that incorrect?

Remove the suffix from the glyphs, too.

Ah! I guess I thought ligature glyphs had to have the liga suffix.

It works perfectly. Thank you so much!

Just a thought: wouldn’t it be more reliable, versatile and easier from all POVs to have those as separate instances? :slight_smile:

How do you mean? A separate font?

Yes, just the whole font with the lines so that the user could set anything in different styles. The slanted version is tricky of course, I’d try solving it with OT positioning.

Oh, I see what you’re getting at. But no. Not at this time. At the moment these ligatures are meant to work only as an extra feature to this typeface.

The design of the ligatures are supposed to work together with the other glyphs in this typeface.