Exemple #1
0
    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
Exemple #2
0
 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
Exemple #3
0
    def link(parser):
        """Link grammar
        Wikimedia EBNF

        start link    = "[[";
        end link      = "]]";
        internal link = start link, full pagename, ["|", label], end link,

        ---
        Internal

        pagename   := ε
        expression := template
                        | link
                        | ε

        link            := '[[' pagename, { expression } ']]'

        The link contain the page name, and 0 or more repetitions of the expression ["|", label]. That is simplified with
        an expression that can by any one of the wikimedia non-terminals (text, template, link for now)
        Watch out left recursion (a link can contain a link)

        TODO add external link too, https://en.wikipedia.org/wiki/Help:Link#External_links
        :param parser:
        :return:
        """

        # expression = sor(expect(Link.end), rep(sor(Grammar.epsilon, Grammar.template, Grammar.link), Link.end))

        def extractor(arr):
            return (lambda _, c, children, __: (c, children))(*arr)

        result = pipe(
            parser,
            seq(
                expect(Link.start), Grammar.epsilon,
                rep(
                    sor(Grammar.epsilon,
                        Grammar.template,
                        Grammar.link,
                        Grammar.formatting,
                        Grammar.linebreak,
                        at_least_one=True), Link.end), expect(Link.end)),
            extractor)

        if result:
            (content, nodes) = result
            node = p.LinkNode(p.LinkP(content.value))
            for n in nodes:
                node.add(n)
            return node

        return None
Exemple #4
0
 def heading(start, end):
     return seq(
         expect(start),
         rep(
             sor(Grammar.epsilon,
                 Grammar.template,
                 Grammar.link,
                 Grammar.formatting,
                 at_least_one=True), end),
         expect(end),
         # expect(LineBreak.start))
         Grammar.linebreak)
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
 def format(start, end):
     return seq(expect(start),
                rep(sor(Grammar.epsilon, Grammar.link), end),
                expect(end))
Exemple #8
0
 def linebreak(parser):
     result = expect(LineBreak.start)(parser)
     if result:
         return p.Node(p.LineBreakP(result.text))
     return None