minor fixes and code cleanup

This commit is contained in:
davidodenwald 2022-11-21 14:38:11 +01:00
parent eca7c619e5
commit 302c7cbd0f
6 changed files with 66 additions and 102 deletions

View file

@ -23,8 +23,7 @@ export type Delimiter = "" | "-" | "+";
export interface Statement extends Node { export interface Statement extends Node {
type: "statement"; type: "statement";
keyword: Keyword; keyword: Keyword;
startDelimiter: Delimiter; delimiter: Delimiter;
endDelimiter: Delimiter;
} }
export interface Block extends Node { export interface Block extends Node {

View file

@ -32,103 +32,82 @@ export const parse: Parser<Node>["parse"] = (text) => {
let match; let match;
let i = 0; let i = 0;
while ((match = root.content.slice(i).match(regex)) !== null) { while ((match = text.slice(i).match(regex)) !== null) {
if (!match.groups || match.index === undefined) { if (!match.groups || match.index === undefined) {
continue; continue;
} }
const matchLength = match[0].length;
// skip script and style blocks
if (match.groups.scriptBlock || match.groups.styleBlock) { if (match.groups.scriptBlock || match.groups.styleBlock) {
i += match.index + match[0].length; i += match.index + matchLength;
continue; continue;
} }
const pre = match.groups.pre || ""; const pre = match.groups.pre || "";
const newline = !!match.groups.newline; const newline = !!match.groups.newline;
const node = match.groups.node; const matchText = match.groups.node;
const expression = match.groups.expression; const expression = match.groups.expression;
const statement = match.groups.statement; const statement = match.groups.statement;
const ignoreBlock = match.groups.ignoreBlock; const ignoreBlock = match.groups.ignoreBlock;
const comment = match.groups.comment; const comment = match.groups.comment;
if (!node && !expression && !statement && !ignoreBlock && !comment) { if (!matchText && !expression && !statement && !ignoreBlock && !comment) {
continue; continue;
} }
const matchText = node;
if (ignoreBlock || comment) {
const placeholder = generatePlaceholder(); const placeholder = generatePlaceholder();
root.content = root.content.replace(matchText, placeholder);
root.nodes[placeholder] = { const node = {
id: placeholder, id: placeholder,
type: "ignore",
content: ignoreBlock || comment,
ownLine: newline, ownLine: newline,
originalText: matchText, originalText: matchText,
index: match.index + i + pre.length, index: match.index + i + pre.length,
length: matchText.length, length: matchText.length,
nodes: root.nodes, nodes: root.nodes,
} as IgnoreBlock; };
i += match.index;
if (ignoreBlock || comment) {
root.content = root.content.replace(matchText, placeholder);
root.nodes[node.id] = {
...node,
type: "ignore",
content: ignoreBlock || comment,
};
} }
if (expression) { if (expression) {
const placeholder = generatePlaceholder();
root.content = root.content.replace(matchText, placeholder); root.content = root.content.replace(matchText, placeholder);
root.nodes[node.id] = {
root.nodes[placeholder] = { ...node,
id: placeholder,
type: "expression", type: "expression",
content: expression, content: expression,
ownLine: newline, };
originalText: matchText,
index: match.index + i + pre.length,
length: matchText.length,
nodes: root.nodes,
} as Expression;
i += match.index;
} }
if (statement) { if (statement) {
const keyword = match.groups.keyword as Keyword; const keyword = match.groups.keyword as Keyword;
const startDelimiter = match.groups.startDelimiter as Delimiter; const delimiter = (match.groups.startDelimiter ||
const endDelimiter = match.groups.endDelimiter as Delimiter; match.groups.endDelimiter) as Delimiter;
if (nonClosingStatements.includes(keyword)) { if (nonClosingStatements.includes(keyword)) {
const placeholder = generatePlaceholder();
root.content = root.content.replace(matchText, placeholder); root.content = root.content.replace(matchText, placeholder);
root.nodes[placeholder] = { root.nodes[node.id] = {
id: placeholder, ...node,
type: "statement", type: "statement",
content: statement, content: statement,
ownLine: newline,
originalText: matchText,
index: match.index + i + pre.length,
length: matchText.length,
keyword, keyword,
startDelimiter, delimiter,
endDelimiter,
nodes: root.nodes,
} as Statement; } as Statement;
i += match.index;
} else if (!keyword.startsWith("end")) { } else if (!keyword.startsWith("end")) {
statementStack.push({ root.nodes[node.id] = {
id: generatePlaceholder(), ...node,
type: "statement" as const, type: "statement",
content: statement, content: statement,
ownLine: newline,
originalText: matchText,
index: match.index + i + pre.length,
length: matchText.length,
keyword, keyword,
startDelimiter, delimiter,
endDelimiter, } as Statement;
nodes: root.nodes, statementStack.push(root.nodes[placeholder] as Statement);
});
i += match.index + matchText.length;
} else { } else {
let start: Statement | undefined; let start: Statement | undefined;
while (!start) { while (!start) {
@ -143,6 +122,7 @@ export const parse: Parser<Node>["parse"] = (text) => {
const startKeyword = keyword.replace("end", ""); const startKeyword = keyword.replace("end", "");
if (startKeyword !== start.keyword) { if (startKeyword !== start.keyword) {
if (start.keyword === "set") { if (start.keyword === "set") {
root.content = root.content.replace(start.originalText, start.id);
start = undefined; start = undefined;
continue; continue;
} }
@ -154,59 +134,49 @@ export const parse: Parser<Node>["parse"] = (text) => {
} }
const end = { const end = {
id: generatePlaceholder(), ...node,
type: "statement" as const, type: "statement",
content: statement, content: statement,
ownLine: newline,
originalText: matchText,
index: match.index + i + pre.length,
length: matchText.length,
keyword, keyword,
startDelimiter, delimiter,
endDelimiter, } as Statement;
nodes: root.nodes, root.nodes[end.id] = end;
};
const placeholder = generatePlaceholder(); const blockText = root.content.slice(
const content = root.content.slice( root.content.indexOf(start.originalText),
start.index + start.length, root.content.indexOf(end.originalText) + end.length
end.index
); );
root.nodes[placeholder] = { const block = {
id: placeholder, id: generatePlaceholder(),
type: "block", type: "block",
start: start, start: start,
end: end, end: end,
content, content: blockText.slice(start.length, blockText.length - end.length),
ownLine: newline, ownLine: newline,
originalText: matchText, originalText: text.slice(start.index, end.index + end.length),
index: start.index, index: start.index,
length: end.index + end.length - start.index, length: end.index + end.length - start.index,
nodes: root.nodes, nodes: root.nodes,
} as Block; } as Block;
root.nodes[block.id] = block;
root.nodes[start.id] = start; root.content = root.content.replace(blockText, block.id);
root.nodes[end.id] = end;
root.content =
root.content.slice(0, start.index) +
placeholder +
root.content.slice(end.index + end.length, root.content.length);
i = start.index + placeholder.length;
} }
} }
i += match.index + matchLength;
} }
const remainingStatement = statementStack.find( for (const stmt of statementStack) {
(stmt) => stmt.keyword !== "set" if (stmt.keyword === "set") {
); root.content = root.content.replace(stmt.originalText, stmt.id);
if (remainingStatement) { } else {
throw new Error( throw new Error(
`No closing statement found for opening statement "${remainingStatement.content}".` `No closing statement found for opening statement "${stmt.content}".`
); );
} }
}
return root; return root;
}; };

View file

@ -38,15 +38,7 @@ const printExpression = (node: Expression): builders.Doc => {
const printStatement = (node: Statement): builders.Doc => { const printStatement = (node: Statement): builders.Doc => {
const statemnt = builders.group( const statemnt = builders.group(
[ ["{%", node.delimiter, " ", node.content, " ", node.delimiter, "%}"],
"{%",
node.startDelimiter,
" ",
node.content,
" ",
node.endDelimiter,
"%}",
],
{ shouldBreak: node.ownLine } { shouldBreak: node.ownLine }
); );
@ -99,6 +91,7 @@ export const embed: Printer<Node>["embed"] = (
([start, end]) => currentDoc.slice(start, end + 1) in node.nodes ([start, end]) => currentDoc.slice(start, end + 1) in node.nodes
); );
if (!idxs.length) { if (!idxs.length) {
ignoreDoc = false;
return currentDoc; return currentDoc;
} }

View file

@ -1,5 +1,6 @@
<ul> <ul>
{%+ set seq +%}
{%- for item in seq -%} {%- for item in seq -%}
<li>{{ item }}</li> <li>{{ item }}</li>
{%- endfor %} {%- endfor -%}
</ul> </ul>

View file

@ -1,4 +1,5 @@
<ul> <ul>
{% set seq +%}
{%-for item in seq -%} {%-for item in seq -%}
<li>{{ item}}</li> <li>{{ item}}</li>
{%- endfor%} {%- endfor%}