package org.jtwig.parser.parboiled.node; import org.jtwig.model.tree.VerbatimNode; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.base.*; import org.jtwig.parser.parboiled.model.Keyword; import org.parboiled.Rule; import static org.parboiled.Parboiled.createParser; public class VerbatimNodeParser extends NodeParser<VerbatimNode> { public VerbatimNodeParser(ParserContext context) { super(VerbatimNodeParser.class, context); createParser(VerbatimContentParser.class, context); } @Override public Rule NodeRule() { PositionTrackerParser positionTrackerParser = parserContext().parser(PositionTrackerParser.class); LimitsParser limitsParser = parserContext().parser(LimitsParser.class); SpacingParser spacingParser = parserContext().parser(SpacingParser.class); LexicParser lexicParser = parserContext().parser(LexicParser.class); VerbatimContentParser verbatimContentParser = parserContext().parser(VerbatimContentParser.class); return Sequence( positionTrackerParser.PushPosition(), // start Sequence( limitsParser.startCode(), spacingParser.Spacing(), lexicParser.Keyword(Keyword.VERBATIM), spacingParser.Spacing(), Mandatory(limitsParser.endCode(), "Missing code island end") ), // content verbatimContentParser.Content(endVerbatim(limitsParser, spacingParser, lexicParser)), endVerbatim(limitsParser, spacingParser, lexicParser), push(new VerbatimNode(positionTrackerParser.pop(1), verbatimContentParser.pop())) ); } Rule endVerbatim(LimitsParser limitsParser, SpacingParser spacingParser, LexicParser lexicParser) { return Sequence( limitsParser.startCode(), spacingParser.Spacing(), lexicParser.Keyword(Keyword.END_VERBATIM), spacingParser.Spacing(), limitsParser.endCode() ); } public static class VerbatimContentParser extends BasicParser<String> { public VerbatimContentParser(ParserContext context) { super(VerbatimContentParser.class, context); } public Rule Content(Rule end) { return Sequence( ZeroOrMore( TestNot(end), ANY ), push(match()) ); } } }