public Rule Verbatim() { StringBuilderVar text = new StringBuilderVar(); StringBuilderVar line = new StringBuilderVar(); return NodeSequence( OneOrMore( ZeroOrMore(BlankLine(), line.append('\n')), Indent(), push(currentIndex()), OneOrMore( FirstOf( Sequence('\t', line.append(repeat(' ', 4-(currentIndex()-1-(Integer)peek())%4))), Sequence(NotNewline(), ANY, line.append(matchedChar())) ) ), Newline(), text.appended(line.getString()).append('\n') && line.clearContents() && drop() ), push(new VerbatimNode(text.getString())) ); }
public Rule FencedCodeBlock() { StringBuilderVar text = new StringBuilderVar(); Var<Integer> markerLength = new Var<Integer>(); return NodeSequence( CodeFence(markerLength), TestNot(CodeFence(markerLength)), // prevent empty matches ZeroOrMore(BlankLine(), text.append('\n')), OneOrMore(TestNot(Newline(), CodeFence(markerLength)), ANY, text.append(matchedChar())), Newline(), push(new VerbatimNode(text.appended('\n').getString(), popAsString())), CodeFence(markerLength), drop() ); }
@Cached public Rule LinkSource() { StringBuilderVar url = new StringBuilderVar(); return FirstOf( Sequence('(', LinkSource(), ')'), Sequence('<', LinkSource(), '>'), Sequence( OneOrMore( FirstOf( Sequence('\\', AnyOf("()"), url.append(matchedChar())), Sequence(TestNot(AnyOf("()>")), Nonspacechar(), url.append(matchedChar())) ) ), push(url.getString()) ), push("") ); }
FirstOf(CrossedOut(BlankLine(), block), tight.set(true)), CrossedOut(itemStart, block), Optional(CrossedOut(Sequence(FirstOf(Sequence("[ ]", taskType.set(1)), Sequence(FirstOf("[x]","[X]"), taskType.set(2))), OneOrMore(Spacechar())), taskListMarker)), block.append(taskListMarker.getString()), Line(block), TestNotItem(), Line(temp), block.append(temp.getString()) && temp.clearContents() ), tight.get() ? push(tightFirstItem.setAndGet(itemNodeCreator.create(parseListBlock(block), taskType.get(), taskListMarker.getString()))) && taskListMarker.clearContents() : fixFirstItem((SuperNode) peek(1)) && push(itemNodeCreator.create(parseListBlock(block.appended('\n')), taskType.get(), taskListMarker.getString())) && taskListMarker.clearContents(), ZeroOrMore(
public Rule ListItemIndentedBlocks(StringBuilderVar block) { StringBuilderVar line = new StringBuilderVar(); return Sequence( OneOrMore( Sequence( // vsch: Important! when accumulating text for recursive parsing it is critical that no characters, of the original text, are left out // if you don't want them to be parsed replace them with crossed out marker, they will be stripped before parsing but the index to the // source position will be correct. If you leave any characters out then the final index of the node will be offset by that many characters, // giving an incorrect result for the AST node. Yes it is critical if you use the AST for syntax highlighting of the source. ZeroOrMore(Sequence(CrossedOutLessOne(BlankLine(), line), line.append('\n'))), CrossedOut(Indent(), line), Line(line), // take the rest of the block's lines, with or without indentations, // but only if they are not a list item ZeroOrMore( TestNot(BlankLine()), TestNotListItem(), Optional(CrossedOut(Indent(), line)), Line(line) ), block.append(line.getString()) && line.clearContents() ) ), // if there is a blank line then we append \n, but leave the blank line for the next item, just in case it needs it // to determine looseness, however this can only be done for the last block in the indented set, otherwise // if we do it for each block then code blocks will have their embedded blank lines doubled and index positions will be off. Optional(Test(BlankLine(), line.append('\n'))) ); }
public Rule BlockQuote() { StringBuilderVar inner = new StringBuilderVar(); StringBuilderVar optional = new StringBuilderVar(); return NodeSequence( OneOrMore( CrossedOut(Sequence('>', Optional(' ')), inner), Line(inner), ZeroOrMore( TestNot('>'), TestNot(BlankLine()), Line(inner) ), // ZeroOrMore(BlankLine()), inner.append(match()) Optional(Sequence(OneOrMore(BlankLine()), optional.append(match()), Test('>')), inner.append(optional.getString()) && optional.clearContents()) ), // vsch: the block quotes won't parse into Para because they will not be followed by a blank line, // unless the last line of the block quote is an empty block-quote line: ">". We append one here to // take care of that possibility, now that we don't include blank lines after a block quote we add one extra inner.append("\n\n"), // trigger a recursive parsing run on the inner source we just built // and attach the root of the inner parses AST push(new BlockQuoteNode(withIndicesShifted(parseInternal(inner), (Integer) peek()).getChildren())) ); }
TestNotItem(), Line(temp), block.append(temp.getString()) && temp.clearContents() ),
public Rule FootnoteContent() { StringBuilderVar ref = new StringBuilderVar(); StringBuilderVar txt = new StringBuilderVar(); return NodeSequence( '[', OneOrMore(TestNot(']'), ANY, ref.append(matchedChar())), ']', ':', Sp(), ZeroOrMore(TestNot(BlankLine()), ANY, txt.append(matchedChar())), FirstOf(BlankLine(), EOI), push(new LinkContentNode(ref.getString(), txt.getString()))); }
@SuppressSubnodes Rule CaptureLineIgnored() { StringBuilderVar text = new StringBuilderVar(); return Sequence( ZeroOrMore(TestNot(Newline()), BaseParser.ANY), ((IgnoredLineAware) peek()).appendIgnoredLine(text.getString())); }
Rule legend() { StringBuilderVar text = new StringBuilderVar(); return Sequence(Sp(), "legend", Sp(), ":", OneOrMore(TestNot(Newline()), BaseParser.ANY, text.append(matchedChar())), Newline(), ((ChartNode) peek()).displayLegend(text.getString())); }
public Rule attributesRules() { StringBuilderVar text = new StringBuilderVar(); return NodeSequence( Sp(), "{", OneOrMore(TestNot("}"), TestNot(Newline()), BaseParser.ANY, text.append(matchedChar())), "}", Sp(), Newline(), push(new AttributesNode(text.getString())) ); } }
@SuppressSubnodes public Rule Name() { StringBuilderVar text = new StringBuilderVar(); return Sequence(FirstOf( Sequence(Ch('"'), OneOrMore(TestNot('"'), BaseParser.ANY, text.append(matchedChar())), Ch('"')), OneOrMore(TestNot("="), TestNot(Newline()), BaseParser.ANY, text.append(matchedChar()))), push(text.getString()) ); }
@SuppressSubnodes public Rule Value() { StringBuilderVar text = new StringBuilderVar(); return Sequence(FirstOf( Sequence(Ch('"'), OneOrMore(TestNot('"'), BaseParser.ANY, text.append(matchedChar())), Ch('"')), OneOrMore(TestNot("}"), TestNot(","), TestNot(Newline()), BaseParser.ANY, text.append(matchedChar()))), push(text.getString()) ); } }