Parcourir la source

Indent Partials

As referenced in this issue:
https://github.com/janl/mustache.js/issues/562

Partials aren't indented as per the spec:
https://github.com/mustache/spec/blob/master/specs/partials.yml#L13-L15

This adds indentation tracking for partials and applies them to the
first instance of a partial on a line (to not indent inline partials
which would violate a different part of the spec).
pull/613/head
Kevin Dew il y a 9 ans
Parent
révision
ba04216161
3 fichiers modifiés avec 45 ajouts et 9 suppressions
  1. +38
    -4
      mustache.js
  2. +1
    -2
      test/mustache-spec-test.js
  3. +6
    -3
      test/parse-test.js

+ 38
- 4
mustache.js Voir le fichier

@@ -101,6 +101,10 @@
* Tokens that are the root node of a subtree contain two more elements: 1) an
* array of tokens in the subtree and 2) the index in the original template at
* which the closing tag for that section begins.
*
* Tokens for partials also contain two more elements: 1) a string value of
* indendation prior to that tag and 2) the index of that tag on that line -
* eg a value of 2 indicates the partial is the third tag on this line.
*/
function parseTemplate (template, tags) {
if (!template)
@@ -111,6 +115,8 @@
var spaces = []; // Indices of whitespace tokens on the current line
var hasTag = false; // Is there a {{tag}} on the current line?
var nonSpace = false; // Is there a non-space char on the current line?
var indentation = ''; // Tracks indentation for tags that use it
var tagIndex = 0; // Stores a count of number of tags encountered on a line

// Strips all whitespace tokens array for the current line
// if there was a {{#tag}} on it and otherwise only space.
@@ -156,6 +162,8 @@

if (isWhitespace(chr)) {
spaces.push(tokens.length);
if (!nonSpace)
indentation += chr;
} else {
nonSpace = true;
}
@@ -164,8 +172,11 @@
start += 1;

// Check for whitespace on the current line.
if (chr === '\n')
if (chr === '\n') {
stripSpace();
indentation = '';
tagIndex = 0;
}
}
}

@@ -197,7 +208,12 @@
if (!scanner.scan(closingTagRe))
throw new Error('Unclosed tag at ' + scanner.pos);

token = [ type, value, start, scanner.pos ];
if (type == '>') {
token = [ type, value, start, scanner.pos, indentation, tagIndex ];
} else {
token = [ type, value, start, scanner.pos ];
}
tagIndex++;
tokens.push(token);

if (type === '#' || type === '^') {
@@ -542,12 +558,30 @@
return this.renderTokens(token[4], context, partials, originalTemplate);
};

Writer.prototype.indentPartial = function indentPartial (partial, indentation) {
var filteredIndentation = indentation.replace(/[^ \t]/g, '');
var partialByNl = partial.split('\n');
for (var i = 0; i < partialByNl.length; i++) {
if (partialByNl[i].length) {
partialByNl[i] = filteredIndentation + partialByNl[i];
}
}
return partialByNl.join('\n');
};

Writer.prototype.renderPartial = function renderPartial (token, context, partials) {
if (!partials) return;

var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
if (value != null)
return this.renderTokens(this.parse(value), context, partials, value);
if (value != null) {
var tagIndex = token[5];
var indentation = token[4];
var indentedValue = value;
if (tagIndex == 0 && indentation) {
var indentedValue = this.indentPartial(value, indentation);
}
return this.renderTokens(this.parse(indentedValue), context, partials, value);
}
};

Writer.prototype.unescapedValue = function unescapedValue (token, context) {


+ 1
- 2
test/mustache-spec-test.js Voir le fichier

@@ -16,8 +16,7 @@ var skipTests = {
],
partials: [
'Standalone Without Previous Line',
'Standalone Without Newline',
'Standalone Indentation'
'Standalone Without Newline'
],
sections: [
'Standalone Without Newline'


+ 6
- 3
test/parse-test.js Voir le fichier

@@ -40,9 +40,12 @@ var expectations = {
'a\n{{#a}}\n{{#b}}\n{{/b}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 2, 8, [ [ '#', 'b', 9, 15, [], 16 ] ], 23 ], [ 'text', 'b', 30, 31 ] ],
'a\n {{#a}}\n{{#b}}\n{{/b}}\n{{/a}}\nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [ [ '#', 'b', 10, 16, [], 17 ] ], 24 ], [ 'text', 'b', 31, 32 ] ],
'a\n {{#a}}\n{{#b}}\n{{/b}}\n{{/a}} \nb' : [ [ 'text', 'a\n', 0, 2 ], [ '#', 'a', 3, 9, [ [ '#', 'b', 10, 16, [], 17 ] ], 24 ], [ 'text', 'b', 32, 33 ] ],
'{{>abc}}' : [ [ '>', 'abc', 0, 8 ] ],
'{{> abc }}' : [ [ '>', 'abc', 0, 10 ] ],
'{{ > abc }}' : [ [ '>', 'abc', 0, 11 ] ],
'{{>abc}}' : [ [ '>', 'abc', 0, 8, '', 0 ] ],
'{{> abc }}' : [ [ '>', 'abc', 0, 10, '', 0 ] ],
'{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0 ] ],
' {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0 ] ],
' {{> abc }} {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0 ], [ '>', 'abc', 13, 23, ' ', 1 ] ],
'{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0 ] ],
'{{=<% %>=}}' : [ [ '=', '<% %>', 0, 11 ] ],
'{{= <% %> =}}' : [ [ '=', '<% %>', 0, 13 ] ],
'{{=<% %>=}}<%={{ }}=%>' : [ [ '=', '<% %>', 0, 11 ], [ '=', '{{ }}', 11, 22 ] ],


Chargement…
Annuler
Enregistrer