Substitute multiple

In calt, this works:
sub space t by t ;
and this:
sub @t by @t space ;

But this does not work:
sub space @t by @t ;

I would like to use this type of substitute, if implementation is possible.
If nothing else, the alert “Cannot substitute by multiple ligature glyphs” seems to be incorrect.

It looks like what you want is to delete a glyph. Have a look at the Handbook:

1 Like

That is very useful, thank you.

However, in this particular case it does not seem to work in Photoshop, possibly because the program does not like that I delete the space character.
Also in any case where you’d just want to delete a character when it occurs ahead of a particular set of characters, my suggested solution would be useful.

Does it work in other apps, for example in FontGoggles?

While I agree that it should work in Photoshop, it is however not a good testing environment (Adobe apps are still very buggy in many cases, especially the ones that don’t have typography written all over their foreheads). So if it does not work in Photoshop, it does not necessarily mean that the font fails at that job.

FontGoggles or even simple HTML+CSS are better tools to test.

How does your @t class look like?

Yes, you are right. But in this particular case it must work in PS. Whether delete space; works in general is a different question.

It is just an example and I tried different classes, but it is "t t.ss05"

Opentype with the space is very spotty in adobe apps. They use some custom space glyph is something. That breaks normal substitutions if the space is in the context.

Yes. The issue in Adobe seems to arise mainly when space is the last character. For example sub space t by t ; works fine, in both Glyphs and Adobe.

However, my initial question was if there is any way to make the same setup work, but with groups. It appears as though it should work, and it’s simply Glyphs that does not accept specifically sub space @t by @t ;, because of no (apparent) reason.

When writing

sub space @t by @t;

what you are attempting to do is a so-called ligature substitution, since multiple glyphs are replaced by a single glyph. Technically, it’s a GSUB LookupType 4, as outlined in Adobe’s documentation:

And in this documentation the definition for a GSUB LookupType 4 rule is:

substitute <glyph sequence> by <glyph>;

This tells you that after the by, you can just have a single glyph, not a glyph class (or “group”). Otherwise, it would be written <glyph|glyphclass> to also allow glyphs classes after the by.

The feature code in Glyphs uses the same notation as Adobe’s documentation describes it (with a few additions).

In your case, we don’t need to extend GSUB LookupType 4 rules, since the delete (or sub … by NULL) rules linked above suffice.

Thank you, yes, I see now how it makes sense.

What I am missing in that case is to condition the delete to only disappear when in a certain context.

Here is my current solution:

sub space A by A;
sub space B by B;
(...)
sub space y by y;
sub space z by z;

Which in my case produces a different result than:

sub space' [@AZ @az] by NULL;

(Maybe this is very case specific and it works equally good in 99% of all other applications.)

Different in what way? It should work the same.

I agree. So it is interesting I get different results, but again, it is a very specialized font. I have a lot of stuff going on in the features that may affect in different ways, although it is unexpected.
For my part I am ok with my current solution. If you have any further curiosity about why or how it is different, I would be happy to share the results privately. Just send me a message in that case.

@mawns
Alternatively, it could be made in two steps operation.

On a first step – replace space with an alternate no-width space, in the context of your @t class. You need to create this alternate space glyph and make it zero width, it could be called like space.nowidth. Such an approach will preserve your source text, that mean space is still space for a copy/paste purposes.

On a second step – replace the @t class, if you still need to replace it, in the context of the no-width space.

sub space' @t by space.nowidth;
sub space.nowidth @t' by @t2;