Start to make a buildup-based variant system
This commit is contained in:
parent
cfac045755
commit
618ef2702d
4 changed files with 362 additions and 367 deletions
|
@ -1,6 +1,6 @@
|
|||
$$include '../../../meta/macros.ptl'
|
||||
|
||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||
import [mix fallback weaveSuffix] from"../../../support/utils.mjs"
|
||||
import [Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs"
|
||||
|
||||
glyph-module
|
||||
|
@ -168,44 +168,25 @@ glyph-block Letter-Latin-Lower-M : begin
|
|||
flat df.rightSB [Math.max (top - [SmallMSmooth df]) (rbot + 0.1)]
|
||||
curl df.rightSB rbot [heading Downward]
|
||||
|
||||
define BodyConfig : object
|
||||
"" { SmallMArches 0 }
|
||||
"earlessCornerDoubleArch" { EarlessCornerDoubleArchSmallMShape 1 }
|
||||
"earlessRoundedDoubleArch" { EarlessRoundedDoubleArchSmallMShape 1 }
|
||||
"earlessSingleArch" { EarlessSingleArchSmallMShape 1 }
|
||||
define SmallMConfig : weaveSuffix
|
||||
object
|
||||
"" { SmallMArches 0 }
|
||||
"earlessCornerDoubleArch" { EarlessCornerDoubleArchSmallMShape 1 }
|
||||
"earlessRoundedDoubleArch" { EarlessRoundedDoubleArchSmallMShape 1 }
|
||||
"earlessSingleArch" { EarlessSingleArchSmallMShape 1 }
|
||||
object
|
||||
"" { 0 }
|
||||
"shortLeg" { 1 }
|
||||
object
|
||||
"" { 0 }
|
||||
"tailed" { 1 }
|
||||
object
|
||||
"serifless" { no-shape }
|
||||
"serifed" { FullSerifs }
|
||||
"topLeftSerifed" { LtSerifs }
|
||||
"topLeftAndBottomRightSerifed" { LtRbSerifs }
|
||||
|
||||
define TailConfig : object
|
||||
"" { 0 }
|
||||
"tailed" { 1 }
|
||||
|
||||
define LegConfig : object
|
||||
"" { 0 }
|
||||
"shortLeg" { 1 }
|
||||
|
||||
define SerifConfig : object
|
||||
"" { AutoSerifs }
|
||||
"serifless" { no-shape }
|
||||
"serifed" { FullSerifs }
|
||||
"topLeftSerifed" { LtSerifs }
|
||||
"topLeftAndBottomRightSerifed" { LtRbSerifs }
|
||||
|
||||
define [join-suffix parts] : begin
|
||||
local suffix ""
|
||||
foreach part [items-of parts] : do
|
||||
if part : begin
|
||||
local toAppend : if suffix ([part.charAt 0 :.toUpperCase] + [part.slice 1]) part
|
||||
set suffix : suffix + toAppend
|
||||
return suffix
|
||||
|
||||
define SmallMConfig {.}
|
||||
foreach { suffixBody { Body earless } } [Object.entries BodyConfig]
|
||||
foreach { suffixLeg { shortLeg } } [Object.entries LegConfig]
|
||||
foreach { suffixTail { tailed } } [Object.entries TailConfig]
|
||||
foreach { suffixSerifs { Serifs } } [Object.entries SerifConfig] : begin
|
||||
local suffix : join-suffix { suffixBody suffixLeg suffixTail suffixSerifs }
|
||||
set SmallMConfig.(suffix) { Body Serifs tailed shortLeg earless }
|
||||
|
||||
foreach { suffix { Body Serifs tailed shortLeg earless } } [Object.entries SmallMConfig] : do
|
||||
foreach { suffix { {Body earless} {tailed} {shortLeg} {Serifs} } } [pairs-of SmallMConfig] : do
|
||||
define [mShapeBody df height] : glyph-proc
|
||||
include : Body height 0 [if shortLeg [SmallMShortLegHeight height df] 0] [if tailed ([SmallMSmoothHeight height df] + O) 0] df
|
||||
if tailed : include : RightwardTailedBar df.rightSB 0 [SmallMSmoothHeight height df] (sw -- df.mvs)
|
||||
|
|
|
@ -25,3 +25,30 @@ export function bez3(a, b, c, d, t) {
|
|||
t * t * t * d
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export function joinCamel(a, b) {
|
||||
if (!a) return b;
|
||||
if (!b) return a;
|
||||
return a + b[0].toUpperCase() + b.slice(1);
|
||||
}
|
||||
|
||||
export function weaveSuffix(...configs) {
|
||||
let ans = {};
|
||||
joinSuffixListImpl(ans, "", [], configs);
|
||||
return ans;
|
||||
}
|
||||
|
||||
function joinSuffixListImpl(sink, k, v, configs) {
|
||||
if (!configs.length) {
|
||||
sink[k] = v;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const [keySuffix, valueSuffix] of Object.entries(configs[0])) {
|
||||
const k1 = joinCamel(k, keySuffix);
|
||||
const v1 = [...v, valueSuffix];
|
||||
joinSuffixListImpl(sink, k1, v1, configs.slice(1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { joinCamel } from "./utils.mjs";
|
||||
|
||||
export function apply(data, para, argv) {
|
||||
const parsed = parse(data, argv);
|
||||
let tagSet = new Set();
|
||||
|
@ -67,7 +69,6 @@ class SelectorTree {
|
|||
|
||||
class Prime {
|
||||
constructor(key, cfg) {
|
||||
if (!cfg.variants) throw new Error(`Missing variants in ${key}`);
|
||||
this.key = key;
|
||||
this.sampler = cfg.sampler;
|
||||
this.samplerExplain = cfg.samplerExplain;
|
||||
|
@ -79,10 +80,18 @@ class Prime {
|
|||
: [...(cfg.sampler || "")];
|
||||
this.tag = cfg.tag;
|
||||
this.slopeDependent = !!cfg.slopeDependent;
|
||||
this.variants = new Map();
|
||||
this.hotChars = cfg.hotChars ? [...cfg.hotChars] : this.descSampleText;
|
||||
for (const varKey in cfg.variants) {
|
||||
const variant = cfg.variants[varKey];
|
||||
|
||||
this.variants = new Map();
|
||||
|
||||
let variantConfig = cfg.variants;
|
||||
if (!variantConfig && cfg["variants-buildup"]) {
|
||||
const vb = new VariantBuilder(cfg["variants-buildup"]);
|
||||
variantConfig = vb.process();
|
||||
}
|
||||
if (!variantConfig) throw new Error(`Missing variants in ${key}`);
|
||||
for (const varKey in variantConfig) {
|
||||
const variant = variantConfig[varKey];
|
||||
this.variants.set(varKey, new PrimeVariant(varKey, cfg.tag, variant));
|
||||
}
|
||||
}
|
||||
|
@ -190,3 +199,191 @@ class Composite {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Systematic Variant Building
|
||||
///
|
||||
|
||||
class VariantBuilder {
|
||||
constructor(cfg) {
|
||||
this.entry = cfg.entry;
|
||||
this.descriptionLeader = cfg.descriptionLeader;
|
||||
this.stages = new Map();
|
||||
for (const [key, stage] of Object.entries(cfg.stages)) {
|
||||
this.stages.set(key, new VbStage(key, stage));
|
||||
}
|
||||
}
|
||||
process() {
|
||||
const globalState = new VbGlobalState(this.stages);
|
||||
const localState = new VbLocalState();
|
||||
localState.descriptionLeader = this.descriptionLeader;
|
||||
globalState.stages.get(this.entry).accept(globalState, localState);
|
||||
let ans = {};
|
||||
for (const item of globalState.sink) {
|
||||
let cfg = item.createPrimeVariant();
|
||||
ans[cfg.key] = cfg;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
class VbStage {
|
||||
constructor(stage, raw) {
|
||||
this.stage = stage;
|
||||
this.defaultAlternative = new VbStageAlternative(this.stage, "*", {});
|
||||
this.alternatives = new Map();
|
||||
for (const k in raw) {
|
||||
if (k === "*") {
|
||||
this.defaultAlternative = new VbStageAlternative(this.stage, "*", raw[k]);
|
||||
} else {
|
||||
this.alternatives.set(k, new VbStageAlternative(this.stage, k, raw[k]));
|
||||
}
|
||||
}
|
||||
|
||||
for (const v of this.alternatives.values()) v.fallback(this.defaultAlternative);
|
||||
}
|
||||
accept(globalState, localState) {
|
||||
let variantList = Array.from(this.alternatives.values());
|
||||
variantList.sort((a, b) => (a.rank || 0) - (b.rank || 0));
|
||||
for (const v of variantList) {
|
||||
const ans = v.tryAccept(globalState, localState);
|
||||
if (ans) globalState.stages.get(ans.stage).accept(globalState, ans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VbStageAlternative {
|
||||
constructor(stage, key, raw) {
|
||||
this.stage = stage;
|
||||
this.key = key;
|
||||
this.rank = raw.rank;
|
||||
this.next = raw.next;
|
||||
this.keySuffix = raw.keySuffix;
|
||||
this.descriptionSuffix = raw.descriptionSuffix;
|
||||
this.descriptionJoiner = raw.descriptionJoiner || "with";
|
||||
this.disableIf = raw.disableIf;
|
||||
this.selectorSuffix = raw.selectorSuffix;
|
||||
}
|
||||
fallback(defaultAlternative) {
|
||||
this.next = this.next || defaultAlternative.next;
|
||||
this.keySuffix = this.keySuffix || defaultAlternative.keySuffix;
|
||||
this.descriptionSuffix = this.descriptionSuffix || defaultAlternative.descriptionSuffix;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.next) {
|
||||
ans.rank = ++globalState.rank;
|
||||
globalState.sink.push(ans);
|
||||
return null;
|
||||
} else {
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VbGlobalState {
|
||||
constructor(stages) {
|
||||
this.stages = stages;
|
||||
this.rank = 0;
|
||||
this.sink = [];
|
||||
}
|
||||
}
|
||||
|
||||
class VbLocalState {
|
||||
constructor() {
|
||||
this.stage = ".start";
|
||||
this.rank = 0;
|
||||
this.descriptionLeader = "";
|
||||
|
||||
this.assignments = new Map();
|
||||
this.key = [];
|
||||
this.descriptions = new Map();
|
||||
this.selector = new Map();
|
||||
}
|
||||
|
||||
clone() {
|
||||
const ans = new VbLocalState();
|
||||
ans.stage = this.stage;
|
||||
ans.rank = this.rank;
|
||||
ans.descriptionLeader = this.descriptionLeader;
|
||||
ans.assignments = new Map(this.assignments);
|
||||
ans.key = [...this.key];
|
||||
ans.selector = new Map(this.selector);
|
||||
ans.descriptions = new Map();
|
||||
for (const [k, v] of this.descriptions) ans.descriptions.set(k, [...v]);
|
||||
return ans;
|
||||
}
|
||||
|
||||
addDescription(joiner, segment) {
|
||||
if (!this.descriptions.has(joiner)) this.descriptions.set(joiner, []);
|
||||
this.descriptions.get(joiner).push(segment);
|
||||
}
|
||||
addSelector(selector, value) {
|
||||
this.selector.set(selector, joinCamel(this.selector.get(selector), value));
|
||||
}
|
||||
|
||||
produceKey() {
|
||||
return this.key.join("-");
|
||||
}
|
||||
produceDescription() {
|
||||
let desc = [];
|
||||
for (const [joiner, segments] of this.descriptions) {
|
||||
if (!segments.length) continue;
|
||||
desc.push(`${joiner} ${arrayToSentence(segments)}`);
|
||||
}
|
||||
return this.descriptionLeader + " " + desc.join("; ");
|
||||
}
|
||||
|
||||
createPrimeVariant() {
|
||||
return {
|
||||
key: this.produceKey(),
|
||||
rank: this.rank,
|
||||
description: this.produceDescription(),
|
||||
selector: Object.fromEntries(this.selector)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function arrayToSentence(arr) {
|
||||
if (arr.length == 1) return arr[0];
|
||||
let last = arr.pop();
|
||||
return arr.join(", ") + " and " + last;
|
||||
}
|
||||
|
|
|
@ -3400,347 +3400,137 @@ selector.lyogh = "hooky"
|
|||
sampler = "m"
|
||||
tag = "cv38"
|
||||
|
||||
[prime.m.variants.serifless]
|
||||
[prime.m.variants-buildup]
|
||||
entry = "body"
|
||||
descriptionLeader = "`m`"
|
||||
|
||||
[prime.m.variants-buildup.stages.body."*"]
|
||||
next = "leg"
|
||||
|
||||
[prime.m.variants-buildup.stages.body.normal]
|
||||
rank = 1
|
||||
description = "`m` with normal middle leg, touching the baseline"
|
||||
selector.m = "serifless"
|
||||
selector."m/tailless" = "serifless"
|
||||
selector."m/sansSerif" = "serifless"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "serifless"
|
||||
descriptionSuffix = "eared body shape"
|
||||
selectorSuffix.m = ""
|
||||
selectorSuffix."m/tailless" = ""
|
||||
selectorSuffix."m/sansSerif" = ""
|
||||
selectorSuffix."cyrl/te.italic" = ""
|
||||
selectorSuffix.mLTail = ""
|
||||
|
||||
[prime.m.variants.top-left-serifed]
|
||||
[prime.m.variants-buildup.stages.body.earless-corner-double-arch]
|
||||
rank = 2
|
||||
description = "`m` with serif at top left, normal middle leg touching baseline"
|
||||
selector.m = "topLeftSerifed"
|
||||
selector."m/tailless" = "topLeftSerifed"
|
||||
selector."m/sansSerif" = "serifless"
|
||||
selector."cyrl/te.italic" = "topLeftSerifed"
|
||||
selector.mLTail = "topLeftSerifed"
|
||||
keySuffix = "earless-corner-double-arch"
|
||||
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"
|
||||
|
||||
[prime.m.variants.top-left-and-bottom-right-serifed]
|
||||
[prime.m.variants-buildup.stages.body.earless-rounded-double-arch]
|
||||
rank = 3
|
||||
description = "`m` with serifs at top left and bottom right, normal middle leg touching baseline"
|
||||
selector.m = "topLeftAndBottomRightSerifed"
|
||||
selector."m/tailless" = "topLeftAndBottomRightSerifed"
|
||||
selector."m/sansSerif" = "serifless"
|
||||
selector."cyrl/te.italic" = "topLeftAndBottomRightSerifed"
|
||||
selector.mLTail = "topLeftSerifed"
|
||||
keySuffix = "earless-rounded-double-arch"
|
||||
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"
|
||||
|
||||
[prime.m.variants.serifed]
|
||||
[prime.m.variants-buildup.stages.body.earless-single-arch]
|
||||
rank = 4
|
||||
description = "`m` with serifs, normal middle leg touching baseline"
|
||||
selector.m = "serifed"
|
||||
selector."m/tailless" = "serifed"
|
||||
selector."m/sansSerif" = "serifless"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "topLeftSerifed"
|
||||
keySuffix = "earless-single-arch"
|
||||
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"
|
||||
|
||||
[prime.m.variants.tailed-serifless]
|
||||
rank = 5
|
||||
description = "`m` with normal middle leg, touching the baseline, and a curly tail"
|
||||
selector.m = "tailed"
|
||||
selector."m/tailless" = "serifless"
|
||||
selector."m/sansSerif" = "tailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "serifless"
|
||||
[prime.m.variants-buildup.stages.leg."*"]
|
||||
next = "tail"
|
||||
|
||||
[prime.m.variants.tailed-top-left-serifed]
|
||||
rank = 6
|
||||
description = "`m` with serif at top left, normal middle leg touching baseline, and a curly tail"
|
||||
selector.m = "tailedTopLeftSerifed"
|
||||
selector."m/tailless" = "topLeftSerifed"
|
||||
selector."m/sansSerif" = "tailed"
|
||||
selector."cyrl/te.italic" = "tailedTopLeftSerifed"
|
||||
selector.mLTail = "topLeftSerifed"
|
||||
[prime.m.variants-buildup.stages.leg.normal]
|
||||
rank = 1
|
||||
descriptionSuffix = "normal middle leg"
|
||||
selectorSuffix.m = ""
|
||||
selectorSuffix."m/tailless" = ""
|
||||
selectorSuffix."m/sansSerif" = ""
|
||||
selectorSuffix."cyrl/te.italic" = ""
|
||||
selectorSuffix.mLTail = ""
|
||||
|
||||
[prime.m.variants.tailed-serifed]
|
||||
rank = 7
|
||||
description = "`m` with serifs, normal middle leg touching baseline, and a curly tail"
|
||||
selector.m = "tailedSerifed"
|
||||
selector."m/tailless" = "topLeftSerifed"
|
||||
selector."m/sansSerif" = "tailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "topLeftSerifed"
|
||||
[prime.m.variants-buildup.stages.leg.short-leg]
|
||||
rank = 2
|
||||
keySuffix = "short-leg"
|
||||
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"
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch]
|
||||
rank = 8
|
||||
description = "Earless (corner top-left) `m` with normal middle leg touching baseline"
|
||||
selector.m = "earlessCornerDoubleArch"
|
||||
selector."m/tailless" = "earlessCornerDoubleArch"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArch"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "earlessCornerDoubleArch"
|
||||
[prime.m.variants-buildup.stages.tail."*"]
|
||||
next = "serifs"
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-serifed]
|
||||
rank = 9
|
||||
description = "Earless (corner top-left) `m` with normal middle leg touching baseline, and serifs"
|
||||
selector.m = "earlessCornerDoubleArchSerifed"
|
||||
selector."m/tailless" = "earlessCornerDoubleArchSerifed"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArch"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "earlessCornerDoubleArchSerifed"
|
||||
[prime.m.variants-buildup.stages.tail.normal]
|
||||
rank = 1
|
||||
selectorSuffix.m = ""
|
||||
selectorSuffix."m/tailless" = ""
|
||||
selectorSuffix."m/sansSerif" = ""
|
||||
selectorSuffix."cyrl/te.italic" = ""
|
||||
selectorSuffix.mLTail = ""
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-tailed]
|
||||
rank = 10
|
||||
description = "Earless (corner top-left) `m` with normal middle leg touching baseline, and a curly tail"
|
||||
selector.m = "earlessCornerDoubleArchTailed"
|
||||
selector."m/tailless" = "earlessCornerDoubleArch"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArchTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "earlessCornerDoubleArch"
|
||||
[prime.m.variants-buildup.stages.tail.tailed]
|
||||
rank = 2
|
||||
keySuffix = "tailed"
|
||||
descriptionSuffix = "tail"
|
||||
selectorSuffix.m = "tailed"
|
||||
selectorSuffix."m/tailless" = ""
|
||||
selectorSuffix."m/sansSerif" = "tailed"
|
||||
selectorSuffix."cyrl/te.italic" = "tailed"
|
||||
selectorSuffix.mLTail = ""
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-tailed-serifed]
|
||||
rank = 11
|
||||
description = "Earless (corner top-left) `m` with normal middle leg touching baseline, a curly tail, and serifs"
|
||||
selector.m = "earlessCornerDoubleArchTailedSerifed"
|
||||
selector."m/tailless" = "earlessCornerDoubleArchSerifed"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArchTailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "earlessCornerDoubleArchSerifed"
|
||||
[prime.m.variants-buildup.stages.serifs.serifless]
|
||||
rank = 1
|
||||
keySuffix = "serifless"
|
||||
descriptionJoiner = "without"
|
||||
descriptionSuffix = "serifs"
|
||||
selectorSuffix.m = "serifless"
|
||||
selectorSuffix."m/tailless" = "serifless"
|
||||
selectorSuffix."m/sansSerif" = "serifless"
|
||||
selectorSuffix."cyrl/te.italic" = "serifless"
|
||||
selectorSuffix.mLTail = "serifless"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch]
|
||||
rank = 12
|
||||
description = "Earless (rounded top-left) `m` with normal middle leg touching baseline"
|
||||
selector.m = "earlessRoundedDoubleArch"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArch"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArch"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "earlessRoundedDoubleArch"
|
||||
[prime.m.variants-buildup.stages.serifs.top-left-serifed]
|
||||
rank = 2
|
||||
keySuffix = "top-left-serifed"
|
||||
descriptionSuffix = "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"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-serifed]
|
||||
rank = 13
|
||||
description = "Earless (rounded top-left) `m` with normal middle leg touching baseline, and serifs"
|
||||
selector.m = "earlessRoundedDoubleArchSerifed"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArchSerifed"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArch"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "earlessRoundedDoubleArchSerifed"
|
||||
[prime.m.variants-buildup.stages.serifs.top-left-and-bottom-right-serifed]
|
||||
rank = 3
|
||||
keySuffix = "top-left-and-bottom-right-serifed"
|
||||
descriptionSuffix = "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"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-tailed]
|
||||
rank = 14
|
||||
description = "Earless (rounded top-left) `m` with normal middle leg touching baseline, and a curly tail"
|
||||
selector.m = "earlessRoundedDoubleArchTailed"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArch"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArchTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "earlessRoundedDoubleArch"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-tailed-serifed]
|
||||
rank = 15
|
||||
description = "Earless (rounded top-left) `m` with normal middle leg touching baseline, a curly tail, and serifs"
|
||||
selector.m = "earlessRoundedDoubleArchTailedSerifed"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArchSerifed"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArchTailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "earlessRoundedDoubleArchSerifed"
|
||||
|
||||
[prime.m.variants.earless-single-arch]
|
||||
rank = 16
|
||||
description = "Earless (single-arch) `m` with normal middle leg touching baseline"
|
||||
selector.m = "earlessSingleArch"
|
||||
selector."m/tailless" = "earlessSingleArch"
|
||||
selector."m/sansSerif" = "earlessSingleArch"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "earlessSingleArch"
|
||||
|
||||
[prime.m.variants.earless-single-arch-serifed]
|
||||
rank = 17
|
||||
description = "Earless (single-arch) `m` with normal middle leg touching baseline, and serifs"
|
||||
selector.m = "earlessSingleArchSerifed"
|
||||
selector."m/tailless" = "earlessSingleArchSerifed"
|
||||
selector."m/sansSerif" = "earlessSingleArch"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "earlessSingleArchSerifed"
|
||||
|
||||
[prime.m.variants.earless-single-arch-tailed]
|
||||
rank = 18
|
||||
description = "Earless (single-arch) `m` with normal middle leg touching baseline, and a curly tail"
|
||||
selector.m = "earlessSingleArchTailed"
|
||||
selector."m/tailless" = "earlessSingleArch"
|
||||
selector."m/sansSerif" = "earlessSingleArchTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "earlessSingleArch"
|
||||
|
||||
[prime.m.variants.earless-single-arch-tailed-serifed]
|
||||
rank = 19
|
||||
description = "Earless (single-arch) `m` with normal middle leg touching baseline, a curly tail, and serifs"
|
||||
selector.m = "earlessSingleArchTailedSerifed"
|
||||
selector."m/tailless" = "earlessSingleArchSerifed"
|
||||
selector."m/sansSerif" = "earlessSingleArchTailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "earlessSingleArchSerifed"
|
||||
|
||||
[prime.m.variants.short-leg]
|
||||
rank = 20
|
||||
description = "`m` with shorter middle leg, like Ubuntu Mono"
|
||||
selector.m = "shortLeg"
|
||||
selector."m/tailless" = "shortLeg"
|
||||
selector."m/sansSerif" = "shortLeg"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "shortLeg"
|
||||
|
||||
[prime.m.variants.short-leg-top-left-serifed]
|
||||
rank = 21
|
||||
description = "`m` with serif at top left, a shorter middle leg like Ubuntu Mono"
|
||||
selector.m = "shortLegTopLeftSerifed"
|
||||
selector."m/tailless" = "shortLegTopLeftSerifed"
|
||||
selector."m/sansSerif" = "shortLeg"
|
||||
selector."cyrl/te.italic" = "topLeftSerifed"
|
||||
selector.mLTail = "shortLegTopLeftSerifed"
|
||||
|
||||
[prime.m.variants.short-leg-top-left-and-bottom-right-serifed]
|
||||
rank = 22
|
||||
description = "`m` with serifs at top left and bottom right, a shorter middle leg like Ubuntu Mono"
|
||||
selector.m = "shortLegTopLeftAndBottomRightSerifed"
|
||||
selector."m/tailless" = "shortLegTopLeftAndBottomRightSerifed"
|
||||
selector."m/sansSerif" = "shortLeg"
|
||||
selector."cyrl/te.italic" = "topLeftAndBottomRightSerifed"
|
||||
selector.mLTail = "shortLegTopLeftSerifed"
|
||||
|
||||
[prime.m.variants.short-leg-serifed]
|
||||
rank = 23
|
||||
description = "`m` with serifs, a shorter middle leg like Ubuntu Mono"
|
||||
selector.m = "shortLegSerifed"
|
||||
selector."m/tailless" = "shortLegSerifed"
|
||||
selector."m/sansSerif" = "shortLeg"
|
||||
selector."cyrl/te.italic" = "topLeftAndBottomRightSerifed"
|
||||
selector.mLTail = "shortLegTopLeftSerifed"
|
||||
|
||||
[prime.m.variants.short-leg-tailed]
|
||||
rank = 24
|
||||
description = "`m` with shorter middle leg, like Ubuntu Mono, and a curly tail"
|
||||
selector.m = "shortLegTailed"
|
||||
selector."m/tailless" = "shortLeg"
|
||||
selector."m/sansSerif" = "shortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "shortLeg"
|
||||
|
||||
[prime.m.variants.short-leg-tailed-top-left-serifed]
|
||||
rank = 25
|
||||
description = "`m` with serif at top left, a shorter middle leg like Ubuntu Mono, and a curly tail"
|
||||
selector.m = "shortLegTailedTopLeftSerifed"
|
||||
selector."m/tailless" = "shortLegTopLeftSerifed"
|
||||
selector."m/sansSerif" = "shortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailedTopLeftSerifed"
|
||||
selector.mLTail = "shortLegTopLeftSerifed"
|
||||
|
||||
[prime.m.variants.short-leg-tailed-serifed]
|
||||
rank = 26
|
||||
description = "`m` with serif, a shorter middle leg like Ubuntu Mono, and a curly tail"
|
||||
selector.m = "shortLegTailedSerifed"
|
||||
selector."m/tailless" = "shortLegTopLeftSerifed"
|
||||
selector."m/sansSerif" = "shortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailedTopLeftSerifed"
|
||||
selector.mLTail = "shortLegTopLeftSerifed"
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-short-leg]
|
||||
rank = 27
|
||||
description = "Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono"
|
||||
selector.m = "earlessCornerDoubleArchShortLeg"
|
||||
selector."m/tailless" = "earlessCornerDoubleArchShortLeg"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArchShortLeg"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "earlessCornerDoubleArchShortLeg"
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-short-leg-serifed]
|
||||
rank = 28
|
||||
description = "Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono, and serifs"
|
||||
selector.m = "earlessCornerDoubleArchShortLegSerifed"
|
||||
selector."m/tailless" = "earlessCornerDoubleArchShortLegSerifed"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArchShortLeg"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "earlessCornerDoubleArchShortLegSerifed"
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-short-leg-tailed]
|
||||
rank = 29
|
||||
description = "Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail"
|
||||
selector.m = "earlessCornerDoubleArchShortLegTailed"
|
||||
selector."m/tailless" = "earlessCornerDoubleArchShortLeg"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArchShortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "earlessCornerDoubleArchShortLeg"
|
||||
|
||||
[prime.m.variants.earless-corner-double-arch-short-leg-tailed-serifed]
|
||||
rank = 30
|
||||
description = "Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail, and serifs"
|
||||
selector.m = "earlessCornerDoubleArchShortLegTailedSerifed"
|
||||
selector."m/tailless" = "earlessCornerDoubleArchShortLegSerifed"
|
||||
selector."m/sansSerif" = "earlessCornerDoubleArchShortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "earlessCornerDoubleArchShortLegSerifed"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-short-leg]
|
||||
rank = 31
|
||||
description = "Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono"
|
||||
selector.m = "earlessRoundedDoubleArchShortLeg"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArchShortLeg"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArchShortLeg"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "earlessRoundedDoubleArchShortLeg"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-short-leg-serifed]
|
||||
rank = 32
|
||||
description = "Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono, and serifs"
|
||||
selector.m = "earlessRoundedDoubleArchShortLegSerifed"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArchShortLegSerifed"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArchShortLeg"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "earlessRoundedDoubleArchShortLegSerifed"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-short-leg-tailed]
|
||||
rank = 33
|
||||
description = "Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail"
|
||||
selector.m = "earlessRoundedDoubleArchShortLegTailed"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArchShortLeg"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArchShortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "earlessRoundedDoubleArchShortLeg"
|
||||
|
||||
[prime.m.variants.earless-rounded-double-arch-short-leg-tailed-serifed]
|
||||
rank = 34
|
||||
description = "Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail, and serifs"
|
||||
selector.m = "earlessRoundedDoubleArchShortLegTailedSerifed"
|
||||
selector."m/tailless" = "earlessRoundedDoubleArchShortLegSerifed"
|
||||
selector."m/sansSerif" = "earlessRoundedDoubleArchShortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "earlessRoundedDoubleArchShortLegSerifed"
|
||||
|
||||
[prime.m.variants.earless-single-arch-short-leg]
|
||||
rank = 35
|
||||
description = "Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono"
|
||||
selector.m = "earlessSingleArchShortLeg"
|
||||
selector."m/tailless" = "earlessSingleArchShortLeg"
|
||||
selector."m/sansSerif" = "earlessSingleArchShortLeg"
|
||||
selector."cyrl/te.italic" = "serifless"
|
||||
selector.mLTail = "earlessSingleArchShortLeg"
|
||||
|
||||
[prime.m.variants.earless-single-arch-short-leg-serifed]
|
||||
rank = 36
|
||||
description = "Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono, and serifs"
|
||||
selector.m = "earlessSingleArchShortLegSerifed"
|
||||
selector."m/tailless" = "earlessSingleArchShortLegSerifed"
|
||||
selector."m/sansSerif" = "earlessSingleArchShortLeg"
|
||||
selector."cyrl/te.italic" = "serifed"
|
||||
selector.mLTail = "earlessSingleArchShortLegSerifed"
|
||||
|
||||
[prime.m.variants.earless-single-arch-short-leg-tailed]
|
||||
rank = 37
|
||||
description = "Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail"
|
||||
selector.m = "earlessSingleArchShortLegTailed"
|
||||
selector."m/tailless" = "earlessSingleArchShortLeg"
|
||||
selector."m/sansSerif" = "earlessSingleArchShortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailed"
|
||||
selector.mLTail = "earlessSingleArchShortLeg"
|
||||
|
||||
[prime.m.variants.earless-single-arch-short-leg-tailed-serifed]
|
||||
rank = 38
|
||||
description = "Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail, and serifs"
|
||||
selector.m = "earlessSingleArchShortLegTailedSerifed"
|
||||
selector."m/tailless" = "earlessSingleArchShortLegSerifed"
|
||||
selector."m/sansSerif" = "earlessSingleArchShortLegTailed"
|
||||
selector."cyrl/te.italic" = "tailedSerifed"
|
||||
selector.mLTail = "earlessSingleArchShortLegSerifed"
|
||||
[prime.m.variants-buildup.stages.serifs.serifed]
|
||||
rank = 4
|
||||
keySuffix = "serifed"
|
||||
descriptionSuffix = "serifs"
|
||||
selectorSuffix.m = "serifed"
|
||||
selectorSuffix."m/tailless" = "serifed"
|
||||
selectorSuffix."m/sansSerif" = "serifless"
|
||||
selectorSuffix."cyrl/te.italic" = "serifed"
|
||||
selectorSuffix.mLTail = "serifed"
|
||||
|
||||
|
||||
|
||||
|
@ -8895,7 +8685,7 @@ g = "earless-corner"
|
|||
i = "tailed-serifed"
|
||||
k = "symmetric-touching-serifless"
|
||||
l = "tailed-serifed"
|
||||
m = "earless-corner-double-arch-short-leg"
|
||||
m = "earless-corner-double-arch-short-leg-serifless"
|
||||
n = "earless-corner-straight-serifless"
|
||||
p = "earless-corner-serifless"
|
||||
q = "earless-corner-serifless"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue