From fb65ed196df567ab71d63029e7ab36002b12112e Mon Sep 17 00:00:00 2001 From: Mustafa Haddara Date: Thu, 22 Oct 2015 10:33:54 -0400 Subject: Fixed handling of table cell split --- markdown/extensions/tables.py | 51 +++++++++++++++++++++++++++-- tests/extensions/extra/tables.html | 67 ++++++++++++++++++++++++++++++++++++++ tests/extensions/extra/tables.txt | 18 +++++++++- tests/extensions/test.cfg | 2 +- 4 files changed, 134 insertions(+), 4 deletions(-) diff --git a/markdown/extensions/tables.py b/markdown/extensions/tables.py index 368321d..494aaeb 100644 --- a/markdown/extensions/tables.py +++ b/markdown/extensions/tables.py @@ -19,6 +19,7 @@ from __future__ import absolute_import from __future__ import unicode_literals from . import Extension from ..blockprocessors import BlockProcessor +from ..inlinepatterns import BacktickPattern, BACKTICK_RE from ..util import etree @@ -72,7 +73,11 @@ class TableProcessor(BlockProcessor): for i, a in enumerate(align): c = etree.SubElement(tr, tag) try: - c.text = cells[i].strip() + if isinstance(cells[i], str) or isinstance(cells[i], unicode): + c.text = cells[i].strip() + else: + # we've already inserted a code element + c.append(cells[i]) except IndexError: # pragma: no cover c.text = "" if a: @@ -85,7 +90,49 @@ class TableProcessor(BlockProcessor): row = row[1:] if row.endswith('|'): row = row[:-1] - return row.split('|') + return self._split(row, '|') + + def _split(self, row, marker): + """ split a row of text with some code into a list of cells. """ + if self._row_has_unpaired_backticks(row): + # fallback on old behaviour + return row.split(marker) + # modify the backtick pattern to only match at the beginning of the search string + backtick_pattern = BacktickPattern('^' + BACKTICK_RE) + elements = [] + current = '' + i = 0 + while i < len(row): + letter = row[i] + if letter == marker: + if current != '' or len(elements) == 0: + # Don't append empty string unless it is the first element + # The border is already removed when we get the row, then the line is strip()'d + # If the first element is a marker, then we have an empty first cell + elements.append(current) + current = '' + else: + match = backtick_pattern.getCompiledRegExp().match(row[i:]) + if not match: + current += letter + else: + groups = match.groups() + delim = groups[1] # the code block delimeter (ie 1 or more backticks) + row_contents = groups[2] # the text contained inside the code block + i += match.start(4) # jump pointer to the beginning of the rest of the text (group #4) + element = delim + row_contents + delim # reinstert backticks + current += element + i += 1 + elements.append(current) + return elements + + def _row_has_unpaired_backticks(self, row): + count_total_backtick = row.count('`') + count_escaped_backtick = row.count('\`') + count_backtick = count_total_backtick - count_escaped_backtick + # odd number of backticks, + # we won't be able to build correct code blocks + return count_backtick & 1 class TableExtension(Extension): diff --git a/tests/extensions/extra/tables.html b/tests/extensions/extra/tables.html index 85a998d..91337e5 100644 --- a/tests/extensions/extra/tables.html +++ b/tests/extensions/extra/tables.html @@ -168,4 +168,71 @@ Content Cell | Content Cell + +

More inline code block tests

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Column 1Column 2Column 3
word 1word 2word 3
word 1word 2word 3
word 1`word 2word 3
word 1`word 2word 3
word 1word |2word 3
wordssome | codemore words
wordssome | codemore words
wordssome | codemore words
wordssome ` | ` codemore words
wordssome ` | ` codemore words
wordssome ` | ` codemore words
\ No newline at end of file diff --git a/tests/extensions/extra/tables.txt b/tests/extensions/extra/tables.txt index 8acc3c6..1602d1f 100644 --- a/tests/extensions/extra/tables.txt +++ b/tests/extensions/extra/tables.txt @@ -52,4 +52,20 @@ Four spaces is a code block: Content Cell | Content Cell | First Header | Second Header | -| ------------ | ------------- | \ No newline at end of file +| ------------ | ------------- | + +More inline code block tests + +Column 1 | Column 2 | Column 3 +---------|----------|--------- +word 1 | word 2 | word 3 +word 1 | `word 2` | word 3 +word 1 | \`word 2 | word 3 +word 1 | `word 2 | word 3 +word 1 | `word |2` | word 3 +words |`` some | code `` | more words +words |``` some | code ``` | more words +words |```` some | code ```` | more words +words |`` some ` | ` code `` | more words +words |``` some ` | ` code ``` | more words +words |```` some ` | ` code ```` | more words \ No newline at end of file diff --git a/tests/extensions/test.cfg b/tests/extensions/test.cfg index 7e27b29..ce66cfc 100644 --- a/tests/extensions/test.cfg +++ b/tests/extensions/test.cfg @@ -70,4 +70,4 @@ smarty: - markdown.extensions.smarty extension_configs: markdown.extensions.smarty: - smart_angled_quotes: True + smart_angled_quotes: True \ No newline at end of file -- cgit v1.2.3