diff --git a/build-plans.toml b/build-plans.toml index 16f12d555..3626a084f 100644 --- a/build-plans.toml +++ b/build-plans.toml @@ -695,7 +695,7 @@ i = "serifless" j = "flat-hook-serifless" k = "straight-serifless" l = "serifless" -r = "compact" +r = "compact-serifless" t = "flat-hook" u = "toothed-serifless" w = "straight-flat-top-serifless" @@ -727,7 +727,7 @@ i = "serifed" j = "flat-hook-serifed" k = "straight-serifless" l = "serifed" -r = "compact" +r = "compact-serifless" t = "flat-hook" u = "toothed-serifless" w = "straight-flat-top-serifless" diff --git a/changes/24.0.0.md b/changes/24.0.0.md index a3d1476dc..b42aa6f90 100644 --- a/changes/24.0.0.md +++ b/changes/24.0.0.md @@ -1,8 +1,10 @@ * \[**BREAKING**\] Add taller slash, broken slash and broken zero variants for Zero. As a result, current variants are reordered (#1307, #1509, #1678). * \[**BREAKING**\] Add above-baseline crossed variant for Q. As a result, current variants are reordered (#1533). * \[**BREAKING**\] Rectify the variant atlas. As a result, if a character's variant list has motion-serifed, then it will have serifless and serifed variants: the serifed-ness will no longer be controlled by SLAB variable. The characters influenced are `M`, `N`, `P`, `R`, `U`, `V`, `W`, `b`, `h`, `m`, `n`, `p`, `q`, `u`, `v`, `w`, `y`. -* \[**BREAKING**\] Reordered the variants of the following letters: +* \[**BREAKING**\] Renamed and/or reordered the variants of the following letters: - `K`, `k`, Cyrillic Ka. + - `r`. + - `W`, `w`. * Add Characters: - CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN (`U+29BC`). - CIRCLED WHITE BULLET (`U+29BE`). diff --git a/font-src/glyphs/index.ptl b/font-src/glyphs/index.ptl index d19758360..09b7afc08 100644 --- a/font-src/glyphs/index.ptl +++ b/font-src/glyphs/index.ptl @@ -8,18 +8,11 @@ import [DesignParameters] from"../meta/aesthetics.mjs" extern isFinite -import [mix linreg clamp fallback] from"../support/utils.mjs" +import [mix linreg clamp fallback $NamedParameterPair$] from"../support/utils.mjs" import [calculateMetrics setFontMetrics GenDivFrame] from"../meta/aesthetics.mjs" $$include '../meta/macros.ptl' -define [$NamedParameterPair$ l r] : begin - set this.left l - set this.right r - return this - -define [$DoNothing$] nothing - export : define [buildGlyphs para recursive] : begin local glyphStore : new GlyphStore @@ -110,7 +103,6 @@ export : define [buildGlyphs para recursive] : begin $assignUnicodeImpl$ $defineGlyphBlockImpl$ $execState$ - $DoNothing$ Metrics : Object.assign {.} Metrics para recursive diff --git a/font-src/glyphs/letter/latin/lower-r.ptl b/font-src/glyphs/letter/latin/lower-r.ptl index 73f7344c7..9866d6bc8 100644 --- a/font-src/glyphs/letter/latin/lower-r.ptl +++ b/font-src/glyphs/letter/latin/lower-r.ptl @@ -1,6 +1,6 @@ $$include '../../../meta/macros.ptl' -import [mix linreg clamp fallback] from"../../../support/utils.mjs" +import [mix linreg clamp fallback SuffixCfg] from"../../../support/utils.mjs" import [Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs" glyph-module @@ -149,29 +149,38 @@ glyph-block Letter-Latin-Lower-R : begin curl (xBar - Stroke * HVContrast) 0 [heading Downward] if doBottomSerif : include : rBottomSerif 0 - define SmallRConfig : object - 'serifless' { StandardShape dfN rStraight { 0 0 } } - 'serifed' { StandardShape dfN rSerifed { 1 1 } } - 'topSerifed' { StandardShape dfN rSerifed { 1 0 } } - 'baseSerifed' { StandardShape dfN rSerifed { 0 1 } } - 'earlessCorner' { EarlessCornerShape dfN rEarless { 0 0 } } - 'earlessCornerSerifed' { EarlessCornerShape dfN rEarless { 0 1 } } - 'earlessRounded' { EarlessRoundedShape dfN rEarless { 0 0 } } - 'earlessRoundedSerifed' { EarlessRoundedShape dfN rEarless { 0 1 } } - 'hookless' { CompactShape dfN rNarrow { 0 0 } } - 'hooklessSerifed' { CompactShape dfN rNarrowSerifed { 1 1 } } - 'hooklessTopSerifed' { CompactShape dfN rNarrowSerifed { 1 0 } } - 'hooklessBaseSerifed' { CompactShape dfN rNarrowSerifed { 0 1 } } - 'compact' { CompactShape dfR rNarrow { 0 0 } } - 'compactSerifed' { CompactShape dfR rNarrowSerifed { 1 1 } } - 'compactTopSerifed' { CompactShape dfR rNarrowSerifed { 1 0 } } - 'compactBaseSerifed' { CompactShape dfR rNarrowSerifed { 0 1 } } - 'cornerHooked' { CornerHookShape dfN rCornerHooked { 0 0 } } - 'cornerHookedSerifed' { CornerHookShape dfN rCornerHookedSerifed { 1 1 } } - 'cornerHookedTopSerifed' { CornerHookShape dfN rCornerHookedSerifed { 1 0 } } - 'cornerHookedBaseSerifed' { CornerHookShape dfN rCornerHookedSerifed { 0 1 } } + define [FlapHooklessShape df md doTopSerif doBottomSerif] : glyph-proc + define [object xBar rBottomSerif xArchMiddle setMarks] : RDim df md + set-base-anchor 'overlay' (xBar - 0.5 * Stroke * HVContrast) (XH / 2) + include : setMarks doTopSerif + include : dispiro + widths.lhs + g4.left.start (xArchMiddle - CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]) (XH - O) + archv + flat (xBar - Stroke * HVContrast) (XH - SmallArchDepthA) + curl (xBar - Stroke * HVContrast) 0 [heading Downward] + if doBottomSerif : include : rBottomSerif 0 - foreach { suffix { F df mode { doTS doBS } } } [Object.entries SmallRConfig] : do + define SmallRConfig : SuffixCfg.weave + # Body + object + '' { StandardShape dfN rStraight } + earlessCorner { EarlessCornerShape dfN rEarless } + earlessRounded { EarlessRoundedShape dfN rEarless } + hookless { CompactShape dfN rNarrow } + cornerHooked { CornerHookShape dfN rCornerHooked } + compact { CompactShape dfR rNarrow } + hooklessFlap { FlapHooklessShape dfN rNarrow } + compactFlap { FlapHooklessShape dfR rNarrow } + + # Serifs + object + serifless { 0 0 } + topSerifed { 1 0 } + baseSerifed { 0 1 } + serifed { 1 1 } + + foreach { suffix { {F df mode} {doTS doBS} } } [pairs-of SmallRConfig] : do create-glyph "r.\(suffix)" : glyph-proc set-width df.width include : df.markSet.e @@ -256,34 +265,5 @@ glyph-block Letter-Latin-Lower-R : begin include : dfR.markSet.e include : BBRShape dfN rStraight 0 0 - - create-glyph 'rFlap.serifless' : glyph-proc - set-width dfN.width - include : dfN.markSet.e - define [object rBottomSerif] : RDim dfN rEarless - include : EarlessRoundedShape dfN rEarless 0 0 - create-forked-glyph 'rFlap.serifed' : rBottomSerif 0 - - define [rFlapHooklessShape df] : glyph-proc - include : df.markSet.e - define [object xBar rBottomSerif xArchMiddle] : RDim df rNarrow - set-base-anchor 'overlay' (xBar - 0.5 * Stroke * HVContrast) (XH / 2) - include : dispiro - widths.lhs - g4.left.start (xArchMiddle - CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]) (XH - O) - archv - flat (xBar - Stroke * HVContrast) (XH - SmallArchDepthA) - curl (xBar - Stroke * HVContrast) 0 [heading Downward] - if SLAB : include : rBottomSerif 0 - - create-glyph 'rFlap.hookless' : glyph-proc - set-width dfN.width - include : rFlapHooklessShape dfN - - create-glyph 'rFlap.compact' : glyph-proc - set-width dfR.width - include : rFlapHooklessShape dfR - - select-variant 'rFlap' 0x27E - + select-variant 'rFlap' 0x27E (shapeFrom -- 'r') CreateAccentedComposition 'rFlapTildeOver' 0x1D73 'rFlap' 'tildeOver' diff --git a/font-src/glyphs/letter/latin/lower-t.ptl b/font-src/glyphs/letter/latin/lower-t.ptl index 429f1e47e..128033664 100644 --- a/font-src/glyphs/letter/latin/lower-t.ptl +++ b/font-src/glyphs/letter/latin/lower-t.ptl @@ -1,6 +1,6 @@ $$include '../../../meta/macros.ptl' -import [mix linreg clamp fallback] from"../../../support/utils.mjs" +import [mix fallback SuffixCfg] from"../../../support/utils.mjs" import [Dotless CvDecompose] from"../../../support/gr.mjs" glyph-module @@ -207,26 +207,19 @@ glyph-block Letter-Latin-Lower-T : begin include : VBar.m df.middle 0 top include : HCrossBar.top df.middle (df.middle + df.div * LongJut) yCrossBar - define SmallTConfig : object - standard { [DivFrame 1] Standard Ascender } - diagonalTailed { dfNarrowT DiagTail Ascender } - flatHook { dfNarrowT Flat Ascender } - cross { dfNarrowT Cross Ascender } - hooklessAsymmetric { dfNarrowT HooklessAsymmetric Ascender } + define SmallTConfig :SuffixCfg.weave + object # body + standard { [DivFrame 1] Standard } + diagonalTailed { dfNarrowT DiagTail } + flatHook { dfNarrowT Flat } + cross { dfNarrowT Cross } + hooklessAsymmetric { dfNarrowT HooklessAsymmetric } + object # height + "" Ascender + shortNeck yShortNeck1 + shortNeck2 yShortNeck2 - standardShortNeck { [DivFrame 1] Standard yShortNeck1 } - diagonalTailedShortNeck { dfNarrowT DiagTail yShortNeck1 } - flatHookShortNeck { dfNarrowT Flat yShortNeck1 } - crossShortNeck { dfNarrowT Cross yShortNeck1 } - hooklessAsymmetricShortNeck { dfNarrowT HooklessAsymmetric yShortNeck1 } - - standardShortNeck2 { [DivFrame 1] Standard yShortNeck2 } - diagonalTailedShortNeck2 { dfNarrowT DiagTail yShortNeck2 } - flatHookShortNeck2 { dfNarrowT Flat yShortNeck2 } - crossShortNeck2 { dfNarrowT Cross yShortNeck2 } - hooklessAsymmetricShortNeck2 { dfNarrowT HooklessAsymmetric yShortNeck2 } - - foreach { suffix { df Style top } } [Object.entries SmallTConfig] : do + foreach { suffix { {df Style} top } } [pairs-of SmallTConfig] : do create-glyph "t.\(suffix)" : glyph-proc set-width df.width include : df.markSet.b @@ -399,4 +392,4 @@ glyph-block Letter-Latin-Lower-T : begin xLeft + (BBD / 2) + LongJut + TBalance2 begin yCrossBar begin BBS - Rect Ascender 0 xLeft (xLeft + BBD) \ No newline at end of file + Rect Ascender 0 xLeft (xLeft + BBD) diff --git a/font-src/glyphs/letter/latin/w.ptl b/font-src/glyphs/letter/latin/w.ptl index bb78ec9df..1a6a3458a 100644 --- a/font-src/glyphs/letter/latin/w.ptl +++ b/font-src/glyphs/letter/latin/w.ptl @@ -1,6 +1,6 @@ $$include '../../../meta/macros.ptl' -import [mix linreg clamp fallback] from"../../../support/utils.mjs" +import [mix fallback SuffixCfg] from"../../../support/utils.mjs" import [Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs" glyph-module @@ -323,43 +323,32 @@ glyph-block Letter-Latin-W : begin define [WCursiveImpl df top bodyType serifsType] : WCursiveImplImpl false df top bodyType serifsType define [WHookTopCursive df top bodyType serifsType] : WCursiveImplImpl true df top bodyType serifsType - define WConfig : object - cyrlCapialOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA SERIFS-CYRL-OMEGA } - cyrlSmallOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA SERIFS-CURSIVE } + define WConfig : SuffixCfg.weave + # Body + object + straight { WShapeImpl WHooktopShape FORM-STRAIGHT } + straightAsymmetric { WShapeImpl WHooktopShape FORM-ASYMMETRIC } + straightDoubleV { WShapeImpl WHooktopShape FORM-DOUBLE-V } + straightFlatTop { WShapeImpl WHooktopShape FORM-FLAT-TOP } + straightVerticalSides { WVertSides WVSHookTopShape FORM-STRAIGHT } + curly { WShapeImpl WHooktopShape FORM-CURLY } + cursive { WCursiveImpl WHookTopCursive FORM-CURLY } + cyrlCapialOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA } + cyrlSmallOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA } - straightAsymmetric { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-ASYMMETRIC } - straightDoubleV { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-DOUBLE-V } - straightFlatTop { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-AUTO } - straight { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-AUTO } - straightVerticalSides { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-AUTO } - curly { WShapeImpl WHooktopShape FORM-CURLY SERIFS-AUTO } - cursive { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-CURSIVE } + # Serifs + function [body] : if (body == 'cyrlCapialOmega' || body == 'cyrlSmallOmega') + then : object ["" SERIFS-CYRL-OMEGA] + else : object + serifless SERIFS-NONE + motionSerifed SERIFS-MOTION + serifed : match body + [Just 'straightAsymmetric'] SERIFS-ASYMMETRIC-ALL + [Just 'straightDoubleV'] SERIFS-DOUBLE-V-ALL + [Just 'cursive'] SERIFS-MOTION + __ SERIFS-ALL - straightAsymmetricSerifless { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-NONE } - straightDoubleVSerifless { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-NONE } - straightFlatTopSerifless { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-NONE } - straightVerticalSidesSerifless { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-NONE } - straightSerifless { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-NONE } - curlySerifless { WShapeImpl WHooktopShape FORM-CURLY SERIFS-NONE } - cursiveSerifless { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-NONE } - - straightAsymmetricMotionSerifed { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-MOTION } - straightDoubleVMotionSerifed { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-MOTION } - straightFlatTopMotionSerifed { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-MOTION } - straightVerticalSidesMotionSerifed { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-MOTION } - straightMotionSerifed { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-MOTION } - curlyMotionSerifed { WShapeImpl WHooktopShape FORM-CURLY SERIFS-MOTION } - cursiveMotionSerifed { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-MOTION } - - straightAsymmetricSerifed { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-ASYMMETRIC-ALL } - straightDoubleVSerifed { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-DOUBLE-V-ALL } - straightFlatTopSerifed { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-ALL } - straightVerticalSidesSerifed { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-ALL } - straightSerifed { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-ALL } - curlySerifed { WShapeImpl WHooktopShape FORM-CURLY SERIFS-ALL } - cursiveSerifed { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-MOTION } - - foreach { suffix { implT hookTopImplT bodyType slabType } } [Object.entries WConfig] : do + foreach { suffix { {implT hookTopImplT bodyType} slabType } } [pairs-of WConfig] : do create-glyph "W.\(suffix)" : glyph-proc local df : DivFrame para.diversityM 3 set-width df.width diff --git a/font-src/glyphs/number/0.ptl b/font-src/glyphs/number/0.ptl index 796a9406c..ddfb84fdb 100644 --- a/font-src/glyphs/number/0.ptl +++ b/font-src/glyphs/number/0.ptl @@ -1,6 +1,6 @@ $$include '../../meta/macros.ptl' -import [mix linreg clamp fallback] from"../../support/utils.mjs" +import [mix clamp fallback SuffixCfg] from"../../support/utils.mjs" import [AnyCv getGrMesh VS01] from"../../support/gr.mjs" glyph-module @@ -105,8 +105,8 @@ glyph-block Digits-Zero : begin define [BrokenVerticalBar top] : difference VBar.m Middle (0 + O) (top - O) [Math.min (CircleInnerWidth * 0.375) OverlayStroke] intersection - MaskAbove (top * (1/2 + 1/16)) - MaskBelow (top * (1/2 - 1/16)) + MaskAbove (top * (1/2 - 1/16)) + MaskBelow (top * (1/2 + 1/16)) define [ZeroDotShape top] : begin local halfDotWidth : Math.min DotRadius (CircleInnerWidth / 4) @@ -150,50 +150,48 @@ glyph-block Digits-Zero : begin Middle + halfDotWidth - OX begin 0 - define ZeroConfig : object - 'unslashed' { null null } - 'slashed' { ZeroSlash null } - 'reverseSlashed' { ZeroRevSlash null } - 'tallSlashed' { ZeroTallSlash null } - 'tallReverseSlashed' { ZeroTallRevSlash null } - 'dotted' { ZeroDotShape null } - 'longDotted' { ZeroLongDotShape null } - 'slashedSplit' { ZeroSlash InsetShape } - 'reverseSlashedSplit' { ZeroRevSlash InsetShape } - 'brokenSlash' { BrokenTallSlash null } - 'brokenReverseSlash' { BrokenTallRevSlash null } - 'brokenVerticalBar' { BrokenVerticalBar null } - 'slashedCutout' { CutoutSlash Cutout } - 'reverseSlashedCutout' { CutoutRevSlash Cutout } - 'tallSlashedCutout' { CutoutTallSlash Cutout } - 'tallReverseSlashedCutout' { CutoutTallRevSlash Cutout } - 'verticalBarCutout' { CutoutVerticalBar Cutout } - 'topRightCutout' { TopRightCutoutSlash Cutout } + define ZeroConfig : SuffixCfg.weave + object # outline shape + '' { ZeroOutlineShape ZeroOutlineMask } + 'oval' { ZeroOvalShape ZeroOvalMask } + object # overlay/cutout + 'unslashed' { null null } + 'slashed' { ZeroSlash null } + 'reverseSlashed' { ZeroRevSlash null } + 'tallSlashed' { ZeroTallSlash null } + 'tallReverseSlashed' { ZeroTallRevSlash null } + 'dotted' { ZeroDotShape null } + 'longDotted' { ZeroLongDotShape null } + 'slashedSplit' { ZeroSlash InsetShape } + 'reverseSlashedSplit' { ZeroRevSlash InsetShape } + 'brokenSlash' { BrokenTallSlash null } + 'brokenReverseSlash' { BrokenTallRevSlash null } + 'brokenVerticalBar' { BrokenVerticalBar null } + 'slashedCutout' { CutoutSlash Cutout } + 'reverseSlashedCutout' { CutoutRevSlash Cutout } + 'tallSlashedCutout' { CutoutTallSlash Cutout } + 'tallReverseSlashedCutout' { CutoutTallRevSlash Cutout } + 'verticalBarCutout' { CutoutVerticalBar Cutout } + 'topRightCutout' { TopRightCutoutSlash Cutout } - define Shapes : object - '' { ZeroOutlineShape ZeroOutlineMask } - 'Oval' { ZeroOvalShape ZeroOvalMask } - - define Infixes : object + define Heights : object 'lnum' { CAP [function [] : MarkSet.capital] } 'onum' { OnumHeight [function [] : OnumMarks.e] } - foreach { shapeSuffix { Outline Mask } } [Object.entries Shapes] : begin - foreach { infix { height Marks } } [Object.entries Infixes] : begin - local zeroShape : Outline height - foreach { suffix { Overlay Postproc } } [Object.entries ZeroConfig] : begin - create-glyph "zero.\(infix).\(suffix)\(shapeSuffix)" : glyph-proc - include : Marks - - local overlayShape : if Overlay [Overlay height] null - if Postproc - : then : begin - include : Postproc zeroShape overlayShape Mask height - : else : begin - include zeroShape - if Overlay : if Mask - include : intersection overlayShape : Mask height - include overlayShape + foreach { suffix { {Outline Mask} {Overlay Postproc} } } [pairs-of ZeroConfig] : begin + foreach { infix { height Marks } } [pairs-of Heights] : begin + create-glyph "zero.\(infix).\(suffix)" : glyph-proc + include : Marks + local zeroShape : Outline height + local overlayShape : if Overlay [Overlay height] null + if Postproc + : then : begin + include : Postproc zeroShape overlayShape Mask height + : else : begin + include zeroShape + if Overlay : if Mask + include : intersection overlayShape : Mask height + include overlayShape select-variant 'zero.lnum' [CodeLnum '0'] (follow -- 'zero') select-variant 'zero.onum' [CodeOnum '0'] (follow -- 'zero') diff --git a/font-src/meta/macros.ptl b/font-src/meta/macros.ptl index 7f8561cf2..89e87b12e 100644 --- a/font-src/meta/macros.ptl +++ b/font-src/meta/macros.ptl @@ -1,6 +1,11 @@ ### Autoarg macro define-operator "--" 890 'right' : syntax-rules `(@l -- @r) [atom l] : dirty `[new $NamedParameterPair$ @{".quote" [formOf l]} @r] + `(@{".quote" l} -- @r) : dirty `[new $NamedParameterPair$ @l @r] + +### Arbitrary pair operator +define-operator "~>" 880 'right' : syntax-rules + `(@l ~> @r) `{.left @l .right @r} ### Macro for identity match define-macro Just : begin @@ -30,7 +35,7 @@ define-macro params : syntax-rules local declarations `[begin] local namedAssigns `[begin] local indexAssigns `[begin] - local tearDowns `[begin] + local tearDowns `[begin] local j 0 foreach [pf : items-of : formOf _pairs] : begin @@ -204,14 +209,13 @@ define-macro glyph-block : syntax-rules ([typeof form] === "string") : set variableSet.(form) true traceBody body - traceBody `[$NamedParameterPair$ $DoNothing$ $createAndSaveGlyphImpl$ $assignUnicodeImpl$] + traceBody `[$NamedParameterPair$ $createAndSaveGlyphImpl$ $assignUnicodeImpl$ $execState$] set externEnv.$glyphBlockVariableUsage$ variableSet - define captureImports `[$createAndSaveGlyphImpl$ $NamedParameterPair$ - $assignUnicodeImpl$ $DoNothing$ $execState$ - Metrics para recursive glyphStore glyph-is-needed SpiroFns BooleFns MarkSet AS_BASE - ALSO_METRICS buildGlyphs tagged DivFrame fontMetrics] + define captureImports `[$createAndSaveGlyphImpl$ $NamedParameterPair$ $assignUnicodeImpl$ + $execState$ Metrics para recursive glyphStore glyph-is-needed SpiroFns BooleFns + MarkSet AS_BASE ALSO_METRICS buildGlyphs tagged DivFrame fontMetrics] define metricImports `[DesignParameters UPM HalfUPM Width SB CAP XH Ascender Descender Contrast SymbolMid ParenTop ParenBot OperTop OperBot TackTop TackBot PlusTop PlusBot diff --git a/font-src/otl/gsub-ccmp.ptl b/font-src/otl/gsub-ccmp.ptl index 960d7059f..3fe44f7a8 100644 --- a/font-src/otl/gsub-ccmp.ptl +++ b/font-src/otl/gsub-ccmp.ptl @@ -1,12 +1,11 @@ +$$include '../meta/macros.ptl' + import [AddCommonFeature AddFeature AddLookup AddFeatureLookup ChainRuleBuilder BeginLookupBlock EndLookupBlock UkMapToLookup UkMap2ToLookup] from"./table-util.mjs" import [AnyCv Dotless TieMark TieGlyph OgonekTrY IsSuperscript IsSubscript] from"../support/gr.mjs" import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs" extern Set -define-operator "~>" 880 'right' : syntax-rules - `(@l ~> @r) `{.left @l .right @r} - define-macro Ccmp-Group : syntax-rules `[Ccmp-Group @description @body] dirty `[$ExecCcmpGroup$ [function [export-lookup chain-rule] @[formOf body]]] diff --git a/font-src/otl/gsub-cv-ss.ptl b/font-src/otl/gsub-cv-ss.ptl index d5698e49f..a169a5ac3 100644 --- a/font-src/otl/gsub-cv-ss.ptl +++ b/font-src/otl/gsub-cv-ss.ptl @@ -1,3 +1,5 @@ +$$include '../meta/macros.ptl' + import [AddLookup AddCommonFeature PickCommonFeature AddFeatureLookup PickLookup BeginLookupBlock EndLookupBlock ChainRuleBuilder] from"./table-util.mjs" import [Cv AnyCv CvDecompose RightDependentLink RightDependentTrigger] from"../support/gr.mjs" @@ -5,8 +7,6 @@ extern Map extern Set define look-around null -define-operator "~>" 880 'right' : syntax-rules - `(@l ~> @r) `{.left @l .right @r} define [FeatureName tag] : tag + '_cvss' define [SsLookupName tag] : 'lookup_ss_' + tag diff --git a/font-src/otl/gsub-frac.ptl b/font-src/otl/gsub-frac.ptl index f3717af33..adddf55d1 100644 --- a/font-src/otl/gsub-frac.ptl +++ b/font-src/otl/gsub-frac.ptl @@ -1,9 +1,8 @@ +$$include '../meta/macros.ptl' + import [AddCommonFeature AddFeature AddLookup BeginLookupBlock EndLookupBlock ChainRuleBuilder] from"./table-util.mjs" import [NumeratorForm DenominatorForm] from"../support/gr.mjs" -define-operator "~>" 880 'right' : syntax-rules - `(@l ~> @r) `{.left @l .right @r} - # Name-driven feature pairs export : define [buildFrac sink glyphStore] : begin local rec : BeginLookupBlock sink diff --git a/font-src/otl/gsub-ligation.ptl b/font-src/otl/gsub-ligation.ptl index 263e52090..6601767e1 100644 --- a/font-src/otl/gsub-ligation.ptl +++ b/font-src/otl/gsub-ligation.ptl @@ -1,10 +1,9 @@ +$$include '../meta/macros.ptl' + import [AddCommonFeature AddFeature ChainRuleBuilder BeginLookupBlock EndLookupBlock] from"./table-util.mjs" extern Map extern Set -define-operator "~>" 880 'right' : syntax-rules - `(@l ~> @r) `{.left @l .right @r} - define [arrowBarX s] : lambda [t] : t.map : lambda [x] "\(x).arrowBar.\(s)" define [lsx s] : lambda [t] : t.map : lambda [x] "\(x).lig.\(s)" define [csx s] : lambda [t] : t.map : lambda [x] "\(x).\(s)" diff --git a/font-src/otl/gsub-thousands.ptl b/font-src/otl/gsub-thousands.ptl index dc87a3cb5..83824c246 100644 --- a/font-src/otl/gsub-thousands.ptl +++ b/font-src/otl/gsub-thousands.ptl @@ -1,7 +1,6 @@ -import [AddCommonFeature AddFeature AddLookup ChainRuleBuilder QueryRelatedGlyphs BeginLookupBlock EndLookupBlock] from"./table-util.mjs" +$$include '../meta/macros.ptl' -define-operator "~>" 880 'right' : syntax-rules - `(@l ~> @r) `{.left @l .right @r} +import [AddCommonFeature AddFeature AddLookup ChainRuleBuilder QueryRelatedGlyphs BeginLookupBlock EndLookupBlock] from"./table-util.mjs" export : define [buildGsubThousands sink para] : begin local rec : BeginLookupBlock sink diff --git a/font-src/support/utils.mjs b/font-src/support/utils.mjs index 47b2d1cc4..8aa3c49d8 100644 --- a/font-src/support/utils.mjs +++ b/font-src/support/utils.mjs @@ -34,28 +34,49 @@ export function joinCamel(a, b) { return a + b[0].toUpperCase() + b.slice(1); } -function joinSuffixListImpl(sink, k, v, configs) { +function joinSuffixListImpl(sink, k, v, telescope, configs) { if (!configs.length) { sink[k] = v; return; } - for (const [keySuffix, valueSuffix] of Object.entries(configs[0])) { + let [item, ...rest] = configs; + if (item instanceof Function) item = item(...telescope); + if (!item) return; + + for (const [keySuffix, valueSuffix] of Object.entries(item)) { const k1 = joinCamel(k, keySuffix); const v1 = [...v, valueSuffix]; - joinSuffixListImpl(sink, k1, v1, configs.slice(1)); + const telescope1 = [...telescope, keySuffix]; + joinSuffixListImpl(sink, k1, v1, telescope1, rest); } } export const SuffixCfg = { weave: function (...configs) { let ans = {}; - joinSuffixListImpl(ans, "", [], configs); + joinSuffixListImpl(ans, "", [], [], configs); return ans; }, combine: function (...configs) { let ans = {}; for (const item of configs) for (const [k, v] of Object.entries(item)) ans[k] = v; return ans; + }, + collect: function (pairs) { + let ans = {}; + for (const pair of pairs) { + if (pair) ans[pair.left] = pair.right; + } + return ans; } }; + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +export class $NamedParameterPair$ { + constructor(l, r) { + this.left = l; + this.right = r; + } +} diff --git a/font-src/support/variant-data.mjs b/font-src/support/variant-data.mjs index 260019396..fa0a31abb 100644 --- a/font-src/support/variant-data.mjs +++ b/font-src/support/variant-data.mjs @@ -261,55 +261,36 @@ class VbStageAlternative { this.key = key; this.rank = raw.rank; this.next = raw.next; - if (key !== "*") this.keySuffix = raw.keySuffix ?? key; - this.descriptionSuffix = raw.descriptionSuffix; - this.descriptionJoiner = raw.descriptionJoiner || "with"; + this.mode = raw.mode; this.disableIf = raw.disableIf; - this.selectorSuffix = raw.selectorSuffix; + if (key !== "*") this.keyAffix = raw.keyAffix ?? key; + this.descriptionAffix = raw.descriptionAffix; + this.descriptionJoiner = raw.descriptionJoiner || "with"; + this.selectorAffix = raw.selectorAffix; } fallback(defaultAlternative) { this.next = this.next || defaultAlternative.next; - this.keySuffix = this.keySuffix || defaultAlternative.keySuffix; - this.descriptionSuffix = this.descriptionSuffix || defaultAlternative.descriptionSuffix; + this.mode = this.mode || defaultAlternative.mode || "append"; + this.keyAffix = this.keyAffix || defaultAlternative.keyAffix; + this.descriptionAffix = this.descriptionAffix || defaultAlternative.descriptionAffix; this.descriptionJoiner = this.descriptionJoiner || defaultAlternative.descriptionJoiner; this.disableIf = this.disableIf || defaultAlternative.disableIf; - this.selectorSuffix = this.selectorSuffix || defaultAlternative.selectorSuffix; } tryAccept(globalState, localState) { - // Detect whether this alternative is applicable. - if (this.disableIf) { - for (const branch of this.disableIf) { - let statementMatches = true; - for (let [k, v] of Object.entries(branch)) { - v = v.trim(); - if (/^NOT(?=\s)/.test(v)) { - v = v.slice(3).trim(); - if (localState.assignments.get(k) === v) { - statementMatches = false; - break; - } - } else { - if (localState.assignments.get(k) !== v) { - statementMatches = false; - break; - } - } - } - if (statementMatches) return null; - } - } + // Reject if disable conditions match + if (this.shouldReject(localState)) return null; // Accept this alternative. const ans = localState.clone(); ans.stage = this.next; ans.assignments.set(this.stage, this.key); - if (this.keySuffix) ans.key.push(this.keySuffix); - if (this.descriptionJoiner && this.descriptionSuffix) - ans.addDescription(this.descriptionJoiner, this.descriptionSuffix); - if (this.selectorSuffix) - for (const [selector, suffix] of Object.entries(this.selectorSuffix)) - ans.addSelector(selector, suffix); + if (this.keyAffix) ans.addKeyAffix(this.mode, this.keyAffix); + if (this.descriptionJoiner && this.descriptionAffix) + ans.addDescription(this.mode, this.descriptionJoiner, this.descriptionAffix); + if (this.selectorAffix) + for (const [selector, suffix] of Object.entries(this.selectorAffix)) + ans.addSelectorAffix(this.mode, selector, suffix); if (!this.next) { ans.rank = ++globalState.rank; @@ -319,6 +300,31 @@ class VbStageAlternative { return ans; } } + + shouldReject(localState) { + if (!this.disableIf) return false; + + for (const branch of this.disableIf) { + let statementMatches = true; + for (let [k, v] of Object.entries(branch)) { + v = v.trim(); + if (/^NOT(?=\s)/.test(v)) { + v = v.slice(3).trim(); + if (localState.assignments.get(k) === v) { + statementMatches = false; + break; + } + } else { + if (localState.assignments.get(k) !== v) { + statementMatches = false; + break; + } + } + } + if (statementMatches) return true; + } + return false; + } } class VbGlobalState { @@ -354,13 +360,56 @@ class VbLocalState { return ans; } - addDescription(joiner, segment) { + addKeyAffix(mode, segment) { + switch (mode) { + case "append": + this.key.push(segment); + return; + case "prepend": + this.key.unshift(segment); + return; + case "replace": + this.key = [segment]; + return; + default: + throw new Error(`Invalid key affix mode: ${mode}`); + } + } + + addDescription(mode, joiner, segment) { if (!segment) return; if (!this.descriptions.has(joiner)) this.descriptions.set(joiner, []); - this.descriptions.get(joiner).push(segment); + + let descriptionSentence = this.descriptions.get(joiner); + switch (mode) { + case "append": + descriptionSentence.push(segment); + return; + case "prepend": + descriptionSentence.unshift(segment); + return; + case "replace": + descriptionSentence.length = 0; + descriptionSentence.push(segment); + return; + default: + throw new Error(`Invalid description affix mode: ${mode}`); + } } - addSelector(selector, value) { - this.selector.set(selector, joinCamel(this.selector.get(selector), value)); + addSelectorAffix(mode, selector, value) { + switch (mode) { + case "append": + this.selector.set(selector, joinCamel(this.selector.get(selector), value)); + return; + case "prepend": + this.selector.set(selector, joinCamel(value, this.selector.get(selector))); + return; + case "replace": + this.selector.set(selector, value); + return; + default: + throw new Error(`Invalid selector affix mode: ${mode}`); + } } produceKey() { @@ -388,5 +437,5 @@ class VbLocalState { function arrayToSentence(arr) { if (arr.length == 1) return arr[0]; let last = arr.pop(); - return arr.join(", ") + " and " + last; + return arr.join(", ") + ", and " + last; } diff --git a/params/variants.toml b/params/variants.toml index 393973943..dd041ebda 100644 --- a/params/variants.toml +++ b/params/variants.toml @@ -702,85 +702,85 @@ next = "serifs" [prime.capital-k.variants-buildup.stages.body.straight] rank = 1 -descriptionSuffix = "straight shape" -selectorSuffix.K = "straight" -selectorSuffix."K/sansSerif" = "straight" -selectorSuffix."grek/KaiSymbol" = "straight" -selectorSuffix."grek/kappa" = "straight" -selectorSuffix.KDescender = "straight" +descriptionAffix = "straight shape" +selectorAffix.K = "straight" +selectorAffix."K/sansSerif" = "straight" +selectorAffix."grek/KaiSymbol" = "straight" +selectorAffix."grek/kappa" = "straight" +selectorAffix.KDescender = "straight" [prime.capital-k.variants-buildup.stages.body.curly] rank = 2 -descriptionSuffix = "curly shape" -selectorSuffix.K = "curly" -selectorSuffix."K/sansSerif" = "curly" -selectorSuffix."grek/KaiSymbol" = "curly" -selectorSuffix."grek/kappa" = "curly" -selectorSuffix.KDescender = "curly" +descriptionAffix = "curly shape" +selectorAffix.K = "curly" +selectorAffix."K/sansSerif" = "curly" +selectorAffix."grek/KaiSymbol" = "curly" +selectorAffix."grek/kappa" = "curly" +selectorAffix.KDescender = "curly" [prime.capital-k.variants-buildup.stages.body.symmetric-touching] rank = 3 -descriptionSuffix = "symmetric legs touching the vertical bar" -selectorSuffix.K = "symmetricTouching" -selectorSuffix."K/sansSerif" = "symmetricTouching" -selectorSuffix."grek/KaiSymbol" = "symmetricTouching" -selectorSuffix."grek/kappa" = "symmetricTouching" -selectorSuffix.KDescender = "symmetricTouching" +descriptionAffix = "symmetric legs touching the vertical bar" +selectorAffix.K = "symmetricTouching" +selectorAffix."K/sansSerif" = "symmetricTouching" +selectorAffix."grek/KaiSymbol" = "symmetricTouching" +selectorAffix."grek/kappa" = "symmetricTouching" +selectorAffix.KDescender = "symmetricTouching" [prime.capital-k.variants-buildup.stages.body.symmetric-connected] rank = 4 -descriptionSuffix = "symmetric legs connected to the vertical bar" -selectorSuffix.K = "symmetricConnected" -selectorSuffix."K/sansSerif" = "symmetricConnected" -selectorSuffix."grek/KaiSymbol" = "symmetricConnected" -selectorSuffix."grek/kappa" = "symmetricConnected" -selectorSuffix.KDescender = "symmetricConnected" +descriptionAffix = "symmetric legs connected to the vertical bar" +selectorAffix.K = "symmetricConnected" +selectorAffix."K/sansSerif" = "symmetricConnected" +selectorAffix."grek/KaiSymbol" = "symmetricConnected" +selectorAffix."grek/kappa" = "symmetricConnected" +selectorAffix.KDescender = "symmetricConnected" [prime.capital-k.variants-buildup.stages.serifs.serifless] rank = 1 -descriptionSuffix = "serifs" +descriptionAffix = "serifs" descriptionJoiner = "without" -selectorSuffix.K = "serifless" -selectorSuffix."K/sansSerif" = "serifless" -selectorSuffix."grek/KaiSymbol" = "serifless" -selectorSuffix."grek/kappa" = "serifless" -selectorSuffix.KDescender = "serifless" +selectorAffix.K = "serifless" +selectorAffix."K/sansSerif" = "serifless" +selectorAffix."grek/KaiSymbol" = "serifless" +selectorAffix."grek/kappa" = "serifless" +selectorAffix.KDescender = "serifless" [prime.capital-k.variants-buildup.stages.serifs.top-left-serifed] rank = 2 -descriptionSuffix = "serifs at top left" -selectorSuffix.K = "topLeftSerifed" -selectorSuffix."K/sansSerif" = "serifless" -selectorSuffix."grek/KaiSymbol" = "topLeftSerifed" -selectorSuffix."grek/kappa" = "serifless" -selectorSuffix.KDescender = "topLeftSerifed" +descriptionAffix = "serifs at top left" +selectorAffix.K = "topLeftSerifed" +selectorAffix."K/sansSerif" = "serifless" +selectorAffix."grek/KaiSymbol" = "topLeftSerifed" +selectorAffix."grek/kappa" = "serifless" +selectorAffix.KDescender = "topLeftSerifed" [prime.capital-k.variants-buildup.stages.serifs.bottom-right-serifed] rank = 3 -descriptionSuffix = "serifs at bottom right" -selectorSuffix.K = "bottomRightSerifed" -selectorSuffix."K/sansSerif" = "serifless" -selectorSuffix."grek/KaiSymbol" = "bottomRightSerifed2" -selectorSuffix."grek/kappa" = "serifless" -selectorSuffix.KDescender = "bottomRightSerifed" +descriptionAffix = "serifs at bottom right" +selectorAffix.K = "bottomRightSerifed" +selectorAffix."K/sansSerif" = "serifless" +selectorAffix."grek/KaiSymbol" = "bottomRightSerifed2" +selectorAffix."grek/kappa" = "serifless" +selectorAffix.KDescender = "bottomRightSerifed" [prime.capital-k.variants-buildup.stages.serifs.top-left-and-bottom-right-serifed] rank = 4 -descriptionSuffix = "serifs at top left and bottom right" -selectorSuffix.K = "topLeftAndBottomRightSerifed" -selectorSuffix."K/sansSerif" = "serifless" -selectorSuffix."grek/KaiSymbol" = "topLeftAndBottomRightSerifed2" -selectorSuffix."grek/kappa" = "serifless" -selectorSuffix.KDescender = "topLeftSerifed" +descriptionAffix = "serifs at top left and bottom right" +selectorAffix.K = "topLeftAndBottomRightSerifed" +selectorAffix."K/sansSerif" = "serifless" +selectorAffix."grek/KaiSymbol" = "topLeftAndBottomRightSerifed2" +selectorAffix."grek/kappa" = "serifless" +selectorAffix.KDescender = "topLeftSerifed" [prime.capital-k.variants-buildup.stages.serifs.serifed] rank = 5 -descriptionSuffix = "serifs" -selectorSuffix.K = "serifed" -selectorSuffix."K/sansSerif" = "serifless" -selectorSuffix."grek/KaiSymbol" = "serifed2" -selectorSuffix."grek/kappa" = "serifless" -selectorSuffix.KDescender = "serifed" +descriptionAffix = "serifs" +selectorAffix.K = "serifed" +selectorAffix."K/sansSerif" = "serifless" +selectorAffix."grek/KaiSymbol" = "serifed2" +selectorAffix."grek/kappa" = "serifless" +selectorAffix.KDescender = "serifed" @@ -1397,131 +1397,76 @@ selector.VHookTop = "curlySerifed" sampler = "W" tag = "cv22" -[prime.capital-w.variants.straight-serifless] +[prime.capital-w.variants-buildup] +entry = "body" +descriptionLeader = "`W`" + +[prime.capital-w.variants-buildup.stages.body."*"] +next = "serifs" + +[prime.capital-w.variants-buildup.stages.body.straight] rank = 1 -description = "Standard, straight `W`, without serifs" -selector.W = "straightSerifless" -selector."W/sansSerif" = "straightSerifless" -selector.WHookTop = "straightSerifless" +descriptionAffix = "standard, straight body" +selectorAffix.W = "straight" +selectorAffix."W/sansSerif" = "straight" +selectorAffix.WHookTop = "straight" -[prime.capital-w.variants.straight-motion-serifed] +[prime.capital-w.variants-buildup.stages.body.curly] rank = 2 -description = "Standard, straight `W`, with motion serifs" -selector.W = "straightMotionSerifed" -selector."W/sansSerif" = "straightSerifless" -selector.WHookTop = "straightMotionSerifed" +descriptionAffix = "curly body" +selectorAffix.W = "curly" +selectorAffix."W/sansSerif" = "curly" +selectorAffix.WHookTop = "curly" -[prime.capital-w.variants.straight-serifed] +[prime.capital-w.variants-buildup.stages.body.straight-flat-top] rank = 3 -description = "Standard, straight `W`, with serifs" -selector.W = "straightSerifed" -selector."W/sansSerif" = "straightSerifless" -selector.WHookTop = "straightSerifed" +descriptionAffix = "straight body shape that the middle is forced to be aligned the top" +selectorAffix.W = "straightFlatTop" +selectorAffix."W/sansSerif" = "straightFlatTop" +selectorAffix.WHookTop = "straightFlatTop" -[prime.capital-w.variants.curly-serifless] +[prime.capital-w.variants-buildup.stages.body.straight-double-v] rank = 4 -description = "Slightly curly `W`, like Iosevka 2.x, without serifs" -selector.W = "curlySerifless" -selector."W/sansSerif" = "curlySerifless" -selector.WHookTop = "curlySerifless" +descriptionAffix = "body shape like double V" +selectorAffix.W = "straightDoubleV" +selectorAffix."W/sansSerif" = "straightDoubleV" +selectorAffix.WHookTop = "straightDoubleV" -[prime.capital-w.variants.curly-motion-serifed] +[prime.capital-w.variants-buildup.stages.body.straight-asymmetric] rank = 5 -description = "Slightly curly `W`, like Iosevka 2.x, with motion serifs" -selector.W = "curlyMotionSerifed" -selector."W/sansSerif" = "curlySerifless" -selector.WHookTop = "curlyMotionSerifed" +descriptionAffix = "asymmetric shape" +selectorAffix.W = "straightAsymmetric" +selectorAffix."W/sansSerif" = "straightAsymmetric" +selectorAffix.WHookTop = "straightAsymmetric" -[prime.capital-w.variants.curly-serifed] +[prime.capital-w.variants-buildup.stages.body.straight-vertical-sides] rank = 6 -description = "Slightly curly `W`, like Iosevka 2.x, with serifs" -selector.W = "curlySerifed" -selector."W/sansSerif" = "curlySerifless" -selector.WHookTop = "curlySerifed" +descriptionAffix = "body shape with vertical sides" +selectorAffix.W = "straightVerticalSides" +selectorAffix."W/sansSerif" = "straightVerticalSides" +selectorAffix.WHookTop = "straightVerticalSides" -[prime.capital-w.variants.straight-flat-top-serifless] -rank = 7 -description = "Standard, straight `W`, and the middle is forced to be aligned the top, without serifs" -selector.W = "straightFlatTopSerifless" -selector."W/sansSerif" = "straightFlatTopSerifless" -selector.WHookTop = "straightFlatTopSerifless" +[prime.capital-w.variants-buildup.stages.serifs.serifless] +rank = 1 +descriptionAffix = "serifs" +descriptionJoiner = "without" +selectorAffix.W = "serifless" +selectorAffix."W/sansSerif" = "serifless" +selectorAffix.WHookTop = "serifless" -[prime.capital-w.variants.straight-flat-top-motion-serifed] -rank = 8 -description = "Standard, straight `W`, and the middle is forced to be aligned the top, with motion serifs" -selector.W = "straightFlatTopMotionSerifed" -selector."W/sansSerif" = "straightFlatTopSerifless" -selector.WHookTop = "straightFlatTopMotionSerifed" +[prime.capital-w.variants-buildup.stages.serifs.motion-serifed] +rank = 2 +descriptionAffix = "motion serifs" +selectorAffix.W = "motionSerifed" +selectorAffix."W/sansSerif" = "serifless" +selectorAffix.WHookTop = "motionSerifed" -[prime.capital-w.variants.straight-flat-top-serifed] -rank = 9 -description = "Standard, straight `W`, and the middle is forced to be aligned the top, with serifs" -selector.W = "straightFlatTopSerifed" -selector."W/sansSerif" = "straightFlatTopSerifless" -selector.WHookTop = "straightFlatTopSerifed" - -[prime.capital-w.variants.straight-double-v-serifless] -rank = 10 -description = "Straight `W` looks like double V, without serifs" -selector.W = "straightDoubleVSerifless" -selector."W/sansSerif" = "straightDoubleVSerifless" -selector.WHookTop = "straightDoubleVSerifless" - -[prime.capital-w.variants.straight-double-v-motion-serifed] -rank = 11 -description = "Straight `W` looks like double V, with motion serifs" -selector.W = "straightDoubleVMotionSerifed" -selector."W/sansSerif" = "straightDoubleVSerifless" -selector.WHookTop = "straightDoubleVMotionSerifed" - -[prime.capital-w.variants.straight-double-v-serifed] -rank = 12 -description = "Straight `W` looks like double V, with serifs" -selector.W = "straightDoubleVSerifed" -selector."W/sansSerif" = "straightDoubleVSerifless" -selector.WHookTop = "straightDoubleVSerifed" - -[prime.capital-w.variants.straight-asymmetric-serifless] -rank = 13 -description = "Straight `W` looks asymmetric, without serifs" -selector.W = "straightAsymmetricSerifless" -selector."W/sansSerif" = "straightAsymmetricSerifless" -selector.WHookTop = "straightAsymmetricSerifless" - -[prime.capital-w.variants.straight-asymmetric-motion-serifed] -rank = 14 -description = "Straight `W` looks asymmetric, with motion serifs" -selector.W = "straightAsymmetricMotionSerifed" -selector."W/sansSerif" = "straightAsymmetricSerifless" -selector.WHookTop = "straightAsymmetricMotionSerifed" - -[prime.capital-w.variants.straight-asymmetric-serifed] -rank = 15 -description = "Straight `W` looks asymmetric, with serifs" -selector.W = "straightAsymmetricSerifed" -selector."W/sansSerif" = "straightAsymmetricSerifless" -selector.WHookTop = "straightAsymmetricSerifed" - -[prime.capital-w.variants.straight-vertical-sides-serifless] -rank = 16 -description = "Straight `W` with vertical sides, without serifs" -selector.W = "straightVerticalSidesSerifless" -selector."W/sansSerif" = "straightVerticalSidesSerifless" -selector.WHookTop = "straightVerticalSidesSerifless" - -[prime.capital-w.variants.straight-vertical-sides-motion-serifed] -rank = 17 -description = "Straight `W` with vertical sides and motion serifs" -selector.W = "straightVerticalSidesMotionSerifed" -selector."W/sansSerif" = "straightVerticalSidesSerifless" -selector.WHookTop = "straightVerticalSidesMotionSerifed" - -[prime.capital-w.variants.straight-vertical-sides-serifed] -rank = 18 -description = "Straight `W` with vertical sides and serifs" -selector.W = "straightVerticalSidesSerifed" -selector."W/sansSerif" = "straightVerticalSidesSerifless" -selector.WHookTop = "straightVerticalSidesSerifed" +[prime.capital-w.variants-buildup.stages.serifs.serifed] +rank = 3 +descriptionAffix = "serifs" +selectorAffix.W = "serifed" +selectorAffix."W/sansSerif" = "serifless" +selectorAffix.WHookTop = "serifed" @@ -1642,108 +1587,108 @@ next = "serifs" [prime.capital-z.variants-buildup.stages.body.straight] rank = 1 -descriptionSuffix = "straight body shape" -selectorSuffix.Z = "straight" -selectorSuffix."Z/sansSerif" = "straight" -selectorSuffix."Z/reduced" = "straight" -selectorSuffix."Z/reduced/sansSerif" = "straight" -selectorSuffix.ZDesc = "straight" -selectorSuffix."ZDesc/reduced" = "straight" +descriptionAffix = "straight body shape" +selectorAffix.Z = "straight" +selectorAffix."Z/sansSerif" = "straight" +selectorAffix."Z/reduced" = "straight" +selectorAffix."Z/reduced/sansSerif" = "straight" +selectorAffix.ZDesc = "straight" +selectorAffix."ZDesc/reduced" = "straight" [prime.capital-z.variants-buildup.stages.body.curly] rank = 2 -descriptionSuffix = "curly body shape" -selectorSuffix.Z = "curly" -selectorSuffix."Z/sansSerif" = "curly" -selectorSuffix."Z/reduced" = "curly" -selectorSuffix."Z/reduced/sansSerif" = "curly" -selectorSuffix.ZDesc = "curly" -selectorSuffix."ZDesc/reduced" = "curly" +descriptionAffix = "curly body shape" +selectorAffix.Z = "curly" +selectorAffix."Z/sansSerif" = "curly" +selectorAffix."Z/reduced" = "curly" +selectorAffix."Z/reduced/sansSerif" = "curly" +selectorAffix.ZDesc = "curly" +selectorAffix."ZDesc/reduced" = "curly" [prime.capital-z.variants-buildup.stages.body.cursive] rank = 3 next = "overlay" -descriptionSuffix = "cursive body shape" -selectorSuffix.Z = "cursive" -selectorSuffix."Z/sansSerif" = "cursive" -selectorSuffix."Z/reduced" = "cursive" -selectorSuffix."Z/reduced/sansSerif" = "cursive" -selectorSuffix.ZDesc = "cursive" -selectorSuffix."ZDesc/reduced" = "cursive" +descriptionAffix = "cursive body shape" +selectorAffix.Z = "cursive" +selectorAffix."Z/sansSerif" = "cursive" +selectorAffix."Z/reduced" = "cursive" +selectorAffix."Z/reduced/sansSerif" = "cursive" +selectorAffix.ZDesc = "cursive" +selectorAffix."ZDesc/reduced" = "cursive" [prime.capital-z.variants-buildup.stages.serifs."*"] next = "overlay" [prime.capital-z.variants-buildup.stages.serifs.serifless] rank = 1 -descriptionSuffix = "serifs" +descriptionAffix = "serifs" descriptionJoiner = "without" -selectorSuffix.Z = "serifless" -selectorSuffix."Z/sansSerif" = "serifless" -selectorSuffix."Z/reduced" = "serifless" -selectorSuffix."Z/reduced/sansSerif" = "serifless" -selectorSuffix.ZDesc = "serifless" -selectorSuffix."ZDesc/reduced" = "serifless" +selectorAffix.Z = "serifless" +selectorAffix."Z/sansSerif" = "serifless" +selectorAffix."Z/reduced" = "serifless" +selectorAffix."Z/reduced/sansSerif" = "serifless" +selectorAffix.ZDesc = "serifless" +selectorAffix."ZDesc/reduced" = "serifless" [prime.capital-z.variants-buildup.stages.serifs.serifed] rank = 2 -descriptionSuffix = "serifs" -selectorSuffix.Z = "serifed" -selectorSuffix."Z/sansSerif" = "serifless" -selectorSuffix."Z/reduced" = "serifed" -selectorSuffix."Z/reduced/sansSerif" = "serifless" -selectorSuffix.ZDesc = "topSerifed" -selectorSuffix."ZDesc/reduced" = "topSerifed" +descriptionAffix = "serifs" +selectorAffix.Z = "serifed" +selectorAffix."Z/sansSerif" = "serifless" +selectorAffix."Z/reduced" = "serifed" +selectorAffix."Z/reduced/sansSerif" = "serifless" +selectorAffix.ZDesc = "topSerifed" +selectorAffix."ZDesc/reduced" = "topSerifed" [prime.capital-z.variants-buildup.stages.serifs.bottom-serifed] rank = 3 -descriptionSuffix = "serifs at bottom" -selectorSuffix.Z = "bottomSerifed" -selectorSuffix."Z/sansSerif" = "serifless" -selectorSuffix."Z/reduced" = "bottomSerifed" -selectorSuffix."Z/reduced/sansSerif" = "serifless" -selectorSuffix.ZDesc = "serifless" -selectorSuffix."ZDesc/reduced" = "serifless" +descriptionAffix = "serifs at bottom" +selectorAffix.Z = "bottomSerifed" +selectorAffix."Z/sansSerif" = "serifless" +selectorAffix."Z/reduced" = "bottomSerifed" +selectorAffix."Z/reduced/sansSerif" = "serifless" +selectorAffix.ZDesc = "serifless" +selectorAffix."ZDesc/reduced" = "serifless" [prime.capital-z.variants-buildup.stages.serifs.top-serifed] rank = 4 -descriptionSuffix = "serifs at top" -selectorSuffix.Z = "topSerifed" -selectorSuffix."Z/sansSerif" = "serifless" -selectorSuffix."Z/reduced" = "topSerifed" -selectorSuffix."Z/reduced/sansSerif" = "serifless" -selectorSuffix.ZDesc = "topSerifed" -selectorSuffix."ZDesc/reduced" = "topSerifed" +descriptionAffix = "serifs at top" +selectorAffix.Z = "topSerifed" +selectorAffix."Z/sansSerif" = "serifless" +selectorAffix."Z/reduced" = "topSerifed" +selectorAffix."Z/reduced/sansSerif" = "serifless" +selectorAffix.ZDesc = "topSerifed" +selectorAffix."ZDesc/reduced" = "topSerifed" [prime.capital-z.variants-buildup.stages.overlay.no-overlay] rank = 1 -keySuffix = "" -selectorSuffix.Z = "" -selectorSuffix."Z/sansSerif" = "" -selectorSuffix."Z/reduced" = "" -selectorSuffix."Z/reduced/sansSerif" = "" -selectorSuffix.ZDesc = "" -selectorSuffix."ZDesc/reduced" = "" +keyAffix = "" +selectorAffix.Z = "" +selectorAffix."Z/sansSerif" = "" +selectorAffix."Z/reduced" = "" +selectorAffix."Z/reduced/sansSerif" = "" +selectorAffix.ZDesc = "" +selectorAffix."ZDesc/reduced" = "" [prime.capital-z.variants-buildup.stages.overlay.with-crossbar] rank = 2 -descriptionSuffix = "a diagonal crossbar" -selectorSuffix.Z = "withCrossBar" -selectorSuffix."Z/sansSerif" = "withCrossBar" -selectorSuffix."Z/reduced" = "" -selectorSuffix."Z/reduced/sansSerif" = "" -selectorSuffix.ZDesc = "withCrossBar" -selectorSuffix."ZDesc/reduced" = "" +descriptionAffix = "a diagonal crossbar" +selectorAffix.Z = "withCrossBar" +selectorAffix."Z/sansSerif" = "withCrossBar" +selectorAffix."Z/reduced" = "" +selectorAffix."Z/reduced/sansSerif" = "" +selectorAffix.ZDesc = "withCrossBar" +selectorAffix."ZDesc/reduced" = "" [prime.capital-z.variants-buildup.stages.overlay.with-horizontal-crossbar] rank = 3 -descriptionSuffix = "a horizontal crossbar" -selectorSuffix.Z = "withHorizontalCrossBar" -selectorSuffix."Z/sansSerif" = "withHorizontalCrossBar" -selectorSuffix."Z/reduced" = "" -selectorSuffix."Z/reduced/sansSerif" = "" -selectorSuffix.ZDesc = "withHorizontalCrossBar" -selectorSuffix."ZDesc/reduced" = "" +descriptionAffix = "a horizontal crossbar" +selectorAffix.Z = "withHorizontalCrossBar" +selectorAffix."Z/sansSerif" = "withHorizontalCrossBar" +selectorAffix."Z/reduced" = "" +selectorAffix."Z/reduced/sansSerif" = "" +selectorAffix.ZDesc = "withHorizontalCrossBar" +selectorAffix."ZDesc/reduced" = "" @@ -2782,95 +2727,95 @@ next = "serifs" [prime.k.variants-buildup.stages.body.straight] rank = 1 -descriptionSuffix = "standard shape" -selectorSuffix.k = "straight" -selectorSuffix."k/sansSerif" = "straight" -selectorSuffix.kHookTop = "straight" -selectorSuffix.kDescender = "straight" +descriptionAffix = "standard shape" +selectorAffix.k = "straight" +selectorAffix."k/sansSerif" = "straight" +selectorAffix.kHookTop = "straight" +selectorAffix.kDescender = "straight" [prime.k.variants-buildup.stages.body.curly] rank = 2 -descriptionSuffix = "curly shape" -selectorSuffix.k = "curly" -selectorSuffix."k/sansSerif" = "curly" -selectorSuffix.kHookTop = "curly" -selectorSuffix.kDescender = "curly" +descriptionAffix = "curly shape" +selectorAffix.k = "curly" +selectorAffix."k/sansSerif" = "curly" +selectorAffix.kHookTop = "curly" +selectorAffix.kDescender = "curly" [prime.k.variants-buildup.stages.body.symmetric-touching] rank = 3 -descriptionSuffix = "symmetric legs touching the vertical bar" -selectorSuffix.k = "symmetricTouching" -selectorSuffix."k/sansSerif" = "symmetricTouching" -selectorSuffix.kHookTop = "symmetricTouching" -selectorSuffix.kDescender = "symmetricTouching" +descriptionAffix = "symmetric legs touching the vertical bar" +selectorAffix.k = "symmetricTouching" +selectorAffix."k/sansSerif" = "symmetricTouching" +selectorAffix.kHookTop = "symmetricTouching" +selectorAffix.kDescender = "symmetricTouching" [prime.k.variants-buildup.stages.body.symmetric-connected] rank = 4 -descriptionSuffix = "symmetric legs connected to the vertical bar" -selectorSuffix.k = "symmetricConnected" -selectorSuffix."k/sansSerif" = "symmetricConnected" -selectorSuffix.kHookTop = "symmetricConnected" -selectorSuffix.kDescender = "symmetricConnected" +descriptionAffix = "symmetric legs connected to the vertical bar" +selectorAffix.k = "symmetricConnected" +selectorAffix."k/sansSerif" = "symmetricConnected" +selectorAffix.kHookTop = "symmetricConnected" +selectorAffix.kDescender = "symmetricConnected" [prime.k.variants-buildup.stages.body.cursive] rank = 5 -descriptionSuffix = "cursive loop" -selectorSuffix.k = "cursive" -selectorSuffix."k/sansSerif" = "cursive" -selectorSuffix.kHookTop = "cursive" -selectorSuffix.kDescender = "cursive" +descriptionAffix = "cursive loop" +selectorAffix.k = "cursive" +selectorAffix."k/sansSerif" = "cursive" +selectorAffix.kHookTop = "cursive" +selectorAffix.kDescender = "cursive" [prime.k.variants-buildup.stages.body.diagonal-tailed-cursive] rank = 6 -descriptionSuffix = "cursive loop plus diagonal tail" -selectorSuffix.k = "cursiveTailed" -selectorSuffix."k/sansSerif" = "cursiveTailed" -selectorSuffix.kHookTop = "cursiveTailed" -selectorSuffix.kDescender = "cursiveTailed" +descriptionAffix = "cursive loop plus diagonal tail" +selectorAffix.k = "cursiveTailed" +selectorAffix."k/sansSerif" = "cursiveTailed" +selectorAffix.kHookTop = "cursiveTailed" +selectorAffix.kDescender = "cursiveTailed" [prime.k.variants-buildup.stages.serifs.serifless] rank = 1 -descriptionSuffix = "serifs" +descriptionAffix = "serifs" descriptionJoiner = "without" -selectorSuffix.k = "serifless" -selectorSuffix."k/sansSerif" = "serifless" -selectorSuffix.kHookTop = "serifless" -selectorSuffix.kDescender = "serifless" +selectorAffix.k = "serifless" +selectorAffix."k/sansSerif" = "serifless" +selectorAffix.kHookTop = "serifless" +selectorAffix.kDescender = "serifless" [prime.k.variants-buildup.stages.serifs.top-left-serifed] rank = 2 -descriptionSuffix = "serifs at top left" -selectorSuffix.k = "topLeftSerifed" -selectorSuffix."k/sansSerif" = "serifless" -selectorSuffix.kHookTop = "serifless" -selectorSuffix.kDescender = "topLeftSerifed" +descriptionAffix = "serifs at top left" +selectorAffix.k = "topLeftSerifed" +selectorAffix."k/sansSerif" = "serifless" +selectorAffix.kHookTop = "serifless" +selectorAffix.kDescender = "topLeftSerifed" [prime.k.variants-buildup.stages.serifs.bottom-right-serifed] rank = 3 disableIf = [ { body = "diagonal-tailed-cursive" } ] -descriptionSuffix = "serifs at top left" -selectorSuffix.k = "bottomRightSerifed" -selectorSuffix."k/sansSerif" = "serifless" -selectorSuffix.kHookTop = "bottomRightSerifed" -selectorSuffix.kDescender = "bottomRightSerifed" +descriptionAffix = "serifs at top left" +selectorAffix.k = "bottomRightSerifed" +selectorAffix."k/sansSerif" = "serifless" +selectorAffix.kHookTop = "bottomRightSerifed" +selectorAffix.kDescender = "bottomRightSerifed" [prime.k.variants-buildup.stages.serifs.top-left-and-bottom-right-serifed] rank = 4 disableIf = [ { body = "diagonal-tailed-cursive" } ] -descriptionSuffix = "serifs at top left and bottom right" -selectorSuffix.k = "topLeftAndBottomRightSerifed" -selectorSuffix."k/sansSerif" = "serifless" -selectorSuffix.kHookTop = "bottomRightSerifed" -selectorSuffix.kDescender = "topLeftAndBottomRightSerifed" +descriptionAffix = "serifs at top left and bottom right" +selectorAffix.k = "topLeftAndBottomRightSerifed" +selectorAffix."k/sansSerif" = "serifless" +selectorAffix.kHookTop = "bottomRightSerifed" +selectorAffix.kDescender = "topLeftAndBottomRightSerifed" [prime.k.variants-buildup.stages.serifs.serifed] rank = 5 disableIf = [ { body = "diagonal-tailed-cursive" } ] -descriptionSuffix = "serifs" -selectorSuffix.k = "serifed" -selectorSuffix."k/sansSerif" = "serifless" -selectorSuffix.kHookTop = "serifed" -selectorSuffix.kDescender = "serifed" +descriptionAffix = "serifs" +selectorAffix.k = "serifed" +selectorAffix."k/sansSerif" = "serifless" +selectorAffix.kHookTop = "serifed" +selectorAffix.kDescender = "serifed" @@ -3048,122 +2993,122 @@ next = "leg" [prime.m.variants-buildup.stages.body.normal] rank = 1 -keySuffix = "" -descriptionSuffix = "eared body shape" -selectorSuffix.m = "" -selectorSuffix."m/tailless" = "" -selectorSuffix."m/sansSerif" = "" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "" +keyAffix = "" +descriptionAffix = "eared body shape" +selectorAffix.m = "" +selectorAffix."m/tailless" = "" +selectorAffix."m/sansSerif" = "" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "" [prime.m.variants-buildup.stages.body.earless-corner-double-arch] rank = 2 -descriptionSuffix = "earless (corner top-left) double-arch body shape" -selectorSuffix.m = "earlessCornerDoubleArch" -selectorSuffix."m/tailless" = "earlessCornerDoubleArch" -selectorSuffix."m/sansSerif" = "earlessCornerDoubleArch" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "earlessCornerDoubleArch" +descriptionAffix = "earless (corner top-left) double-arch body shape" +selectorAffix.m = "earlessCornerDoubleArch" +selectorAffix."m/tailless" = "earlessCornerDoubleArch" +selectorAffix."m/sansSerif" = "earlessCornerDoubleArch" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "earlessCornerDoubleArch" [prime.m.variants-buildup.stages.body.earless-rounded-double-arch] rank = 3 -descriptionSuffix = "earless (rounded top-left) double-arch body shape" -selectorSuffix.m = "earlessRoundedDoubleArch" -selectorSuffix."m/tailless" = "earlessRoundedDoubleArch" -selectorSuffix."m/sansSerif" = "earlessRoundedDoubleArch" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "earlessRoundedDoubleArch" +descriptionAffix = "earless (rounded top-left) double-arch body shape" +selectorAffix.m = "earlessRoundedDoubleArch" +selectorAffix."m/tailless" = "earlessRoundedDoubleArch" +selectorAffix."m/sansSerif" = "earlessRoundedDoubleArch" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "earlessRoundedDoubleArch" [prime.m.variants-buildup.stages.body.earless-single-arch] rank = 4 -descriptionSuffix = "earless (corner top-left) body shape" -selectorSuffix.m = "earlessSingleArch" -selectorSuffix."m/tailless" = "earlessSingleArch" -selectorSuffix."m/sansSerif" = "earlessSingleArch" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "earlessSingleArch" +descriptionAffix = "earless (corner top-left) body shape" +selectorAffix.m = "earlessSingleArch" +selectorAffix."m/tailless" = "earlessSingleArch" +selectorAffix."m/sansSerif" = "earlessSingleArch" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "earlessSingleArch" [prime.m.variants-buildup.stages.leg."*"] next = "tail" [prime.m.variants-buildup.stages.leg.normal] rank = 1 -keySuffix = "" -descriptionSuffix = "normal middle leg" -selectorSuffix.m = "" -selectorSuffix."m/tailless" = "" -selectorSuffix."m/sansSerif" = "" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "" +keyAffix = "" +descriptionAffix = "normal middle leg" +selectorAffix.m = "" +selectorAffix."m/tailless" = "" +selectorAffix."m/sansSerif" = "" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "" [prime.m.variants-buildup.stages.leg.short-leg] rank = 2 -descriptionSuffix = "shorter middle leg (like Ubuntu Mono)" -selectorSuffix.m = "shortLeg" -selectorSuffix."m/tailless" = "shortLeg" -selectorSuffix."m/sansSerif" = "shortLeg" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "shortLeg" +descriptionAffix = "shorter middle leg (like Ubuntu Mono)" +selectorAffix.m = "shortLeg" +selectorAffix."m/tailless" = "shortLeg" +selectorAffix."m/sansSerif" = "shortLeg" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "shortLeg" [prime.m.variants-buildup.stages.tail."*"] next = "serifs" [prime.m.variants-buildup.stages.tail.normal] rank = 1 -keySuffix = "" -selectorSuffix.m = "" -selectorSuffix."m/tailless" = "" -selectorSuffix."m/sansSerif" = "" -selectorSuffix."cyrl/te.italic" = "" -selectorSuffix.mLTail = "" +keyAffix = "" +selectorAffix.m = "" +selectorAffix."m/tailless" = "" +selectorAffix."m/sansSerif" = "" +selectorAffix."cyrl/te.italic" = "" +selectorAffix.mLTail = "" [prime.m.variants-buildup.stages.tail.tailed] rank = 2 -descriptionSuffix = "tail" -selectorSuffix.m = "tailed" -selectorSuffix."m/tailless" = "" -selectorSuffix."m/sansSerif" = "tailed" -selectorSuffix."cyrl/te.italic" = "tailed" -selectorSuffix.mLTail = "" +descriptionAffix = "tail" +selectorAffix.m = "tailed" +selectorAffix."m/tailless" = "" +selectorAffix."m/sansSerif" = "tailed" +selectorAffix."cyrl/te.italic" = "tailed" +selectorAffix.mLTail = "" [prime.m.variants-buildup.stages.serifs.serifless] rank = 1 descriptionJoiner = "without" -descriptionSuffix = "serifs" -selectorSuffix.m = "serifless" -selectorSuffix."m/tailless" = "serifless" -selectorSuffix."m/sansSerif" = "serifless" -selectorSuffix."cyrl/te.italic" = "serifless" -selectorSuffix.mLTail = "serifless" +descriptionAffix = "serifs" +selectorAffix.m = "serifless" +selectorAffix."m/tailless" = "serifless" +selectorAffix."m/sansSerif" = "serifless" +selectorAffix."cyrl/te.italic" = "serifless" +selectorAffix.mLTail = "serifless" [prime.m.variants-buildup.stages.serifs.top-left-serifed] rank = 2 -descriptionSuffix = "serif at top left" +descriptionAffix = "serif at top left" disableIf = [ { body = "NOT normal" } ] -selectorSuffix.m = "topLeftSerifed" -selectorSuffix."m/tailless" = "topLeftSerifed" -selectorSuffix."m/sansSerif" = "serifless" -selectorSuffix."cyrl/te.italic" = "topLeftSerifed" -selectorSuffix.mLTail = "topLeftSerifed" +selectorAffix.m = "topLeftSerifed" +selectorAffix."m/tailless" = "topLeftSerifed" +selectorAffix."m/sansSerif" = "serifless" +selectorAffix."cyrl/te.italic" = "topLeftSerifed" +selectorAffix.mLTail = "topLeftSerifed" [prime.m.variants-buildup.stages.serifs.top-left-and-bottom-right-serifed] rank = 3 -descriptionSuffix = "serifs at top left and bottom right" +descriptionAffix = "serifs at top left and bottom right" disableIf = [ { body = "NOT normal" }, { tail = "tailed" } ] -selectorSuffix.m = "topLeftAndBottomRightSerifed" -selectorSuffix."m/tailless" = "topLeftAndBottomRightSerifed" -selectorSuffix."m/sansSerif" = "serifless" -selectorSuffix."cyrl/te.italic" = "topLeftAndBottomRightSerifed" -selectorSuffix.mLTail = "topLeftSerifed" +selectorAffix.m = "topLeftAndBottomRightSerifed" +selectorAffix."m/tailless" = "topLeftAndBottomRightSerifed" +selectorAffix."m/sansSerif" = "serifless" +selectorAffix."cyrl/te.italic" = "topLeftAndBottomRightSerifed" +selectorAffix.mLTail = "topLeftSerifed" [prime.m.variants-buildup.stages.serifs.serifed] rank = 4 -descriptionSuffix = "serifs" -selectorSuffix.m = "serifed" -selectorSuffix."m/tailless" = "serifed" -selectorSuffix."m/sansSerif" = "serifless" -selectorSuffix."cyrl/te.italic" = "serifed" -selectorSuffix.mLTail = "serifed" +descriptionAffix = "serifs" +selectorAffix.m = "serifed" +selectorAffix."m/tailless" = "serifed" +selectorAffix."m/sansSerif" = "serifless" +selectorAffix."cyrl/te.italic" = "serifed" +selectorAffix.mLTail = "serifed" @@ -3522,185 +3467,107 @@ selector.qHookTop = "diagonalTailed" sampler = "r" tag = "cv42" -[prime.r.variants.serifless] +[prime.r.variants-buildup] +entry = "body" +descriptionLeader = "`r`" + +[prime.r.variants-buildup.stages.body."*"] +next = "serifs" + +[prime.r.variants-buildup.stages.body.normal] rank = 1 -description = "Straight, serif-less `r`" -selector.r = "serifless" -selector."r/sansSerif" = "serifless" -selector.rRTail = "serifless" -selector."rTurnRTail" = "serifless" -selector."rFlap" = "serifless" +keyAffix = "" +descriptionAffix = "normal body shape" +selectorAffix.r = "" +selectorAffix."r/sansSerif" = "" +selectorAffix.rRTail = "" +selectorAffix."rTurnRTail" = "" +selectorAffix."rFlap" = "earlessRounded" -[prime.r.variants.serifed] +[prime.r.variants-buildup.stages.body.earless-corner] rank = 2 -description = "`r` with serif at both top and bottom" -selector.r = "serifed" -selector."r/sansSerif" = "serifless" -selector.rRTail = "topSerifed" -selector."rTurnRTail" = "serifed" -selector."rFlap" = "serifed" +descriptionAffix = "earless (corner top-left) body shape" +selectorAffix.r = "earlessCorner" +selectorAffix."r/sansSerif" = "earlessCorner" +selectorAffix.rRTail = "earlessCorner" +selectorAffix."rTurnRTail" = "" +selectorAffix."rFlap" = "earlessCorner" -[prime.r.variants.top-serifed] +[prime.r.variants-buildup.stages.body.earless-rounded] rank = 3 -description = "`r` with serifs at top-left only" -selector.r = "topSerifed" -selector."r/sansSerif" = "serifless" -selector.rRTail = "topSerifed" -selector."rTurnRTail" = "topSerifed" -selector."rFlap" = "serifless" +descriptionAffix = "earless (rounded top-left) body shape" +selectorAffix.r = "earlessRounded" +selectorAffix."r/sansSerif" = "earlessRounded" +selectorAffix.rRTail = "earlessRounded" +selectorAffix."rTurnRTail" = "" +selectorAffix."rFlap" = "earlessRounded" -[prime.r.variants.base-serifed] +[prime.r.variants-buildup.stages.body.hookless] rank = 4 -description = "`r` with serifs at top-left only" -selector.r = "baseSerifed" -selector."r/sansSerif" = "serifless" -selector.rRTail = "serifless" -selector."rTurnRTail" = "serifed" -selector."rFlap" = "serifed" +descriptionAffix = "hookless body shape" +selectorAffix.r = "hookless" +selectorAffix."r/sansSerif" = "hookless" +selectorAffix.rRTail = "hookless" +selectorAffix."rTurnRTail" = "hookless" +selectorAffix."rFlap" = "hooklessFlap" -[prime.r.variants.earless-corner] +[prime.r.variants-buildup.stages.body.corner-hooked] rank = 5 -description = "Earless (corner top-left), serif-less `r`" -selector.r = "earlessCorner" -selector."r/sansSerif" = "earlessCorner" -selector.rRTail = "earlessCorner" -selector."rTurnRTail" = "serifless" -selector."rFlap" = "serifless" +descriptionAffix = "corner-hooked body shape" +selectorAffix.r = "cornerHooked" +selectorAffix."r/sansSerif" = "hookless" +selectorAffix.rRTail = "cornerHooked" +selectorAffix."rTurnRTail" = "cornerHooked" +selectorAffix."rFlap" = "hooklessFlap" -[prime.r.variants.earless-corner-serifed] +[prime.r.variants-buildup.stages.body.compact] rank = 6 -description = "Earless (corner top-left), serifed `r`" -selector.r = "earlessCornerSerifed" -selector."r/sansSerif" = "earlessCorner" -selector.rRTail = "earlessCorner" -selector."rTurnRTail" = "serifed" -selector."rFlap" = "serifed" +descriptionAffix = "compact body shape (identical to 'hookless' for monospace fonts)" +selectorAffix.r = "compact" +selectorAffix."r/sansSerif" = "compact" +selectorAffix.rRTail = "compact" +selectorAffix."rTurnRTail" = "compact" +selectorAffix."rFlap" = "compactFlap" -[prime.r.variants.earless-rounded] -rank = 7 -description = "Earless (rounded top-left), serif-less `r`" -selector.r = "earlessRounded" -selector."r/sansSerif" = "earlessRounded" -selector.rRTail = "earlessRounded" -selector."rTurnRTail" = "serifless" -selector."rFlap" = "serifless" +[prime.r.variants-buildup.stages.serifs.serifless] +rank = 1 +descriptionJoiner = "without" +descriptionAffix = "serifs" +selectorAffix.r = "serifless" +selectorAffix."r/sansSerif" = "serifless" +selectorAffix.rRTail = "serifless" +selectorAffix."rTurnRTail" = "serifless" +selectorAffix."rFlap" = "serifless" -[prime.r.variants.earless-rounded-serifed] -rank = 8 -description = "Earless (rounded top-left), serifed `r`" -selector.r = "earlessRoundedSerifed" -selector."r/sansSerif" = "earlessRounded" -selector.rRTail = "earlessRounded" -selector."rTurnRTail" = "serifed" -selector."rFlap" = "serifed" +[prime.r.variants-buildup.stages.serifs.top-serifed] +rank = 2 +disableIf = [ { body = "earless-corner" }, { body = "earless-rounded" } ] +descriptionAffix = "serif at top" +selectorAffix.r = "topSerifed" +selectorAffix."r/sansSerif" = "serifless" +selectorAffix.rRTail = "topSerifed" +selectorAffix."rTurnRTail" = "serifless" +selectorAffix."rFlap" = "serifless" -[prime.r.variants.hookless] -rank = 9 -description = "Hookless, serifless `r`" -selector.r = "hookless" -selector."r/sansSerif" = "hookless" -selector.rRTail = "hookless" -selector."rTurnRTail" = "hookless" -selector."rFlap" = "hookless" +[prime.r.variants-buildup.stages.serifs.base-serifed] +rank = 3 +disableIf = [ { body = "earless-corner" }, { body = "earless-rounded" } ] +descriptionAffix = "serif at bottom" +selectorAffix.r = "baseSerifed" +selectorAffix."r/sansSerif" = "serifless" +selectorAffix.rRTail = "serifless" +selectorAffix."rTurnRTail" = "serifed" +selectorAffix."rFlap" = "serifed" -[prime.r.variants.hookless-serifed] -rank = 10 -description = "Hookless `r` with top and bottom serifs" -selector.r = "hooklessSerifed" -selector."r/sansSerif" = "hookless" -selector.rRTail = "hooklessSerifed" -selector."rTurnRTail" = "hooklessSerifed" -selector."rFlap" = "hookless" +[prime.r.variants-buildup.stages.serifs.serifed] +rank = 4 +descriptionAffix = "serifs" +selectorAffix.r = "serifed" +selectorAffix."r/sansSerif" = "serifless" +selectorAffix.rRTail = "serifed" +selectorAffix."rTurnRTail" = "serifed" +selectorAffix."rFlap" = "serifed" -[prime.r.variants.hookless-top-serifed] -rank = 11 -description = "Hookless `r` with top serif" -selector.r = "hooklessTopSerifed" -selector."r/sansSerif" = "hookless" -selector.rRTail = "hooklessSerifed" -selector."rTurnRTail" = "hooklessSerifed" -selector."rFlap" = "hookless" - -[prime.r.variants.hookless-base-serifed] -rank = 12 -description = "Hookless `r` with bottom serif" -selector.r = "hooklessBaseSerifed" -selector."r/sansSerif" = "hookless" -selector.rRTail = "hookless" -selector."rTurnRTail" = "hooklessSerifed" -selector."rFlap" = "hookless" - -[prime.r.variants.corner-hooked] -rank = 13 -description = "`r` with vertical corner hook downwards" -selector.r = "cornerHooked" -selector."r/sansSerif" = "compact" -selector.rRTail = "cornerHooked" -selector."rTurnRTail" = "cornerHooked" -selector."rFlap" = "serifless" - -[prime.r.variants.corner-hooked-serifed] -rank = 14 -description = "`r` with vertical corner hook downwards, top and bottom serifs" -selector.r = "cornerHookedSerifed" -selector."r/sansSerif" = "compact" -selector.rRTail = "cornerHookedSerifed" -selector."rTurnRTail" = "cornerHookedSerifed" -selector."rFlap" = "serifed" - -[prime.r.variants.corner-hooked-top-serifed] -rank = 15 -description = "`r` with vertical corner hook downwards and top serif" -selector.r = "cornerHookedTopSerifed" -selector."r/sansSerif" = "compact" -selector.rRTail = "cornerHookedSerifed" -selector."rTurnRTail" = "cornerHookedSerifed" -selector."rFlap" = "serifless" - -[prime.r.variants.corner-hooked-base-serifed] -rank = 16 -description = "`r` with vertical corner hook downwards and bottom serif" -selector.r = "cornerHookedBaseSerifed" -selector."r/sansSerif" = "compact" -selector.rRTail = "cornerHooked" -selector."rTurnRTail" = "cornerHookedSerifed" -selector."rFlap" = "serifed" - -[prime.r.variants.compact] -rank = 17 -description = "Hookless and compact, serifless `r`. Identical to `compact` for monospace fonts" -selector.r = "compact" -selector."r/sansSerif" = "compact" -selector.rRTail = "compact" -selector."rTurnRTail" = "compact" -selector."rFlap" = "compact" - -[prime.r.variants.compact-serifed] -rank = 18 -description = "Hookless and compact `r` with top and bottom serifs. Identical to `compact-serifed` for monospace fonts" -selector.r = "compactSerifed" -selector."r/sansSerif" = "compact" -selector.rRTail = "compactSerifed" -selector."rTurnRTail" = "compactSerifed" -selector."rFlap" = "compact" - -[prime.r.variants.compact-top-serifed] -rank = 19 -description = "Hookless and compact `r` with top serif. Identical to `compact-top-serifed` for monospace fonts" -selector.r = "compactTopSerifed" -selector."r/sansSerif" = "compact" -selector.rRTail = "compactSerifed" -selector."rTurnRTail" = "compactSerifed" -selector."rFlap" = "compact" - -[prime.r.variants.compact-base-serifed] -rank = 20 -description = "Hookless and compact `r` with bottom serif. Identical to `compact-base-serifed` for monospace fonts" -selector.r = "compactBaseSerifed" -selector."r/sansSerif" = "compact" -selector.rRTail = "compact" -selector."rTurnRTail" = "compactSerifed" -selector."rFlap" = "compact" [prime.s] @@ -3768,200 +3635,119 @@ selector.sRTail = "bilateralInwardSerifed" sampler = "t" tag = "cv44" -[prime.t.variants.standard] +[prime.t.variants-buildup] +entry = "height" +descriptionLeader = "`t`" + +[prime.t.variants-buildup.stages.body."*"] +mode = "prepend" + +[prime.t.variants-buildup.stages.height."*"] +next = "body" + +[prime.t.variants-buildup.stages.body.standard] rank = 1 -description = "Standard `t` shape" -selector.t = "standard" -selector."t/phoneticLeft1" = "flatHook" -selector."t/phoneticLeft2" = "flatHook" -selector."t/phoneticLeft3" = "standard" -selector.tHookTop = "standard" -selector.tRTail = "flatHook" -selector.tLTail = "standard" -selector.tCurlyTail = "standard" -selector."tsLig/upperHalf" = "standard" +descriptionAffix = "standard body shape" +selectorAffix.t = "standard" +selectorAffix."t/phoneticLeft1" = "flatHook" +selectorAffix."t/phoneticLeft2" = "flatHook" +selectorAffix."t/phoneticLeft3" = "standard" +selectorAffix.tHookTop = "standard" +selectorAffix.tRTail = "flatHook" +selectorAffix.tLTail = "standard" +selectorAffix.tCurlyTail = "standard" +selectorAffix."tsLig/upperHalf" = "standard" -[prime.t.variants.flat-hook] +[prime.t.variants-buildup.stages.body.flat-hook] rank = 2 -description = "`t` with flat hook" -selector.t = "flatHook" -selector."t/phoneticLeft1" = "flatHook" -selector."t/phoneticLeft2" = "flatHook" -selector."t/phoneticLeft3" = "flatHook" -selector.tHookTop = "flatHook" -selector.tRTail = "flatHook" -selector.tLTail = "flatHook" -selector.tCurlyTail = "flatHook" -selector."tsLig/upperHalf" = "standard" +descriptionAffix = "body with flat hook" +selectorAffix.t = "flatHook" +selectorAffix."t/phoneticLeft1" = "flatHook" +selectorAffix."t/phoneticLeft2" = "flatHook" +selectorAffix."t/phoneticLeft3" = "flatHook" +selectorAffix.tHookTop = "flatHook" +selectorAffix.tRTail = "flatHook" +selectorAffix.tLTail = "flatHook" +selectorAffix.tCurlyTail = "flatHook" +selectorAffix."tsLig/upperHalf" = "standard" -[prime.t.variants.diagonal-tailed] +[prime.t.variants-buildup.stages.body.diagonal-tailed] rank = 3 -description = "`t` with diagonal tail" -selector.t = "diagonalTailed" -selector."t/phoneticLeft1" = "flatHook" -selector."t/phoneticLeft2" = "flatHook" -selector."t/phoneticLeft3" = "diagonalTailed" -selector.tHookTop = "diagonalTailed" -selector.tRTail = "flatHook" -selector.tLTail = "diagonalTailed" -selector.tCurlyTail = "standard" -selector."tsLig/upperHalf" = "standard" +descriptionAffix = "body with diagonal tail" +selectorAffix.t = "diagonalTailed" +selectorAffix."t/phoneticLeft1" = "flatHook" +selectorAffix."t/phoneticLeft2" = "flatHook" +selectorAffix."t/phoneticLeft3" = "diagonalTailed" +selectorAffix.tHookTop = "diagonalTailed" +selectorAffix.tRTail = "flatHook" +selectorAffix.tLTail = "diagonalTailed" +selectorAffix.tCurlyTail = "standard" +selectorAffix."tsLig/upperHalf" = "standard" -[prime.t.variants.cross] +[prime.t.variants-buildup.stages.body.cross] rank = 4 -description = "Futura-like `t` shape" -selector.t = "cross" -selector."t/phoneticLeft1" = "cross" -selector."t/phoneticLeft2" = "cross" -selector."t/phoneticLeft3" = "cross" -selector.tHookTop = "cross" -selector.tRTail = "cross" -selector.tLTail = "cross" -selector.tCurlyTail = "cross" -selector."tsLig/upperHalf" = "standard" +descriptionAffix = "Futura-like body shape" +selectorAffix.t = "cross" +selectorAffix."t/phoneticLeft1" = "cross" +selectorAffix."t/phoneticLeft2" = "cross" +selectorAffix."t/phoneticLeft3" = "cross" +selectorAffix.tHookTop = "cross" +selectorAffix.tRTail = "cross" +selectorAffix.tLTail = "cross" +selectorAffix.tCurlyTail = "cross" +selectorAffix."tsLig/upperHalf" = "standard" -[prime.t.variants.hookless-asymmetric] +[prime.t.variants-buildup.stages.body.hookless-asymmetric] rank = 5 -description = "`t` without hook and with ony half the cross bar" -selector.t = "hooklessAsymmetric" -selector."t/phoneticLeft1" = "hooklessAsymmetric" -selector."t/phoneticLeft2" = "hooklessAsymmetric" -selector."t/phoneticLeft3" = "hooklessAsymmetric" -selector.tHookTop = "hooklessAsymmetric" -selector.tRTail = "hooklessAsymmetric" -selector.tLTail = "hooklessAsymmetric" -selector.tCurlyTail = "hooklessAsymmetric" -selector."tsLig/upperHalf" = "standard" +descriptionAffix = "hookless asymmetric body shape (only half the cross bar)" +selectorAffix.t = "hooklessAsymmetric" +selectorAffix."t/phoneticLeft1" = "hooklessAsymmetric" +selectorAffix."t/phoneticLeft2" = "hooklessAsymmetric" +selectorAffix."t/phoneticLeft3" = "hooklessAsymmetric" +selectorAffix.tHookTop = "hooklessAsymmetric" +selectorAffix.tRTail = "hooklessAsymmetric" +selectorAffix.tLTail = "hooklessAsymmetric" +selectorAffix.tCurlyTail = "hooklessAsymmetric" +selectorAffix."tsLig/upperHalf" = "standard" -[prime.t.variants.standard-short-neck] -rank = 6 -description = "Standard `t` shape with a shorter neck" -selector.t = "standardShortNeck" -selector."t/phoneticLeft1" = "flatHookShortNeck" -selector."t/phoneticLeft2" = "flatHookShortNeck" -selector."t/phoneticLeft3" = "standard" -selector.tHookTop = "standard" -selector.tRTail = "flatHookShortNeck" -selector.tLTail = "standardShortNeck" -selector.tCurlyTail = "standardShortNeck" -selector."tsLig/upperHalf" = "standardShortNeck" +[prime.t.variants-buildup.stages.height.full] +rank = 1 +keyAffix = "" +selectorAffix.t = "" +selectorAffix."t/phoneticLeft1" = "" +selectorAffix."t/phoneticLeft2" = "" +selectorAffix."t/phoneticLeft3" = "" +selectorAffix.tHookTop = "" +selectorAffix.tRTail = "" +selectorAffix.tLTail = "" +selectorAffix.tCurlyTail = "" +selectorAffix."tsLig/upperHalf" = "" -[prime.t.variants.flat-hook-short-neck] -rank = 7 -description = "`t` with flat hook and a slightly shorter neck" -selector.t = "flatHookShortNeck" -selector."t/phoneticLeft1" = "flatHookShortNeck" -selector."t/phoneticLeft2" = "flatHookShortNeck" -selector."t/phoneticLeft3" = "flatHook" -selector.tHookTop = "flatHook" -selector.tRTail = "flatHookShortNeck" -selector.tLTail = "flatHookShortNeck" -selector.tCurlyTail = "flatHookShortNeck" -selector."tsLig/upperHalf" = "standardShortNeck" +[prime.t.variants-buildup.stages.height.short-neck] +rank = 2 +descriptionAffix = "a shorter neck" +selectorAffix.t = "shortNeck" +selectorAffix."t/phoneticLeft1" = "shortNeck" +selectorAffix."t/phoneticLeft2" = "shortNeck" +selectorAffix."t/phoneticLeft3" = "" +selectorAffix.tHookTop = "" +selectorAffix.tRTail = "shortNeck" +selectorAffix.tLTail = "shortNeck" +selectorAffix.tCurlyTail = "shortNeck" +selectorAffix."tsLig/upperHalf" = "shortNeck" -[prime.t.variants.diagonal-tailed-short-neck] -rank = 8 -description = "`t` with diagonal tail and a shorter neck" -selector.t = "diagonalTailedShortNeck" -selector."t/phoneticLeft1" = "flatHookShortNeck" -selector."t/phoneticLeft2" = "flatHookShortNeck" -selector."t/phoneticLeft3" = "diagonalTailed" -selector.tHookTop = "diagonalTailed" -selector.tRTail = "flatHookShortNeck" -selector.tLTail = "diagonalTailedShortNeck" -selector.tCurlyTail = "standardShortNeck" -selector."tsLig/upperHalf" = "standardShortNeck" - -[prime.t.variants.cross-short-neck] -rank = 9 -description = "Futura-like `t` shape with a shorter neck" -selector.t = "crossShortNeck" -selector."t/phoneticLeft1" = "crossShortNeck" -selector."t/phoneticLeft2" = "crossShortNeck" -selector."t/phoneticLeft3" = "cross" -selector.tHookTop = "cross" -selector.tRTail = "crossShortNeck" -selector.tLTail = "crossShortNeck" -selector.tCurlyTail = "crossShortNeck" -selector."tsLig/upperHalf" = "standardShortNeck" - -[prime.t.variants.hookless-asymmetric-short-neck] -rank = 10 -description = "`t` without hook, with ony half the cross bar and a shorter neck" -selector.t = "hooklessAsymmetricShortNeck" -selector."t/phoneticLeft1" = "hooklessAsymmetricShortNeck" -selector."t/phoneticLeft2" = "hooklessAsymmetricShortNeck" -selector."t/phoneticLeft3" = "hooklessAsymmetric" -selector.tHookTop = "cross" -selector.tRTail = "hooklessAsymmetricShortNeck" -selector.tLTail = "hooklessAsymmetricShortNeck" -selector.tCurlyTail = "hooklessAsymmetricShortNeck" -selector."tsLig/upperHalf" = "standardShortNeck" - -[prime.t.variants.standard-short-neck2] -rank = 11 -description = "Standard `t` shape with a more shorter neck" -selector.t = "standardShortNeck2" -selector."t/phoneticLeft1" = "flatHookShortNeck2" -selector."t/phoneticLeft2" = "flatHookShortNeck2" -selector."t/phoneticLeft3" = "standard" -selector.tHookTop = "standard" -selector.tRTail = "flatHookShortNeck2" -selector.tLTail = "standardShortNeck2" -selector.tCurlyTail = "standardShortNeck2" -selector."tsLig/upperHalf" = "standardShortNeck2" - -[prime.t.variants.flat-hook-short-neck2] -rank = 12 -description = "`t` with flat hook and a more shorter neck" -selector.t = "flatHookShortNeck2" -selector."t/phoneticLeft1" = "flatHookShortNeck2" -selector."t/phoneticLeft2" = "flatHookShortNeck2" -selector."t/phoneticLeft3" = "flatHook" -selector.tHookTop = "flatHook" -selector.tRTail = "flatHookShortNeck2" -selector.tLTail = "flatHookShortNeck2" -selector.tCurlyTail = "flatHookShortNeck2" -selector."tsLig/upperHalf" = "standardShortNeck2" - -[prime.t.variants.diagonal-tailed-short-neck2] -rank = 13 -description = "`t` with diagonal tail and a more shorter neck" -selector.t = "diagonalTailedShortNeck2" -selector."t/phoneticLeft1" = "flatHookShortNeck2" -selector."t/phoneticLeft2" = "flatHookShortNeck2" -selector."t/phoneticLeft3" = "diagonalTailed" -selector.tHookTop = "diagonalTailed" -selector.tRTail = "flatHookShortNeck2" -selector.tLTail = "diagonalTailedShortNeck2" -selector.tCurlyTail = "standardShortNeck2" -selector."tsLig/upperHalf" = "standardShortNeck2" - -[prime.t.variants.cross-short-neck2] -rank = 14 -description = "Futura-like `t` shape with a more shorter neck" -selector.t = "crossShortNeck2" -selector."t/phoneticLeft1" = "crossShortNeck2" -selector."t/phoneticLeft2" = "crossShortNeck2" -selector."t/phoneticLeft3" = "cross" -selector.tHookTop = "cross" -selector.tRTail = "crossShortNeck2" -selector.tLTail = "crossShortNeck2" -selector.tCurlyTail = "crossShortNeck2" -selector."tsLig/upperHalf" = "standardShortNeck2" - -[prime.t.variants.hookless-asymmetric-short-neck2] -rank = 15 -description = "`t` without hook, with ony half the cross bar and a more shorter neck" -selector.t = "hooklessAsymmetricShortNeck2" -selector."t/phoneticLeft1" = "hooklessAsymmetricShortNeck2" -selector."t/phoneticLeft2" = "hooklessAsymmetricShortNeck2" -selector."t/phoneticLeft3" = "hooklessAsymmetric" -selector.tHookTop = "hooklessAsymmetric" -selector.tRTail = "hooklessAsymmetricShortNeck2" -selector.tLTail = "hooklessAsymmetricShortNeck2" -selector.tCurlyTail = "hooklessAsymmetricShortNeck2" -selector."tsLig/upperHalf" = "standardShortNeck2" +[prime.t.variants-buildup.stages.height.short-neck2] +rank = 3 +descriptionAffix = "a more shorter neck" +selectorAffix.t = "shortNeck2" +selectorAffix."t/phoneticLeft1" = "shortNeck2" +selectorAffix."t/phoneticLeft2" = "shortNeck2" +selectorAffix."t/phoneticLeft3" = "" +selectorAffix.tHookTop = "" +selectorAffix.tRTail = "shortNeck2" +selectorAffix.tLTail = "shortNeck2" +selectorAffix.tCurlyTail = "shortNeck2" +selectorAffix."tsLig/upperHalf" = "shortNeck2" @@ -4219,145 +4005,84 @@ selector."v/nonCursive" = "straightMotionSerifed" sampler = "w" tag = "cv47" -[prime.w.variants.straight-serifless] +[prime.w.variants-buildup] +entry = "body" +descriptionLeader = "`w`" + +[prime.w.variants-buildup.stages.body."*"] +next = "serifs" + +[prime.w.variants-buildup.stages.body.straight] rank = 1 -description = "Standard, straight `w`, without serifs" -selector.w = "straightSerifless" -selector."w/sansSerif" = "straightSerifless" -selector.wHookTop = "straightSerifless" +descriptionAffix = "standard, straight body" +selectorAffix.w = "straight" +selectorAffix."w/sansSerif" = "straight" +selectorAffix.wHookTop = "straight" -[prime.w.variants.straight-motion-serifed] +[prime.w.variants-buildup.stages.body.curly] rank = 2 -description = "Standard, straight `w`, with motion serifs" -selector.w = "straightMotionSerifed" -selector."w/sansSerif" = "straightSerifless" -selector.wHookTop = "straightMotionSerifed" +descriptionAffix = "curly body" +selectorAffix.w = "curly" +selectorAffix."w/sansSerif" = "curly" +selectorAffix.wHookTop = "curly" -[prime.w.variants.straight-serifed] +[prime.w.variants-buildup.stages.body.straight-flat-top] rank = 3 -description = "Standard, straight `w`, with serifs" -selector.w = "straightSerifed" -selector."w/sansSerif" = "straightSerifless" -selector.wHookTop = "straightSerifed" +descriptionAffix = "straight body shape that the middle is forced to be aligned the top" +selectorAffix.w = "straightFlatTop" +selectorAffix."w/sansSerif" = "straightFlatTop" +selectorAffix.wHookTop = "straightFlatTop" -[prime.w.variants.curly-serifless] +[prime.w.variants-buildup.stages.body.straight-double-v] rank = 4 -description = "Slightly curly `w`, like Iosevka 2.x, without serifs" -selector.w = "curlySerifless" -selector."w/sansSerif" = "curlySerifless" -selector.wHookTop = "curlySerifless" +descriptionAffix = "body shape like double V" +selectorAffix.w = "straightDoubleV" +selectorAffix."w/sansSerif" = "straightDoubleV" +selectorAffix.wHookTop = "straightDoubleV" -[prime.w.variants.curly-motion-serifed] +[prime.w.variants-buildup.stages.body.straight-asymmetric] rank = 5 -description = "Slightly curly `w`, like Iosevka 2.x, with motion serifs" -selector.w = "curlyMotionSerifed" -selector."w/sansSerif" = "curlySerifless" -selector.wHookTop = "curlyMotionSerifed" +descriptionAffix = "asymmetric shape" +selectorAffix.w = "straightAsymmetric" +selectorAffix."w/sansSerif" = "straightAsymmetric" +selectorAffix.wHookTop = "straightAsymmetric" -[prime.w.variants.curly-serifed] +[prime.w.variants-buildup.stages.body.straight-vertical-sides] rank = 6 -description = "Slightly curly `w`, like Iosevka 2.x, with serifs" -selector.w = "curlySerifed" -selector."w/sansSerif" = "curlySerifless" -selector.wHookTop = "curlySerifed" +descriptionAffix = "body shape with vertical sides" +selectorAffix.w = "straightVerticalSides" +selectorAffix."w/sansSerif" = "straightVerticalSides" +selectorAffix.wHookTop = "straightVerticalSides" -[prime.w.variants.straight-flat-top-serifless] -rank = 7 -description = "Standard, straight `w`, and the middle is forced to be aligned the top, without serifs" -selector.w = "straightFlatTopSerifless" -selector."w/sansSerif" = "straightFlatTopSerifless" -selector.wHookTop = "straightFlatTopSerifless" +[prime.w.variants-buildup.stages.body.cursive] +rank = 6 +descriptionAffix = "body shape with vertical sides" +selectorAffix.w = "cursive" +selectorAffix."w/sansSerif" = "cursive" +selectorAffix.wHookTop = "cursive" -[prime.w.variants.straight-flat-top-motion-serifed] -rank = 8 -description = "Standard, straight `w`, and the middle is forced to be aligned the top, with motion serifs" -selector.w = "straightFlatTopMotionSerifed" -selector."w/sansSerif" = "straightFlatTopSerifless" -selector.wHookTop = "straightFlatTopMotionSerifed" +[prime.w.variants-buildup.stages.serifs.serifless] +rank = 1 +descriptionAffix = "serifs" +descriptionJoiner = "without" +selectorAffix.w = "serifless" +selectorAffix."w/sansSerif" = "serifless" +selectorAffix.wHookTop = "serifless" -[prime.w.variants.straight-flat-top-serifed] -rank = 9 -description = "Standard, straight `w`, and the middle is forced to be aligned the top, with serifs" -selector.w = "straightFlatTopSerifed" -selector."w/sansSerif" = "straightFlatTopSerifless" -selector.wHookTop = "straightFlatTopSerifed" +[prime.w.variants-buildup.stages.serifs.motion-serifed] +rank = 2 +disableIf = [{ body = "cursive" }] +descriptionAffix = "motion serifs" +selectorAffix.w = "motionSerifed" +selectorAffix."w/sansSerif" = "serifless" +selectorAffix.wHookTop = "motionSerifed" -[prime.w.variants.straight-double-v-serifless] -rank = 10 -description = "Straight `w` looks like double V, without serifs" -selector.w = "straightDoubleVSerifless" -selector."w/sansSerif" = "straightDoubleVSerifless" -selector.wHookTop = "straightDoubleVSerifless" - -[prime.w.variants.straight-double-v-motion-serifed] -rank = 11 -description = "Straight `w` looks like double V, with motion serifs" -selector.w = "straightDoubleVMotionSerifed" -selector."w/sansSerif" = "straightDoubleVSerifless" -selector.wHookTop = "straightDoubleVMotionSerifed" - -[prime.w.variants.straight-double-v-serifed] -rank = 12 -description = "Straight `w` looks like double V, with serifs" -selector.w = "straightDoubleVSerifed" -selector."w/sansSerif" = "straightDoubleVSerifless" -selector.wHookTop = "straightDoubleVSerifed" - -[prime.w.variants.straight-asymmetric-serifless] -rank = 13 -description = "Straight `w` looks asymmetric, without serifs" -selector.w = "straightAsymmetricSerifless" -selector."w/sansSerif" = "straightAsymmetricSerifless" -selector.wHookTop = "straightAsymmetricSerifless" - -[prime.w.variants.straight-asymmetric-motion-serifed] -rank = 14 -description = "Straight `w` looks asymmetric, with motion serifs" -selector.w = "straightAsymmetricMotionSerifed" -selector."w/sansSerif" = "straightAsymmetricSerifless" -selector.wHookTop = "straightAsymmetricMotionSerifed" - -[prime.w.variants.straight-asymmetric-serifed] -rank = 15 -description = "Straight `w` looks asymmetric, with serifs" -selector.w = "straightAsymmetricSerifed" -selector."w/sansSerif" = "straightAsymmetricSerifless" -selector.wHookTop = "straightAsymmetricSerifed" - -[prime.w.variants.straight-vertical-sides-serifless] -rank = 16 -description = "Straight `w` with vertical sides, without serifs" -selector.w = "straightVerticalSidesSerifless" -selector."w/sansSerif" = "straightVerticalSidesSerifless" -selector.wHookTop = "straightVerticalSidesSerifless" - -[prime.w.variants.straight-vertical-sides-motion-serifed] -rank = 17 -description = "Straight `w` with vertical sides and motion serifs" -selector.w = "straightVerticalSidesMotionSerifed" -selector."w/sansSerif" = "straightVerticalSidesSerifless" -selector.wHookTop = "straightVerticalSidesMotionSerifed" - -[prime.w.variants.straight-vertical-sides-serifed] -rank = 18 -description = "Straight `w` with vertical sides and serifs" -selector.w = "straightVerticalSidesSerifed" -selector."w/sansSerif" = "straightVerticalSidesSerifless" -selector.wHookTop = "straightVerticalSidesSerifed" - -[prime.w.variants.cursive-serifless] -rank = 19 -description = "Cursive `w`, without serifs" -selector.w = "cursiveSerifless" -selector."w/sansSerif" = "cursiveSerifless" -selector.wHookTop = "cursiveSerifless" - -[prime.w.variants.cursive-serifed] -rank = 20 -description = "Cursive `w` with motion serifs" -selector.w = "cursiveSerifed" -selector."w/sansSerif" = "cursiveSerifless" -selector.wHookTop = "cursiveSerifed" +[prime.w.variants-buildup.stages.serifs.serifed] +rank = 3 +descriptionAffix = "serifs" +selectorAffix.w = "serifed" +selectorAffix."w/sansSerif" = "serifless" +selectorAffix.wHookTop = "serifed" @@ -4586,98 +4311,98 @@ next = "serifs" [prime.z.variants-buildup.stages.body.straight] rank = 1 -descriptionSuffix = "straight body shape" -selectorSuffix.z = "straight" -selectorSuffix."z/sansSerif" = "straight" -selectorSuffix."z/reduced" = "straight" -selectorSuffix.zDesc = "straight" -selectorSuffix."zDesc/reduced" = "straight" +descriptionAffix = "straight body shape" +selectorAffix.z = "straight" +selectorAffix."z/sansSerif" = "straight" +selectorAffix."z/reduced" = "straight" +selectorAffix.zDesc = "straight" +selectorAffix."zDesc/reduced" = "straight" [prime.z.variants-buildup.stages.body.curly] rank = 2 -descriptionSuffix = "curly body shape" -selectorSuffix.z = "curly" -selectorSuffix."z/sansSerif" = "curly" -selectorSuffix."z/reduced" = "curly" -selectorSuffix.zDesc = "curly" -selectorSuffix."zDesc/reduced" = "curly" +descriptionAffix = "curly body shape" +selectorAffix.z = "curly" +selectorAffix."z/sansSerif" = "curly" +selectorAffix."z/reduced" = "curly" +selectorAffix.zDesc = "curly" +selectorAffix."zDesc/reduced" = "curly" [prime.z.variants-buildup.stages.body.cursive] rank = 3 next = "overlay" -descriptionSuffix = "cursive body shape" -selectorSuffix.z = "cursive" -selectorSuffix."z/sansSerif" = "cursive" -selectorSuffix."z/reduced" = "cursive" -selectorSuffix.zDesc = "cursive" -selectorSuffix."zDesc/reduced" = "cursive" +descriptionAffix = "cursive body shape" +selectorAffix.z = "cursive" +selectorAffix."z/sansSerif" = "cursive" +selectorAffix."z/reduced" = "cursive" +selectorAffix.zDesc = "cursive" +selectorAffix."zDesc/reduced" = "cursive" [prime.z.variants-buildup.stages.serifs."*"] next = "overlay" [prime.z.variants-buildup.stages.serifs.serifless] rank = 1 -descriptionSuffix = "serifs" +descriptionAffix = "serifs" descriptionJoiner = "without" -selectorSuffix.z = "serifless" -selectorSuffix."z/sansSerif" = "serifless" -selectorSuffix."z/reduced" = "serifless" -selectorSuffix.zDesc = "serifless" -selectorSuffix."zDesc/reduced" = "serifless" +selectorAffix.z = "serifless" +selectorAffix."z/sansSerif" = "serifless" +selectorAffix."z/reduced" = "serifless" +selectorAffix.zDesc = "serifless" +selectorAffix."zDesc/reduced" = "serifless" [prime.z.variants-buildup.stages.serifs.serifed] rank = 2 -descriptionSuffix = "serifs" -selectorSuffix.z = "serifed" -selectorSuffix."z/sansSerif" = "serifless" -selectorSuffix."z/reduced" = "serifed" -selectorSuffix.zDesc = "topSerifed" -selectorSuffix."zDesc/reduced" = "topSerifed" +descriptionAffix = "serifs" +selectorAffix.z = "serifed" +selectorAffix."z/sansSerif" = "serifless" +selectorAffix."z/reduced" = "serifed" +selectorAffix.zDesc = "topSerifed" +selectorAffix."zDesc/reduced" = "topSerifed" [prime.z.variants-buildup.stages.serifs.bottom-serifed] rank = 3 -descriptionSuffix = "serifs at bottom" -selectorSuffix.z = "bottomSerifed" -selectorSuffix."z/sansSerif" = "serifless" -selectorSuffix."z/reduced" = "bottomSerifed" -selectorSuffix.zDesc = "serifless" -selectorSuffix."zDesc/reduced" = "serifless" +descriptionAffix = "serifs at bottom" +selectorAffix.z = "bottomSerifed" +selectorAffix."z/sansSerif" = "serifless" +selectorAffix."z/reduced" = "bottomSerifed" +selectorAffix.zDesc = "serifless" +selectorAffix."zDesc/reduced" = "serifless" [prime.z.variants-buildup.stages.serifs.top-serifed] rank = 4 -descriptionSuffix = "serifs at top" -selectorSuffix.z = "topSerifed" -selectorSuffix."z/sansSerif" = "serifless" -selectorSuffix."z/reduced" = "topSerifed" -selectorSuffix.zDesc = "topSerifed" -selectorSuffix."zDesc/reduced" = "topSerifed" +descriptionAffix = "serifs at top" +selectorAffix.z = "topSerifed" +selectorAffix."z/sansSerif" = "serifless" +selectorAffix."z/reduced" = "topSerifed" +selectorAffix.zDesc = "topSerifed" +selectorAffix."zDesc/reduced" = "topSerifed" [prime.z.variants-buildup.stages.overlay.no-overlay] rank = 1 -keySuffix = "" -selectorSuffix.z = "" -selectorSuffix."z/sansSerif" = "" -selectorSuffix."z/reduced" = "" -selectorSuffix.zDesc = "" -selectorSuffix."zDesc/reduced" = "" +keyAffix = "" +selectorAffix.z = "" +selectorAffix."z/sansSerif" = "" +selectorAffix."z/reduced" = "" +selectorAffix.zDesc = "" +selectorAffix."zDesc/reduced" = "" [prime.z.variants-buildup.stages.overlay.with-crossbar] rank = 2 -descriptionSuffix = "a diagonal crossbar" -selectorSuffix.z = "withCrossBar" -selectorSuffix."z/sansSerif" = "withCrossBar" -selectorSuffix."z/reduced" = "" -selectorSuffix.zDesc = "withCrossBar" -selectorSuffix."zDesc/reduced" = "" +descriptionAffix = "a diagonal crossbar" +selectorAffix.z = "withCrossBar" +selectorAffix."z/sansSerif" = "withCrossBar" +selectorAffix."z/reduced" = "" +selectorAffix.zDesc = "withCrossBar" +selectorAffix."zDesc/reduced" = "" [prime.z.variants-buildup.stages.overlay.with-horizontal-crossbar] rank = 3 -descriptionSuffix = "a horizontal crossbar" -selectorSuffix.z = "withHorizontalCrossBar" -selectorSuffix."z/sansSerif" = "withHorizontalCrossBar" -selectorSuffix."z/reduced" = "" -selectorSuffix.zDesc = "withHorizontalCrossBar" -selectorSuffix."zDesc/reduced" = "" +descriptionAffix = "a horizontal crossbar" +selectorAffix.z = "withHorizontalCrossBar" +selectorAffix."z/sansSerif" = "withHorizontalCrossBar" +selectorAffix."z/reduced" = "" +selectorAffix.zDesc = "withHorizontalCrossBar" +selectorAffix."zDesc/reduced" = "" @@ -5280,76 +5005,76 @@ next = "serifs" [prime.cyrl-capital-ka.variants-buildup.stages.body.straight] rank = 1 -descriptionSuffix = "straight shape" -selectorSuffix."cyrl/Ka" = "straight" -selectorSuffix."cyrl/KaDescender" = "straight" -selectorSuffix."cyrl/KaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/KaHook" = "symmetricConnectedKH" +descriptionAffix = "straight shape" +selectorAffix."cyrl/Ka" = "straight" +selectorAffix."cyrl/KaDescender" = "straight" +selectorAffix."cyrl/KaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/KaHook" = "symmetricConnectedKH" [prime.cyrl-capital-ka.variants-buildup.stages.body.curly] rank = 2 -descriptionSuffix = "curly shape" -selectorSuffix."cyrl/Ka" = "curly" -selectorSuffix."cyrl/KaDescender" = "curly" -selectorSuffix."cyrl/KaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/KaHook" = "symmetricConnectedKH" +descriptionAffix = "curly shape" +selectorAffix."cyrl/Ka" = "curly" +selectorAffix."cyrl/KaDescender" = "curly" +selectorAffix."cyrl/KaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/KaHook" = "symmetricConnectedKH" [prime.cyrl-capital-ka.variants-buildup.stages.body.symmetric-touching] rank = 3 -descriptionSuffix = "symmetric legs touching the vertical bar" -selectorSuffix."cyrl/Ka" = "symmetricTouching" -selectorSuffix."cyrl/KaDescender" = "symmetricTouching" -selectorSuffix."cyrl/KaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/KaHook" = "symmetricConnectedKH" +descriptionAffix = "symmetric legs touching the vertical bar" +selectorAffix."cyrl/Ka" = "symmetricTouching" +selectorAffix."cyrl/KaDescender" = "symmetricTouching" +selectorAffix."cyrl/KaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/KaHook" = "symmetricConnectedKH" [prime.cyrl-capital-ka.variants-buildup.stages.body.symmetric-connected] rank = 4 -descriptionSuffix = "symmetric legs connected to the vertical bar" -selectorSuffix."cyrl/Ka" = "symmetricConnected" -selectorSuffix."cyrl/KaDescender" = "symmetricConnected" -selectorSuffix."cyrl/KaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/KaHook" = "symmetricConnectedKH" +descriptionAffix = "symmetric legs connected to the vertical bar" +selectorAffix."cyrl/Ka" = "symmetricConnected" +selectorAffix."cyrl/KaDescender" = "symmetricConnected" +selectorAffix."cyrl/KaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/KaHook" = "symmetricConnectedKH" [prime.cyrl-capital-ka.variants-buildup.stages.serifs.serifless] rank = 1 -descriptionSuffix = "serifs" +descriptionAffix = "serifs" descriptionJoiner = "without" -selectorSuffix."cyrl/Ka" = "serifless" -selectorSuffix."cyrl/KaDescender" = "serifless" -selectorSuffix."cyrl/KaVBar" = "serifless" -selectorSuffix."cyrl/KaHook" = "serifless" +selectorAffix."cyrl/Ka" = "serifless" +selectorAffix."cyrl/KaDescender" = "serifless" +selectorAffix."cyrl/KaVBar" = "serifless" +selectorAffix."cyrl/KaHook" = "serifless" [prime.cyrl-capital-ka.variants-buildup.stages.serifs.top-left-serifed] rank = 2 -descriptionSuffix = "serifs at top left" -selectorSuffix."cyrl/Ka" = "topLeftSerifed" -selectorSuffix."cyrl/KaDescender" = "topLeftSerifed" -selectorSuffix."cyrl/KaVBar" = "topLeftSerifed" -selectorSuffix."cyrl/KaHook" = "topLeftSerifed" +descriptionAffix = "serifs at top left" +selectorAffix."cyrl/Ka" = "topLeftSerifed" +selectorAffix."cyrl/KaDescender" = "topLeftSerifed" +selectorAffix."cyrl/KaVBar" = "topLeftSerifed" +selectorAffix."cyrl/KaHook" = "topLeftSerifed" [prime.cyrl-capital-ka.variants-buildup.stages.serifs.bottom-right-serifed] rank = 3 -descriptionSuffix = "serifs at bottom right" -selectorSuffix."cyrl/Ka" = "bottomRightSerifed" -selectorSuffix."cyrl/KaDescender" = "bottomRightSerifed" -selectorSuffix."cyrl/KaVBar" = "bottomRightSerifed" -selectorSuffix."cyrl/KaHook" = "serifless" +descriptionAffix = "serifs at bottom right" +selectorAffix."cyrl/Ka" = "bottomRightSerifed" +selectorAffix."cyrl/KaDescender" = "bottomRightSerifed" +selectorAffix."cyrl/KaVBar" = "bottomRightSerifed" +selectorAffix."cyrl/KaHook" = "serifless" [prime.cyrl-capital-ka.variants-buildup.stages.serifs.top-left-and-bottom-right-serifed] rank = 4 -descriptionSuffix = "serifs at top left and bottom right" -selectorSuffix."cyrl/Ka" = "topLeftAndBottomRightSerifed" -selectorSuffix."cyrl/KaDescender" = "topLeftAndBottomRightSerifed" -selectorSuffix."cyrl/KaVBar" = "topLeftAndBottomRightSerifed" -selectorSuffix."cyrl/KaHook" = "topLeftSerifed" +descriptionAffix = "serifs at top left and bottom right" +selectorAffix."cyrl/Ka" = "topLeftAndBottomRightSerifed" +selectorAffix."cyrl/KaDescender" = "topLeftAndBottomRightSerifed" +selectorAffix."cyrl/KaVBar" = "topLeftAndBottomRightSerifed" +selectorAffix."cyrl/KaHook" = "topLeftSerifed" [prime.cyrl-capital-ka.variants-buildup.stages.serifs.serifed] rank = 5 -descriptionSuffix = "serifs" -selectorSuffix."cyrl/Ka" = "serifed" -selectorSuffix."cyrl/KaDescender" = "serifed" -selectorSuffix."cyrl/KaVBar" = "serifed" -selectorSuffix."cyrl/KaHook" = "serifedKH" +descriptionAffix = "serifs" +selectorAffix."cyrl/Ka" = "serifed" +selectorAffix."cyrl/KaDescender" = "serifed" +selectorAffix."cyrl/KaVBar" = "serifed" +selectorAffix."cyrl/KaHook" = "serifedKH" @@ -5367,76 +5092,76 @@ next = "serifs" [prime.cyrl-ka.variants-buildup.stages.body.straight] rank = 1 -descriptionSuffix = "straight shape" -selectorSuffix."cyrl/ka" = "straight" -selectorSuffix."cyrl/kaDescender" = "straight" -selectorSuffix."cyrl/kaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/kaHook" = "symmetricConnectedKH" +descriptionAffix = "straight shape" +selectorAffix."cyrl/ka" = "straight" +selectorAffix."cyrl/kaDescender" = "straight" +selectorAffix."cyrl/kaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/kaHook" = "symmetricConnectedKH" [prime.cyrl-ka.variants-buildup.stages.body.curly] rank = 2 -descriptionSuffix = "curly shape" -selectorSuffix."cyrl/ka" = "curly" -selectorSuffix."cyrl/kaDescender" = "curly" -selectorSuffix."cyrl/kaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/kaHook" = "symmetricConnectedKH" +descriptionAffix = "curly shape" +selectorAffix."cyrl/ka" = "curly" +selectorAffix."cyrl/kaDescender" = "curly" +selectorAffix."cyrl/kaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/kaHook" = "symmetricConnectedKH" [prime.cyrl-ka.variants-buildup.stages.body.symmetric-touching] rank = 3 -descriptionSuffix = "symmetric legs touching the vertical bar" -selectorSuffix."cyrl/ka" = "symmetricTouching" -selectorSuffix."cyrl/kaDescender" = "symmetricTouching" -selectorSuffix."cyrl/kaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/kaHook" = "symmetricConnectedKH" +descriptionAffix = "symmetric legs touching the vertical bar" +selectorAffix."cyrl/ka" = "symmetricTouching" +selectorAffix."cyrl/kaDescender" = "symmetricTouching" +selectorAffix."cyrl/kaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/kaHook" = "symmetricConnectedKH" [prime.cyrl-ka.variants-buildup.stages.body.symmetric-connected] rank = 4 -descriptionSuffix = "symmetric legs connected to the vertical bar" -selectorSuffix."cyrl/ka" = "symmetricConnected" -selectorSuffix."cyrl/kaDescender" = "symmetricConnected" -selectorSuffix."cyrl/kaVBar" = "symmetricConnectedVB" -selectorSuffix."cyrl/kaHook" = "symmetricConnectedKH" +descriptionAffix = "symmetric legs connected to the vertical bar" +selectorAffix."cyrl/ka" = "symmetricConnected" +selectorAffix."cyrl/kaDescender" = "symmetricConnected" +selectorAffix."cyrl/kaVBar" = "symmetricConnectedVB" +selectorAffix."cyrl/kaHook" = "symmetricConnectedKH" [prime.cyrl-ka.variants-buildup.stages.serifs.serifless] rank = 1 -descriptionSuffix = "serifs" +descriptionAffix = "serifs" descriptionJoiner = "without" -selectorSuffix."cyrl/ka" = "serifless" -selectorSuffix."cyrl/kaDescender" = "serifless" -selectorSuffix."cyrl/kaVBar" = "serifless" -selectorSuffix."cyrl/kaHook" = "serifless" +selectorAffix."cyrl/ka" = "serifless" +selectorAffix."cyrl/kaDescender" = "serifless" +selectorAffix."cyrl/kaVBar" = "serifless" +selectorAffix."cyrl/kaHook" = "serifless" [prime.cyrl-ka.variants-buildup.stages.serifs.top-left-serifed] rank = 2 -descriptionSuffix = "serifs at top left" -selectorSuffix."cyrl/ka" = "topLeftSerifed" -selectorSuffix."cyrl/kaDescender" = "topLeftSerifed" -selectorSuffix."cyrl/kaVBar" = "topLeftSerifed" -selectorSuffix."cyrl/kaHook" = "topLeftSerifed" +descriptionAffix = "serifs at top left" +selectorAffix."cyrl/ka" = "topLeftSerifed" +selectorAffix."cyrl/kaDescender" = "topLeftSerifed" +selectorAffix."cyrl/kaVBar" = "topLeftSerifed" +selectorAffix."cyrl/kaHook" = "topLeftSerifed" [prime.cyrl-ka.variants-buildup.stages.serifs.bottom-right-serifed] rank = 3 -descriptionSuffix = "serifs at bottom right" -selectorSuffix."cyrl/ka" = "bottomRightSerifed" -selectorSuffix."cyrl/kaDescender" = "bottomRightSerifed" -selectorSuffix."cyrl/kaVBar" = "bottomRightSerifed" -selectorSuffix."cyrl/kaHook" = "serifless" +descriptionAffix = "serifs at bottom right" +selectorAffix."cyrl/ka" = "bottomRightSerifed" +selectorAffix."cyrl/kaDescender" = "bottomRightSerifed" +selectorAffix."cyrl/kaVBar" = "bottomRightSerifed" +selectorAffix."cyrl/kaHook" = "serifless" [prime.cyrl-ka.variants-buildup.stages.serifs.top-left-and-bottom-right-serifed] rank = 4 -descriptionSuffix = "serifs at top left and bottom right" -selectorSuffix."cyrl/ka" = "topLeftAndBottomRightSerifed" -selectorSuffix."cyrl/kaDescender" = "topLeftAndBottomRightSerifed" -selectorSuffix."cyrl/kaVBar" = "topLeftAndBottomRightSerifed" -selectorSuffix."cyrl/kaHook" = "topLeftSerifed" +descriptionAffix = "serifs at top left and bottom right" +selectorAffix."cyrl/ka" = "topLeftAndBottomRightSerifed" +selectorAffix."cyrl/kaDescender" = "topLeftAndBottomRightSerifed" +selectorAffix."cyrl/kaVBar" = "topLeftAndBottomRightSerifed" +selectorAffix."cyrl/kaHook" = "topLeftSerifed" [prime.cyrl-ka.variants-buildup.stages.serifs.serifed] rank = 5 -descriptionSuffix = "serifs" -selectorSuffix."cyrl/ka" = "serifed" -selectorSuffix."cyrl/kaDescender" = "serifed" -selectorSuffix."cyrl/kaVBar" = "serifed" -selectorSuffix."cyrl/kaHook" = "serifedKH" +descriptionAffix = "serifs" +selectorAffix."cyrl/ka" = "serifed" +selectorAffix."cyrl/kaDescender" = "serifed" +selectorAffix."cyrl/kaVBar" = "serifed" +selectorAffix."cyrl/kaHook" = "serifedKH" @@ -5842,257 +5567,157 @@ selector."cyrl/yery" = "cursiveTailed" sampler = "0" tag = "cv76" -[prime.zero.variants.unslashed] +[prime.zero.variants-buildup] +entry = "body" +descriptionLeader = "Zero (`0`)" + +[prime.zero.variants-buildup.stages.body."*"] +next = "overlays" + +[prime.zero.variants-buildup.stages.body.standard] rank = 1 -description = "O-like Zero (`0`)" -selector.zero = "unslashed" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +keyAffix = "" +descriptionAffix = "standard shape" +selectorAffix.zero = "" +selectorAffix."zero/forceSlashed" = "" +selectorAffix."zero/forceUnslashed" = "" -[prime.zero.variants.slashed] +[prime.zero.variants-buildup.stages.body.oval] rank = 2 -description = "Slashed Zero (`0`)" -selector.zero = "slashed" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +keyAffix = "oval" +descriptionAffix = "standard shape" +selectorAffix.zero = "oval" +selectorAffix."zero/forceSlashed" = "oval" +selectorAffix."zero/forceUnslashed" = "oval" -[prime.zero.variants.reverse-slashed] +[prime.zero.variants-buildup.stages.overlays.unslashed] +rank = 1 +description = "slash" +descriptionJoiner = "without" +selectorAffix.zero = "unslashed" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" + +[prime.zero.variants-buildup.stages.overlays.slashed] +rank = 2 +description = "slash" +selectorAffix.zero = "slashed" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" + +[prime.zero.variants-buildup.stages.overlays.reverse-slashed] rank = 3 -description = "Reverse-slashed Zero (`0`)" -selector.zero = "reverseSlashed" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "revese slash" +selectorAffix.zero = "reverseSlashed" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.tall-slashed] +[prime.zero.variants-buildup.stages.overlays.tall-slashed] rank = 4 -description = "Slashed Zero (`0`) with a taller slash" -selector.zero = "tallSlashed" -selector."zero/forceSlashed" = "tallSlashed" -selector."zero/forceUnslashed" = "unslashed" +description = "tall slash" +selectorAffix.zero = "tallSlashed" +selectorAffix."zero/forceSlashed" = "tallSlashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.tall-reverse-slashed] +[prime.zero.variants-buildup.stages.overlays.tall-reverse-slashed] rank = 5 -description = "Reverse-slashed Zero (`0`) with a taller slash" -selector.zero = "tallReverseSlashed" -selector."zero/forceSlashed" = "tallSlashed" -selector."zero/forceUnslashed" = "unslashed" +description = "tall reverse slash" +selectorAffix.zero = "tallReverseSlashed" +selectorAffix."zero/forceSlashed" = "tallSlashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.dotted] +[prime.zero.variants-buildup.stages.overlays.dotted] rank = 6 -description = "Dotted Zero (`0`)" -selector.zero = "dotted" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "center dot" +selectorAffix.zero = "dotted" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.long-dotted] +[prime.zero.variants-buildup.stages.overlays.long-dotted] rank = 7 -description = "Long-dotted Zero (`0`) like Hack" -selector.zero = "longDotted" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "long center dot" +selectorAffix.zero = "longDotted" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.slashed-split] +[prime.zero.variants-buildup.stages.overlays.slashed-split] rank = 8 -description = "Slashed Zero (`0`) with slash separated from the outline" -selector.zero = "slashedSplit" -selector."zero/forceSlashed" = "slashedSplit" -selector."zero/forceUnslashed" = "unslashed" +description = "slash separated from the outline" +selectorAffix.zero = "slashedSplit" +selectorAffix."zero/forceSlashed" = "slashedSplit" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.reverse-slashed-split] +[prime.zero.variants-buildup.stages.overlays.reverse-slashed-split] rank = 9 -description = "Reverse-slashed Zero (`0`) with slash separated from the outline" -selector.zero = "reverseSlashedSplit" -selector."zero/forceSlashed" = "slashedSplit" -selector."zero/forceUnslashed" = "unslashed" +description = "reverse slash separated from the outline" +selectorAffix.zero = "reverseSlashedSplit" +selectorAffix."zero/forceSlashed" = "slashedSplit" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.broken-slash] +[prime.zero.variants-buildup.stages.overlays.broken-slash] rank = 10 -description = "Slashed Zero (`0`) with slash broken in the middle like Fixedsys" -selector.zero = "brokenSlash" -selector."zero/forceSlashed" = "brokenSlash" -selector."zero/forceUnslashed" = "unslashed" +description = "slash broken in the middle (like in Fixedsys)" +selectorAffix.zero = "brokenSlash" +selectorAffix."zero/forceSlashed" = "brokenSlash" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.broken-reverse-slash] +[prime.zero.variants-buildup.stages.overlays.broken-reverse-slash] rank = 11 -description = "Reverse-slashed Zero (`0`) with slash broken in the middle" -selector.zero = "brokenReverseSlash" -selector."zero/forceSlashed" = "brokenSlash" -selector."zero/forceUnslashed" = "unslashed" +description = "reverse slash broken in the middle" +selectorAffix.zero = "brokenReverseSlash" +selectorAffix."zero/forceSlashed" = "brokenSlash" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.broken-vertical-bar] +[prime.zero.variants-buildup.stages.overlays.broken-vertical-bar] rank = 12 -description = "Zero (`0`) with vertical bar broken in the middle" -selector.zero = "brokenVerticalBar" -selector."zero/forceSlashed" = "brokenSlash" -selector."zero/forceUnslashed" = "unslashed" +description = "vertical bar broken in the middle" +selectorAffix.zero = "brokenVerticalBar" +selectorAffix."zero/forceSlashed" = "brokenSlash" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.slashed-cutout] +[prime.zero.variants-buildup.stages.overlays.slashed-cutout] rank = 13 -description = "O-like Zero (`0`) with a slash cutout" -selector.zero = "slashedCutout" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "a slash cutout" +selectorAffix.zero = "slashedCutout" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.reverse-slashed-cutout] +[prime.zero.variants-buildup.stages.overlays.reverse-slashed-cutout] rank = 14 -description = "O-like Zero (`0`) with a reverse-slash cutout" -selector.zero = "reverseSlashedCutout" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "a reverse-slash cutout" +selectorAffix.zero = "reverseSlashedCutout" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.tall-slashed-cutout] +[prime.zero.variants-buildup.stages.overlays.tall-slashed-cutout] rank = 15 -description = "O-like Zero (`0`) with a taller slash cutout" -selector.zero = "tallSlashedCutout" -selector."zero/forceSlashed" = "tallSlashed" -selector."zero/forceUnslashed" = "unslashed" +description = "a taller slash cutout" +selectorAffix.zero = "tallSlashedCutout" +selectorAffix."zero/forceSlashed" = "tallSlashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.tall-reverse-slashed-cutout] +[prime.zero.variants-buildup.stages.overlays.tall-reverse-slashed-cutout] rank = 16 -description = "O-like Zero (`0`) with a taller reverse-slash cutout" -selector.zero = "tallReverseSlashedCutout" -selector."zero/forceSlashed" = "tallSlashed" -selector."zero/forceUnslashed" = "unslashed" +description = "a taller reverse-slash cutout" +selectorAffix.zero = "tallReverseSlashedCutout" +selectorAffix."zero/forceSlashed" = "tallSlashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.vertical-bar-cutout] +[prime.zero.variants-buildup.stages.overlays.vertical-bar-cutout] rank = 17 -description = "O-like Zero (`0`) with a vertical bar cutout" -selector.zero = "verticalBarCutout" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "a vertical bar cutout" +selectorAffix.zero = "verticalBarCutout" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.top-right-cutout] +[prime.zero.variants-buildup.stages.overlays.top-right-cutout] rank = 18 -description = "O-like Zero (`0`) with the top-right bit cutout" -selector.zero = "topRightCutout" -selector."zero/forceSlashed" = "slashed" -selector."zero/forceUnslashed" = "unslashed" +description = "the top-right bit cutout" +selectorAffix.zero = "topRightCutout" +selectorAffix."zero/forceSlashed" = "slashed" +selectorAffix."zero/forceUnslashed" = "unslashed" -[prime.zero.variants.unslashed-oval] -rank = 19 -description = "O-like Zero (`0`) but more round" -selector.zero = "unslashedOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" -[prime.zero.variants.slashed-oval] -rank = 20 -description = "Slashed Zero (`0`) but more round" -selector.zero = "slashedOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.reverse-slashed-oval] -rank = 21 -description = "Reverse-slashed Zero (`0`) but more round" -selector.zero = "reverseSlashedOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.tall-slashed-oval] -rank = 22 -description = "Slashed Zero (`0`) with a taller slash and more round" -selector.zero = "tallSlashedOval" -selector."zero/forceSlashed" = "tallSlashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.tall-reverse-slashed-oval] -rank = 23 -description = "Reverse-slashed Zero (`0`) with a taller slash and more round" -selector.zero = "tallReverseSlashedOval" -selector."zero/forceSlashed" = "tallSlashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.dotted-oval] -rank = 24 -description = "Dotted Zero (`0`) but more round" -selector.zero = "dottedOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.long-dotted-oval] -rank = 25 -description = "Long-dotted Zero (`0`) like Hack but more round" -selector.zero = "longDottedOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.slashed-split-oval] -rank = 26 -description = "Slashed Zero (`0`) with slash separated from the outline and more round" -selector.zero = "slashedSplitOval" -selector."zero/forceSlashed" = "slashedSplitOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.reverse-slashed-split-oval] -rank = 27 -description = "Reverse-slashed Zero (`0`) with slash separated from the outline and more round" -selector.zero = "reverseSlashedSplitOval" -selector."zero/forceSlashed" = "slashedSplitOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.broken-slash-oval] -rank = 28 -description = "Slashed Zero (`0`) with slash broken in the middle like Fixedsys and more round" -selector.zero = "brokenSlashOval" -selector."zero/forceSlashed" = "brokenSlashOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.broken-reverse-slash-oval] -rank = 29 -description = "Reverse-slashed Zero (`0`) with slash broken in the middle and more round" -selector.zero = "brokenReverseSlashOval" -selector."zero/forceSlashed" = "brokenSlashOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.broken-vertical-bar-oval] -rank = 30 -description = "Zero (`0`) with vertical bar broken in the middle and more round" -selector.zero = "brokenVerticalBarOval" -selector."zero/forceSlashed" = "brokenSlashOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.slashed-cutout-oval] -rank = 31 -description = "O-like Zero (`0`) with a slash cutout and more round" -selector.zero = "slashedCutoutOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.reverse-slashed-cutout-oval] -rank = 32 -description = "O-like Zero (`0`) with a reverse-slash cutout and more round" -selector.zero = "reverseSlashedCutoutOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.tall-slashed-cutout-oval] -rank = 33 -description = "O-like Zero (`0`) with a taller slash cutout and more round" -selector.zero = "tallSlashedCutoutOval" -selector."zero/forceSlashed" = "tallSlashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.tall-reverse-slashed-cutout-oval] -rank = 34 -description = "O-like Zero (`0`) with a taller reverse-slash cutout and more round" -selector.zero = "tallReverseSlashedCutoutOval" -selector."zero/forceSlashed" = "tallSlashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.vertical-bar-cutout-oval] -rank = 35 -description = "O-like Zero (`0`) with a vertical bar cutout and more round" -selector.zero = "verticalBarCutoutOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" - -[prime.zero.variants.top-right-cutout-oval] -rank = 36 -description = "O-like Zero (`0`) with the top-right bit cutout and more round" -selector.zero = "topRightCutoutOval" -selector."zero/forceSlashed" = "slashedOval" -selector."zero/forceUnslashed" = "unslashedOval" [prime.one] sampler = "1" @@ -7650,7 +7275,7 @@ lower-mu = "tailless" cyrl-capital-ka = "symmetric-connected-serifless" cyrl-ka = "symmetric-connected-serifless" cyrl-capital-u = "straight-turn" -zero = "dotted-oval" +zero = "oval-dotted" one = "base" two = "straight-neck" six = "closed-contour" @@ -7696,7 +7321,7 @@ i = "serifed" j = "serifed" k = "straight-serifless" l = "serifed-flat-tailed" -r = "hookless" +r = "hookless-serifless" y = "straight-turn-serifless" long-s = "flat-hook-serifless" eszet = "longs-s-lig" @@ -7748,7 +7373,7 @@ j = "serifed" k = "symmetric-touching-serifless" l = "serifed-flat-tailed" q = "earless-corner-serifless" -r = "corner-hooked" +r = "corner-hooked-serifless" y = "straight-turn-serifless" long-s = "flat-hook-serifless" eszet = "longs-s-lig" @@ -7820,7 +7445,7 @@ cyrl-capital-ka = "curly-serifless" cyrl-ka = "curly-serifless" cyrl-capital-ya = "curly" cyrl-ya = "curly" -zero = "reverse-slashed-split-oval" +zero = "oval-reverse-slashed-split" four = "closed" six = "closed-contour" seven = "curly-serifless" @@ -7889,7 +7514,7 @@ i = "hooky" j = "serifed" k = "straight-serifless" l = "tailed-serifed" -r = "hookless" +r = "hookless-serifless" w = "straight-flat-top-serifless" y = "straight-turn-serifless" eszet = "longs-s-lig" @@ -7897,7 +7522,7 @@ long-s = "flat-hook-serifless" lower-alpha = "tailed-barred" lower-lambda = "straight-turn" cyrl-capital-u = "straight-turn" -zero = "dotted-oval" +zero = "oval-dotted" one = "base-flat-top-serif" two = "straight-neck" four = "closed" @@ -8021,7 +7646,7 @@ m = "earless-corner-double-arch-short-leg-serifless" n = "earless-corner-straight-serifless" p = "earless-corner-serifless" q = "earless-corner-serifless" -r = "earless-corner" +r = "earless-corner-serifless" u = "toothless-corner-serifless" y = "straight-turn-serifless" eszet = "longs-s-lig" @@ -8033,7 +7658,7 @@ micro-sign = "toothless-corner" cyrl-capital-ka = "symmetric-touching-serifless" cyrl-ka = "symmetric-touching-serifless" cyrl-capital-u = "straight-turn" -zero = "dotted-oval" +zero = "oval-dotted" one = "base" four = "closed" five = "oblique-upper-left-bar" @@ -8102,7 +7727,7 @@ long-s = "flat-hook-serifless" eszet = "longs-s-lig" lower-iota = "tailed" cyrl-capital-u = "straight-turn" -zero = "slashed-oval" +zero = "oval-slashed" one = "base" four = "closed" six = "closed-contour" @@ -8398,7 +8023,7 @@ i = "serifed-flat-tailed" l = "serifed-flat-tailed" m = "tailed-serifless" n = "tailed-serifless" -r = "corner-hooked-serifed" +r = "corner-hooked-top-serifed" s = "unilateral-inward-serifed" v = "cursive-serifed" w = "cursive-serifless"