Mercurial > hatta
changeset 2485:c2bd1f3dcd4b
Recursive block quote parsing
| author | Sam Toyer <sam@qxcv.net> |
|---|---|
| date | Fri, 24 Jun 2016 14:42:58 +1000 |
| parents | 38c292be7040 |
| children | c022854d3895 |
| files | hatta/parser.py tests/test_hatta.py tests/test_parser.py |
| diffstat | 3 files changed, 60 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/hatta/parser.py Sun Apr 17 12:58:17 2016 -0400 +++ b/hatta/parser.py Fri Jun 24 14:42:58 2016 +1000 @@ -219,19 +219,18 @@ yield ret links[:] = [] - def parse(self): + def parse(self, enumerated_lines=None): """Parse a list of lines of wiki markup, yielding HTML for it.""" - self.headings = {} - self.stack = [] - self.line_no = 0 + if enumerated_lines is None: + enumerated_lines = self.enumerated_lines def key(enumerated_line): line_no, line = enumerated_line name, params = self.block_rules.match_one(line) return name or "_block_paragraph" - for kind, block in itertools.groupby(self.enumerated_lines, key): + for kind, block in itertools.groupby(enumerated_lines, key): func = getattr(self, kind) for part in func(block): yield part @@ -546,32 +545,18 @@ @block_rules(quote_pat, 80) def _block_quote(self, block): - level = 0 - in_p = False - for self.line_no, line in block: - nest = len(self.quote_re.match(line).group(0).strip()) - if nest == level: - yield u'\n' - while nest > level: - if in_p: - yield '%s</p>' % self.pop_to("") - in_p = False - yield '<blockquote>' - level += 1 - while nest < level: - if in_p: - yield '%s</p>' % self.pop_to("") - in_p = False - yield '</blockquote>' - level -= 1 - content = line.lstrip().lstrip('>').strip() - if not in_p: - yield '<p id="line_%d">' % self.line_no - in_p = True - yield u"".join(self.parse_line(content)) - if in_p: - yield '%s</p>' % self.pop_to("") - yield '</blockquote>' * level + yield '<blockquote>' + + def remove_lead(enumerated_line): + line_no, line = enumerated_line + stripped = line.lstrip()[1:].lstrip() + return (line_no, stripped) + + enumerated_lines = map(remove_lead, block) + for content in self.parse(enumerated_lines): + yield content + + yield '</blockquote>' @block_rules(ur"^<<<<<<< local\s*$", 30) def _block_conflict(self, block):
--- a/tests/test_hatta.py Sun Apr 17 12:58:17 2016 -0400 +++ b/tests/test_hatta.py Fri Jun 24 14:42:58 2016 +1000 @@ -138,12 +138,17 @@ return u"<a></a>" def image(addr, label=None, class_=None, image=None, alt=None): return u"<img>" - return u''.join(parser(text.split('\n'), link, image)) + lines = '\n\r'.join(text.split('\n')).split('\r') + return u''.join(parser(lines, link, image)) test_cases = { u"""hello world""": u"""<p id="line_0">hello world</p>""", #-------------------------------------------------------------------- +u"""hello +world""": u"""<p id="line_0">hello +world</p>""", +#-------------------------------------------------------------------- u"""{{{ some code more @@ -152,7 +157,8 @@ {{{ more code }}}""": u"""<pre class="code" id="line_1">some code -more</pre><p id="line_4">some text</p><pre class="code" id="line_6">more code</pre>""", +more</pre><p id="line_4">some text +</p><pre class="code" id="line_6">more code</pre>""", #-------------------------------------------------------------------- u"""{{{#!python some code @@ -162,16 +168,20 @@ {{{#!bash more code }}}""": u"""<div class="highlight"><pre id="line_1">some code -more</pre></div><p id="line_4">some text</p><div class="highlight"><pre id="line_6">more code</pre></div>""", +more</pre></div><p id="line_4">some text +</p><div class="highlight"><pre id="line_6">more code</pre></div>""", #-------------------------------------------------------------------- u"""Here's a quote: > Here is > another //quote//: >> A quote **within >> a quote -normal text""": u"""<p id="line_0">Here's a quote:</p><blockquote><p id="line_1">Here is -another <i>quote</i>:</p><blockquote><p id="line_3">A quote <b>within -a quote</b></p></blockquote></blockquote><p id="line_5">normal text</p>""", +normal text""": u"""<p id="line_0">Here's a quote: +</p><blockquote><p id="line_1">Here is +another <i>quote</i>: +</p><blockquote><p id="line_3">A quote <b>within +a quote +</b></p></blockquote></blockquote><p id="line_5">normal text</p>""", #-------------------------------------------------------------------- u"""* sample list ** sublist
--- a/tests/test_parser.py Sun Apr 17 12:58:17 2016 -0400 +++ b/tests/test_parser.py Fri Jun 24 14:42:58 2016 +1000 @@ -397,3 +397,31 @@ html = parse(u'This is ##monotyped## text.') assert html == """<p id="line_0">This is <tt>monotyped</tt> text.</p>""" + def test_inline_quote(self): + html = parse(u'> //Simple// quote with\n> one paragraph') + assert html == """ + <blockquote> + <p id="line_0"><i>Simple</i> quote with\none paragraph</p> + </blockquote> + """ + + def test_block_quote(self): + html = parse(u'> //Complex// quote\n> with\n>\n> = extra markup') + assert html == """ + <blockquote> + <p id="line_0"><i>Complex</i> quote\nwith</p> + <a name="head-1"></a><h1 id="line_3">extra markup</h1> + </blockquote> + """ + + def test_nested_quotes(self): + html = parse(u'> Outer quote\n>> Inner quote') + assert html == """ + <blockquote> + <p id="line_0">Outer quote</p> + <blockquote> + <p id="line_1">Inner quote</p> + </blockquote> + </blockquote> + """ +
