def template(parser): """Template grammar Wikimedia ABNF template = "{{", title, { "|", part }, "}}" ; part = [ name, "=" ], value ; title = text ; ------ Internal text := ε template := '{{' text '}}' Templates are used to call functions and do some particular formatting Only the title might be necessary, this is why the template is simplified with a simple text inside brackets, therefore there is no recursion. :param parser: :return: """ result = pipe( parser, seq(expect(Template.start), Grammar.epsilon, expect(Template.end)), extract) if result: return p.Node(p.TemplateP(result.value)) return None
def comment(parser): result = pipe( parser, seq(expect(Comment.start), Grammar.epsilon, expect(Comment.end)), extract) if result: return p.Node(p.CommentP(result.value)) return None
def epsilon(parser): """Basic epsilon that consume the token and proceed aka Text for now. Maybe i'll further extend this to handle cases like left-recursion :param parser: :return: """ result = expect(Text.start)(parser) if result: return p.Node(p.TextP(result.text)) return None
def formatting(parser): match = [ItalicAndBold, Bold, Italic] def format(start, end): return seq(expect(start), rep(sor(Grammar.epsilon, Grammar.link), end), expect(end)) def extractor(r): _, arr, __ = r return arr[0] try: result = pipe(parser, sor(*[format(i.start, i.end) for i in match]), extractor) if result: return p.Node(p.FormattingP(result.value)) return None except ParseError as e: raise e
def list_item(parser): def extractor(r): _, arr, _ = r return arr result = pipe( parser, seq( expect(List.start), rep( sor(Grammar.epsilon, Grammar.template, Grammar.link, Grammar.headings, Grammar.list, at_least_one=True), LineBreak.end), expect(LineBreak.end, False)), extractor) if result: # return result node = p.Node(None) node.children = result return node return None
def linebreak(parser): result = expect(LineBreak.start)(parser) if result: return p.Node(p.LineBreakP(result.text)) return None