Reintroduce whitespace control parsing fix with legacy override by tkindy · Pull Request #903 · HubSpot/jinjava · GitHub
Skip to content
Merged
19 changes: 18 additions & 1 deletion src/main/java/com/hubspot/jinjava/LegacyOverrides.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,7 @@ public int getType() {
@Override
protected void parse() {
this.expr = WhitespaceUtils.unwrap(image, "{{", "}}");

if (WhitespaceUtils.startsWith(expr, "-")) {
setLeftTrim(true);
this.expr = WhitespaceUtils.unwrap(expr, "-", "");
}
if (WhitespaceUtils.endsWith(expr, "-")) {
setRightTrim(true);
this.expr = WhitespaceUtils.unwrap(expr, "", "-");
}

this.expr = handleTrim(expr);
this.expr = StringUtils.trimToEmpty(this.expr);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.hubspot.jinjava.tree.parse;

import com.hubspot.jinjava.util.WhitespaceUtils;

public class LenientWhitespaceControlParser implements WhitespaceControlParser {

@Override
public boolean hasLeftTrim(String unwrapped) {
return WhitespaceUtils.startsWith(unwrapped, "-");
}

@Override
public String stripLeft(String unwrapped) {
return WhitespaceUtils.unwrap(unwrapped, "-", "");
}

@Override
public boolean hasRightTrim(String unwrapped) {
return WhitespaceUtils.endsWith(unwrapped, "-");
}

@Override
public String stripRight(String unwrapped) {
return WhitespaceUtils.unwrap(unwrapped, "", "-");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.hubspot.jinjava.tree.parse;

public class StrictWhitespaceControlParser implements WhitespaceControlParser {

@Override
public boolean hasLeftTrim(String unwrapped) {
return unwrapped.charAt(0) == '-';
}

@Override
public String stripLeft(String unwrapped) {
return unwrapped.substring(1);
}

@Override
public boolean hasRightTrim(String unwrapped) {
return unwrapped.charAt(unwrapped.length() - 1) == '-';
}

@Override
public String stripRight(String unwrapped) {
return unwrapped.substring(0, unwrapped.length() - 1);
}
}
11 changes: 1 addition & 10 deletions src/main/java/com/hubspot/jinjava/tree/parse/TagToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.hubspot.jinjava.tree.parse;

import com.hubspot.jinjava.interpret.TemplateSyntaxException;
import com.hubspot.jinjava.util.WhitespaceUtils;

public class TagToken extends Token {
private static final long serialVersionUID = -4927751270481832992L;
Expand Down Expand Up @@ -54,15 +53,7 @@ protected void parse() {
}

content = image.substring(2, image.length() - 2);

if (WhitespaceUtils.startsWith(content, "-")) {
setLeftTrim(true);
content = WhitespaceUtils.unwrap(content, "-", "");
}
if (WhitespaceUtils.endsWith(content, "-")) {
setRightTrim(true);
content = WhitespaceUtils.unwrap(content, "", "-");
}
content = handleTrim(content);

int nameStart = -1, pos = 0, len = content.length();

Expand Down
33 changes: 33 additions & 0 deletions src/main/java/com/hubspot/jinjava/tree/parse/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
**********************************************************************/
package com.hubspot.jinjava.tree.parse;

import com.hubspot.jinjava.JinjavaConfig;
import com.hubspot.jinjava.LegacyOverrides;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import com.hubspot.jinjava.interpret.UnexpectedTokenException;
import java.io.Serializable;

Expand Down Expand Up @@ -83,6 +86,36 @@ public void setRightTrimAfterEnd(boolean rightTrimAfterEnd) {
this.rightTrimAfterEnd = rightTrimAfterEnd;
}

/**
* Handle any whitespace control characters, capturing whether leading or trailing
* whitespace should be stripped.
* @param unwrapped the content of the block stripped of its delimeters
* @return the content stripped of any whitespace control characters.
*/
protected final String handleTrim(String unwrapped) {
boolean parseWhitespaceControlStrictly = JinjavaInterpreter
.getCurrentMaybe()
.map(JinjavaInterpreter::getConfig)
.map(JinjavaConfig::getLegacyOverrides)
.map(LegacyOverrides::isParseWhitespaceControlStrictly)
.orElse(false);

WhitespaceControlParser parser = parseWhitespaceControlStrictly
? WhitespaceControlParser.STRICT
: WhitespaceControlParser.LENIENT;

String result = unwrapped;
if (parser.hasLeftTrim(result)) {
setLeftTrim(true);
result = parser.stripLeft(result);
}
if (parser.hasRightTrim(result)) {
setRightTrim(true);
result = parser.stripRight(result);
}
return result;
}

public int getStartPosition() {
return startPosition;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.hubspot.jinjava.tree.parse;

public interface WhitespaceControlParser {
WhitespaceControlParser LENIENT = new LenientWhitespaceControlParser();
WhitespaceControlParser STRICT = new StrictWhitespaceControlParser();

boolean hasLeftTrim(String unwrapped);
String stripLeft(String unwrapped);

boolean hasRightTrim(String unwrapped);
String stripRight(String unwrapped);
}
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,14 @@ public void itInterpretsFilterChainsInOrder() {
assertThat(interpreter.render("{{ 'foo' | upper | replace('O', 'A') }}"))
.isEqualTo("FAA");
}

@Test
public void itInterpretsWhitespaceControl() {
assertThat(interpreter.render(". {%- set x = 5 -%} .")).isEqualTo("..");
}

@Test
public void itInterpretsEmptyExpressions() {
assertThat(interpreter.render("{{}}")).isEqualTo("");
}
}