1.1 --- a/moinformat/parsers/common.py Sun Jul 15 14:19:42 2018 +0200
1.2 +++ b/moinformat/parsers/common.py Sun Jul 15 19:20:41 2018 +0200
1.3 @@ -26,6 +26,44 @@
1.4 # Pattern management.
1.5
1.6 ws_excl_nl = r"[ \f\r\t\v]"
1.7 +quotes = "['" '"]' # ['"]
1.8 +
1.9 +def excl(s):
1.10 +
1.11 + "Return a non-matching pattern for 's'."
1.12 +
1.13 + return "(?!%s)" % s
1.14 +
1.15 +def expect(s):
1.16 +
1.17 + "Return a pattern expecting 's'."
1.18 +
1.19 + return "(?=%s)" % s
1.20 +
1.21 +def group(name, s):
1.22 +
1.23 + "Return a pattern group having 'name' and the pattern string 's'."
1.24 +
1.25 + return "(?P<%s>%s)" % (name, s)
1.26 +
1.27 +def optional(s):
1.28 +
1.29 + "Return an optional pattern."
1.30 +
1.31 + return "(?:%s)?" % s
1.32 +
1.33 +def recur(name):
1.34 +
1.35 + "Return a test for a recurrence of group 'name'."
1.36 +
1.37 + return "(?P=%s)" % name
1.38 +
1.39 +def repeat(s, min=None, max=None):
1.40 +
1.41 + "Return a pattern matching 's' for the given 'min' and 'max' limits."
1.42 +
1.43 + return "%s{%s,%s}" % (s, min is not None and min or "",
1.44 + max is not None and max or "")
1.45
1.46 def get_patterns(syntax):
1.47
1.48 @@ -38,6 +76,7 @@
1.49 patterns = {}
1.50 for name, value in syntax.items():
1.51 value = value.replace(r"\N", ws_excl_nl)
1.52 + value = value.replace(r"\Q", quotes)
1.53 patterns[name] = re.compile(value, re.UNICODE | re.MULTILINE)
1.54 return patterns
1.55
1.56 @@ -317,7 +356,7 @@
1.57 """
1.58
1.59 if self.read_until(["header"], False) == "": # None means no header
1.60 - region.type = self.match_group()
1.61 + region.type = self.match_group("args")
1.62
1.63 def parse_region_opaque(self, region):
1.64