core/converters/template.converter.ts
core/converters/template.converter.ts is a file in Bane's Lab Site. 46 lines of code and 15 definitions.
import {
BINDING_ASSIGN,
BINDING_HEAD,
HOLE_CLOSE,
HOLE_OPEN,
QUOTE_MARKS,
} from "#configuration/constants/anatomy.constants";
import type { TemplateParts } from "#types/code.types";
export const templatePartsOf = function templatePartsOf(text: string): TemplateParts | null {
if (!text.includes(HOLE_OPEN)) {
return null;
}
const holes: string[] = [];
const literals: string[] = [];
let at = 0;
let open = text.indexOf(HOLE_OPEN);
let close = open === -1 ? -1 : text.indexOf(HOLE_CLOSE, open + HOLE_OPEN.length);
while (open !== -1 && close !== -1) {
literals.push(text.slice(at, open));
holes.push(text.slice(open + HOLE_OPEN.length, close).trim());
at = close + HOLE_CLOSE.length;
open = text.indexOf(HOLE_OPEN, at);
close = open === -1 ? -1 : text.indexOf(HOLE_CLOSE, open + HOLE_OPEN.length);
}
literals.push(text.slice(at));
return { holes, literals };
};
const bindingValueOf = function bindingValueOf(source: string, name: string): string | null {
const head = BINDING_HEAD + name + BINDING_ASSIGN;
const start = source.indexOf(head);
const quote = start === -1 ? "" : source.charAt(start + head.length);
if (quote.length === 0 || !QUOTE_MARKS.includes(quote)) {
return null;
}
const valueStart = start + head.length + quote.length;
const end = source.indexOf(quote, valueStart);
const value = end === -1 ? "" : source.slice(valueStart, end);
return value.length === 0 || value.includes(HOLE_OPEN) ? null : value;
};
export const foldedOf = function foldedOf(parts: TemplateParts, source: string): string | null {
const values = parts.holes.map((hole) => bindingValueOf(source, hole));
if (values.some((value) => value === null)) {
return null;
}
return parts.literals.map((literal, at) => literal + (values.at(at) ?? "")).join("");
};