package org.jtwig.parser.parboiled.node; import com.google.common.base.Optional; import org.jtwig.model.tree.ContentEscapeNode; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.base.*; import org.jtwig.parser.parboiled.expression.StringExpressionParser; import org.parboiled.Rule; import org.parboiled.annotations.Label; import static org.parboiled.Parboiled.createParser; public class ContentEscapeNodeParser extends NodeParser<ContentEscapeNode> { public ContentEscapeNodeParser(ParserContext context) { super(ContentEscapeNodeParser.class, context); createParser(EscapeModeParser.class, context); } @Override @Label("Auto Escape") public Rule NodeRule() { PositionTrackerParser positionTrackerParser = parserContext().parser(PositionTrackerParser.class); LimitsParser limitsParser = parserContext().parser(LimitsParser.class); LexicParser lexicParser = parserContext().parser(LexicParser.class); EscapeModeParser escapeModeParser = parserContext().parser(EscapeModeParser.class); SpacingParser spacingParser = parserContext().parser(SpacingParser.class); CompositeNodeParser nodeParser = parserContext().parser(CompositeNodeParser.class); return Sequence( positionTrackerParser.PushPosition(), // Open Tag Sequence( limitsParser.startCode(), spacingParser.Spacing(), lexicParser.Keyword("contentescape"), spacingParser.Spacing(), FirstOf( Sequence( escapeModeParser.EscapeMode(), spacingParser.Spacing() ), escapeModeParser.push(null) ), Mandatory(limitsParser.endCode(), "Missing code island end") ), nodeParser.NodeRule(), // End Mandatory(Sequence( limitsParser.startCode(), spacingParser.Spacing(), lexicParser.Keyword("endcontentescape"), spacingParser.Spacing(), Mandatory(limitsParser.endCode(), "Missing code island end") ), "Missing endcontentescape tag"), push(new ContentEscapeNode(positionTrackerParser.pop(2), nodeParser.pop(), Optional.fromNullable(escapeModeParser.pop()))) ); } public static class EscapeModeParser extends BasicParser<String> { public EscapeModeParser(ParserContext context) { super(EscapeModeParser.class, context); } public Rule EscapeMode() { StringExpressionParser parser = parserContext().parser(StringExpressionParser.class); return FirstOf( Sequence( parser.ExpressionRule(), push(parser.pop().getConstantValue().toString().toUpperCase()) ), Sequence( String("false"), push("none") ), push(null) ); } } }