diff --git a/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java b/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java index f6702518b..0ff644a47 100644 --- a/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java +++ b/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java @@ -217,7 +217,7 @@ public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockPar } int newColumn = listData.contentColumn; - ListItemParser listItemParser = new ListItemParser(newColumn - state.getColumn()); + ListItemParser listItemParser = new ListItemParser(state.getIndent(), newColumn - state.getColumn()); // prepend the list block if needed if (!(matched instanceof ListBlockParser) || diff --git a/commonmark/src/main/java/org/commonmark/internal/ListItemParser.java b/commonmark/src/main/java/org/commonmark/internal/ListItemParser.java index 6f03770b3..49722dff2 100644 --- a/commonmark/src/main/java/org/commonmark/internal/ListItemParser.java +++ b/commonmark/src/main/java/org/commonmark/internal/ListItemParser.java @@ -20,8 +20,10 @@ public class ListItemParser extends AbstractBlockParser { private boolean hadBlankLine; - public ListItemParser(int contentIndent) { + public ListItemParser(int markerIndent, int contentIndent) { this.contentIndent = contentIndent; + block.setMarkerIndent(markerIndent); + block.setContentIndent(contentIndent); } @Override diff --git a/commonmark/src/main/java/org/commonmark/node/ListItem.java b/commonmark/src/main/java/org/commonmark/node/ListItem.java index aa526be01..21f4e2b82 100644 --- a/commonmark/src/main/java/org/commonmark/node/ListItem.java +++ b/commonmark/src/main/java/org/commonmark/node/ListItem.java @@ -2,8 +2,53 @@ public class ListItem extends Block { + private int markerIndent; + private int contentIndent; + @Override public void accept(Visitor visitor) { visitor.visit(this); } + + /** + * Returns the indent of the marker such as "-" or "1." in columns (spaces or tab stop of 4). + *
+ * Some examples and their marker indent: + *
- Foo+ * Marker indent: 0 + *
- Foo+ * Marker indent: 1 + *
1. Foo+ * Marker indent: 2 + */ + public int getMarkerIndent() { + return markerIndent; + } + + public void setMarkerIndent(int markerIndent) { + this.markerIndent = markerIndent; + } + + /** + * Returns the indent of the content in columns (spaces or tab stop of 4). The content indent is counted from the + * beginning of the line and includes the marker on the first line. + *
+ * Some examples and their content indent: + *
- Foo+ * Content indent: 2 + *
- Foo+ * Content indent: 3 + *
1. Foo+ * Content indent: 5 + *
+ * Note that subsequent lines in the same list item need to be indented by at least the content indent to be counted
+ * as part of the list item.
+ */
+ public int getContentIndent() {
+ return contentIndent;
+ }
+
+ public void setContentIndent(int contentIndent) {
+ this.contentIndent = contentIndent;
+ }
}
diff --git a/commonmark/src/test/java/org/commonmark/test/ListBlockParserTest.java b/commonmark/src/test/java/org/commonmark/test/ListBlockParserTest.java
new file mode 100644
index 000000000..a8a03fb74
--- /dev/null
+++ b/commonmark/src/test/java/org/commonmark/test/ListBlockParserTest.java
@@ -0,0 +1,67 @@
+package org.commonmark.test;
+
+import org.commonmark.node.ListItem;
+import org.commonmark.node.Node;
+import org.commonmark.parser.Parser;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class ListBlockParserTest {
+
+ private static final Parser PARSER = Parser.builder().build();
+
+ @Test
+ public void testBulletListIndents() {
+ assertListItemIndents("* foo", 0, 2);
+ assertListItemIndents(" * foo", 1, 3);
+ assertListItemIndents(" * foo", 2, 4);
+ assertListItemIndents(" * foo", 3, 5);
+
+ assertListItemIndents("* foo", 0, 3);
+ assertListItemIndents("* foo", 0, 4);
+ assertListItemIndents("* foo", 0, 5);
+ assertListItemIndents(" * foo", 1, 4);
+ assertListItemIndents(" * foo", 3, 8);
+
+ // The indent is relative to any containing blocks
+ assertListItemIndents("> * foo", 0, 2);
+ assertListItemIndents("> * foo", 1, 3);
+ assertListItemIndents("> * foo", 1, 4);
+
+ // Tab counts as 3 spaces here (to the next tab stop column of 4) -> content indent is 1+3
+ assertListItemIndents("*\tfoo", 0, 4);
+
+ // Empty list, content indent is expected to be 2
+ assertListItemIndents("-\n", 0, 2);
+ }
+
+ @Test
+ public void testOrderedListIndents() {
+ assertListItemIndents("1. foo", 0, 3);
+ assertListItemIndents(" 1. foo", 1, 4);
+ assertListItemIndents(" 1. foo", 2, 5);
+ assertListItemIndents(" 1. foo", 3, 6);
+
+ assertListItemIndents("1. foo", 0, 4);
+ assertListItemIndents("1. foo", 0, 5);
+ assertListItemIndents("1. foo", 0, 6);
+ assertListItemIndents(" 1. foo", 1, 5);
+ assertListItemIndents(" 1. foo", 2, 8);
+
+ assertListItemIndents("> 1. foo", 0, 3);
+ assertListItemIndents("> 1. foo", 1, 4);
+ assertListItemIndents("> 1. foo", 1, 5);
+
+ assertListItemIndents("1.\tfoo", 0, 4);
+ }
+
+ private void assertListItemIndents(String input, int expectedMarkerIndent, int expectedContentIndent) {
+ Node doc = PARSER.parse(input);
+ ListItem listItem = Nodes.find(doc, ListItem.class);
+ assertNotNull(listItem);
+ assertEquals(expectedMarkerIndent, listItem.getMarkerIndent());
+ assertEquals(expectedContentIndent, listItem.getContentIndent());
+ }
+}
diff --git a/commonmark/src/test/java/org/commonmark/test/Nodes.java b/commonmark/src/test/java/org/commonmark/test/Nodes.java
index bbc019a6a..25ce75836 100644
--- a/commonmark/src/test/java/org/commonmark/test/Nodes.java
+++ b/commonmark/src/test/java/org/commonmark/test/Nodes.java
@@ -14,4 +14,27 @@ public static List