website overhaul
This commit is contained in:
parent
beace051c7
commit
2fce3d1f13
7 changed files with 237 additions and 189 deletions
|
@ -34,15 +34,15 @@ function LinkedGlyphProp(key) {
|
|||
};
|
||||
}
|
||||
|
||||
export const Nwid = OtlTaggedProp("Nwid", "NWID");
|
||||
export const Wwid = OtlTaggedProp("Wwid", "WWID");
|
||||
export const Lnum = OtlTaggedProp("Lnum", "lnum");
|
||||
export const Onum = OtlTaggedProp("Onum", "onum");
|
||||
export const AplForm = OtlTaggedProp("AplForm", "APLF");
|
||||
export const Nwid = OtlTaggedProp("Nwid", "NWID", "Wide cell");
|
||||
export const Wwid = OtlTaggedProp("Wwid", "WWID", "Narrow cell");
|
||||
export const Lnum = OtlTaggedProp("Lnum", "lnum", "Lining number");
|
||||
export const Onum = OtlTaggedProp("Onum", "onum", "Old-style number");
|
||||
export const AplForm = OtlTaggedProp("AplForm", "APLF", "APL form");
|
||||
export const NumeratorForm = OtlTaggedProp("Numerator", "numr");
|
||||
export const DenominatorForm = OtlTaggedProp("Denominator", "dnom");
|
||||
function OtlTaggedProp(key, otlTag) {
|
||||
return { ...LinkedGlyphProp(key), otlTag };
|
||||
function OtlTaggedProp(key, otlTag, description) {
|
||||
return { ...LinkedGlyphProp(key), otlTag, description };
|
||||
}
|
||||
|
||||
export const CvDecompose = DecompositionProp("CvDecompose");
|
||||
|
@ -145,12 +145,14 @@ export const Joining = {
|
|||
|
||||
const CvTagCache = new Map();
|
||||
|
||||
export function Cv(tag, rank) {
|
||||
export function Cv(tag, rank, rankGroup, description) {
|
||||
const key = tag + "#" + rank;
|
||||
if (CvTagCache.has(key)) return CvTagCache.get(key);
|
||||
const rel = {
|
||||
tag,
|
||||
rank,
|
||||
rankGroup,
|
||||
description,
|
||||
get(glyph) {
|
||||
if (glyph && glyph.related && glyph.related.cv) return glyph.related.cv[key];
|
||||
else return null;
|
||||
|
@ -320,39 +322,63 @@ export function createGrDisplaySheet(glyphStore, gid) {
|
|||
if (!glyph) return [];
|
||||
// Query selected typographic features -- mostly NWID and WWID
|
||||
let typographicFeatures = [];
|
||||
displayQueryPairFeatures(glyphStore, gid, Nwid, Wwid, typographicFeatures);
|
||||
displayQueryPairFeatures(glyphStore, gid, Lnum, Onum, typographicFeatures);
|
||||
displayQuerySingleFeature(glyphStore, gid, AplForm, typographicFeatures);
|
||||
displayQueryPairFeatures(glyphStore, gid, "Width", Nwid, Wwid, typographicFeatures);
|
||||
displayQueryPairFeatures(glyphStore, gid, "Number Form", Lnum, Onum, typographicFeatures);
|
||||
displayQuerySingleFeature(glyphStore, gid, "APL Form", AplForm, typographicFeatures);
|
||||
|
||||
// Query selected character variants
|
||||
let charVariantFeatures = [];
|
||||
const decomposition = CvDecompose.get(glyph) || PseudoCvDecompose.get(glyph);
|
||||
if (decomposition) {
|
||||
const variantAssignmentSet = new Set();
|
||||
const tagSet = new Set();
|
||||
for (const componentGn of decomposition) {
|
||||
const component = glyphStore.queryByName(componentGn);
|
||||
if (!component) continue;
|
||||
queryCvFeatureTagsOf(charVariantFeatures, componentGn, component, variantAssignmentSet);
|
||||
queryCvFeatureTagsOf(charVariantFeatures, componentGn, component, tagSet);
|
||||
}
|
||||
} else {
|
||||
queryCvFeatureTagsOf(charVariantFeatures, gid, glyph, null);
|
||||
}
|
||||
return [typographicFeatures, charVariantFeatures];
|
||||
}
|
||||
function displayQueryPairFeatures(gs, gid, grCis, grTrans, sink) {
|
||||
|
||||
function FeatureSeries(name, groups) {
|
||||
return {
|
||||
name,
|
||||
groups
|
||||
};
|
||||
}
|
||||
|
||||
function displayQueryPairFeatures(gs, gid, name, grCis, grTrans, sink) {
|
||||
const g = gs.queryByName(gid);
|
||||
if (!g) return;
|
||||
const glyphIsHidden = /^\./.test(gid);
|
||||
if (glyphIsHidden) return;
|
||||
if (grCis.get(g) || grTrans.get(g)) {
|
||||
sink.push(`'${grCis.otlTag}' 1`, `'${grTrans.otlTag}' 1`);
|
||||
sink.push(
|
||||
FeatureSeries(name, [
|
||||
[
|
||||
{ css: `'${grCis.otlTag}' 1`, description: grCis.description },
|
||||
{ css: `'${grTrans.otlTag}' 1`, description: grTrans.description }
|
||||
]
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
function displayQuerySingleFeature(gs, gid, grCis, sink) {
|
||||
function displayQuerySingleFeature(gs, gid, name, grCis, sink) {
|
||||
const g = gs.queryByName(gid);
|
||||
if (!g) return;
|
||||
const glyphIsHidden = /^\./.test(gid);
|
||||
if (glyphIsHidden) return;
|
||||
if (grCis.get(g)) {
|
||||
sink.push(`'${grCis.otlTag}' 0`, `'${grCis.otlTag}' 1`);
|
||||
sink.push(
|
||||
FeatureSeries(name, [
|
||||
[
|
||||
{ css: `'${grCis.otlTag}' 0`, description: grCis.description + " disabled" },
|
||||
{ css: `'${grCis.otlTag}' 1`, description: grCis.description + " enabled" }
|
||||
]
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
function byTagPreference(a, b) {
|
||||
|
@ -362,30 +388,29 @@ function byTagPreference(a, b) {
|
|||
if (ua > ub) return 1;
|
||||
return 0;
|
||||
}
|
||||
function queryCvFeatureTagsOf(sink, gid, glyph, variantAssignmentSet) {
|
||||
function queryCvFeatureTagsOf(sink, gid, glyph, tagSet) {
|
||||
const cvs = AnyCv.query(glyph).sort(byTagPreference);
|
||||
let existingGlyphs = new Set();
|
||||
let m = new Map();
|
||||
let existingFeatures = new Map();
|
||||
|
||||
for (const gr of cvs) {
|
||||
const tag = gr.tag;
|
||||
const target = gr.get(glyph);
|
||||
if (target === gid) continue;
|
||||
if (existingGlyphs.has(target)) continue;
|
||||
existingGlyphs.add(target);
|
||||
let g = m.get(tag);
|
||||
if (!g) {
|
||||
g = [];
|
||||
m.set(tag, g);
|
||||
}
|
||||
const assignCss = `'${tag}' ${gr.rank}`;
|
||||
if (!variantAssignmentSet) {
|
||||
g.push(assignCss);
|
||||
} else if (!variantAssignmentSet.has(assignCss)) {
|
||||
g.push(assignCss);
|
||||
variantAssignmentSet.add(assignCss);
|
||||
|
||||
let series = existingFeatures.get(gr.tag);
|
||||
if (!series) {
|
||||
if (tagSet) {
|
||||
if (tagSet.has(gr.tag)) continue;
|
||||
tagSet.add(gr.tag);
|
||||
}
|
||||
series = FeatureSeries(gr.tag, [[]]);
|
||||
existingFeatures.set(gr.tag, series);
|
||||
}
|
||||
|
||||
const featureApp = { css: `'${gr.tag}' ${gr.rank}`, description: gr.description };
|
||||
if (!series.groups[gr.rankGroup]) series.groups[gr.rankGroup] = [];
|
||||
series.groups[gr.rankGroup].push(featureApp);
|
||||
}
|
||||
for (const g of m.values()) if (g.length) sink.push(g);
|
||||
for (const g of existingFeatures.values()) sink.push(g);
|
||||
}
|
||||
|
||||
export function linkSuffixGr(gs, suffix, gr) {
|
||||
|
|
|
@ -215,10 +215,12 @@ class VariantBuilder {
|
|||
}
|
||||
}
|
||||
process() {
|
||||
const globalState = new VbGlobalState(this.stages);
|
||||
const globalState = new VbGlobalState(this.entry, 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();
|
||||
|
@ -285,6 +287,7 @@ class VbStageAlternative {
|
|||
const ans = localState.clone();
|
||||
ans.stage = this.next;
|
||||
ans.assignments.set(this.stage, this.key);
|
||||
if (this.stage === globalState.entry) ans.rankGroup = this.rank;
|
||||
if (this.keyAffix) ans.addKeyAffix(this.mode, this.keyAffix);
|
||||
if (this.descriptionJoiner && this.descriptionAffix)
|
||||
ans.addDescription(this.mode, this.descriptionJoiner, this.descriptionAffix);
|
||||
|
@ -328,7 +331,8 @@ class VbStageAlternative {
|
|||
}
|
||||
|
||||
class VbGlobalState {
|
||||
constructor(stages) {
|
||||
constructor(entry, stages) {
|
||||
this.entry = entry;
|
||||
this.stages = stages;
|
||||
this.rank = 0;
|
||||
this.sink = [];
|
||||
|
@ -339,6 +343,7 @@ class VbLocalState {
|
|||
constructor() {
|
||||
this.stage = ".start";
|
||||
this.rank = 0;
|
||||
this.rankGroup = 0;
|
||||
this.descriptionLeader = "";
|
||||
|
||||
this.assignments = new Map();
|
||||
|
@ -351,6 +356,7 @@ class VbLocalState {
|
|||
const ans = new VbLocalState();
|
||||
ans.stage = this.stage;
|
||||
ans.rank = this.rank;
|
||||
ans.rankGroup = this.rankGroup;
|
||||
ans.descriptionLeader = this.descriptionLeader;
|
||||
ans.assignments = new Map(this.assignments);
|
||||
ans.key = [...this.key];
|
||||
|
@ -428,6 +434,7 @@ class VbLocalState {
|
|||
return {
|
||||
key: this.produceKey(),
|
||||
rank: this.rank,
|
||||
rankGroup: this.rankGroup,
|
||||
description: this.produceDescription(),
|
||||
selector: Object.fromEntries(this.selector)
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue