Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 14x 14x 662x 211x 211x 211x 451x 451x 181x 32x 451x 28x 28x 28x 423x 423x 423x 14x 80x 80x 8x 80x 80x 651x 651x 651x 656x 30x 626x 651x 80x 14x 5x 5x 5x 5x 9x 3x 3x 2x 3x 3x 6x 6x 6x 6x 6x 5x | import { lexText, Token } from "shared/lib/compiler/lexText";
export interface FontData {
id: string;
img: HTMLImageElement;
isMono: boolean;
widths: number[];
mapping: Record<string, number | number[]>;
table: number[];
}
export const resolveMapping = (
input: string,
mapping?: Record<string, number | number[]>,
): { codes: number[]; length: number } => {
if (!mapping) {
const code = input.codePointAt(0) ?? 0;
const length = code > 0xffff ? 2 : 1;
return { codes: [code], length };
}
let longestMatch = "";
for (const key of Object.keys(mapping)) {
if (input.startsWith(key) && key.length > longestMatch.length) {
longestMatch = key;
}
}
if (longestMatch) {
const raw = mapping[longestMatch];
const codes = Array.isArray(raw) ? raw : [raw];
return { codes, length: longestMatch.length };
}
const code = input.codePointAt(0) ?? 0;
const length = code > 0xffff ? 2 : 1;
return { codes: [code], length };
};
export const encodeString = (
inStr: string,
mapping?: Record<string, number | number[]>,
): string => {
let output = "";
const decodedStr = inStr
.replace(/\\([0-7]{3})/g, (_, oct) => String.fromCharCode(parseInt(oct, 8)))
.replace(/\\x([0-9A-Fa-f]+)/g, (_, hex) =>
String.fromCharCode(parseInt(hex, 16)),
);
let i = 0;
while (i < decodedStr.length) {
const slice = decodedStr.slice(i);
const { codes, length } = resolveMapping(slice, mapping);
for (const code of codes) {
if (code < 32 || code > 127 || code === 34) {
output += "\\" + (code & 0xff).toString(8).padStart(3, "0");
} else {
output += String.fromCharCode(code);
}
}
i += length;
}
return output;
};
export const lexTextWithMapping = (
text: string,
fontsData: Record<string, FontData>,
fontId: string,
preferPreviewValue?: boolean,
): Token[] => {
const rawTokens = lexText(text);
const result: Token[] = [];
let font = fontsData[fontId];
for (const token of rawTokens) {
if (token.type === "font") {
const newFont = fontsData[token.fontId];
if (newFont) {
font = newFont;
}
result.push(token);
continue;
}
if (token.type === "text") {
const value =
preferPreviewValue && token.previewValue !== undefined
? token.previewValue
: token.value;
const encoded = encodeString(value, font?.mapping);
const encodedTokens = lexText(encoded);
result.push(...encodedTokens);
} else E{
result.push(token);
}
}
return result;
};
|