Skip to content

Commit aa32a8e

Browse files
authored
Merge pull request #268 from commonmark/issue-255-dangling-pipe
Fix GFM table parser to handle dangling pipe correctly (fixes #255)
2 parents 0bc0b2d + 7584f00 commit aa32a8e

File tree

3 files changed

+78
-19
lines changed

3 files changed

+78
-19
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
66
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
77
with the exception that 0.x versions can break between minor versions.
88

9+
## [Unreleased]
10+
### Fixed
11+
- A single pipe (optional whitespace) now ends a table instead of crashing or
12+
being treated as an empty row, for consistency with GitHub (#255).
13+
914
## [0.19.0] - 2022-06-02
1015
### Added
1116
- YAML front matter extension: Limited support for single and double
@@ -362,6 +367,7 @@ Initial release of commonmark-java, a port of commonmark.js with extensions
362367
for autolinking URLs, GitHub flavored strikethrough and tables.
363368
364369
370+
[Unreleased]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.19.0...HEAD
365371
[0.19.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.18.2...commonmark-parent-0.19.0
366372
[0.18.2]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.18.1...commonmark-parent-0.18.2
367373
[0.18.1]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.18.0...commonmark-parent-0.18.1

commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,16 @@ public class TableBlockParser extends AbstractBlockParser {
1919
private final List<SourceLine> rowLines = new ArrayList<>();
2020
private final List<TableCell.Alignment> columns;
2121

22+
private boolean canHaveLazyContinuationLines = true;
23+
2224
private TableBlockParser(List<TableCell.Alignment> columns, SourceLine headerLine) {
2325
this.columns = columns;
2426
this.rowLines.add(headerLine);
2527
}
2628

2729
@Override
2830
public boolean canHaveLazyContinuationLines() {
29-
return true;
31+
return canHaveLazyContinuationLines;
3032
}
3133

3234
@Override
@@ -36,7 +38,17 @@ public Block getBlock() {
3638

3739
@Override
3840
public BlockContinue tryContinue(ParserState state) {
39-
if (Parsing.find('|', state.getLine().getContent(), 0) != -1) {
41+
CharSequence content = state.getLine().getContent();
42+
int pipe = Parsing.find('|', content, state.getNextNonSpaceIndex());
43+
if (pipe != -1) {
44+
if (pipe == state.getNextNonSpaceIndex()) {
45+
// If we *only* have a pipe character (and whitespace), that is not a valid table row and ends the table.
46+
if (Parsing.skipSpaceTab(content, pipe + 1, content.length()) == content.length()) {
47+
// We also don't want the pipe to be added via lazy continuation.
48+
canHaveLazyContinuationLines = false;
49+
return BlockContinue.none();
50+
}
51+
}
4052
return BlockContinue.atIndex(state.getIndex());
4153
} else {
4254
return BlockContinue.none();
@@ -128,7 +140,7 @@ private static List<SourceLine> split(SourceLine line) {
128140
// This row has leading/trailing pipes - skip the leading pipe
129141
cellStart = nonSpace + 1;
130142
// Strip whitespace from the end but not the pipe or we could miss an empty ("||") cell
131-
int nonSpaceEnd = Parsing.skipSpaceTabBackwards(row, row.length() - 1, cellStart + 1);
143+
int nonSpaceEnd = Parsing.skipSpaceTabBackwards(row, row.length() - 1, cellStart);
132144
cellEnd = nonSpaceEnd + 1;
133145
}
134146
List<SourceLine> cells = new ArrayList<>();

commonmark-ext-gfm-tables/src/test/java/org/commonmark/ext/gfm/tables/TablesTest.java

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -261,21 +261,21 @@ public void pipesOnOutsideZeroLengthHeaders() {
261261
"-|-------------|-\n" +
262262
"1| 2 |3",
263263
"<table>\n" +
264-
"<thead>\n" +
265-
"<tr>\n" +
266-
"<th></th>\n" +
267-
"<th>center header</th>\n" +
268-
"<th></th>\n" +
269-
"</tr>\n" +
270-
"</thead>\n" +
271-
"<tbody>\n" +
272-
"<tr>\n" +
273-
"<td>1</td>\n" +
274-
"<td>2</td>\n" +
275-
"<td>3</td>\n" +
276-
"</tr>\n" +
277-
"</tbody>\n" +
278-
"</table>\n");
264+
"<thead>\n" +
265+
"<tr>\n" +
266+
"<th></th>\n" +
267+
"<th>center header</th>\n" +
268+
"<th></th>\n" +
269+
"</tr>\n" +
270+
"</thead>\n" +
271+
"<tbody>\n" +
272+
"<tr>\n" +
273+
"<td>1</td>\n" +
274+
"<td>2</td>\n" +
275+
"<td>3</td>\n" +
276+
"</tr>\n" +
277+
"</tbody>\n" +
278+
"</table>\n");
279279
}
280280

281281
@Test
@@ -664,6 +664,47 @@ public void issue142() {
664664
"</table>\n");
665665
}
666666

667+
@Test
668+
public void danglingPipe() {
669+
assertRendering("Abc|Def\n" +
670+
"---|---\n" +
671+
"1|2\n" +
672+
"|", "<table>\n" +
673+
"<thead>\n" +
674+
"<tr>\n" +
675+
"<th>Abc</th>\n" +
676+
"<th>Def</th>\n" +
677+
"</tr>\n" +
678+
"</thead>\n" +
679+
"<tbody>\n" +
680+
"<tr>\n" +
681+
"<td>1</td>\n" +
682+
"<td>2</td>\n" +
683+
"</tr>\n" +
684+
"</tbody>\n" +
685+
"</table>\n" +
686+
"<p>|</p>\n");
687+
688+
assertRendering("Abc|Def\n" +
689+
"---|---\n" +
690+
"1|2\n" +
691+
" | ", "<table>\n" +
692+
"<thead>\n" +
693+
"<tr>\n" +
694+
"<th>Abc</th>\n" +
695+
"<th>Def</th>\n" +
696+
"</tr>\n" +
697+
"</thead>\n" +
698+
"<tbody>\n" +
699+
"<tr>\n" +
700+
"<td>1</td>\n" +
701+
"<td>2</td>\n" +
702+
"</tr>\n" +
703+
"</tbody>\n" +
704+
"</table>\n" +
705+
"<p>|</p>\n");
706+
}
707+
667708
@Test
668709
public void attributeProviderIsApplied() {
669710
AttributeProviderFactory factory = new AttributeProviderFactory() {
@@ -718,7 +759,7 @@ public void sourceSpans() {
718759

719760
TableBlock block = (TableBlock) document.getFirstChild();
720761
assertEquals(Arrays.asList(SourceSpan.of(0, 0, 7), SourceSpan.of(1, 0, 7),
721-
SourceSpan.of(2, 0, 4), SourceSpan.of(3, 0, 8), SourceSpan.of(4, 0, 3)),
762+
SourceSpan.of(2, 0, 4), SourceSpan.of(3, 0, 8), SourceSpan.of(4, 0, 3)),
722763
block.getSourceSpans());
723764

724765
TableHead head = (TableHead) block.getFirstChild();

0 commit comments

Comments
 (0)