minor fixes and code cleanup
This commit is contained in:
parent
eca7c619e5
commit
302c7cbd0f
6 changed files with 66 additions and 102 deletions
|
@ -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 {
|
||||||
|
|
138
src/parser.ts
138
src/parser.ts
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<ul>
|
<ul>
|
||||||
|
{% set seq +%}
|
||||||
{%-for item in seq -%}
|
{%-for item in seq -%}
|
||||||
<li>{{ item}}</li>
|
<li>{{ item}}</li>
|
||||||
{%- endfor%}
|
{%- endfor%}
|
||||||
|
|
Loading…
Reference in a new issue