# HG changeset patch # User Paul Boddie # Date 1533057348 -7200 # Node ID de69e3bc8121c8339a29ab72c2f0a4ab3020f921 # Parent 76b28b3931f54190f6dc86a50f100898a707d570 Added anchor syntax and Moin-compatible macro. diff -r 76b28b3931f5 -r de69e3bc8121 moinformat/macros/anchor.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/moinformat/macros/anchor.py Tue Jul 31 19:15:48 2018 +0200 @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +""" +Anchor macro for Moin compatibility. + +Copyright (C) 2018 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +from moinformat.macros.common import Macro +from moinformat.tree.moin import Anchor + +class AnchorMacro(Macro): + + "An anchor macro." + + name = "Anchor" + + def evaluate(self): + + "Evaluate the macro, producing an anchor node." + + # Obtain the concatenated arguments since they might contain commas. + + argstr = ",".join(self.node.args) + + # Replace the macro node with the anchor. + + macro = self.node + macro.parent.replace(macro, Anchor(argstr)) + +macro = AnchorMacro + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 76b28b3931f5 -r de69e3bc8121 moinformat/parsers/moin.py --- a/moinformat/parsers/moin.py Tue Jul 31 19:14:38 2018 +0200 +++ b/moinformat/parsers/moin.py Tue Jul 31 19:15:48 2018 +0200 @@ -35,12 +35,12 @@ # Document tree nodes. -from moinformat.tree.moin import Break, DefItem, DefTerm, FontStyle, Heading, \ - Larger, LineBreak, Link, List, ListItem, \ - Macro, Monospace, Region, Rule, Smaller, \ - Strikethrough, Subscript, Superscript, Table, \ - TableAttr, TableAttrs, TableCell, TableRow, \ - Text, Underline +from moinformat.tree.moin import Anchor, Break, DefItem, DefTerm, FontStyle, \ + Heading, Larger, LineBreak, Link, List, \ + ListItem, Macro, Monospace, Region, Rule, \ + Smaller, Strikethrough, Subscript, \ + Superscript, Table, TableAttr, TableAttrs, \ + TableCell, TableRow, Text, Underline join = "".join @@ -481,6 +481,11 @@ # Complete inline pattern handlers. + def parse_anchor(self, region): + target = self.match_group("target") + anchor = Anchor(target) + region.append_inline(anchor) + def parse_linebreak(self, region): region.append_inline(LineBreak()) @@ -619,6 +624,10 @@ # Complete inline patterns are for markup features that do not support # arbitrary content within them: + "anchor" : join((r"\(\(", # (( + group("target", ".*?"), # target + r"\)\)")), # )) + "linebreak" : r"\\\\", # \\ "link" : join((r"\[\[", # [[ @@ -706,8 +715,9 @@ ] inline_pattern_names = [ - "fontstyle", "larger", "linebreak", "link", "macro", "monospace", - "regionstart", "smaller", "strike", "sub", "super", "underline", + "anchor", "fontstyle", "larger", "linebreak", "link", "macro", + "monospace", "regionstart", "smaller", "strike", "sub", "super", + "underline", ] list_pattern_names = [ @@ -740,6 +750,7 @@ handlers = { None : end_region, + "anchor" : parse_anchor, "attrname" : parse_attrname, "break" : parse_break, "colour" : parse_colour, diff -r 76b28b3931f5 -r de69e3bc8121 moinformat/serialisers/html/moin.py --- a/moinformat/serialisers/html/moin.py Tue Jul 31 19:14:38 2018 +0200 +++ b/moinformat/serialisers/html/moin.py Tue Jul 31 19:15:48 2018 +0200 @@ -247,6 +247,9 @@ def end_underline(self): self.out("") + def anchor(self, target): + self.out("" % escape_attr(make_id(target))) + def break_(self): pass diff -r 76b28b3931f5 -r de69e3bc8121 moinformat/serialisers/moin/moin.py --- a/moinformat/serialisers/moin/moin.py Tue Jul 31 19:14:38 2018 +0200 +++ b/moinformat/serialisers/moin/moin.py Tue Jul 31 19:15:48 2018 +0200 @@ -179,6 +179,9 @@ def end_underline(self): self.out("__") + def anchor(self, target): + self.out("((%s))" % target) + def break_(self): self.out("\n") diff -r 76b28b3931f5 -r de69e3bc8121 moinformat/tree/moin.py --- a/moinformat/tree/moin.py Tue Jul 31 19:14:38 2018 +0200 +++ b/moinformat/tree/moin.py Tue Jul 31 19:15:48 2018 +0200 @@ -584,6 +584,22 @@ def empty(self): return False +class Anchor(Node): + + "Anchor details." + + def __init__(self, target): + self.target = target + + def __repr__(self): + return "Anchor(%r)" % self.target + + def prettyprint(self, indent=""): + return "%sAnchor: target=%r" % (indent, self.target) + + def to_string(self, out): + out.anchor(self.target) + class Break(Node): "A paragraph break." diff -r 76b28b3931f5 -r de69e3bc8121 tests/test_anchors.tree --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_anchors.tree Tue Jul 31 19:15:48 2018 +0200 @@ -0,0 +1,43 @@ +Region + Heading + Text + Break + Block + Anchor + Text + Break + Block + Anchor + Text + Break + Heading + Text + Underline + Text + Break + Block + Text + Break + Block + Anchor + Text + Break + Block + Text + Link + Text + Text + Break + Block + Macro + Text + Heading + Text + Break + Block + Text + Break + Block + Text + Link + Text diff -r 76b28b3931f5 -r de69e3bc8121 tests/test_anchors.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_anchors.txt Tue Jul 31 19:15:48 2018 +0200 @@ -0,0 +1,22 @@ += Level 1 = + +((Number #1 anchor)) +Some text. + +((Text, anchored.)) Some text referenced elsewhere. + += Heading __Underlined__ = + +Some more text. + +((Anchored!)) +More anchored text. + +A [[#Heading Underlined|link]] to the above heading. + +<> += Macro-Anchored Heading = + +Yet more text. + +Link to the [[#Number #1 anchor]].