1.1 --- a/moinformat/__init__.py Mon Jul 16 00:08:09 2018 +0200
1.2 +++ b/moinformat/__init__.py Mon Jul 16 19:20:37 2018 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Moin wiki format tools.
1.6
1.7 -Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -19,7 +19,7 @@
1.13 this program. If not, see <http://www.gnu.org/licenses/>.
1.14 """
1.15
1.16 -from moinformat.parsers import parse, parsers
1.17 -from moinformat.serialisers import serialise, serialisers
1.18 +from moinformat.parsers import parse, parsers as all_parsers
1.19 +from moinformat.serialisers import serialise, serialisers as all_serialisers
1.20
1.21 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/moinformat/parsers/moin.py Mon Jul 16 00:08:09 2018 +0200
2.2 +++ b/moinformat/parsers/moin.py Mon Jul 16 19:20:37 2018 +0200
2.3 @@ -411,7 +411,9 @@
2.4 region.append_inline(link)
2.5
2.6 def parse_monospace(self, region):
2.7 - self.parse_inline(region, Monospace, "monospace")
2.8 + span = Monospace([])
2.9 + self.parse_region_details(span, ["monospaceend"])
2.10 + region.append_inline(span)
2.11
2.12 def parse_smaller(self, region):
2.13 self.parse_inline(region, Smaller, "smaller")
2.14 @@ -552,7 +554,7 @@
2.15
2.16 "headingend" : join((group("pad", r"\N+"), # ws...
2.17 group("level", "=+"), # =...
2.18 - group("extra", r"\N*$"))), # ws (optional)
2.19 + group("extra", r"\N*\n"))), # ws (optional) nl
2.20
2.21 # List contents:
2.22
3.1 --- a/tests/test1.txt Mon Jul 16 00:08:09 2018 +0200
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,9 +0,0 @@
3.4 -Hello
3.5 -{{{{#!wiki
3.6 -A region
3.7 - {{{
3.8 -Another
3.9 -}}}
3.10 -End
3.11 -}}}}
3.12 -XXX
4.1 --- a/tests/test10.txt Mon Jul 16 00:08:09 2018 +0200
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,9 +0,0 @@
4.4 -= Level 1 =
4.5 -Text
4.6 - == Level 2 Heading ==
4.7 -Text
4.8 -Not == a heading ==
4.9 -== Not a heading == either
4.10 -= Mismatched heading ==
4.11 -== Another mismatched heading =
4.12 -=== Heading __Underlined__ ===
5.1 --- a/tests/test11.txt Mon Jul 16 00:08:09 2018 +0200
5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
5.3 @@ -1,17 +0,0 @@
5.4 -''Some'' emphasised text. ''Emphasised''''text''.
5.5 -
5.6 -'''Strong ''and italic'' text.'''
5.7 -
5.8 -''Italic and '''strong'''''. '''''Both'', strong'''. '''''Both''', italic''.
5.9 -
5.10 -'''Strong''''''text'''.
5.11 -
5.12 -Some `monospace` text. `Mono, '''strong'''`, __underlined__, __''under''lined__.
5.13 -
5.14 -H,,2,,O + CO,,2,,
5.15 -
5.16 -== e = mc^2^ ==
5.17 -
5.18 -~+Larger...+~ and ~-smaller-~
5.19 -
5.20 -Some --(deleted)-- text.
6.1 --- a/tests/test12.txt Mon Jul 16 00:08:09 2018 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,10 +0,0 @@
6.4 -||<20%|2-2)^> Cell 1 || Cell 2 ||
6.5 -|| '''Cell 3''' ||<#FF0000 width="15%"> ''Cell 4'' ||
6.6 -
6.7 -|| Not a table
6.8 - || Also not a table
6.9 -|| Almost a table || ...
6.10 -|| A table, trailing space ||
6.11 -
6.12 -||<20%%name="value"> Bad separator ||
6.13 -||<20%xx-2> Strange attributes ||
7.1 --- a/tests/test13.txt Mon Jul 16 00:08:09 2018 +0200
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,9 +0,0 @@
7.4 -Wiki format
7.5 -
7.6 -{{{#!table
7.7 -'''Cell 1''' || Cell 2
7.8 -==
7.9 -Cell 3 || Cell 4
7.10 -}}}
7.11 -
7.12 -Wiki format again
8.1 --- a/tests/test2.txt Mon Jul 16 00:08:09 2018 +0200
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,13 +0,0 @@
8.4 -XXX
8.5 - * Item 1
8.6 - * Item 1.1
8.7 - * Item 2
8.8 - . Item 3
8.9 - . Item 3.1
8.10 - . Item 3.1.1
8.11 - * Item A
8.12 -XXX
8.13 - * Boring
8.14 - * Flat
8.15 - * List
8.16 -XXX
9.1 --- a/tests/test3.txt Mon Jul 16 00:08:09 2018 +0200
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,24 +0,0 @@
9.4 -XXX
9.5 - a. Appendix
9.6 -
9.7 - i. Romanus eunt domus!
9.8 - I. What did they do for us?
9.9 - I. {{{Did for us}}}
9.10 - 1. {{{
9.11 -Doing ''for'' us}}}
9.12 - 1. {{{#!python
9.13 -motto = "Romanus eunt domus!"
9.14 -}}}
9.15 - a.#18 The Romans.
9.16 -
9.17 - 1. Starting from one
9.18 - 1. Two
9.19 - 1.#3 Three?
9.20 - 1. Four?
9.21 - 1. Three
9.22 - 1.#10 New list at ten
9.23 -
9.24 - I.#100 Century
9.25 - I. Century plus one
9.26 -
9.27 -The end!
10.1 --- a/tests/test4.txt Mon Jul 16 00:08:09 2018 +0200
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,5 +0,0 @@
10.4 - term:: item
10.5 -not a term:: nor an item
10.6 - term::
10.7 - :: item
10.8 - ::non-item
12.1 --- a/tests/test6.txt Mon Jul 16 00:08:09 2018 +0200
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,7 +0,0 @@
12.4 -Hello
12.5 -{{{{
12.6 -Start
12.7 -}}}
12.8 -Still in region
12.9 -}}}}
12.10 -End
13.1 --- a/tests/test7.txt Mon Jul 16 00:08:09 2018 +0200
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,1 +0,0 @@
13.4 -Hello {{{world}}} again
14.1 --- a/tests/test8.txt Mon Jul 16 00:08:09 2018 +0200
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,3 +0,0 @@
14.4 -XXX
14.5 -
14.6 -YYY
15.1 --- a/tests/test9.txt Mon Jul 16 00:08:09 2018 +0200
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,6 +0,0 @@
15.4 -XXX
15.5 -----
15.6 -YYY
15.7 - ----still a rule
15.8 -also still a rule----
15.9 -EOF
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/tests/test_deflists.txt Mon Jul 16 19:20:37 2018 +0200
17.3 @@ -0,0 +1,5 @@
17.4 + term:: item
17.5 +not a term:: nor an item
17.6 + term::
17.7 + :: item
17.8 + ::non-item
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/tests/test_formatting.txt Mon Jul 16 19:20:37 2018 +0200
19.3 @@ -0,0 +1,17 @@
19.4 +''Some'' emphasised text. ''Emphasised''''text''.
19.5 +
19.6 +'''Strong ''and italic'' text.'''
19.7 +
19.8 +''Italic and '''strong'''''. '''''Both'', strong'''. '''''Both''', italic''.
19.9 +
19.10 +'''Strong''''''text'''.
19.11 +
19.12 +Some `monospace` text. `Mono, '''strong'''`, `mono, `'''`strong`''', __underlined__, __''under''lined__.
19.13 +
19.14 +H,,2,,O + CO,,2,,
19.15 +
19.16 +== e = mc^2^ ==
19.17 +
19.18 +~+Larger...+~ and ~-smaller-~
19.19 +
19.20 +Some --(deleted)-- text.
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/tests/test_headings.txt Mon Jul 16 19:20:37 2018 +0200
20.3 @@ -0,0 +1,9 @@
20.4 += Level 1 =
20.5 +Text
20.6 + == Level 2 Heading ==
20.7 +Text
20.8 +Not == a heading ==
20.9 +== Not a heading == either
20.10 += Mismatched heading ==
20.11 +== Another mismatched heading =
20.12 +=== Heading __Underlined__ ===
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/tests/test_paragraphs.txt Mon Jul 16 19:20:37 2018 +0200
23.3 @@ -0,0 +1,3 @@
23.4 +XXX
23.5 +
23.6 +YYY
24.1 --- a/tests/test_parser.py Mon Jul 16 00:08:09 2018 +0200
24.2 +++ b/tests/test_parser.py Mon Jul 16 19:20:37 2018 +0200
24.3 @@ -1,6 +1,6 @@
24.4 #!/usr/bin/env python
24.5
24.6 -from os.path import abspath, join, split
24.7 +from os.path import abspath, exists, join, split
24.8 import sys
24.9
24.10 dirname = split(abspath(sys.argv[0]))[0]
24.11 @@ -12,43 +12,186 @@
24.12 if split(parent)[1] == "MoinLight":
24.13 sys.path.append(parent)
24.14
24.15 -from moinformat import parse, parsers, serialise, serialisers
24.16 +from moinformat import all_parsers, all_serialisers, parse, serialise
24.17 +from moinformat.tree import Container
24.18 from glob import glob
24.19
24.20 -def test_input(s):
24.21 - d = parse(s, parsers)
24.22 +def test_input(d, s):
24.23 +
24.24 + "Compare serialised output from 'd' with its original form 's'."
24.25 +
24.26 o = serialise(d)
24.27
24.28 - print o == s
24.29 + identical = o == s
24.30
24.31 if quiet:
24.32 - return
24.33 + return identical
24.34
24.35 + # Show output versus input comparison result.
24.36 +
24.37 + print identical
24.38 print "-" * 60
24.39 print o
24.40 - if o != s:
24.41 + if not identical:
24.42 print "-" * 60
24.43 print s
24.44 print "-" * 60
24.45 - print serialise(d, serialisers["html"])
24.46 + print serialise(d, all_serialisers["html"])
24.47 + print "-" * 60
24.48 + print
24.49 +
24.50 + return identical
24.51 +
24.52 +def test_tree(d, t, ts):
24.53 +
24.54 + "Compare tree structure 'd' with simplified, expected form 't' from 'ts'."
24.55 +
24.56 + failing = t.test(d)
24.57 +
24.58 + if quiet:
24.59 + return not failing
24.60 +
24.61 + # Show tree versus expected forms.
24.62 +
24.63 + print not failing
24.64 print "-" * 60
24.65 print d.prettyprint()
24.66 + if failing:
24.67 + simple, tree = failing
24.68 + print "-" * 60
24.69 + print tree.prettyprint()
24.70 + print "-" * 60
24.71 + print simple.prettyprint()
24.72 + print "-" * 60
24.73 + print ts
24.74 + print "-" * 60
24.75 print
24.76
24.77 + return not failing
24.78 +
24.79 +class Node:
24.80 +
24.81 + "A simplified tree node representation."
24.82 +
24.83 + def __init__(self, name):
24.84 + self.name = name
24.85 + self.nodes = []
24.86 +
24.87 + def __repr__(self):
24.88 + return "Node(%r, ...)" % self.name
24.89 +
24.90 + def prettyprint(self, indent=""):
24.91 + l = [indent + self.name]
24.92 + for node in self.nodes:
24.93 + l.append(node.prettyprint(indent + " "))
24.94 + return "\n".join(l)
24.95 +
24.96 + def append(self, node):
24.97 + self.nodes.append(node)
24.98 +
24.99 + def test(self, other):
24.100 +
24.101 + """
24.102 + Test whether this node is considered equivalent to 'other', where
24.103 + 'other' is a moinparser.tree node.
24.104 +
24.105 + Return any failing tree nodes or None.
24.106 + """
24.107 +
24.108 + if other.__class__.__name__ != self.name:
24.109 + return self, other
24.110 +
24.111 + if isinstance(other, Container):
24.112 + for node, other_node in map(None, self.nodes, other.nodes):
24.113 + if node is None or other_node is None:
24.114 + return self, other
24.115 + if node.test(other_node):
24.116 + return node, other_node
24.117 +
24.118 + return None
24.119 +
24.120 +def parse_tree(s):
24.121 +
24.122 + "Parse the tree structure representation in 's'."
24.123 +
24.124 + indent = 0
24.125 + branches = []
24.126 +
24.127 + for line in s.split("\n"):
24.128 + line = line.rstrip()
24.129 + if not line:
24.130 + continue
24.131 +
24.132 + new_indent = line.rfind(" ") + 1
24.133 + node = Node(line[new_indent:])
24.134 +
24.135 + # Establish a branch to add nodes to.
24.136 +
24.137 + if not branches:
24.138 + branches.append(node)
24.139 + else:
24.140 + # Note the current node as outermost branch.
24.141 +
24.142 + if new_indent > indent:
24.143 + branches.append(node)
24.144 + else:
24.145 + # Reduced indent involves obtaining an inner branch again.
24.146 +
24.147 + while indent > new_indent:
24.148 + del branches[-1]
24.149 + indent -= 2
24.150 +
24.151 + # Note the current node as outermost branch.
24.152 +
24.153 + branches[-1] = node
24.154 +
24.155 + # Append the current node to the parent branch.
24.156 +
24.157 + branches[-2].append(node)
24.158 +
24.159 + indent = new_indent
24.160 +
24.161 + return branches[0]
24.162 +
24.163 +def readfile(filename):
24.164 +
24.165 + "Read the contents of 'filename' and return them."
24.166 +
24.167 + f = open(filename)
24.168 + try:
24.169 + return f.read()
24.170 + finally:
24.171 + f.close()
24.172 +
24.173 if __name__ == "__main__":
24.174 args = sys.argv[1:]
24.175 +
24.176 quiet = "-q" in args
24.177 if quiet:
24.178 del args[args.index("-q")]
24.179 +
24.180 filenames = args or glob(join(dirname, "test*.txt"))
24.181 filenames.sort()
24.182
24.183 for filename in filenames:
24.184 - f = open(filename)
24.185 - try:
24.186 + tree_filename = "%s.tree" % filename.rsplit(".", 1)[0]
24.187 +
24.188 + s = readfile(filename)
24.189 + d = parse(s, all_parsers)
24.190 +
24.191 + if exists(tree_filename):
24.192 + ts = readfile(tree_filename)
24.193 + t = parse_tree(ts)
24.194 + else:
24.195 + ts = None
24.196 +
24.197 + if not quiet:
24.198 print filename
24.199 - test_input(f.read())
24.200 - finally:
24.201 - f.close()
24.202 +
24.203 + identical = test_input(d, s)
24.204 + tree_identical = ts and test_tree(d, t, ts)
24.205 +
24.206 + if quiet:
24.207 + print "%s %s: %s" % (identical, tree_identical, filename)
24.208
24.209 # vim: tabstop=4 expandtab shiftwidth=4
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/tests/test_region_endings.txt Mon Jul 16 19:20:37 2018 +0200
25.3 @@ -0,0 +1,7 @@
25.4 +Hello
25.5 +{{{{
25.6 +Start
25.7 +}}}
25.8 +Still in region
25.9 +}}}}
25.10 +End
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/tests/test_regions_inline.txt Mon Jul 16 19:20:37 2018 +0200
27.3 @@ -0,0 +1,1 @@
27.4 +Hello {{{world}}} again
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/tests/test_rules.txt Mon Jul 16 19:20:37 2018 +0200
29.3 @@ -0,0 +1,6 @@
29.4 +XXX
29.5 +----
29.6 +YYY
29.7 + ----still a rule
29.8 +also still a rule----
29.9 +EOF
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/tests/test_table_parser.txt Mon Jul 16 19:20:37 2018 +0200
30.3 @@ -0,0 +1,9 @@
30.4 +Wiki format
30.5 +
30.6 +{{{#!table
30.7 +'''Cell 1''' || Cell 2
30.8 +==
30.9 +Cell 3 || Cell 4
30.10 +}}}
30.11 +
30.12 +Wiki format again
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/tests/test_tables.txt Mon Jul 16 19:20:37 2018 +0200
31.3 @@ -0,0 +1,10 @@
31.4 +||<20%|2-2)^> Cell 1 || Cell 2 ||
31.5 +|| '''Cell 3''' ||<#FF0000 width="15%"> ''Cell 4'' ||
31.6 +
31.7 +|| Not a table
31.8 + || Also not a table
31.9 +|| Almost a table || ...
31.10 +|| A table, trailing space ||
31.11 +
31.12 +||<20%%name="value"> Bad separator ||
31.13 +||<20%xx-2> Strange attributes ||