Jetons

Tutorial
by Rainer Erich Scheichelbauer
en fr

22 December 2020

Bien entendu vous pouvez toujours écrire tout votre code de fonction vous-mêmes. Mais ce n’est pas nécessaire. Les jetons vous aident à automatiser votre code de fonction de manière futée.

Ajoutez du code de fonction dynamique avec des jetons. D’un point de vue syntaxique, les jetons sont des morceaux de code qui suivent un signe $ dollar. Vous pouvez utiliser les jetons pour deux raison: interpoler les valeurs numériques et les prédicats de classes de glyphes pour faire la collecte des noms de glyphes.

Valeurs numériques

Pour commencer, vous pouvez utiliser la syntaxe de jeton valeur numérique plutôt que la syntaxe bâclée ‘jeton numérique’. Les valeurs numériques sont définies sous Fichier > Informations de police > Masters > Valeurs numériques. En résumé, les valeurs numériques sont des variables qui s’interpolent. Par exemple, dans Masters, définissez une valeur numérique pad de 50 pour le master maigre, et de 5 pour le master gras:

Dans votre code de fonction, vous pouvez ajouter une fonction kern (crénage) avec quelque chose comme ceci:

pos @L @A $pad;

Puis dans le code de fonction GPOS qui en résulte, la valeur pad respective interpolée sera insérée à la place du jeton. Sympa. Et si vous avez besoin de quelque chose de plus complexe? Ajoutons une fonction cpsp (d’espacement des capitales) avec une règle de positionnement comme ceci:

pos @brackets <$pad 0 ${pad*2} 0>;

Vous avez bien vu. À l’intérieur d’une structure ${...}, vous pouvez ajouter des calculs. C’est très utile pour toutes sortes de codes GPOS manuels. Un bon exemple se trouve dans le tutoriel Positionner avec des valeurs numériques.

Prédicats de classe de glyphes

Les prédicats de classe de glyphes aussi référés sous les noms ‘jetons de classe’ ou ‘jetons prédicats’, ont une structure $[...], sont dynamiquement élargis en une liste de noms de glyphes séparés par des espaces; ce qui est utile pour les définitions de classe dans votre code de fonction OpenType. Vous placez le code Apple NSPredicate entre les crochets afin de filtrer les glyphes. Cela fonctionne de façon semblable à un filtre futé en mode Aperçu police (Cmd-Opt-1). En fait, sous le capot, les filtres futés utilisent le NSPredicate.

Un exemple:

sub [ $[case==smallCaps] ] slash' by slash.sc;

La structure $[case==smallCaps] consiste en l’objet case, un opérateur de comparaison == et une valeur smallCaps. Dans ce cas particulier, la valeur est l’une des ces constantes prédéfinies: noCase, upper, lower, smallCaps, minor et other. Les constantes correspondent aux options dans les informations de glyphe accessibles via Édition > Informations de la sélection. Le jeton est donc étendu en une liste de noms de glyphes séparés d’une espace; ces noms correspondent à cette comparaison que le prédicat évalue comme vraie: dans ce cas, tous les glyphes ou la casse est égale à des petites capitales. En d’autres mots, nous obtiendrons a.sc b.sc c.sc d.sc et ainsi de suite. La ligne complète est donc développée ainsi:

sub [ a.sc b.sc c.sc d.sc ] slash' by slash.sc;

… et fort probablement beaucoup, beaucoup plus de glyphes que les quatre ci-haut. Ce qui est vraiment bien est que cela se fait dynamiquement, nul besoin de recueillir vous-mêmes tous les glyphes petites capitales, ou de vous soucier de sous-ensembles, puisque ce code de fonction est en tout temps mis a jour automatiquement. De plus, vous pouvez insérer ce jeton n’importe où dans votre code Prefix, Classes ou Features. Afin de vérifier un jeton prédicat, Opt-cliquez sur le code de jeton et une liste de glyphes surgira:

L’aperçu est valide pour l’ensemble actuel de glyphes exportables, et sera affiché avec les glyphes du master présentement sélectionné.

Récapitulons. Un jeton prédicat débute avec un signe dollar $, suivi de crochets [], à l’intérieur desquels nous plaçons un objet de comparaison. Un objet de comparaison est une expression logique qui compare une propriété spécifique de chaque glyphe exportable (l’‘objet prédicat’) à une valeur, habituellement un nombre ou une chaîne. Pour la comparaison, il utilise l’un des opérateurs de comparaison NSPredicate disponibles. Chaque glyphe pour lequel l’expression s’avère vraie se retrouvera sur l’éventuelle liste de noms de glyphes.

Objets prédicats

En principe, tout attribut de l’objet GSGlyph est un objet valide pour une expression prédicat. Vous pouvez exécuter print("\n".join(dir(GSGlyph))) dans la fenêtre Macro puis dénicher les prédicats dans le résultat. Vous pouvez consulter la documentation de GSGlyph sur docu.glyphsapp.com.

Objets booléens

Une propriété de glyphe booléenne peut évaluer si cela est true ou false(vrai ou faux), ou encore dans une épellation alternative, yes ou no (oui ou non). Vous pouvez donc faire la comparaison de cette façon: $[hasComponents == true]. Les propriétés de glyphe suivantes sont disponibles:

hasAlignedWidth
hasAnnotations
hasComponents
hasCorners
hasCustomGlyphInfo
hasHints
hasPostScriptHints
hasSpecialLayers
hasTrueTypeHints
isAligned
isAppleColorGlyph
isColorGlyph
isCornerGlyph
isHangulKeyGlyph
isSVGColorGlyph
isSmartGlyph
justLocked
locked
mastersCompatible
outlineHasChanges

Objets numériques

Les nombres peuvent être entiers ou avec décimales. Ils peuvent être comparés à d’autres nombres avec les opérations mathématiques habituelles, par exemple $[countOfUnicodes > 0]. Les propriétés suivantes sont disponibles:

case
changeCount
colorIndex
countOfLayers
countOfPartsSettings
countOfTags
countOfUnicodes
direction

Il est vrai que techniquement, case est un nombre entier, mais normalement vous en feriez la comparaison avec les constantes que j’ai mentionnées précédemment.

De nombreuses valeurs numériques qui vous tiennent à cœur sont attachées aux calques, et non aux glyphes, p. ex., layer0.width, layer0.LSB, etc. Pour des informations sur les propriétés de calques qui sont disponibles, jetez un coup d’œil à la documentation GSLayer sur docu.glyphsapp.com.

Objets de chaîne

Des chaînes sont des morceaux de texte. Vous pouvez les comparer à une chaîne de référence de cette façon: $[name like "*.ss01*"]. Cette chaîne de référence doit être tapée entre des apostrophes dactylographiques "..." dt peut contenir des jokers comme *. Les propriétés de glyphe suivantes sont disponibles sous forme de chaînes:

baseString
bottomKerningGroup
bottomMetricsKey
category
charName
charString
description
glyphDataEntryString
lastChange
leftKerningGroup
leftKerningKey
leftMetricsKey
name
note
production
productionName
rightKerningGroup
rightKerningKey
rightMetricsKey
script
sortName
sortNameKeep
string
subCategory
topKerningGroup
topMetricsKey
unicode
unicodeChar
unicodeString
vertWidthMetricsKey
widthMetricsKey

Objets complexes

Habituellement vous accéderiez à leurs attributs, tels layer0.width.

glyphInfo 
layer0
userData

Le seul qui ait vraiment du sens est layer0 qui représente le premier calque du glyphe, c’est-à-dire, le premier master. Vous pouvez accéder ses propriétés GSLayer avec la familière notation avec point. properties with the familiar dot notation. Vous pouvez même creuser dans l’arbre d’objet et faire des choses comme $[layer0.anchors.top.y > 600].

Presque tous les objets glyphInfo comme unicode, script ou subCategory sont accessibles directement comme des attributs de glyphes; vous n’aurez donc pas souvent besoin de glyphInfo, excepté peut-être pour les glyphInfo.accents, mais j’ignore à quoi cela pourrait bien servir. Et userData peut être n’importe quoi, mais n’est vraiment accessible que grâce à l’écriture de scripts. Cela n’aura donc du sens seulement dans des conditions très particulières.

Opérateurs et composés de comparaison

Selon la documentation NSPredicate, vous pouvez utiliser les opérateurs de comparaison suivants avec autant d’espace blanc que vous voulez, en bas de casse et capitales, selon ce qui fonctionne mieux pour vous.

  • BEGINSWITH L’objet débute avec la valeur, p. ex., $[name beginswith "x"]
  • CONTAINS L’objet contient la valeur, p. ex., $[name contains ".alt"]
  • ENDSWITH L’objet termine avec la valeur, p. ex., $[name endswith ".sc"]
  • LIKE L’objet est égal à la valeur; ? et sont permis comme caractères de remplacement, où ? correspond à 1 caractère et correspond à 0 ou plus de caractères. Par exemple: $[name like "?.sc" or name like "*.sc*"]
  • MATCHES L’objet est équivalent à l’expression du côté droit using a regex-style comparison according to ICU v3. This only makes sense for regex nerds. If you do not know what regular expressions are, ignore this.
  • =, == L’objet est égal à la valeur. $[layer0.LSB = 0]
  • >=, => L’objet est plus grand que ou égal à la valeur. $[layer0.RSB >= 0]
  • <=, =< L’objet est plus petit que ou égal à la valeur. $[layer0.countOfPaths <= 3]
  • > L’objet est plus grand que la valeur. $[countOfUnicodes > 1]
  • < L’objet est plus petit que la valeur. $[layer0.LSB < 0]
  • !=, <> L’objet n’est pas égal à la valeur. $[layer0.countOfHints != 0]
  • BETWEEN L’objet est entre, ou égal à l’une des deux, les deux valeurs étant placées entre accolades et séparées par une virgule. Par exemple, $[layer0.width between {400,600}] ou $[name between {"V","Z"}]
  • IN L’objet doit apparaître dans la collection de valeurs, celles-ci étant placées entre accolades et séparées par une virgule. $[layer0.width in {200, 400, 600}] (Techniquement, IN est une agrégation, mais je l’inclus tout de même ici.)

Compounds sont des concaténations logiques de multiples comparaisons. Vous les reconnaîtrez si vous êtes déjà familier avec le codage:

  • AND, && AND logique, combine deux ou plusieurs comparaisons. L’expression entière est évaluée vraie seulement si toutes les comparaisons sont vraies. P. ex., $[layer0.LSB < 0 and layer0.RSB < 0]
  • OR, || OR logique, combine deux ou plusieurs comparaisons. L’expression entière est évaluée vraie si au moins l’une des comparaisons est vraie. P. ex., $[name endswith "superior" or name beginswith "ord"]
  • NOT, ! opérateur logique NOT, invalide toutes les comparaisons qui suivent. Ce qui est un peu délicat est d’ajouter un préfixe à un prédicat afin de l’invalider. P. ex., $[not layer0.width in {200, 400, 600}] sélectionne tous les glyphes pour lesquels la chasse du premier n’est pas l’un des trois nombres.

Code échantillon

En guise d’inspiration, voici un aide-mémoire pour les jetons prédicats:

$[name endswith '.sc'] # will expand to all glyph names that end in ".sc"
$[layer0.width < 500] # layer0 = first master
$[layers.count > 1] # compare numbers with: == != <= >= < >
$[direction == 2] # 0=LTR, 1=BiDi, 2=RTL
$[colorIndex == 5]
$[case == smallCaps] # predefined constants: noCase, upper, lower, smallCaps, minor, other
$[name matches "S|s.*"] # "matches": regular expression
$[leftMetricsKey like "*"] # "like": wildcard search
$[name like "*e*"] # e anywhere in the glyph name
$[script like "latin"]
$[category like "Separator"]
$[leftKerningGroup like "H"]
$[rightKerningGroup like "L"]
$[unicode beginswith "03"] # beginswith, endswith, contains
$[note contains "love it"] # glyph note
$[countOfUnicodes > 1]
$[countOfLayers > 1]
$[subCategory like "Arrow"]
$[hasHints == 0] # boolean: false, no, 0 versus true, yes, 1
$[isColorGlyph == true]
$[hasComponents == true and script == "latin"] # connect multiple conditions with ORor AND
$[hasTrueTypeHints == false]
$[hasAlignedWidth == true]
$[hasPostScriptHints == true]
$[hasAnnotations == true]
$[hasCorners == true] # corners = corner components
$[hasSpecialLayers == yes] # special layers = color, brace and bracket layers
$[isHangulKeyGlyph == no]

Whaouh, il y a de quoi satisfaire les geeks parmi nous, ce qui me laisse vraiment curieux de découvrir quels usages vous en ferez. Amusez-vous bien!


Traduction française de Nathalie Dumont.