Skip to content

Commit 2a74121

Browse files
Merge pull request #730 from mikamikasuki/fix/table-multibacktick-code-spans
Fix table boundaries around multi-backtick code spans
2 parents 27cd678 + ff03066 commit 2a74121

6 files changed

Lines changed: 59 additions & 4 deletions

File tree

‎CHANGES.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## python-markdown2 2.5.6 (not yet released)
44

5+
- [pull #730] Fix `tables` extra splitting multi-backtick code spans at a leading pipe and merging cells after a code span containing literal backticks.
56
- [pull #729] Fix `tables` extra merging cells when a pipe directly follows a code span, as in compact rows like `|`-v`|verbose|`.
67
- [pull #725] Fix `tables` extra dropping escaped pipes at the end of header and body rows.
78
- [pull #687] Fix AssertionError hashing HTML blocks spread over multiple lines (#686)

‎README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ as a script:
103103
The `footnotes` extra keeps the same number when a footnote is referenced more
104104
than once.
105105

106+
The `tables` extra supports code spans delimited by single or multiple backticks,
107+
including an operator cell such as ```` ``|`` ````. A pipe immediately after the
108+
closing delimiter separates the next cell.
109+
106110
There are a number of currently implemented extras for tables, footnotes,
107111
syntax coloring of `<pre>`-blocks, auto-linking patterns, table of contents,
108112
Smarty Pants (for fancy quotes, dashes, etc.) and more. See the [Extras

‎lib/markdown2.py‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4260,12 +4260,19 @@ def _split_row(row: str) -> list[str]:
42604260
# An escaped final pipe belongs to the last cell, not the table border.
42614261
if not row.endswith(r'\|'):
42624262
row = row.removesuffix('|')
4263+
code_spans = list(Markdown._code_span_re.finditer(row))
4264+
code_starts = {m.start(2) for m in code_spans}
4265+
code_ends = {m.end() for m in code_spans}
42634266
cells, start = [], 0
42644267
for m in re.finditer(r'(?<!\\)\|', row):
4265-
# A pipe right after the backtick that opens a code span (`|`) stays in
4266-
# the cell; one right after a closing backtick is a cell border.
4267-
if m.start() and row[m.start() - 1] == '`' and row.count('`', 0, m.start()) % 2:
4268-
continue
4268+
pos = m.start()
4269+
# A pipe after an opening backtick delimiter stays in the cell.
4270+
# A pipe after the matching closing delimiter is a cell border.
4271+
if pos and row[pos - 1] == '`':
4272+
if pos in code_starts or (
4273+
pos not in code_ends and row.count('`', 0, pos) % 2
4274+
):
4275+
continue
42694276
cells.append(row[start:m.start()])
42704277
start = m.end()
42714278
cells.append(row[start:])
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<table>
2+
<thead>
3+
<tr>
4+
<th>Operator</th>
5+
<th>Meaning</th>
6+
</tr>
7+
</thead>
8+
<tbody>
9+
<tr>
10+
<td><code>|</code></td>
11+
<td>bitwise or</td>
12+
</tr>
13+
<tr>
14+
<td><code>|</code></td>
15+
<td>bitwise or</td>
16+
</tr>
17+
<tr>
18+
<td><code>|</code></td>
19+
<td>bitwise or</td>
20+
</tr>
21+
<tr>
22+
<td><code>x`y</code></td>
23+
<td>literal backtick</td>
24+
</tr>
25+
<tr>
26+
<td><code>x``y</code></td>
27+
<td>two literal backticks</td>
28+
</tr>
29+
<tr>
30+
<td><code>|</code></td>
31+
<td><code>or</code></td>
32+
</tr>
33+
</tbody>
34+
</table>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extras": ["tables"]}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| Operator | Meaning |
2+
| --- | --- |
3+
| `|` | bitwise or |
4+
| ``|`` | bitwise or |
5+
| ````|```` | bitwise or |
6+
|``x`y``|literal backtick|
7+
|````x``y````|two literal backticks|
8+
|``|``|`or`|

0 commit comments

Comments
 (0)