Skip to content

Commit 0f3f4f3

Browse files
authored
Merge pull request #269 from commonmark/issue-267-strikethrough
Adjust GFM strikethrough parsing (fixes #267)
2 parents aa32a8e + 4ad649f commit 0f3f4f3

File tree

9 files changed

+85
-29
lines changed

9 files changed

+85
-29
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ with the exception that 0.x versions can break between minor versions.
88

99
## [Unreleased]
1010
### 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).
11+
- GitHub tables: A single pipe (optional whitespace) now ends a table
12+
instead of crashing or being treated as an empty row, for consistency
13+
with GitHub (#255).
14+
- GitHub strikethrough: A single tilde now also works, and more than two
15+
tildes are not accepted anymore. This brings us in line with what
16+
GitHub actually does, which is a bit underspecified (#267)
1317

1418
## [0.19.0] - 2022-06-02
1519
### Added

commonmark-ext-gfm-strikethrough/src/main/java/org/commonmark/ext/gfm/strikethrough/internal/StrikethroughDelimiterProcessor.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,33 @@ public char getClosingCharacter() {
2222

2323
@Override
2424
public int getMinLength() {
25-
return 2;
25+
return 1;
2626
}
2727

2828
@Override
2929
public int process(DelimiterRun openingRun, DelimiterRun closingRun) {
30-
if (openingRun.length() >= 2 && closingRun.length() >= 2) {
31-
// Use exactly two delimiters even if we have more, and don't care about internal openers/closers.
30+
if (openingRun.length() == closingRun.length() && openingRun.length() <= 2) {
31+
// GitHub only accepts either one or two delimiters, but not a mix or more than that.
3232

3333
Text opener = openingRun.getOpener();
3434

3535
// Wrap nodes between delimiters in strikethrough.
3636
Node strikethrough = new Strikethrough();
3737

3838
SourceSpans sourceSpans = new SourceSpans();
39-
sourceSpans.addAllFrom(openingRun.getOpeners(2));
39+
sourceSpans.addAllFrom(openingRun.getOpeners(openingRun.length()));
4040

4141
for (Node node : Nodes.between(opener, closingRun.getCloser())) {
4242
strikethrough.appendChild(node);
4343
sourceSpans.addAll(node.getSourceSpans());
4444
}
4545

46-
sourceSpans.addAllFrom(closingRun.getClosers(2));
46+
sourceSpans.addAllFrom(closingRun.getClosers(closingRun.length()));
4747
strikethrough.setSourceSpans(sourceSpans.getSourceSpans());
4848

4949
opener.insertAfter(strikethrough);
5050

51-
return 2;
51+
return openingRun.length();
5252
} else {
5353
return 0;
5454
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.commonmark.ext.gfm.strikethrough;
2+
3+
import org.commonmark.Extension;
4+
import org.commonmark.parser.Parser;
5+
import org.commonmark.renderer.html.HtmlRenderer;
6+
import org.commonmark.testutil.RenderingTestCase;
7+
import org.commonmark.testutil.TestResources;
8+
import org.commonmark.testutil.example.Example;
9+
import org.commonmark.testutil.example.ExampleReader;
10+
import org.junit.Test;
11+
import org.junit.runner.RunWith;
12+
import org.junit.runners.Parameterized;
13+
import org.junit.runners.Parameterized.Parameters;
14+
15+
import java.util.Collections;
16+
import java.util.List;
17+
import java.util.Set;
18+
19+
@RunWith(Parameterized.class)
20+
public class StrikethroughSpecTest extends RenderingTestCase {
21+
22+
private static final Set<Extension> EXTENSIONS = Collections.singleton(StrikethroughExtension.create());
23+
private static final Parser PARSER = Parser.builder().extensions(EXTENSIONS).build();
24+
private static final HtmlRenderer RENDERER = HtmlRenderer.builder().extensions(EXTENSIONS).build();
25+
26+
private final Example example;
27+
28+
public StrikethroughSpecTest(Example example) {
29+
this.example = example;
30+
}
31+
32+
@Parameters(name = "{0}")
33+
public static List<Object[]> data() {
34+
return ExampleReader.readExampleObjects(TestResources.getGfmSpec(), "strikethrough");
35+
}
36+
37+
@Test
38+
public void testHtmlRendering() {
39+
assertRendering(example.getSource(), example.getHtml());
40+
}
41+
42+
@Override
43+
protected String render(String source) {
44+
return RENDERER.render(PARSER.parse(source));
45+
}
46+
}

commonmark-ext-gfm-strikethrough/src/test/java/org/commonmark/ext/gfm/strikethrough/StrikethroughTest.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ public class StrikethroughTest extends RenderingTestCase {
2626
.extensions(EXTENSIONS).build();
2727

2828
@Test
29-
public void oneTildeIsNotEnough() {
30-
assertRendering("~foo~", "<p>~foo~</p>\n");
29+
public void oneTildeIsEnough() {
30+
assertRendering("~foo~", "<p><del>foo</del></p>\n");
3131
}
3232

3333
@Test
34-
public void twoTildesYay() {
34+
public void twoTildesWorksToo() {
3535
assertRendering("~~foo~~", "<p><del>foo</del></p>\n");
3636
}
3737

@@ -48,23 +48,22 @@ public void unmatched() {
4848

4949
@Test
5050
public void threeInnerThree() {
51-
assertRendering("a ~~~foo~~~", "<p>a ~<del>foo</del>~</p>\n");
51+
assertRendering("a ~~~foo~~~", "<p>a ~~~foo~~~</p>\n");
5252
}
5353

5454
@Test
5555
public void twoInnerThree() {
56-
assertRendering("~~foo~~~", "<p><del>foo</del>~</p>\n");
56+
assertRendering("~~foo~~~", "<p>~~foo~~~</p>\n");
5757
}
5858

5959
@Test
6060
public void tildesInside() {
6161
assertRendering("~~foo~bar~~", "<p><del>foo~bar</del></p>\n");
6262
assertRendering("~~foo~~bar~~", "<p><del>foo</del>bar~~</p>\n");
63-
assertRendering("~~foo~~~bar~~", "<p><del>foo</del>~bar~~</p>\n");
64-
assertRendering("~~foo~~~~bar~~", "<p><del>foo</del><del>bar</del></p>\n");
65-
assertRendering("~~foo~~~~~bar~~", "<p><del>foo</del>~<del>bar</del></p>\n");
66-
assertRendering("~~foo~~~~~~bar~~", "<p><del>foo</del>~~<del>bar</del></p>\n");
67-
assertRendering("~~foo~~~~~~~bar~~", "<p><del>foo</del>~~~<del>bar</del></p>\n");
63+
assertRendering("~~foo~~~bar~~", "<p><del>foo~~~bar</del></p>\n");
64+
assertRendering("~~foo~~~~bar~~", "<p><del>foo~~~~bar</del></p>\n");
65+
assertRendering("~~foo~~~~~bar~~", "<p><del>foo~~~~~bar</del></p>\n");
66+
assertRendering("~~foo~~~~~~bar~~", "<p><del>foo~~~~~~bar</del></p>\n");
6867
}
6968

7069
@Test

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,7 @@ public TablesSpecTest(Example example) {
3232

3333
@Parameters(name = "{0}")
3434
public static List<Object[]> data() {
35-
List<Example> examples = ExampleReader.readExamples(TestResources.class.getResource("/gfm-spec.txt"));
36-
List<Object[]> data = new ArrayList<>();
37-
for (Example example : examples) {
38-
if (example.getInfo().contains("table")) {
39-
data.add(new Object[]{example});
40-
}
41-
}
42-
return data;
35+
return ExampleReader.readExampleObjects(TestResources.getGfmSpec(), "table");
4336
}
4437

4538
@Test

commonmark-test-util/src/main/java/org/commonmark/testutil/TestResources.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public static URL getSpec() {
1414
return TestResources.class.getResource("/spec.txt");
1515
}
1616

17+
public static URL getGfmSpec() {
18+
return TestResources.class.getResource("/gfm-spec.txt");
19+
}
20+
1721
public static List<URL> getRegressions() {
1822
return Arrays.asList(
1923
TestResources.class.getResource("/cmark-regression.txt"),

commonmark-test-util/src/main/java/org/commonmark/testutil/example/ExampleReader.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ public static List<Example> readExamples(URL url) {
4242
}
4343
}
4444

45+
public static List<Object[]> readExampleObjects(URL url, String info) {
46+
List<Example> examples = readExamples(url);
47+
List<Object[]> data = new ArrayList<>();
48+
for (Example example : examples) {
49+
if (example.getInfo().contains(info)) {
50+
data.add(new Object[]{example});
51+
}
52+
}
53+
return data;
54+
}
55+
4556
public static List<String> readExampleSources(URL url) {
4657
List<Example> examples = ExampleReader.readExamples(url);
4758
List<String> result = new ArrayList<>();

commonmark-ext-gfm-tables/src/test/resources/gfm-spec.txt renamed to commonmark-test-util/src/main/resources/gfm-spec.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,7 +2077,7 @@ followed by one of the strings (case-insensitive) `address`,
20772077
`h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`,
20782078
`html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`,
20792079
`nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`,
2080-
`section`, `source`, `summary`, `table`, `tbody`, `td`,
2080+
`section`, `summary`, `table`, `tbody`, `td`,
20812081
`tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed
20822082
by [whitespace], the end of the line, the string `>`, or
20832083
the string `/>`.\
@@ -10224,4 +10224,3 @@ closers:
1022410224

1022510225
After we're done, we remove all delimiters above `stack_bottom` from the
1022610226
delimiter stack.
10227-

etc/update-spec.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fi
77

88
version=$1
99
curl -L "https://raw.githubusercontent.com/commonmark/commonmark-spec/$version/spec.txt" -o commonmark-test-util/src/main/resources/spec.txt
10-
curl -L "https://raw.githubusercontent.com/github/cmark-gfm/master/test/spec.txt" -o commonmark-ext-gfm-tables/src/test/resources/gfm-spec.txt
10+
curl -L "https://raw.githubusercontent.com/github/cmark-gfm/master/test/spec.txt" -o commonmark-test-util/src/main/resources/gfm-spec.txt
1111

1212
echo "Check cmark and commonmark.js regression.txt:"
1313
echo "https://github.com/commonmark/cmark/blob/master/test/regression.txt"

0 commit comments

Comments
 (0)