Skip to content

Commit 2e4f1f7

Browse files
committed
Merge pull request #437 from MustafaHaddara/table-inline-code
Table inline code
2 parents 20b17c2 + fb65ed1 commit 2e4f1f7

File tree

4 files changed

+134
-4
lines changed

4 files changed

+134
-4
lines changed

markdown/extensions/tables.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from __future__ import unicode_literals
2020
from . import Extension
2121
from ..blockprocessors import BlockProcessor
22+
from ..inlinepatterns import BacktickPattern, BACKTICK_RE
2223
from ..util import etree
2324

2425

@@ -72,7 +73,11 @@ def _build_row(self, row, parent, align, border):
7273
for i, a in enumerate(align):
7374
c = etree.SubElement(tr, tag)
7475
try:
75-
c.text = cells[i].strip()
76+
if isinstance(cells[i], str) or isinstance(cells[i], unicode):
77+
c.text = cells[i].strip()
78+
else:
79+
# we've already inserted a code element
80+
c.append(cells[i])
7681
except IndexError: # pragma: no cover
7782
c.text = ""
7883
if a:
@@ -85,7 +90,49 @@ def _split_row(self, row, border):
8590
row = row[1:]
8691
if row.endswith('|'):
8792
row = row[:-1]
88-
return row.split('|')
93+
return self._split(row, '|')
94+
95+
def _split(self, row, marker):
96+
""" split a row of text with some code into a list of cells. """
97+
if self._row_has_unpaired_backticks(row):
98+
# fallback on old behaviour
99+
return row.split(marker)
100+
# modify the backtick pattern to only match at the beginning of the search string
101+
backtick_pattern = BacktickPattern('^' + BACKTICK_RE)
102+
elements = []
103+
current = ''
104+
i = 0
105+
while i < len(row):
106+
letter = row[i]
107+
if letter == marker:
108+
if current != '' or len(elements) == 0:
109+
# Don't append empty string unless it is the first element
110+
# The border is already removed when we get the row, then the line is strip()'d
111+
# If the first element is a marker, then we have an empty first cell
112+
elements.append(current)
113+
current = ''
114+
else:
115+
match = backtick_pattern.getCompiledRegExp().match(row[i:])
116+
if not match:
117+
current += letter
118+
else:
119+
groups = match.groups()
120+
delim = groups[1] # the code block delimeter (ie 1 or more backticks)
121+
row_contents = groups[2] # the text contained inside the code block
122+
i += match.start(4) # jump pointer to the beginning of the rest of the text (group #4)
123+
element = delim + row_contents + delim # reinstert backticks
124+
current += element
125+
i += 1
126+
elements.append(current)
127+
return elements
128+
129+
def _row_has_unpaired_backticks(self, row):
130+
count_total_backtick = row.count('`')
131+
count_escaped_backtick = row.count('\`')
132+
count_backtick = count_total_backtick - count_escaped_backtick
133+
# odd number of backticks,
134+
# we won't be able to build correct code blocks
135+
return count_backtick & 1
89136

90137

91138
class TableExtension(Extension):

tests/extensions/extra/tables.html

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,71 @@ <h2>Table Tests</h2>
168168
</tr>
169169
</thead>
170170
<tbody></tbody>
171+
</table>
172+
<p>More inline code block tests</p>
173+
<table>
174+
<thead>
175+
<tr>
176+
<th>Column 1</th>
177+
<th>Column 2</th>
178+
<th>Column 3</th>
179+
</tr>
180+
</thead>
181+
<tbody>
182+
<tr>
183+
<td>word 1</td>
184+
<td>word 2</td>
185+
<td>word 3</td>
186+
</tr>
187+
<tr>
188+
<td>word 1</td>
189+
<td><code>word 2</code></td>
190+
<td>word 3</td>
191+
</tr>
192+
<tr>
193+
<td>word 1</td>
194+
<td>`word 2</td>
195+
<td>word 3</td>
196+
</tr>
197+
<tr>
198+
<td>word 1</td>
199+
<td>`word 2</td>
200+
<td>word 3</td>
201+
</tr>
202+
<tr>
203+
<td>word 1</td>
204+
<td><code>word |2</code></td>
205+
<td>word 3</td>
206+
</tr>
207+
<tr>
208+
<td>words</td>
209+
<td><code>some | code</code></td>
210+
<td>more words</td>
211+
</tr>
212+
<tr>
213+
<td>words</td>
214+
<td><code>some | code</code></td>
215+
<td>more words</td>
216+
</tr>
217+
<tr>
218+
<td>words</td>
219+
<td><code>some | code</code></td>
220+
<td>more words</td>
221+
</tr>
222+
<tr>
223+
<td>words</td>
224+
<td><code>some ` | ` code</code></td>
225+
<td>more words</td>
226+
</tr>
227+
<tr>
228+
<td>words</td>
229+
<td><code>some ` | ` code</code></td>
230+
<td>more words</td>
231+
</tr>
232+
<tr>
233+
<td>words</td>
234+
<td><code>some ` | ` code</code></td>
235+
<td>more words</td>
236+
</tr>
237+
</tbody>
171238
</table>

tests/extensions/extra/tables.txt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,20 @@ Four spaces is a code block:
5252
Content Cell | Content Cell
5353

5454
| First Header | Second Header |
55-
| ------------ | ------------- |
55+
| ------------ | ------------- |
56+
57+
More inline code block tests
58+
59+
Column 1 | Column 2 | Column 3
60+
---------|----------|---------
61+
word 1 | word 2 | word 3
62+
word 1 | `word 2` | word 3
63+
word 1 | \`word 2 | word 3
64+
word 1 | `word 2 | word 3
65+
word 1 | `word |2` | word 3
66+
words |`` some | code `` | more words
67+
words |``` some | code ``` | more words
68+
words |```` some | code ```` | more words
69+
words |`` some ` | ` code `` | more words
70+
words |``` some ` | ` code ``` | more words
71+
words |```` some ` | ` code ```` | more words

tests/extensions/test.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,4 @@ smarty:
7070
- markdown.extensions.smarty
7171
extension_configs:
7272
markdown.extensions.smarty:
73-
smart_angled_quotes: True
73+
smart_angled_quotes: True

0 commit comments

Comments
 (0)