1.1 --- a/moinformat/__init__.py Mon May 01 00:29:59 2017 +0200
1.2 +++ b/moinformat/__init__.py Mon May 01 18:24:22 2017 +0200
1.3 @@ -19,8 +19,8 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from moinformat.tree import Block, Break, DefItem, DefTerm, Emphasis, Heading, \
1.8 - ListItem, Region, Rule, Strong, Text
1.9 +from moinformat.tree import Block, Break, DefItem, DefTerm, FontStyle, Heading, \
1.10 + ListItem, Monospace, Region, Rule, Text
1.11 import re
1.12
1.13 # Regular expressions.
1.14 @@ -54,13 +54,12 @@
1.15
1.16 # Region contents:
1.17 # Inline patterns:
1.18 - "em" : r"''(?!')", # '' expecting not '
1.19 + "fontstyle" : r"('{2,6})",
1.20 + "monospace" : r"`",
1.21 "rule" : r"(-----*)", # ----...
1.22 - "strong" : r"'''", # '''
1.23
1.24 # Inline contents:
1.25 - "emend" : r"''(?!')|''(?='')",
1.26 - "strongend" : r"'''",
1.27 + "monospaceend" : r"`",
1.28
1.29 # Heading contents:
1.30 "headingend" : r"(\s+)(=+)(\s*\n)", # ws... =... [ws...] nl
1.31 @@ -91,6 +90,12 @@
1.32 self.match = None
1.33 self.matching = None
1.34
1.35 + def rewind(self, length):
1.36 +
1.37 + "Rewind in the string by 'length'."
1.38 +
1.39 + self.pos -= min(length, self.pos)
1.40 +
1.41 def read_until(self, pattern_names, remaining=True):
1.42
1.43 """
1.44 @@ -191,12 +196,13 @@
1.45 parse_region_details(items, region, [
1.46 "break", "heading",
1.47 "defterm", "defterm_empty",
1.48 - "em",
1.49 + "fontstyle",
1.50 "listitem", "listitem_alpha", "listitem_dot", "listitem_num",
1.51 "listitem_roman",
1.52 + "monospace",
1.53 "regionstart", "regionend",
1.54 "rule",
1.55 - "strong"])
1.56 + ])
1.57
1.58 def parse_region_opaque(items, region):
1.59
1.60 @@ -281,12 +287,43 @@
1.61 parse_region_details(items, region, ["deftermsep"])
1.62 parse_defitem(items, region, extra)
1.63
1.64 -def parse_em(items, region):
1.65 +def parse_fontstyle(items, region):
1.66 +
1.67 + "Handle emphasis and strong styles."
1.68 +
1.69 + n = len(items.read_match(1))
1.70 +
1.71 + # Handle endings.
1.72 +
1.73 + if isinstance(region, FontStyle):
1.74 + emphasis = n in (2, 4, 5)
1.75 + strong = n in (3, 5, 6)
1.76 + active = True
1.77
1.78 - "Handle emphasis."
1.79 + if region.emphasis and emphasis:
1.80 + active = region.close_emphasis()
1.81 + n -= 2
1.82 + if region.strong and strong:
1.83 + active = region.close_strong()
1.84 + n -= 3
1.85 +
1.86 + if not active:
1.87 + if n:
1.88 + items.rewind(n)
1.89 + raise StopIteration
1.90
1.91 - span = Emphasis([])
1.92 - parse_region_details(items, span, ["emend", "strong"])
1.93 + elif not n:
1.94 + return
1.95 +
1.96 + # Handle new styles.
1.97 +
1.98 + emphasis = n in (2, 4, 5)
1.99 + strong = n in (3, 5, 6)
1.100 + double = n in (4, 6)
1.101 +
1.102 + span = FontStyle([], emphasis, strong)
1.103 + if not double:
1.104 + parse_region_details(items, span, ["fontstyle", "monospace"])
1.105 region.append_inline(span)
1.106
1.107 def parse_heading(items, region):
1.108 @@ -323,6 +360,14 @@
1.109 region.append(item)
1.110 new_block(region)
1.111
1.112 +def parse_monospace(items, region):
1.113 +
1.114 + "Handle monospace."
1.115 +
1.116 + span = Monospace([])
1.117 + parse_region_details(items, span, ["fontstyle", "monospaceend"])
1.118 + region.append_inline(span)
1.119 +
1.120 def parse_rule(items, region):
1.121
1.122 "Handle a horizontal rule within 'region'."
1.123 @@ -353,14 +398,6 @@
1.124 else:
1.125 region.append_inline(Text(feature))
1.126
1.127 -def parse_strong(items, region):
1.128 -
1.129 - "Handle emboldened text."
1.130 -
1.131 - span = Strong([])
1.132 - parse_region_details(items, span, ["em", "strongend"])
1.133 - region.append_inline(span)
1.134 -
1.135 # Pattern handlers.
1.136
1.137 handlers = {
1.138 @@ -370,8 +407,7 @@
1.139 "defterm_empty" : parse_defterm_empty,
1.140 "deftermend" : end_region,
1.141 "deftermsep" : end_region,
1.142 - "em" : parse_em,
1.143 - "emend" : end_region,
1.144 + "fontstyle" : parse_fontstyle,
1.145 "heading" : parse_heading,
1.146 "headingend" : parse_heading_end,
1.147 "listitemend" : end_region,
1.148 @@ -380,11 +416,11 @@
1.149 "listitem_dot" : parse_listitem,
1.150 "listitem_num" : parse_listitem,
1.151 "listitem_roman" : parse_listitem,
1.152 + "monospace" : parse_monospace,
1.153 + "monospaceend" : end_region,
1.154 "regionstart" : parse_section,
1.155 "regionend" : parse_section_end,
1.156 "rule" : parse_rule,
1.157 - "strong" : parse_strong,
1.158 - "strongend" : end_region,
1.159 }
1.160
1.161 def new_block(region):