@monowind/ascii 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/dist/cdn.d.ts +2 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/cdn.js +30159 -0
- package/dist/cdn.js.map +1 -0
- package/dist/effects.d.ts +16 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/font.d.ts +30 -0
- package/dist/font.d.ts.map +1 -0
- package/dist/fonts/ascii12.d.ts +3 -0
- package/dist/fonts/ascii12.js +8 -0
- package/dist/fonts/ascii9.d.ts +3 -0
- package/dist/fonts/ascii9.js +8 -0
- package/dist/fonts/banner.d.ts +3 -0
- package/dist/fonts/banner.js +8 -0
- package/dist/fonts/bfraktur.d.ts +3 -0
- package/dist/fonts/bfraktur.js +8 -0
- package/dist/fonts/big.d.ts +3 -0
- package/dist/fonts/big.js +8 -0
- package/dist/fonts/bigascii12.d.ts +3 -0
- package/dist/fonts/bigascii12.js +8 -0
- package/dist/fonts/bigascii9.d.ts +3 -0
- package/dist/fonts/bigascii9.js +8 -0
- package/dist/fonts/biggray12.d.ts +3 -0
- package/dist/fonts/biggray12.js +8 -0
- package/dist/fonts/biggray9.d.ts +3 -0
- package/dist/fonts/biggray9.js +8 -0
- package/dist/fonts/bigmono12.d.ts +3 -0
- package/dist/fonts/bigmono12.js +8 -0
- package/dist/fonts/bigmono9.d.ts +3 -0
- package/dist/fonts/bigmono9.js +8 -0
- package/dist/fonts/block.d.ts +3 -0
- package/dist/fonts/block.js +8 -0
- package/dist/fonts/bubble.d.ts +3 -0
- package/dist/fonts/bubble.js +8 -0
- package/dist/fonts/circle.d.ts +3 -0
- package/dist/fonts/circle.js +8 -0
- package/dist/fonts/digital.d.ts +3 -0
- package/dist/fonts/digital.js +8 -0
- package/dist/fonts/emboss.d.ts +3 -0
- package/dist/fonts/emboss.js +8 -0
- package/dist/fonts/emboss2.d.ts +3 -0
- package/dist/fonts/emboss2.js +8 -0
- package/dist/fonts/fauxcyrillic.d.ts +3 -0
- package/dist/fonts/fauxcyrillic.js +8 -0
- package/dist/fonts/fullcyrillic.d.ts +3 -0
- package/dist/fonts/fullcyrillic.js +8 -0
- package/dist/fonts/future.d.ts +3 -0
- package/dist/fonts/future.js +8 -0
- package/dist/fonts/ivrit.d.ts +3 -0
- package/dist/fonts/ivrit.js +8 -0
- package/dist/fonts/lean.d.ts +3 -0
- package/dist/fonts/lean.js +8 -0
- package/dist/fonts/letter.d.ts +3 -0
- package/dist/fonts/letter.js +8 -0
- package/dist/fonts/mini.d.ts +3 -0
- package/dist/fonts/mini.js +8 -0
- package/dist/fonts/mnemonic.d.ts +3 -0
- package/dist/fonts/mnemonic.js +8 -0
- package/dist/fonts/mono12.d.ts +3 -0
- package/dist/fonts/mono12.js +8 -0
- package/dist/fonts/mono9.d.ts +3 -0
- package/dist/fonts/mono9.js +8 -0
- package/dist/fonts/pagga.d.ts +3 -0
- package/dist/fonts/pagga.js +8 -0
- package/dist/fonts/script.d.ts +3 -0
- package/dist/fonts/script.js +8 -0
- package/dist/fonts/shadow.d.ts +3 -0
- package/dist/fonts/shadow.js +8 -0
- package/dist/fonts/slant.d.ts +3 -0
- package/dist/fonts/slant.js +8 -0
- package/dist/fonts/small.d.ts +3 -0
- package/dist/fonts/small.js +8 -0
- package/dist/fonts/smascii12.d.ts +3 -0
- package/dist/fonts/smascii12.js +8 -0
- package/dist/fonts/smascii9.d.ts +3 -0
- package/dist/fonts/smascii9.js +8 -0
- package/dist/fonts/smblock.d.ts +3 -0
- package/dist/fonts/smblock.js +8 -0
- package/dist/fonts/smbraille.d.ts +3 -0
- package/dist/fonts/smbraille.js +8 -0
- package/dist/fonts/smmono12.d.ts +3 -0
- package/dist/fonts/smmono12.js +8 -0
- package/dist/fonts/smmono9.d.ts +3 -0
- package/dist/fonts/smmono9.js +8 -0
- package/dist/fonts/smscript.d.ts +3 -0
- package/dist/fonts/smscript.js +8 -0
- package/dist/fonts/smshadow.d.ts +3 -0
- package/dist/fonts/smshadow.js +8 -0
- package/dist/fonts/smslant.d.ts +3 -0
- package/dist/fonts/smslant.js +8 -0
- package/dist/fonts/standard.d.ts +3 -0
- package/dist/fonts/standard.js +8 -0
- package/dist/fonts/term.d.ts +3 -0
- package/dist/fonts/term.js +8 -0
- package/dist/fonts/wideterm.d.ts +3 -0
- package/dist/fonts/wideterm.js +8 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +190 -0
- package/dist/index.js.map +1 -0
- package/dist/registry-1nauEUck.js +165 -0
- package/dist/registry-1nauEUck.js.map +1 -0
- package/dist/registry.d.ts +13 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/render.d.ts +16 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/sgr.d.ts +22 -0
- package/dist/sgr.d.ts.map +1 -0
- package/fonts/LICENSES/README.md +17 -0
- package/fonts/ascii12.tlf +32804 -0
- package/fonts/ascii9.tlf +26822 -0
- package/fonts/banner.flf +2494 -0
- package/fonts/bfraktur.tlf +118 -0
- package/fonts/big.flf +2204 -0
- package/fonts/bigascii12.tlf +59723 -0
- package/fonts/bigascii9.tlf +47759 -0
- package/fonts/biggray12.tlf +59723 -0
- package/fonts/biggray9.tlf +47759 -0
- package/fonts/bigmono12.tlf +59723 -0
- package/fonts/bigmono9.tlf +47759 -0
- package/fonts/block.flf +1691 -0
- package/fonts/bubble.flf +1630 -0
- package/fonts/circle.tlf +186 -0
- package/fonts/digital.flf +1286 -0
- package/fonts/emboss.tlf +325 -0
- package/fonts/emboss2.tlf +325 -0
- package/fonts/fauxcyrillic.tlf +118 -0
- package/fonts/fullcyrillic.tlf +118 -0
- package/fonts/future.tlf +457 -0
- package/fonts/ivrit.flf +900 -0
- package/fonts/lean.flf +1691 -0
- package/fonts/letter.tlf +840 -0
- package/fonts/mini.flf +899 -0
- package/fonts/mnemonic.flf +3702 -0
- package/fonts/mono12.tlf +32804 -0
- package/fonts/mono9.tlf +26822 -0
- package/fonts/pagga.tlf +534 -0
- package/fonts/script.flf +1493 -0
- package/fonts/shadow.flf +1097 -0
- package/fonts/slant.flf +1295 -0
- package/fonts/small.flf +1097 -0
- package/fonts/smascii12.tlf +32804 -0
- package/fonts/smascii9.tlf +26822 -0
- package/fonts/smblock.tlf +1200 -0
- package/fonts/smbraille.tlf +220 -0
- package/fonts/smmono12.tlf +32804 -0
- package/fonts/smmono9.tlf +26822 -0
- package/fonts/smscript.flf +1097 -0
- package/fonts/smshadow.flf +899 -0
- package/fonts/smslant.flf +1097 -0
- package/fonts/standard.flf +2238 -0
- package/fonts/term.flf +600 -0
- package/fonts/wideterm.tlf +132 -0
- package/package.json +62 -0
- package/src/styles.css +40 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { invalidateLeaves as e } from "monowind";
|
|
2
|
+
//#region src/sgr.ts
|
|
3
|
+
var t = [
|
|
4
|
+
"black",
|
|
5
|
+
"red",
|
|
6
|
+
"green",
|
|
7
|
+
"yellow",
|
|
8
|
+
"blue",
|
|
9
|
+
"magenta",
|
|
10
|
+
"cyan",
|
|
11
|
+
"white"
|
|
12
|
+
], n = (e) => e < 8 ? `var(--mw-ansi-${t[e]})` : `var(--mw-ansi-bright-${t[e - 8]})`;
|
|
13
|
+
function r(e) {
|
|
14
|
+
if (e < 16) return n(e);
|
|
15
|
+
if (e < 232) {
|
|
16
|
+
let t = (e) => e === 0 ? 0 : 55 + e * 40, n = e - 16;
|
|
17
|
+
return `rgb(${t(Math.floor(n / 36))}, ${t(Math.floor(n / 6) % 6)}, ${t(n % 6)})`;
|
|
18
|
+
}
|
|
19
|
+
let t = 8 + (e - 232) * 10;
|
|
20
|
+
return `rgb(${t}, ${t}, ${t})`;
|
|
21
|
+
}
|
|
22
|
+
var i = /\x1b\[([0-9;]*)m/g;
|
|
23
|
+
function a(e) {
|
|
24
|
+
if (!e.includes("\x1B")) return { chars: e };
|
|
25
|
+
let t = "", n = [], r, a = 0, s = !1;
|
|
26
|
+
i.lastIndex = 0;
|
|
27
|
+
for (let c = i.exec(e); c; c = i.exec(e)) {
|
|
28
|
+
for (let i of e.slice(a, c.index)) t += i, n.push(r), r && (s = !0);
|
|
29
|
+
a = c.index + c[0].length, r = o(r, c[1]);
|
|
30
|
+
}
|
|
31
|
+
for (let i of e.slice(a)) t += i, n.push(r), r && (s = !0);
|
|
32
|
+
return s ? {
|
|
33
|
+
chars: t,
|
|
34
|
+
colors: n
|
|
35
|
+
} : { chars: t };
|
|
36
|
+
}
|
|
37
|
+
function o(e, t) {
|
|
38
|
+
let i = t === "" ? [0] : t.split(";").map(Number), a = e ? { ...e } : void 0, o = () => a ??= {};
|
|
39
|
+
for (let e = 0; e < i.length; e++) {
|
|
40
|
+
let t = i[e];
|
|
41
|
+
if (t === 0) a = void 0;
|
|
42
|
+
else if (t === 1) o().bold = !0;
|
|
43
|
+
else if (t === 22) delete a?.bold;
|
|
44
|
+
else if (t >= 30 && t <= 37) o().color = n(t - 30);
|
|
45
|
+
else if (t >= 90 && t <= 97) o().color = n(t - 90 + 8);
|
|
46
|
+
else if (t === 39) delete a?.color;
|
|
47
|
+
else if (t >= 40 && t <= 47) o().backgroundColor = n(t - 40);
|
|
48
|
+
else if (t >= 100 && t <= 107) o().backgroundColor = n(t - 100 + 8);
|
|
49
|
+
else if (t === 49) delete a?.backgroundColor;
|
|
50
|
+
else if (t === 38 || t === 48) {
|
|
51
|
+
let n = t === 38 ? "color" : "backgroundColor";
|
|
52
|
+
i[e + 1] === 5 && i[e + 2] !== void 0 ? (o()[n] = r(i[e + 2]), e += 2) : i[e + 1] === 2 && i[e + 4] !== void 0 && (o()[n] = `rgb(${i[e + 2]}, ${i[e + 3]}, ${i[e + 4]})`, e += 4);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!(a && !a.bold && a.color === void 0 && a.backgroundColor === void 0)) return a;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/font.ts
|
|
59
|
+
var s = [
|
|
60
|
+
196,
|
|
61
|
+
214,
|
|
62
|
+
220,
|
|
63
|
+
228,
|
|
64
|
+
246,
|
|
65
|
+
252,
|
|
66
|
+
223
|
|
67
|
+
], c = /^\s*(-?\d+|-?0[xX][0-9a-fA-F]+|-?0[0-7]+)\b/;
|
|
68
|
+
function l(e) {
|
|
69
|
+
let t = e.split(/\r\n|\r|\n/), n = t[0] ?? "", r = n.slice(0, 5);
|
|
70
|
+
if (r !== "flf2a" && r !== "tlf2a") throw Error(`not a figlet/toilet font (magic "${r}"; zipped fonts must be extracted)`);
|
|
71
|
+
let i = n.charAt(5) || "$", o = n.slice(6).trim().split(/\s+/).map(Number), [l, d, , f, p] = o, m = o[6];
|
|
72
|
+
if (!l || !Number.isFinite(l)) throw Error("font header has no height");
|
|
73
|
+
let { layout: h, rules: g } = u(f ?? -1, m), _ = /* @__PURE__ */ new Map(), v = 1 + (p ?? 0), y = () => {
|
|
74
|
+
if (v >= t.length) return null;
|
|
75
|
+
let e = t.slice(v, v + l);
|
|
76
|
+
if (e.length < l) return null;
|
|
77
|
+
v += l;
|
|
78
|
+
let n = e[0].replace(/\s+$/, ""), r = n.charAt(n.length - 1), i = e.map((e) => {
|
|
79
|
+
let t = e.replace(/\s+$/, ""), n = t.length;
|
|
80
|
+
for (; n > 0 && t.charAt(n - 1) === r;) n--;
|
|
81
|
+
return a(t.slice(0, n));
|
|
82
|
+
}), o = Math.max(0, ...i.map((e) => e.chars.length)), s = i.map((e) => e.chars.padEnd(o, " ")), c = i.some((e) => e.colors), u = {
|
|
83
|
+
lines: s,
|
|
84
|
+
width: o
|
|
85
|
+
};
|
|
86
|
+
return c && (u.colors = i.map((e) => e.colors ?? [])), u;
|
|
87
|
+
};
|
|
88
|
+
for (let e = 32; e <= 126; e++) {
|
|
89
|
+
let t = y();
|
|
90
|
+
if (!t) throw Error(`font ends inside required character ${e}`);
|
|
91
|
+
_.set(e, t);
|
|
92
|
+
}
|
|
93
|
+
if (v < t.length && t[v].trim() !== "" && !c.test(t[v])) for (let e of s) {
|
|
94
|
+
let t = y();
|
|
95
|
+
if (!t) break;
|
|
96
|
+
_.set(e, t);
|
|
97
|
+
}
|
|
98
|
+
for (; v < t.length;) {
|
|
99
|
+
let e = t[v], n = c.exec(e);
|
|
100
|
+
if (!n) break;
|
|
101
|
+
v++;
|
|
102
|
+
let r = y();
|
|
103
|
+
if (!r) break;
|
|
104
|
+
let i = Number(n[1]);
|
|
105
|
+
Number.isFinite(i) && i >= 0 && _.set(i, r);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
height: l,
|
|
109
|
+
baseline: d ?? l,
|
|
110
|
+
hardblank: i,
|
|
111
|
+
layout: h,
|
|
112
|
+
rules: g,
|
|
113
|
+
glyphs: _
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function u(e, t) {
|
|
117
|
+
if (t !== void 0 && Number.isFinite(t)) {
|
|
118
|
+
if (t & 128) {
|
|
119
|
+
let e = t & 63;
|
|
120
|
+
return e > 0 ? {
|
|
121
|
+
layout: "smush-controlled",
|
|
122
|
+
rules: e
|
|
123
|
+
} : {
|
|
124
|
+
layout: "smush-universal",
|
|
125
|
+
rules: 0
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return t & 64 ? {
|
|
129
|
+
layout: "kerning",
|
|
130
|
+
rules: 0
|
|
131
|
+
} : {
|
|
132
|
+
layout: "full",
|
|
133
|
+
rules: 0
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return e === -1 ? {
|
|
137
|
+
layout: "full",
|
|
138
|
+
rules: 0
|
|
139
|
+
} : e === 0 ? {
|
|
140
|
+
layout: "kerning",
|
|
141
|
+
rules: 0
|
|
142
|
+
} : {
|
|
143
|
+
layout: "smush-controlled",
|
|
144
|
+
rules: e & 63
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//#endregion
|
|
148
|
+
//#region src/registry.ts
|
|
149
|
+
var d = /* @__PURE__ */ new Map(), f = (e) => e.toLowerCase().replace(/\.(flf|tlf)$/, "").trim();
|
|
150
|
+
function p(t, n) {
|
|
151
|
+
let r = f(t), i;
|
|
152
|
+
try {
|
|
153
|
+
i = l(n);
|
|
154
|
+
} catch (e) {
|
|
155
|
+
return console.warn(`[monowind] registerAsciiFont("${t}"): ${String(e)}`), null;
|
|
156
|
+
}
|
|
157
|
+
return d.has(r) && console.warn(`[monowind] registerAsciiFont: replacing "${r}" (last registration wins).`), d.set(r, i), e(), i;
|
|
158
|
+
}
|
|
159
|
+
function m(e) {
|
|
160
|
+
return d.get(f(e));
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
export { p as n, l as r, m as t };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=registry-1nauEUck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-1nauEUck.js","names":[],"sources":["../src/sgr.ts","../src/font.ts","../src/registry.ts"],"sourcesContent":["/**\n * SGR (ANSI color escape) extraction for TLF/ANSI-art glyph data: the\n * escapes are stripped from the art and become per-cell paint. The\n * 16-color palette maps to theme-aware tokens (`--mw-ansi-*`, defined\n * with defaults in styles.css) so a font's \"red\" follows the theme;\n * 256-color/true-color escapes pass through as literal CSS colors.\n */\n\nexport interface CellColor {\n color?: string;\n backgroundColor?: string;\n bold?: boolean;\n}\n\n/** Per-cell color state for one line; sparse (undefined = unstyled). */\nexport type CellColors = (CellColor | undefined)[];\n\nconst ANSI_NAMES = [\"black\", \"red\", \"green\", \"yellow\", \"blue\", \"magenta\", \"cyan\", \"white\"] as const;\n\nconst token = (index: number): string =>\n index < 8\n ? `var(--mw-ansi-${ANSI_NAMES[index]})`\n : `var(--mw-ansi-bright-${ANSI_NAMES[index - 8]})`;\n\n/** 256-color cube/grayscale → CSS; 0–15 use the theme tokens. */\nfunction color256(n: number): string {\n if (n < 16) return token(n);\n if (n < 232) {\n const v = (i: number) => (i === 0 ? 0 : 55 + i * 40);\n const cube = n - 16;\n return `rgb(${v(Math.floor(cube / 36))}, ${v(Math.floor(cube / 6) % 6)}, ${v(cube % 6)})`;\n }\n const gray = 8 + (n - 232) * 10;\n return `rgb(${gray}, ${gray}, ${gray})`;\n}\n\n// eslint-disable-next-line no-control-regex\nconst SGR = /\\x1b\\[([0-9;]*)m/g;\n\n/** Split one raw glyph line into plain characters and per-cell color\n * state. Non-SGR escapes are dropped. Returns `colors` only when any\n * cell is styled. */\nexport function parseSgrLine(raw: string): { chars: string; colors?: CellColors } {\n if (!raw.includes(\"\\x1b\")) return { chars: raw };\n let chars = \"\";\n const colors: CellColors = [];\n let state: CellColor | undefined;\n let last = 0;\n let styled = false;\n SGR.lastIndex = 0;\n for (let match = SGR.exec(raw); match; match = SGR.exec(raw)) {\n for (const ch of raw.slice(last, match.index)) {\n chars += ch;\n colors.push(state);\n if (state) styled = true;\n }\n last = match.index + match[0].length;\n state = applySgr(state, match[1]!);\n }\n for (const ch of raw.slice(last)) {\n chars += ch;\n colors.push(state);\n if (state) styled = true;\n }\n return styled ? { chars, colors } : { chars };\n}\n\nfunction applySgr(state: CellColor | undefined, params: string): CellColor | undefined {\n const codes = params === \"\" ? [0] : params.split(\";\").map(Number);\n let next: CellColor | undefined = state ? { ...state } : undefined;\n const ensure = (): CellColor => (next ??= {});\n for (let i = 0; i < codes.length; i++) {\n const code = codes[i]!;\n if (code === 0) next = undefined;\n else if (code === 1) ensure().bold = true;\n else if (code === 22) delete next?.bold;\n else if (code >= 30 && code <= 37) ensure().color = token(code - 30);\n else if (code >= 90 && code <= 97) ensure().color = token(code - 90 + 8);\n else if (code === 39) delete next?.color;\n else if (code >= 40 && code <= 47) ensure().backgroundColor = token(code - 40);\n else if (code >= 100 && code <= 107) ensure().backgroundColor = token(code - 100 + 8);\n else if (code === 49) delete next?.backgroundColor;\n else if (code === 38 || code === 48) {\n const target = code === 38 ? \"color\" : \"backgroundColor\";\n if (codes[i + 1] === 5 && codes[i + 2] !== undefined) {\n ensure()[target] = color256(codes[i + 2]!);\n i += 2;\n } else if (codes[i + 1] === 2 && codes[i + 4] !== undefined) {\n ensure()[target] = `rgb(${codes[i + 2]}, ${codes[i + 3]}, ${codes[i + 4]})`;\n i += 4;\n }\n }\n }\n if (next && !next.bold && next.color === undefined && next.backgroundColor === undefined) {\n return undefined;\n }\n return next;\n}\n","/**\n * FIGlet `.flf` / TOIlet `.tlf` font parsing — sibling formats, one\n * parser (specs/… see the monowind repo's mono-ascii plan): a header\n * line, comment lines, glyphs for ASCII 32–126, seven code-tagged-by-\n * position German characters, then explicitly code-tagged extras.\n * TLF glyph art may be UTF-8 and may embed SGR color escapes, which\n * parse into per-cell paint instead of glyph cells.\n */\n\nimport { parseSgrLine } from \"./sgr.ts\";\nimport type { CellColors } from \"./sgr.ts\";\n\nexport interface Glyph {\n /** Glyph rows as plain characters (escapes stripped), equal width. */\n lines: string[];\n /** Per-row, per-cell color state from embedded SGR escapes; absent\n * for uncolored glyphs. */\n colors?: CellColors[];\n width: number;\n}\n\nexport type HorizontalLayout = \"full\" | \"kerning\" | \"smush-universal\" | \"smush-controlled\";\n\nexport interface AsciiFont {\n height: number;\n baseline: number;\n hardblank: string;\n layout: HorizontalLayout;\n /** Controlled-smushing rule bits 1–6 (FIGfont spec), when layout is\n * smush-controlled. */\n rules: number;\n glyphs: Map<number, Glyph>;\n}\n\n/** The seven characters the spec appends after ASCII 32–126, by\n * position: Ä Ö Ü ä ö ü ß. */\nconst GERMAN_CODES = [196, 214, 220, 228, 246, 252, 223];\n\nconst CODE_TAG = /^\\s*(-?\\d+|-?0[xX][0-9a-fA-F]+|-?0[0-7]+)\\b/;\n\nexport function parseFont(data: string): AsciiFont {\n const lines = data.split(/\\r\\n|\\r|\\n/);\n const header = lines[0] ?? \"\";\n const magic = header.slice(0, 5);\n if (magic !== \"flf2a\" && magic !== \"tlf2a\") {\n throw new Error(`not a figlet/toilet font (magic \"${magic}\"; zipped fonts must be extracted)`);\n }\n const hardblank = header.charAt(5) || \"$\";\n const parts = header.slice(6).trim().split(/\\s+/).map(Number);\n const [height, baseline, , oldLayout, commentLines] = parts;\n const fullLayout = parts[6];\n if (!height || !Number.isFinite(height)) throw new Error(\"font header has no height\");\n\n const { layout, rules } = resolveLayout(oldLayout ?? -1, fullLayout);\n const glyphs = new Map<number, Glyph>();\n let at = 1 + (commentLines ?? 0);\n\n const readGlyph = (): Glyph | null => {\n if (at >= lines.length) return null;\n const raw = lines.slice(at, at + height);\n if (raw.length < height) return null;\n at += height;\n // TOIlet pads glyph lines with spaces AFTER the endmark — trim\n // before detecting (first line's last visible char) and stripping\n // the trailing endmark run.\n const first = raw[0]!.replace(/\\s+$/, \"\");\n const endmark = first.charAt(first.length - 1);\n const parsed = raw.map((line) => {\n const trimmed = line.replace(/\\s+$/, \"\");\n let end = trimmed.length;\n while (end > 0 && trimmed.charAt(end - 1) === endmark) end--;\n return parseSgrLine(trimmed.slice(0, end));\n });\n const width = Math.max(0, ...parsed.map((p) => p.chars.length));\n const glyphLines = parsed.map((p) => p.chars.padEnd(width, \" \"));\n const colored = parsed.some((p) => p.colors);\n const glyph: Glyph = { lines: glyphLines, width };\n if (colored) glyph.colors = parsed.map((p) => p.colors ?? []);\n return glyph;\n };\n\n for (let code = 32; code <= 126; code++) {\n const glyph = readGlyph();\n if (!glyph) throw new Error(`font ends inside required character ${code}`);\n glyphs.set(code, glyph);\n }\n // German block: present unless the next line is an explicit code tag\n // (some TLF fonts skip straight to tagged extras or end here).\n if (at < lines.length && lines[at]!.trim() !== \"\" && !CODE_TAG.test(lines[at]!)) {\n for (const code of GERMAN_CODES) {\n const glyph = readGlyph();\n if (!glyph) break;\n glyphs.set(code, glyph);\n }\n }\n // Code-tagged extras: a tag line (code + comment), then a glyph.\n while (at < lines.length) {\n const tag = lines[at]!;\n const match = CODE_TAG.exec(tag);\n if (!match) break;\n at++;\n const glyph = readGlyph();\n if (!glyph) break;\n const code = Number(match[1]);\n if (Number.isFinite(code) && code >= 0) glyphs.set(code, glyph);\n }\n\n return { height, baseline: baseline ?? height, hardblank, layout, rules, glyphs };\n}\n\n/** FIGfont spec layout resolution: `fullLayout` (when present) has\n * bit 6 = kerning, bit 7 = horizontal smushing, bits 0–5 = the\n * controlled rules; `oldLayout` alone is -1 full width, 0 kerning,\n * >0 controlled smushing with its bits as rules. */\nfunction resolveLayout(\n oldLayout: number,\n fullLayout: number | undefined,\n): { layout: HorizontalLayout; rules: number } {\n if (fullLayout !== undefined && Number.isFinite(fullLayout)) {\n if (fullLayout & 128) {\n const rules = fullLayout & 63;\n return rules > 0\n ? { layout: \"smush-controlled\", rules }\n : { layout: \"smush-universal\", rules: 0 };\n }\n if (fullLayout & 64) return { layout: \"kerning\", rules: 0 };\n return { layout: \"full\", rules: 0 };\n }\n if (oldLayout === -1) return { layout: \"full\", rules: 0 };\n if (oldLayout === 0) return { layout: \"kerning\", rules: 0 };\n return { layout: \"smush-controlled\", rules: oldLayout & 63 };\n}\n","/**\n * The font registry: `font` attribute values resolve here. Its own\n * module so generated font modules can import it without cycling\n * through the package entry.\n */\n\nimport { invalidateLeaves } from \"monowind\";\nimport { parseFont } from \"./font.ts\";\nimport type { AsciiFont } from \"./font.ts\";\n\nconst fonts = new Map<string, AsciiFont>();\n\nconst normalizeName = (name: string): string =>\n name\n .toLowerCase()\n .replace(/\\.(flf|tlf)$/, \"\")\n .trim();\n\n/** Register a font under a name (`font` attribute values resolve\n * here). Accepts raw `.flf`/`.tlf` text — the bring-your-own-file path\n * for fonts we don't redistribute. Last registration wins with a\n * warning; connected hosts relayout. */\nexport function registerAsciiFont(name: string, data: string): AsciiFont | null {\n const key = normalizeName(name);\n let font: AsciiFont;\n try {\n font = parseFont(data);\n } catch (err) {\n console.warn(`[monowind] registerAsciiFont(\"${name}\"): ${String(err)}`);\n return null;\n }\n if (fonts.has(key)) {\n console.warn(`[monowind] registerAsciiFont: replacing \"${key}\" (last registration wins).`);\n }\n fonts.set(key, font);\n invalidateLeaves();\n return font;\n}\n\nexport function asciiFont(name: string): AsciiFont | undefined {\n return fonts.get(normalizeName(name));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The font registry: `font` attribute values resolve here. Its own
|
|
3
|
+
* module so generated font modules can import it without cycling
|
|
4
|
+
* through the package entry.
|
|
5
|
+
*/
|
|
6
|
+
import type { AsciiFont } from "./font.ts";
|
|
7
|
+
/** Register a font under a name (`font` attribute values resolve
|
|
8
|
+
* here). Accepts raw `.flf`/`.tlf` text — the bring-your-own-file path
|
|
9
|
+
* for fonts we don't redistribute. Last registration wins with a
|
|
10
|
+
* warning; connected hosts relayout. */
|
|
11
|
+
export declare function registerAsciiFont(name: string, data: string): AsciiFont | null;
|
|
12
|
+
export declare function asciiFont(name: string): AsciiFont | undefined;
|
|
13
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C;;;wCAGwC;AACxC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAe9E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE7D"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Horizontal FIGlet composition: glyphs join under the font's own
|
|
3
|
+
* layout mode — full width, kerning, or smushing (universal, or
|
|
4
|
+
* controlled by the header's rule bits 1–6, per the FIGfont spec).
|
|
5
|
+
* Vertical smushing is out of scope (single-line banners). Per-cell
|
|
6
|
+
* color state from SGR-colored glyphs rides along and comes out as
|
|
7
|
+
* paint runs.
|
|
8
|
+
*/
|
|
9
|
+
import type { AsciiFont } from "./font.ts";
|
|
10
|
+
import type { LeafRun } from "monowind";
|
|
11
|
+
export interface RenderedAscii {
|
|
12
|
+
lines: string[];
|
|
13
|
+
runs: LeafRun[];
|
|
14
|
+
}
|
|
15
|
+
export declare function renderAscii(text: string, font: AsciiFont): RenderedAscii;
|
|
16
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAS,MAAM,WAAW,CAAC;AAElD,OAAO,KAAK,EAAa,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAOD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,aAAa,CAexE"}
|
package/dist/sgr.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SGR (ANSI color escape) extraction for TLF/ANSI-art glyph data: the
|
|
3
|
+
* escapes are stripped from the art and become per-cell paint. The
|
|
4
|
+
* 16-color palette maps to theme-aware tokens (`--mw-ansi-*`, defined
|
|
5
|
+
* with defaults in styles.css) so a font's "red" follows the theme;
|
|
6
|
+
* 256-color/true-color escapes pass through as literal CSS colors.
|
|
7
|
+
*/
|
|
8
|
+
export interface CellColor {
|
|
9
|
+
color?: string;
|
|
10
|
+
backgroundColor?: string;
|
|
11
|
+
bold?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Per-cell color state for one line; sparse (undefined = unstyled). */
|
|
14
|
+
export type CellColors = (CellColor | undefined)[];
|
|
15
|
+
/** Split one raw glyph line into plain characters and per-cell color
|
|
16
|
+
* state. Non-SGR escapes are dropped. Returns `colors` only when any
|
|
17
|
+
* cell is styled. */
|
|
18
|
+
export declare function parseSgrLine(raw: string): {
|
|
19
|
+
chars: string;
|
|
20
|
+
colors?: CellColors;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=sgr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sgr.d.ts","sourceRoot":"","sources":["../src/sgr.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,MAAM,UAAU,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC,EAAE,CAAC;AAwBnD;;qBAEqB;AACrB,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE,CAuBhF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Font licenses and attribution
|
|
2
|
+
|
|
3
|
+
Every font this package redistributes is listed here with its origin
|
|
4
|
+
and terms. Fonts whose terms are unclear are NOT shipped — bring your
|
|
5
|
+
own file via `registerAsciiFont(name, data)`.
|
|
6
|
+
|
|
7
|
+
- All `.flf` fonts (banner, big, block, bubble, digital, ivrit, lean,
|
|
8
|
+
mini, mnemonic, script, shadow, slant, small, smscript, smshadow,
|
|
9
|
+
smslant, standard, term) — from the FIGlet distribution
|
|
10
|
+
(https://github.com/cmatsuoka/figlet), © their authors (primarily
|
|
11
|
+
Glenn Chappell, with Ian Chai and contributors), distributed under
|
|
12
|
+
FIGlet's BSD-3-Clause license alongside the program.
|
|
13
|
+
- All `.tlf` fonts (ascii9/12, bigascii9/12, biggray9/12, bigmono9/12,
|
|
14
|
+
mono9/12, smascii9/12, smmono9/12, smblock, smbraille, bfraktur,
|
|
15
|
+
circle, emboss, emboss2, fauxcyrillic, fullcyrillic, future, letter,
|
|
16
|
+
pagga, wideterm) — from TOIlet (https://github.com/cacalabs/toilet),
|
|
17
|
+
© Sam Hocevar, WTFPL.
|