@rhinostone/swig-twig 2.0.0 → 2.0.1
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/lib/lexer.js +1 -1
- package/lib/parser.js +57 -3
- package/package.json +2 -2
package/lib/lexer.js
CHANGED
package/lib/parser.js
CHANGED
|
@@ -515,8 +515,16 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
515
515
|
escapeRegExp(cmtOpen) + anyChar + escapeRegExp(cmtClose) +
|
|
516
516
|
')'
|
|
517
517
|
);
|
|
518
|
-
|
|
519
|
-
|
|
518
|
+
// Twig/Jinja2 whitespace-control. `{{- … -}}` / `{%- … -%}` strip
|
|
519
|
+
// surrounding whitespace; the `-?` lives only adjacent to the open /
|
|
520
|
+
// close marker (post-#T23 shape — drop the inner `-?` after `\s*` so
|
|
521
|
+
// `{{ -5 }}` doesn't have its expression-`-` eaten as a strip marker).
|
|
522
|
+
var tagStrip = new RegExp('^' + escapeRegExp(tagOpen) + '-?\\s*|\\s*-?' + escapeRegExp(tagClose) + '$', 'g');
|
|
523
|
+
var varStrip = new RegExp('^' + escapeRegExp(varOpen) + '-?\\s*|\\s*-?' + escapeRegExp(varClose) + '$', 'g');
|
|
524
|
+
var tagStripBefore = new RegExp('^' + escapeRegExp(tagOpen) + '-');
|
|
525
|
+
var tagStripAfter = new RegExp('-' + escapeRegExp(tagClose) + '$');
|
|
526
|
+
var varStripBefore = new RegExp('^' + escapeRegExp(varOpen) + '-');
|
|
527
|
+
var varStripAfter = new RegExp('-' + escapeRegExp(varClose) + '$');
|
|
520
528
|
|
|
521
529
|
var line = 1;
|
|
522
530
|
var stack = [];
|
|
@@ -524,6 +532,29 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
524
532
|
var tokens = [];
|
|
525
533
|
var blocks = {};
|
|
526
534
|
var inVerbatim = false;
|
|
535
|
+
// Carries `-}}` / `-%}` strip-after intent across the chunk boundary.
|
|
536
|
+
// Consumed by the next text chunk (leading whitespace stripped, flag
|
|
537
|
+
// reset). Mirrors native lib/parser.js's closure-scoped `stripNext`.
|
|
538
|
+
var stripNext = false;
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* If the previous token is a Text IR node, strip its trailing
|
|
542
|
+
* whitespace in-place. No-op for non-Text tokens.
|
|
543
|
+
*
|
|
544
|
+
* Mirrors lib/parser.js's stripPrevToken — same one-level-deep
|
|
545
|
+
* limitation: a `{%- endif %}` only strips the trailing whitespace of
|
|
546
|
+
* the last child of the immediately enclosing tag, not deeper.
|
|
547
|
+
*
|
|
548
|
+
* @param {object} token IR node (typed), possibly a Text node.
|
|
549
|
+
* @return {object} Same node; mutated when `type === 'Text'`.
|
|
550
|
+
* @private
|
|
551
|
+
*/
|
|
552
|
+
function stripPrevToken(token) {
|
|
553
|
+
if (token && token.type === 'Text' && typeof token.value === 'string') {
|
|
554
|
+
token.value = token.value.replace(/\s*$/, '');
|
|
555
|
+
}
|
|
556
|
+
return token;
|
|
557
|
+
}
|
|
527
558
|
|
|
528
559
|
/**
|
|
529
560
|
* Build an IROutput node for a `{{ … }}` chunk.
|
|
@@ -628,13 +659,17 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
628
659
|
}
|
|
629
660
|
|
|
630
661
|
utils.each(source.split(splitter), function (chunk) {
|
|
631
|
-
var token, lines;
|
|
662
|
+
var token, lines, stripPrev, prevToken, prevChildToken;
|
|
632
663
|
|
|
633
664
|
if (!chunk) { return; }
|
|
634
665
|
|
|
635
666
|
if (!inVerbatim && utils.startsWith(chunk, varOpen) && utils.endsWith(chunk, varClose)) {
|
|
667
|
+
stripPrev = varStripBefore.test(chunk);
|
|
668
|
+
stripNext = varStripAfter.test(chunk);
|
|
636
669
|
token = parseVariable(chunk.replace(varStrip, ''), line);
|
|
637
670
|
} else if (utils.startsWith(chunk, tagOpen) && utils.endsWith(chunk, tagClose)) {
|
|
671
|
+
stripPrev = tagStripBefore.test(chunk);
|
|
672
|
+
stripNext = tagStripAfter.test(chunk);
|
|
638
673
|
token = parseTag(chunk.replace(tagStrip, ''), line);
|
|
639
674
|
if (token) {
|
|
640
675
|
if (token.name === 'extends') {
|
|
@@ -654,9 +689,28 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
654
689
|
line += lines ? lines.length : 0;
|
|
655
690
|
return;
|
|
656
691
|
} else {
|
|
692
|
+
if (stripNext) {
|
|
693
|
+
chunk = chunk.replace(/^\s*/, '');
|
|
694
|
+
stripNext = false;
|
|
695
|
+
}
|
|
657
696
|
token = ir.text(chunk);
|
|
658
697
|
}
|
|
659
698
|
|
|
699
|
+
// `{{-` / `{%-` strips the previous text chunk's trailing whitespace.
|
|
700
|
+
// Mirrors lib/parser.js: pop tokens.last; if it's a Text node strip
|
|
701
|
+
// it directly, else if it carries `.content` (a tag with body) drill
|
|
702
|
+
// one level into its last child. One-level-deep — matches native.
|
|
703
|
+
if (stripPrev && tokens.length) {
|
|
704
|
+
prevToken = tokens.pop();
|
|
705
|
+
if (prevToken && prevToken.type === 'Text') {
|
|
706
|
+
prevToken = stripPrevToken(prevToken);
|
|
707
|
+
} else if (prevToken && prevToken.content && prevToken.content.length) {
|
|
708
|
+
prevChildToken = stripPrevToken(prevToken.content.pop());
|
|
709
|
+
prevToken.content.push(prevChildToken);
|
|
710
|
+
}
|
|
711
|
+
tokens.push(prevToken);
|
|
712
|
+
}
|
|
713
|
+
|
|
660
714
|
if (token) {
|
|
661
715
|
if (stack.length) {
|
|
662
716
|
stack[stack.length - 1].content.push(token);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhinostone/swig-twig",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Twig-syntax frontend for the @rhinostone/swig-core template engine. Part of the @rhinostone/swig multi-flavor family.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"template",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"node": ">=12"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@rhinostone/swig-core": "2.0.
|
|
25
|
+
"@rhinostone/swig-core": "2.0.1"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|