Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
45 changes: 45 additions & 0 deletions commonmark/src/main/java/org/commonmark/node/ListItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -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).
* <p>
* Some examples and their marker indent:
* <pre>- Foo</pre>
* Marker indent: 0
* <pre> - Foo</pre>
* Marker indent: 1
* <pre> 1. Foo</pre>
* 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.
* <p>
* Some examples and their content indent:
* <pre>- Foo</pre>
* Content indent: 2
* <pre> - Foo</pre>
* Content indent: 3
* <pre> 1. Foo</pre>
* Content indent: 5
* <p>
* 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;
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
23 changes: 23 additions & 0 deletions commonmark/src/test/java/org/commonmark/test/Nodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,27 @@ public static List<Node> getChildren(Node parent) {
}
return children;
}

/**
* Recursively try to find a node with the given type within the children of the specified node.
*
* @param parent The node to get children from (node itself will not be checked)
* @param nodeClass The type of node to find
*/
public static <T> T find(Node parent, Class<T> nodeClass) {
Node node = parent.getFirstChild();
while (node != null) {
Node next = node.getNext();
if (nodeClass.isInstance(node)) {
//noinspection unchecked
return (T) node;
}
T result = find(node, nodeClass);
if (result != null) {
return result;
}
node = next;
}
return null;
}
}