From 337da204eeb5ccc96a5eaeb6aa5b045d531e8c50 Mon Sep 17 00:00:00 2001 From: Yotam Madem Date: Wed, 26 Jun 2019 00:12:35 +0300 Subject: [PATCH] Preserve indentation when rendering partials --- mustache.js | 41 +++++++++++++++++++++++++++++++++++------ test/render-test.js | 8 ++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/mustache.js b/mustache.js index 8ec1b44..7ea9845 100644 --- a/mustache.js +++ b/mustache.js @@ -528,6 +528,7 @@ */ Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, tags) { var buffer = ''; + var indentationContext = {spacer: ''}; var token, symbol, value; for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { @@ -537,18 +538,31 @@ if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate); else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate); - else if (symbol === '>') value = this.renderPartial(token, context, partials, tags); + else if (symbol === '>') value = this.renderPartial(token, context, partials, tags, indentationContext); else if (symbol === '&') value = this.unescapedValue(token, context); else if (symbol === 'name') value = this.escapedValue(token, context); else if (symbol === 'text') value = this.rawValue(token); - if (value !== undefined) + if (value !== undefined) { + this.updateIndentationContext(indentationContext, value); buffer += value; + } } - return buffer; }; + Writer.prototype.updateIndentationContext = function updateIndentationContext (indentationContext, value) { + for (var j = 0; j < value.length; j++) { + if (value[j] == '\n') { + indentationContext.spacer = ''; + } else if (isWhitespace(value[j])) { + indentationContext.spacer += value[j]; + } else { + indentationContext.spacer += ' '; + } + } + }; + Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) { var self = this; var buffer = ''; @@ -592,12 +606,27 @@ return this.renderTokens(token[4], context, partials, originalTemplate); }; - Writer.prototype.renderPartial = function renderPartial (token, context, partials, tags) { + Writer.prototype.renderPartial = function renderPartial (token, context, partials, tags, indentationContext) { if (!partials) return; var value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; - if (value != null) - return this.renderTokens(this.parse(value, tags), context, partials, value); + if (value != null) { + var renderResult = this.renderTokens(this.parse(value, tags), context, partials, value); + return this.indent(renderResult, indentationContext); + } + }; + + Writer.prototype.indent = function indent (value, indentationContext) { + var indentedValue = ''; + var lines = value.split('\n'); + for (var i=0; i