Skip to content

Commit ccdf1a3

Browse files
authored
Merge pull request #311 from commonmark/fix-markdown-renderer-lists-from-ast
Fix markdown renderer for manually created list nodes
2 parents 4a6b944 + 16c6ff2 commit ccdf1a3

10 files changed

Lines changed: 146 additions & 60 deletions

File tree

commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import org.commonmark.node.*;
55
import org.commonmark.parser.block.*;
66

7+
import java.util.Objects;
8+
79
public class ListBlockParser extends AbstractBlockParser {
810

911
private final ListBlock block;
@@ -90,7 +92,7 @@ private static ListData parseList(CharSequence line, final int markerIndex, fina
9092

9193
if (inParagraph) {
9294
// If the list item is ordered, the start number must be 1 to interrupt a paragraph.
93-
if (listBlock instanceof OrderedList && ((OrderedList) listBlock).getStartNumber() != 1) {
95+
if (listBlock instanceof OrderedList && ((OrderedList) listBlock).getMarkerStartNumber() != 1) {
9496
return null;
9597
}
9698
// Empty list item can not interrupt a paragraph.
@@ -116,7 +118,7 @@ private static ListMarkerData parseListMarker(CharSequence line, int index) {
116118
case '*':
117119
if (isSpaceTabOrEnd(line, index + 1)) {
118120
BulletList bulletList = new BulletList();
119-
bulletList.setBulletMarker(c);
121+
bulletList.setMarker(String.valueOf(c));
120122
return new ListMarkerData(bulletList, index + 1);
121123
} else {
122124
return null;
@@ -154,8 +156,8 @@ private static ListMarkerData parseOrderedList(CharSequence line, int index) {
154156
if (digits >= 1 && isSpaceTabOrEnd(line, i + 1)) {
155157
String number = line.subSequence(index, i).toString();
156158
OrderedList orderedList = new OrderedList();
157-
orderedList.setStartNumber(Integer.parseInt(number));
158-
orderedList.setDelimiter(c);
159+
orderedList.setMarkerStartNumber(Integer.parseInt(number));
160+
orderedList.setMarkerDelimiter(String.valueOf(c));
159161
return new ListMarkerData(orderedList, i + 1);
160162
} else {
161163
return null;
@@ -188,17 +190,13 @@ private static boolean isSpaceTabOrEnd(CharSequence line, int index) {
188190
*/
189191
private static boolean listsMatch(ListBlock a, ListBlock b) {
190192
if (a instanceof BulletList && b instanceof BulletList) {
191-
return equals(((BulletList) a).getBulletMarker(), ((BulletList) b).getBulletMarker());
193+
return Objects.equals(((BulletList) a).getMarker(), ((BulletList) b).getMarker());
192194
} else if (a instanceof OrderedList && b instanceof OrderedList) {
193-
return equals(((OrderedList) a).getDelimiter(), ((OrderedList) b).getDelimiter());
195+
return Objects.equals(((OrderedList) a).getMarkerDelimiter(), ((OrderedList) b).getMarkerDelimiter());
194196
}
195197
return false;
196198
}
197199

198-
private static boolean equals(Object a, Object b) {
199-
return (a == null) ? (b == null) : a.equals(b);
200-
}
201-
202200
public static class Factory extends AbstractBlockParserFactory {
203201

204202
@Override

commonmark/src/main/java/org/commonmark/internal/renderer/text/BulletListHolder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import org.commonmark.node.BulletList;
44

55
public class BulletListHolder extends ListHolder {
6-
private final char marker;
6+
private final String marker;
77

88
public BulletListHolder(ListHolder parent, BulletList list) {
99
super(parent);
10-
marker = list.getBulletMarker();
10+
marker = list.getMarker();
1111
}
1212

13-
public char getMarker() {
13+
public String getMarker() {
1414
return marker;
1515
}
1616
}

commonmark/src/main/java/org/commonmark/internal/renderer/text/OrderedListHolder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
import org.commonmark.node.OrderedList;
44

55
public class OrderedListHolder extends ListHolder {
6-
private final char delimiter;
6+
private final String delimiter;
77
private int counter;
88

99
public OrderedListHolder(ListHolder parent, OrderedList list) {
1010
super(parent);
11-
delimiter = list.getDelimiter();
12-
counter = list.getStartNumber();
11+
delimiter = list.getMarkerDelimiter() != null ? list.getMarkerDelimiter() : ".";
12+
counter = list.getMarkerStartNumber() != null ? list.getMarkerStartNumber() : 1;
1313
}
1414

15-
public char getDelimiter() {
15+
public String getDelimiter() {
1616
return delimiter;
1717
}
1818

commonmark/src/main/java/org/commonmark/node/BulletList.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,37 @@
22

33
public class BulletList extends ListBlock {
44

5-
private char bulletMarker;
5+
private String marker;
66

77
@Override
88
public void accept(Visitor visitor) {
99
visitor.visit(this);
1010
}
1111

12+
/**
13+
* @return the bullet list marker that was used, e.g. {@code -}, {@code *} or {@code +}, if available, or null otherwise
14+
*/
15+
public String getMarker() {
16+
return marker;
17+
}
18+
19+
public void setMarker(String marker) {
20+
this.marker = marker;
21+
}
22+
23+
/**
24+
* @deprecated use {@link #getMarker()} instead
25+
*/
26+
@Deprecated
1227
public char getBulletMarker() {
13-
return bulletMarker;
28+
return marker != null && !marker.isEmpty() ? marker.charAt(0) : '\0';
1429
}
1530

31+
/**
32+
* @deprecated use {@link #getMarker()} instead
33+
*/
34+
@Deprecated
1635
public void setBulletMarker(char bulletMarker) {
17-
this.bulletMarker = bulletMarker;
36+
this.marker = bulletMarker != '\0' ? String.valueOf(bulletMarker) : null;
1837
}
19-
2038
}

commonmark/src/main/java/org/commonmark/node/ListItem.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
public class ListItem extends Block {
44

5-
private int markerIndent;
6-
private int contentIndent;
5+
private Integer markerIndent;
6+
private Integer contentIndent;
77

88
@Override
99
public void accept(Visitor visitor) {
1010
visitor.visit(this);
1111
}
1212

1313
/**
14-
* Returns the indent of the marker such as "-" or "1." in columns (spaces or tab stop of 4).
14+
* Returns the indent of the marker such as "-" or "1." in columns (spaces or tab stop of 4) if available, or null
15+
* otherwise.
1516
* <p>
1617
* Some examples and their marker indent:
1718
* <pre>- Foo</pre>
@@ -21,17 +22,17 @@ public void accept(Visitor visitor) {
2122
* <pre> 1. Foo</pre>
2223
* Marker indent: 2
2324
*/
24-
public int getMarkerIndent() {
25+
public Integer getMarkerIndent() {
2526
return markerIndent;
2627
}
2728

28-
public void setMarkerIndent(int markerIndent) {
29+
public void setMarkerIndent(Integer markerIndent) {
2930
this.markerIndent = markerIndent;
3031
}
3132

3233
/**
33-
* Returns the indent of the content in columns (spaces or tab stop of 4). The content indent is counted from the
34-
* beginning of the line and includes the marker on the first line.
34+
* Returns the indent of the content in columns (spaces or tab stop of 4) if available, or null otherwise.
35+
* The content indent is counted from the beginning of the line and includes the marker on the first line.
3536
* <p>
3637
* Some examples and their content indent:
3738
* <pre>- Foo</pre>
@@ -44,11 +45,11 @@ public void setMarkerIndent(int markerIndent) {
4445
* Note that subsequent lines in the same list item need to be indented by at least the content indent to be counted
4546
* as part of the list item.
4647
*/
47-
public int getContentIndent() {
48+
public Integer getContentIndent() {
4849
return contentIndent;
4950
}
5051

51-
public void setContentIndent(int contentIndent) {
52+
public void setContentIndent(Integer contentIndent) {
5253
this.contentIndent = contentIndent;
5354
}
5455
}

commonmark/src/main/java/org/commonmark/node/OrderedList.java

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,65 @@
22

33
public class OrderedList extends ListBlock {
44

5-
private int startNumber;
6-
private char delimiter;
5+
private String markerDelimiter;
6+
private Integer markerStartNumber;
77

88
@Override
99
public void accept(Visitor visitor) {
1010
visitor.visit(this);
1111
}
1212

13+
/**
14+
* @return the start number used in the marker, e.g. {@code 1}, if available, or null otherwise
15+
*/
16+
public Integer getMarkerStartNumber() {
17+
return markerStartNumber;
18+
}
19+
20+
public void setMarkerStartNumber(Integer markerStartNumber) {
21+
this.markerStartNumber = markerStartNumber;
22+
}
23+
24+
/**
25+
* @return the delimiter used in the marker, e.g. {@code .} or {@code )}, if available, or null otherwise
26+
*/
27+
public String getMarkerDelimiter() {
28+
return markerDelimiter;
29+
}
30+
31+
public void setMarkerDelimiter(String markerDelimiter) {
32+
this.markerDelimiter = markerDelimiter;
33+
}
34+
35+
/**
36+
* @deprecated use {@link #getMarkerStartNumber()} instead
37+
*/
38+
@Deprecated
1339
public int getStartNumber() {
14-
return startNumber;
40+
return markerStartNumber != null ? markerStartNumber : 0;
1541
}
1642

43+
/**
44+
* @deprecated use {@link #setMarkerStartNumber} instead
45+
*/
46+
@Deprecated
1747
public void setStartNumber(int startNumber) {
18-
this.startNumber = startNumber;
48+
this.markerStartNumber = startNumber != 0 ? startNumber : null;
1949
}
2050

51+
/**
52+
* @deprecated use {@link #getMarkerDelimiter()} instead
53+
*/
54+
@Deprecated
2155
public char getDelimiter() {
22-
return delimiter;
56+
return markerDelimiter != null && !markerDelimiter.isEmpty() ? markerDelimiter.charAt(0) : '\0';
2357
}
2458

59+
/**
60+
* @deprecated use {@link #setMarkerDelimiter} instead
61+
*/
62+
@Deprecated
2563
public void setDelimiter(char delimiter) {
26-
this.delimiter = delimiter;
64+
this.markerDelimiter = delimiter != '\0' ? String.valueOf(delimiter) : null;
2765
}
28-
2966
}

commonmark/src/main/java/org/commonmark/renderer/html/CoreHtmlNodeRenderer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public void visit(ListItem listItem) {
168168

169169
@Override
170170
public void visit(OrderedList orderedList) {
171-
int start = orderedList.getStartNumber();
171+
int start = orderedList.getMarkerStartNumber() != null ? orderedList.getMarkerStartNumber() : 1;
172172
Map<String, String> attrs = new LinkedHashMap<>();
173173
if (start != 1) {
174174
attrs.put("start", String.valueOf(start));

commonmark/src/main/java/org/commonmark/renderer/markdown/CoreMarkdownNodeRenderer.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -227,33 +227,32 @@ public void visit(OrderedList orderedList) {
227227

228228
@Override
229229
public void visit(ListItem listItem) {
230-
int contentIndent = listItem.getContentIndent();
231-
boolean pushedPrefix = false;
230+
int markerIndent = listItem.getMarkerIndent() != null ? listItem.getMarkerIndent() : 0;
231+
String marker;
232232
if (listHolder instanceof BulletListHolder) {
233233
BulletListHolder bulletListHolder = (BulletListHolder) listHolder;
234-
String marker = repeat(" ", listItem.getMarkerIndent()) + bulletListHolder.bulletMarker;
235-
writer.writePrefix(marker);
236-
writer.writePrefix(repeat(" ", contentIndent - marker.length()));
237-
writer.pushPrefix(repeat(" ", contentIndent));
238-
pushedPrefix = true;
234+
marker = repeat(" ", markerIndent) + bulletListHolder.marker;
239235
} else if (listHolder instanceof OrderedListHolder) {
240236
OrderedListHolder orderedListHolder = (OrderedListHolder) listHolder;
241-
String marker = repeat(" ", listItem.getMarkerIndent()) + orderedListHolder.number + orderedListHolder.delimiter;
237+
marker = repeat(" ", markerIndent) + orderedListHolder.number + orderedListHolder.delimiter;
242238
orderedListHolder.number++;
243-
writer.writePrefix(marker);
244-
writer.writePrefix(repeat(" ", contentIndent - marker.length()));
245-
writer.pushPrefix(repeat(" ", contentIndent));
246-
pushedPrefix = true;
239+
} else {
240+
throw new IllegalStateException("Unknown list holder type: " + listHolder);
247241
}
242+
Integer contentIndent = listItem.getContentIndent();
243+
String spaces = contentIndent != null ? repeat(" ", contentIndent - marker.length()) : " ";
244+
writer.writePrefix(marker);
245+
writer.writePrefix(spaces);
246+
writer.pushPrefix(repeat(" ", marker.length() + spaces.length()));
247+
248248
if (listItem.getFirstChild() == null) {
249249
// Empty list item
250250
writer.block();
251251
} else {
252252
visitChildren(listItem);
253253
}
254-
if (pushedPrefix) {
255-
writer.popPrefix();
256-
}
254+
255+
writer.popPrefix();
257256
}
258257

259258
@Override
@@ -489,22 +488,22 @@ protected ListHolder(ListHolder parent) {
489488
}
490489

491490
private static class BulletListHolder extends ListHolder {
492-
final char bulletMarker;
491+
final String marker;
493492

494493
public BulletListHolder(ListHolder parent, BulletList bulletList) {
495494
super(parent);
496-
this.bulletMarker = bulletList.getBulletMarker();
495+
this.marker = bulletList.getMarker() != null ? bulletList.getMarker() : "-";
497496
}
498497
}
499498

500499
private static class OrderedListHolder extends ListHolder {
501-
final char delimiter;
500+
final String delimiter;
502501
private int number;
503502

504503
protected OrderedListHolder(ListHolder parent, OrderedList orderedList) {
505504
super(parent);
506-
delimiter = orderedList.getDelimiter();
507-
number = orderedList.getStartNumber();
505+
delimiter = orderedList.getMarkerDelimiter() != null ? orderedList.getMarkerDelimiter() : ".";
506+
number = orderedList.getMarkerStartNumber() != null ? orderedList.getMarkerStartNumber() : 1;
508507
}
509508
}
510509

0 commit comments

Comments
 (0)