@lucidkiln/core 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/{ast-1akLiy-A.d.ts → ast-DDhHuwaY.d.ts} +15 -22
- package/dist/ast-DDhHuwaY.d.ts.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{environment-DkfrPazl.d.ts → environment-DBvRrOn0.d.ts} +15 -8
- package/dist/environment-DBvRrOn0.d.ts.map +1 -0
- package/dist/{format-CLCViAPn.js → format-Di6-GUtH.js} +4 -4
- package/dist/{format-CLCViAPn.js.map → format-Di6-GUtH.js.map} +1 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +50 -147
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/{parser-BU5dThuk.js → parser-isboTef0.js} +59 -99
- package/dist/parser-isboTef0.js.map +1 -0
- package/dist/{source-BHcxowQp.js → source-BbikGqIb.js} +25 -97
- package/dist/source-BbikGqIb.js.map +1 -0
- package/dist/syntax.d.ts +1 -1
- package/dist/syntax.js +1 -1
- package/package.json +1 -1
- package/dist/ast-1akLiy-A.d.ts.map +0 -1
- package/dist/environment-DkfrPazl.d.ts.map +0 -1
- package/dist/parser-BU5dThuk.js.map +0 -1
- package/dist/source-BHcxowQp.js.map +0 -1
package/dist/node.d.ts
CHANGED
|
@@ -152,26 +152,14 @@ var Lexer = class {
|
|
|
152
152
|
const standalone = applyStandaloneLines(this.#text, parts);
|
|
153
153
|
const lines = textLines(this.#text, parts, standalone);
|
|
154
154
|
const tokens = [];
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const text = part.kind === "text";
|
|
158
|
-
const at = text ? part.from : part.start;
|
|
159
|
-
if (text && part.from < part.to) tokens.push({
|
|
155
|
+
for (const part of parts) if (part.kind === "text") {
|
|
156
|
+
if (part.from < part.to) tokens.push({
|
|
160
157
|
type: "text",
|
|
161
158
|
value: this.#text.slice(part.from, part.to),
|
|
162
159
|
start: part.from,
|
|
163
160
|
end: part.to
|
|
164
161
|
});
|
|
165
|
-
|
|
166
|
-
type: "text",
|
|
167
|
-
value: "",
|
|
168
|
-
start: at,
|
|
169
|
-
end: at
|
|
170
|
-
});
|
|
171
|
-
if (!text && part.kind !== "comment") for (const token of part.tokens) tokens.push(token);
|
|
172
|
-
const end = text ? part.to : part.start;
|
|
173
|
-
while ((lines[line]?.start ?? Infinity) <= end) line++;
|
|
174
|
-
}
|
|
162
|
+
} else if (part.kind !== "comment") for (const token of part.tokens) tokens.push(token);
|
|
175
163
|
tokens.push({
|
|
176
164
|
type: "eof",
|
|
177
165
|
value: "",
|
|
@@ -701,9 +689,6 @@ const textLines = (text, parts, removed) => {
|
|
|
701
689
|
indentEnd
|
|
702
690
|
});
|
|
703
691
|
};
|
|
704
|
-
const first = parts[0];
|
|
705
|
-
const start = contentStart(text);
|
|
706
|
-
if (first && (first.kind !== "text" || first.from === start)) add(start);
|
|
707
692
|
for (const part of parts) {
|
|
708
693
|
if (part.kind !== "text") continue;
|
|
709
694
|
for (let newline = newlineIn(text, part.start, part.end); newline !== -1; newline = newlineIn(text, newline + 1, part.end)) {
|
|
@@ -718,11 +703,10 @@ const textLines = (text, parts, removed) => {
|
|
|
718
703
|
//#region src/parser/indent.ts
|
|
719
704
|
/** The bodies a statement holds. Branches share their tag's body. A component's fills are bodies of their own, inside the component's. */
|
|
720
705
|
const bodiesOf = (node) => {
|
|
721
|
-
const own = (lists
|
|
706
|
+
const own = (lists) => ({
|
|
722
707
|
open: node.span.start,
|
|
723
708
|
end: node.span.end,
|
|
724
|
-
lists
|
|
725
|
-
full
|
|
709
|
+
lists
|
|
726
710
|
});
|
|
727
711
|
switch (node.type) {
|
|
728
712
|
case "If": return [own([...node.branches.map((branch) => branch.body), node.alternate ?? []])];
|
|
@@ -730,16 +714,15 @@ const bodiesOf = (node) => {
|
|
|
730
714
|
case "Component": return [...node.fills.map((fill) => ({
|
|
731
715
|
open: fill.span.start,
|
|
732
716
|
end: fill.span.end,
|
|
733
|
-
lists: [fill.body]
|
|
734
|
-
|
|
735
|
-
})), own([node.body, ...node.fills.map((fill) => fill.body)], true)];
|
|
717
|
+
lists: [fill.body]
|
|
718
|
+
})), own([node.body, ...node.fills.map((fill) => fill.body)])];
|
|
736
719
|
case "Island": return [{
|
|
737
720
|
...own([node.body]),
|
|
738
721
|
keep: true
|
|
739
722
|
}];
|
|
740
723
|
case "Block":
|
|
741
724
|
case "Slot":
|
|
742
|
-
case "Add":
|
|
725
|
+
case "Add":
|
|
743
726
|
case "SetBlock":
|
|
744
727
|
case "Macro":
|
|
745
728
|
case "Cache":
|
|
@@ -797,15 +780,16 @@ const preformatted = (text, textTokens) => {
|
|
|
797
780
|
return ranges;
|
|
798
781
|
};
|
|
799
782
|
/**
|
|
800
|
-
*
|
|
783
|
+
* Removes the extra indentation inside tags that stand on their own line: the spaces and tabs that every content line
|
|
784
|
+
* inside shares, beyond the tag's own indentation. It happens when compiling, so rendering is no slower.
|
|
801
785
|
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
* - Sets `lines` on text nodes: where each line of text starts, to take the indentation of where the text is inserted.
|
|
786
|
+
* Also sets the indentation of `islands` whose tags stand on lines of their own, since a deferred island writes its
|
|
787
|
+
* tags back as `<kiln-island>` lines. See `IslandStatement`.
|
|
805
788
|
*
|
|
806
|
-
* Lines inside `<pre>` and `<textarea>` keep their whitespace. Amounts come from the source alone, so nested tags each
|
|
789
|
+
* Lines inside `<pre>` and `<textarea>` keep their whitespace. Amounts come from the source alone, so nested tags each
|
|
790
|
+
* remove their own step whatever order they are visited in. Then the text nodes holding those offsets are rebuilt.
|
|
807
791
|
*/
|
|
808
|
-
const
|
|
792
|
+
const removeIndentation = (ast, text, { tokens, standalone, lines }, islands) => {
|
|
809
793
|
const textTokens = tokens.filter((token) => token.type === "text");
|
|
810
794
|
const pre = preformatted(text, textTokens);
|
|
811
795
|
const inPre = (offset) => {
|
|
@@ -823,28 +807,19 @@ const arrangeIndentation = (ast, text, { tokens, standalone, lines }, placedNode
|
|
|
823
807
|
indentEnd
|
|
824
808
|
};
|
|
825
809
|
};
|
|
826
|
-
const
|
|
827
|
-
const
|
|
828
|
-
for (const node of placedNodes) {
|
|
810
|
+
const islandLines = [];
|
|
811
|
+
for (const node of islands) {
|
|
829
812
|
if (inPre(node.span.start)) continue;
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
line: lineOf(end)
|
|
835
|
-
});
|
|
836
|
-
}
|
|
837
|
-
if (!standalone.has(node.span.start)) continue;
|
|
838
|
-
placed.push({
|
|
813
|
+
const end = text.lastIndexOf("{%", node.span.end - 1);
|
|
814
|
+
const open = standalone.has(node.span.start) ? lineOf(node.span.start) : null;
|
|
815
|
+
const close = standalone.has(end) ? lineOf(end) : null;
|
|
816
|
+
if (open || close) islandLines.push({
|
|
839
817
|
node,
|
|
840
|
-
|
|
818
|
+
open,
|
|
819
|
+
end: close
|
|
841
820
|
});
|
|
842
821
|
}
|
|
843
|
-
const contentLines =
|
|
844
|
-
...textLines,
|
|
845
|
-
...placed.map((item) => item.line),
|
|
846
|
-
...islandEnds.map((item) => item.line)
|
|
847
|
-
].sort((a, b) => a.start - b.start) : textLines;
|
|
822
|
+
const contentLines = islandLines.length > 0 ? [...textLines, ...islandLines.flatMap((item) => [item.open, item.end].filter((line) => line !== null))].sort((a, b) => a.start - b.start) : textLines;
|
|
848
823
|
const cuts = [];
|
|
849
824
|
const indentOf = (offset) => {
|
|
850
825
|
const line = lineOf(offset);
|
|
@@ -860,6 +835,7 @@ const arrangeIndentation = (ast, text, { tokens, standalone, lines }, placedNode
|
|
|
860
835
|
const first = firstAtLeast(contentLines, newline + 1, (line) => line.start);
|
|
861
836
|
const last = firstAtLeast(contentLines, to, (line) => line.start);
|
|
862
837
|
if (first >= last) return;
|
|
838
|
+
const own = indentOf(body.open);
|
|
863
839
|
let shared = Infinity;
|
|
864
840
|
const firstLine = contentLines[first];
|
|
865
841
|
for (let i = first; i < last; i++) {
|
|
@@ -868,16 +844,11 @@ const arrangeIndentation = (ast, text, { tokens, standalone, lines }, placedNode
|
|
|
868
844
|
while (length < line.indentEnd - line.start && text[line.start + length] === text[firstLine.start + length]) length++;
|
|
869
845
|
shared = Math.min(shared, length);
|
|
870
846
|
}
|
|
871
|
-
|
|
872
|
-
if (
|
|
873
|
-
const own = indentOf(body.open);
|
|
874
|
-
if (shared <= own.length) return;
|
|
875
|
-
if (text.slice(firstLine.start, firstLine.start + own.length) !== own) return;
|
|
876
|
-
keep = own.length;
|
|
877
|
-
} else if (shared === 0) return;
|
|
847
|
+
if (shared <= own.length) return;
|
|
848
|
+
if (text.slice(firstLine.start, firstLine.start + own.length) !== own) return;
|
|
878
849
|
for (let i = first; i < last; i++) {
|
|
879
850
|
const line = contentLines[i];
|
|
880
|
-
cuts.push([line.start +
|
|
851
|
+
cuts.push([line.start + own.length, line.start + shared]);
|
|
881
852
|
}
|
|
882
853
|
};
|
|
883
854
|
const visit = (list) => {
|
|
@@ -908,37 +879,28 @@ const arrangeIndentation = (ast, text, { tokens, standalone, lines }, placedNode
|
|
|
908
879
|
}
|
|
909
880
|
return out + text.slice(Math.min(at, end), end);
|
|
910
881
|
};
|
|
911
|
-
for (const { node,
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
882
|
+
for (const { node, open, end } of islandLines) {
|
|
883
|
+
if (open) node.indent = uncut(open.start, open.indentEnd);
|
|
884
|
+
if (end) node.closing = {
|
|
885
|
+
indent: open !== null && end.start === open.start ? null : uncut(end.start, end.indentEnd),
|
|
886
|
+
newline: text.includes("\n", node.span.end)
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
if (merged.length === 0) return;
|
|
916
890
|
const hasCut = (start, end) => {
|
|
917
891
|
const range = merged[firstAtLeast(merged, start, (range) => range[1] - 1)];
|
|
918
892
|
return range !== void 0 && range[0] < end;
|
|
919
893
|
};
|
|
920
894
|
const rewrite = (list) => {
|
|
921
895
|
for (const node of list) {
|
|
922
|
-
if (node.type === "Text") {
|
|
923
|
-
let line = firstAtLeast(textLines, node.span.start, (l) => l.start);
|
|
924
|
-
const hasLines = (textLines[line]?.start ?? Infinity) <= node.span.end;
|
|
925
|
-
const cut = hasCut(node.span.start, node.span.end);
|
|
926
|
-
if (!hasLines && !cut) continue;
|
|
896
|
+
if (node.type === "Text" && hasCut(node.span.start, node.span.end)) {
|
|
927
897
|
let value = "";
|
|
928
|
-
let size = 0;
|
|
929
|
-
const starts = [];
|
|
930
898
|
for (let i = firstAtLeast(textTokens, node.span.start, (t) => t.start); i < textTokens.length; i++) {
|
|
931
899
|
const token = textTokens[i];
|
|
932
900
|
if (token.end > node.span.end) break;
|
|
933
|
-
|
|
934
|
-
if (cut) {
|
|
935
|
-
const piece = uncut(token.start, token.end);
|
|
936
|
-
value += piece;
|
|
937
|
-
size += piece.length;
|
|
938
|
-
} else size += token.end - token.start;
|
|
901
|
+
value += uncut(token.start, token.end);
|
|
939
902
|
}
|
|
940
|
-
|
|
941
|
-
if (starts.length > 0) node.lines = starts;
|
|
903
|
+
node.value = value;
|
|
942
904
|
}
|
|
943
905
|
const bodies = bodiesOf(node);
|
|
944
906
|
if (bodies.length > 0) for (const child of childLists(bodies)) rewrite(child);
|
|
@@ -967,7 +929,7 @@ const parse = (text, options) => {
|
|
|
967
929
|
const lexed = lex(text);
|
|
968
930
|
const parser = new Parser(lexed.tokens, options);
|
|
969
931
|
const ast = parser.parseTemplate(text.length);
|
|
970
|
-
|
|
932
|
+
removeIndentation(ast, text, lexed, parser.islands);
|
|
971
933
|
return {
|
|
972
934
|
ast,
|
|
973
935
|
problems: [...lexed.problems, ...parser.problems]
|
|
@@ -1018,8 +980,8 @@ const describeToken = (token) => {
|
|
|
1018
980
|
};
|
|
1019
981
|
var Parser = class {
|
|
1020
982
|
problems = [];
|
|
1021
|
-
/** Every
|
|
1022
|
-
|
|
983
|
+
/** Every island, for `removeIndentation`. */
|
|
984
|
+
islands = [];
|
|
1023
985
|
#tokens;
|
|
1024
986
|
#options;
|
|
1025
987
|
#index = 0;
|
|
@@ -1275,14 +1237,14 @@ var Parser = class {
|
|
|
1275
1237
|
case "outlet": {
|
|
1276
1238
|
const name = this.#parseStringLiteral("an outlet name");
|
|
1277
1239
|
const close = this.#expectTagEnd();
|
|
1278
|
-
return
|
|
1240
|
+
return {
|
|
1279
1241
|
type: "Outlet",
|
|
1280
1242
|
name,
|
|
1281
1243
|
span: {
|
|
1282
1244
|
start: open.start,
|
|
1283
1245
|
end: close.end
|
|
1284
1246
|
}
|
|
1285
|
-
}
|
|
1247
|
+
};
|
|
1286
1248
|
}
|
|
1287
1249
|
case "flush": {
|
|
1288
1250
|
const close = this.#expectTagEnd();
|
|
@@ -1593,7 +1555,7 @@ var Parser = class {
|
|
|
1593
1555
|
if (this.#peek().type !== "tagClose") {
|
|
1594
1556
|
const expression = this.#parseExpression();
|
|
1595
1557
|
const close = this.#expectTagEnd();
|
|
1596
|
-
return
|
|
1558
|
+
return {
|
|
1597
1559
|
type: "Block",
|
|
1598
1560
|
name,
|
|
1599
1561
|
body: [{
|
|
@@ -1608,13 +1570,13 @@ var Parser = class {
|
|
|
1608
1570
|
start: open.start,
|
|
1609
1571
|
end: close.end
|
|
1610
1572
|
}
|
|
1611
|
-
}
|
|
1573
|
+
};
|
|
1612
1574
|
}
|
|
1613
1575
|
this.#expectTagEnd();
|
|
1614
1576
|
const { body, end } = this.#parseBody(["endblock"]);
|
|
1615
1577
|
if (end) this.#finishEndTag(name);
|
|
1616
1578
|
else this.#unclosed("block", open, "endblock");
|
|
1617
|
-
return
|
|
1579
|
+
return {
|
|
1618
1580
|
type: "Block",
|
|
1619
1581
|
name,
|
|
1620
1582
|
body,
|
|
@@ -1622,7 +1584,7 @@ var Parser = class {
|
|
|
1622
1584
|
start: open.start,
|
|
1623
1585
|
end: this.#lastEnd
|
|
1624
1586
|
}
|
|
1625
|
-
}
|
|
1587
|
+
};
|
|
1626
1588
|
}
|
|
1627
1589
|
#parseInclude(open) {
|
|
1628
1590
|
const template = this.#parseExpression();
|
|
@@ -1638,7 +1600,7 @@ var Parser = class {
|
|
|
1638
1600
|
ignoreMissing = true;
|
|
1639
1601
|
}
|
|
1640
1602
|
const close = this.#expectTagEnd();
|
|
1641
|
-
return
|
|
1603
|
+
return {
|
|
1642
1604
|
type: "Include",
|
|
1643
1605
|
template,
|
|
1644
1606
|
with: withValue,
|
|
@@ -1647,7 +1609,7 @@ var Parser = class {
|
|
|
1647
1609
|
start: open.start,
|
|
1648
1610
|
end: close.end
|
|
1649
1611
|
}
|
|
1650
|
-
}
|
|
1612
|
+
};
|
|
1651
1613
|
}
|
|
1652
1614
|
#parseComponent(open) {
|
|
1653
1615
|
const header = this.#header(() => {
|
|
@@ -1696,7 +1658,7 @@ var Parser = class {
|
|
|
1696
1658
|
}
|
|
1697
1659
|
});
|
|
1698
1660
|
}
|
|
1699
|
-
return
|
|
1661
|
+
return {
|
|
1700
1662
|
type: "Component",
|
|
1701
1663
|
...header,
|
|
1702
1664
|
fills,
|
|
@@ -1705,11 +1667,7 @@ var Parser = class {
|
|
|
1705
1667
|
start: open.start,
|
|
1706
1668
|
end: this.#lastEnd
|
|
1707
1669
|
}
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
#placed(node) {
|
|
1711
|
-
this.placed.push(node);
|
|
1712
|
-
return node;
|
|
1670
|
+
};
|
|
1713
1671
|
}
|
|
1714
1672
|
#parseStringLiteral(what) {
|
|
1715
1673
|
const token = this.#peek();
|
|
@@ -1722,7 +1680,7 @@ var Parser = class {
|
|
|
1722
1680
|
const { body, end } = this.#parseBody(["endslot"]);
|
|
1723
1681
|
if (end) this.#finishEndTag();
|
|
1724
1682
|
else this.#unclosed("slot", open, "endslot");
|
|
1725
|
-
return
|
|
1683
|
+
return {
|
|
1726
1684
|
type: "Slot",
|
|
1727
1685
|
name,
|
|
1728
1686
|
body,
|
|
@@ -1730,7 +1688,7 @@ var Parser = class {
|
|
|
1730
1688
|
start: open.start,
|
|
1731
1689
|
end: this.#lastEnd
|
|
1732
1690
|
}
|
|
1733
|
-
}
|
|
1691
|
+
};
|
|
1734
1692
|
}
|
|
1735
1693
|
#parseMacro(open) {
|
|
1736
1694
|
const header = this.#header(() => {
|
|
@@ -1898,7 +1856,7 @@ var Parser = class {
|
|
|
1898
1856
|
const { body, end } = this.#parseBody(["endisland"]);
|
|
1899
1857
|
if (end) this.#finishEndTag();
|
|
1900
1858
|
else this.#unclosed("island", open, "endisland");
|
|
1901
|
-
|
|
1859
|
+
const island = {
|
|
1902
1860
|
type: "Island",
|
|
1903
1861
|
...header,
|
|
1904
1862
|
body,
|
|
@@ -1906,7 +1864,9 @@ var Parser = class {
|
|
|
1906
1864
|
start: open.start,
|
|
1907
1865
|
end: this.#lastEnd
|
|
1908
1866
|
}
|
|
1909
|
-
}
|
|
1867
|
+
};
|
|
1868
|
+
this.islands.push(island);
|
|
1869
|
+
return island;
|
|
1910
1870
|
}
|
|
1911
1871
|
#parseApply(open) {
|
|
1912
1872
|
const filters = this.#header(() => {
|
|
@@ -2664,4 +2624,4 @@ var Parser = class {
|
|
|
2664
2624
|
//#endregion
|
|
2665
2625
|
export { ESCAPE_STRATEGIES as a, DEFAULT_SLOT as i, contentStart as n, scanParts as r, parse as t };
|
|
2666
2626
|
|
|
2667
|
-
//# sourceMappingURL=parser-
|
|
2627
|
+
//# sourceMappingURL=parser-isboTef0.js.map
|