UNPKG

xweb-templating

Version:

A cli tool for converting 'tags' to regular html, php or some other format

130 lines (111 loc) 4.11 kB
import { workerData, parentPort } from "worker_threads"; import requireFromString from "require-from-string"; import { error } from "../log.js"; const CONFIG = workerData.CONFIG; // Import all the tags const TAG_MODULES = []; for (const TAG of workerData.tags) { TAG_MODULES.push(requireFromString(TAG)); } type ConverStatus = { ignore_next_char_command: boolean } type TagConverter = { from: string, to(...paramaters: string[]): string } function find_tag_converter(tag_name: string, TAG_SETS: TagConverter[][]): TagConverter | undefined { for (const TAG_SET of TAG_SETS) { for (const TAG of TAG_SET) { if (TAG.from == tag_name) return TAG; } } error("run/convert", `Could not find tag named '${tag_name}'`); return undefined; } function seperate_arguments(argument_str: string, seperator: string): string[] { let nest_level = 1; const PARAMATERS: string[] = [""]; for (const CHAR of argument_str) { if (CHAR == "(") { nest_level++; } else if (CHAR == ")") { nest_level--; } if (CHAR == seperator && nest_level == 1) { PARAMATERS.push(""); continue; } PARAMATERS[PARAMATERS.length - 1] += CHAR; } return PARAMATERS.map(paramater => paramater.trim()); } function find_arguments_string(str: string, start: number): string { if (str[start] != "(") return ""; let nest_level = 1; let scan_position = start + 1; let content = "("; let is_inside_string = false; while (scan_position < str.length && nest_level > 0) { if (str[scan_position] == "\"") { is_inside_string = !is_inside_string; } if (!is_inside_string) { if (str[scan_position] == "(") { nest_level++; } else if (str[scan_position] == ")") { nest_level--; } } content += str[scan_position]; scan_position++; } return content; } let OUTPUT = ""; const STATUS: ConverStatus = { ignore_next_char_command: false }; const CONTENT = workerData.content; for (let char_index = 0; char_index < CONTENT.length; char_index++) { if (STATUS.ignore_next_char_command) { STATUS.ignore_next_char_command = false; OUTPUT += CONTENT[char_index]; continue; } if (CONTENT[char_index] == "\\") { STATUS.ignore_next_char_command = true; continue; } if (workerData.CONFIG.use.tags && CONTENT[char_index] == "@") { const TAG_START = CONTENT .slice(char_index, CONTENT.length) .match(/^@[A-Za-z0-9\-_$.]*/)[0]; const TAG_NAME = TAG_START.slice(1, TAG_START.length); const TAG_ARGUMENTS_STRING = find_arguments_string(CONTENT, char_index + TAG_START.length); const TAG_ARGUMENTS = seperate_arguments(TAG_ARGUMENTS_STRING.slice(1, -1), ","); OUTPUT += find_tag_converter(TAG_NAME, TAG_MODULES)?.to(...TAG_ARGUMENTS); char_index += TAG_START.length + TAG_ARGUMENTS_STRING.length - 1; continue; } if (workerData.CONFIG.use.inline && CONTENT.slice(char_index, char_index + CONFIG.inline.from.start.length) == CONFIG.inline.from.start) { let content = ""; let nest_level = 1; let index = char_index + CONFIG.inline.from.start.length; while (index < CONTENT.length && !(nest_level > 0 && CONTENT.slice(index, index + CONFIG.inline.from.end.length) == CONFIG.inline.from.end)) { content += CONTENT[index]; if (CONTENT[index] == "{" || CONTENT[index] == "(") { nest_level++; } if (CONTENT[index] == "}" || CONTENT[index] == ")") { nest_level--; } index++; } OUTPUT += CONFIG.inline.to.start + content + CONFIG.inline.to.end; char_index += CONFIG.inline.from.start.length + content.length + CONFIG.inline.from.end.length - 1; continue; } OUTPUT += CONTENT[char_index]; } parentPort?.postMessage(OUTPUT);