# HG changeset patch # User Paul Boddie # Date 1493655862 -7200 # Node ID ca3330f1c2342ab8c828f5db727b90447da24b24 # Parent 6b231d75d301926dcac6fd8ec54e0d1cdabb15e5 Merged handling of emphasised and strong text. Added monospaced text support. diff -r 6b231d75d301 -r ca3330f1c234 moinformat/__init__.py --- a/moinformat/__init__.py Mon May 01 00:29:59 2017 +0200 +++ b/moinformat/__init__.py Mon May 01 18:24:22 2017 +0200 @@ -19,8 +19,8 @@ this program. If not, see . """ -from moinformat.tree import Block, Break, DefItem, DefTerm, Emphasis, Heading, \ - ListItem, Region, Rule, Strong, Text +from moinformat.tree import Block, Break, DefItem, DefTerm, FontStyle, Heading, \ + ListItem, Monospace, Region, Rule, Text import re # Regular expressions. @@ -54,13 +54,12 @@ # Region contents: # Inline patterns: - "em" : r"''(?!')", # '' expecting not ' + "fontstyle" : r"('{2,6})", + "monospace" : r"`", "rule" : r"(-----*)", # ----... - "strong" : r"'''", # ''' # Inline contents: - "emend" : r"''(?!')|''(?='')", - "strongend" : r"'''", + "monospaceend" : r"`", # Heading contents: "headingend" : r"(\s+)(=+)(\s*\n)", # ws... =... [ws...] nl @@ -91,6 +90,12 @@ self.match = None self.matching = None + def rewind(self, length): + + "Rewind in the string by 'length'." + + self.pos -= min(length, self.pos) + def read_until(self, pattern_names, remaining=True): """ @@ -191,12 +196,13 @@ parse_region_details(items, region, [ "break", "heading", "defterm", "defterm_empty", - "em", + "fontstyle", "listitem", "listitem_alpha", "listitem_dot", "listitem_num", "listitem_roman", + "monospace", "regionstart", "regionend", "rule", - "strong"]) + ]) def parse_region_opaque(items, region): @@ -281,12 +287,43 @@ parse_region_details(items, region, ["deftermsep"]) parse_defitem(items, region, extra) -def parse_em(items, region): +def parse_fontstyle(items, region): + + "Handle emphasis and strong styles." + + n = len(items.read_match(1)) + + # Handle endings. + + if isinstance(region, FontStyle): + emphasis = n in (2, 4, 5) + strong = n in (3, 5, 6) + active = True - "Handle emphasis." + if region.emphasis and emphasis: + active = region.close_emphasis() + n -= 2 + if region.strong and strong: + active = region.close_strong() + n -= 3 + + if not active: + if n: + items.rewind(n) + raise StopIteration - span = Emphasis([]) - parse_region_details(items, span, ["emend", "strong"]) + elif not n: + return + + # Handle new styles. + + emphasis = n in (2, 4, 5) + strong = n in (3, 5, 6) + double = n in (4, 6) + + span = FontStyle([], emphasis, strong) + if not double: + parse_region_details(items, span, ["fontstyle", "monospace"]) region.append_inline(span) def parse_heading(items, region): @@ -323,6 +360,14 @@ region.append(item) new_block(region) +def parse_monospace(items, region): + + "Handle monospace." + + span = Monospace([]) + parse_region_details(items, span, ["fontstyle", "monospaceend"]) + region.append_inline(span) + def parse_rule(items, region): "Handle a horizontal rule within 'region'." @@ -353,14 +398,6 @@ else: region.append_inline(Text(feature)) -def parse_strong(items, region): - - "Handle emboldened text." - - span = Strong([]) - parse_region_details(items, span, ["em", "strongend"]) - region.append_inline(span) - # Pattern handlers. handlers = { @@ -370,8 +407,7 @@ "defterm_empty" : parse_defterm_empty, "deftermend" : end_region, "deftermsep" : end_region, - "em" : parse_em, - "emend" : end_region, + "fontstyle" : parse_fontstyle, "heading" : parse_heading, "headingend" : parse_heading_end, "listitemend" : end_region, @@ -380,11 +416,11 @@ "listitem_dot" : parse_listitem, "listitem_num" : parse_listitem, "listitem_roman" : parse_listitem, + "monospace" : parse_monospace, + "monospaceend" : end_region, "regionstart" : parse_section, "regionend" : parse_section_end, "rule" : parse_rule, - "strong" : parse_strong, - "strongend" : end_region, } def new_block(region): diff -r 6b231d75d301 -r ca3330f1c234 moinformat/serialisers.py --- a/moinformat/serialisers.py Mon May 01 00:29:59 2017 +0200 +++ b/moinformat/serialisers.py Mon May 01 18:24:22 2017 +0200 @@ -80,6 +80,12 @@ def end_listitem(self, indent, marker): pass + def start_monospace(self): + self.out("`") + + def end_monospace(self): + self.out("`") + def start_strong(self): self.out("'''") @@ -154,6 +160,12 @@ def end_listitem(self, indent, marker): self.out("") + def start_monospace(self): + self.out("") + + def end_monospace(self): + self.out("") + def start_strong(self): self.out("") diff -r 6b231d75d301 -r ca3330f1c234 moinformat/tree.py --- a/moinformat/tree.py Mon May 01 00:29:59 2017 +0200 +++ b/moinformat/tree.py Mon May 01 18:24:22 2017 +0200 @@ -187,21 +187,46 @@ self._to_string(out) out.end_defterm(self.pad) -class Emphasis(Container): +class FontStyle(Container): + + "Emphasised and/or strong text." + + def __init__(self, nodes, emphasis=False, strong=False): + Container.__init__(self, nodes) + self.emphasis = emphasis + self.strong = strong - "Emphasised text." + def close_emphasis(self): + if self.strong: + span = FontStyle(self.nodes, emphasis=True) + self.nodes = [span] + self.emphasis = False + return self.strong + + def close_strong(self): + if self.emphasis: + span = FontStyle(self.nodes, strong=True) + self.nodes = [span] + self.strong = False + return self.emphasis def __repr__(self): - return "Emphasis(%r)" % self.nodes + return "FontStyle(%r, %r, %r)" % (self.nodes, self.emphasis, self.strong) def prettyprint(self, indent=""): - l = ["%sEmphasis" % indent] + l = ["%sFontStyle: emphasis=%r strong=%r" % (indent, self.emphasis, self.strong)] return self._prettyprint(l, indent) def to_string(self, out): - out.start_emphasis() + if self.emphasis: + out.start_emphasis() + elif self.strong: + out.start_strong() self._to_string(out) - out.end_emphasis() + if self.emphasis: + out.end_emphasis() + elif self.strong: + out.end_strong() class Heading(Container): @@ -251,21 +276,21 @@ self._to_string(out) out.end_listitem(self.indent, self.marker) -class Strong(Container): +class Monospace(Container): - "Emboldened text." + "Monospace text." def __repr__(self): - return "Strong(%r)" % self.nodes + return "Monospace(%r)" % self.nodes def prettyprint(self, indent=""): - l = ["%sStrong" % indent] + l = ["%sMonospace" % indent] return self._prettyprint(l, indent) def to_string(self, out): - out.start_strong() + out.start_monospace() self._to_string(out) - out.end_strong() + out.end_monospace() diff -r 6b231d75d301 -r ca3330f1c234 tests/test_parser.py --- a/tests/test_parser.py Mon May 01 00:29:59 2017 +0200 +++ b/tests/test_parser.py Mon May 01 18:24:22 2017 +0200 @@ -93,17 +93,15 @@ """) sl.append("""\ -Hello ''emphasised text''. - -''More'' emphasised text. - -''Emphasised''''text''. - -Some '''strong''' text. +''Some'' emphasised text. ''Emphasised''''text''. '''Strong ''and italic'' text.''' -''Italic and '''strong'''''. +''Italic and '''strong'''''. '''''Both'', strong'''. '''''Both''', italic''. + +'''Strong''''''text'''. + +Some `monospace` text. '''`Mono`, strong'''. """) dl = map(parse, sl)