import { argumentNotEmptyString } from "../safe"; import { MapOf } from "../interfaces"; import { TraceSource, DebugLevel } from "../log/TraceSource"; import m = require("module"); const trace = TraceSource.get(m.id); const splitRx = /(<%=|<%~|\[%~|\[%=|<%|\[%|%\]|%>)/; export enum TokenType { None, Text, OpenInlineBlock, OpenFilterBlock, OpenBlock, CloseBlock } const tokenMap: MapOf = { "<%": TokenType.OpenBlock, "[%": TokenType.OpenBlock, "<%=": TokenType.OpenInlineBlock, "[%=": TokenType.OpenInlineBlock, "<%~": TokenType.OpenFilterBlock, "[%~": TokenType.OpenFilterBlock, "%>": TokenType.CloseBlock, "%]": TokenType.CloseBlock }; export interface ITemplateParser { next(): boolean; token(): TokenType; value(): string; } export class TemplateParser implements ITemplateParser { _tokens: string[]; _pos = -1; _type: TokenType; _value: string | undefined; constructor(text: string) { argumentNotEmptyString(text, "text"); this._tokens = text.split(splitRx); this._type = TokenType.None; } next() { this._pos++; if (this._pos < this._tokens.length) { this._value = this._tokens[this._pos]; this._type = tokenMap[this._value] || TokenType.Text; return true; } else { this._type = TokenType.None; this._value = undefined; return false; } } token() { return this._type; } value() { if (!this._value) throw new Error("The current token doesn't have a value"); return this._value; } }