diff --git a/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java b/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java index 27dbde7cf..29a6c5de8 100644 --- a/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java +++ b/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java @@ -297,6 +297,11 @@ private void setNewColumn(int newColumn) { while (column < newColumn && index != line.length()) { advance(); } + if (column > newColumn) { + // Last character was a tab and we overshot our target + index--; + column = newColumn; + } } private void advance() { diff --git a/commonmark/src/test/java/org/commonmark/test/ParserTest.java b/commonmark/src/test/java/org/commonmark/test/ParserTest.java index d6a46d58d..6c6915919 100644 --- a/commonmark/src/test/java/org/commonmark/test/ParserTest.java +++ b/commonmark/src/test/java/org/commonmark/test/ParserTest.java @@ -5,7 +5,6 @@ import org.commonmark.parser.Parser; import org.commonmark.parser.block.*; import org.commonmark.spec.SpecReader; -import org.hamcrest.CoreMatchers; import org.junit.Test; import java.io.IOException; @@ -13,9 +12,9 @@ import java.io.InputStreamReader; import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; public class ParserTest { @@ -47,6 +46,35 @@ public void customBlockParserFactory() { assertEquals("hey", ((Text) document.getFirstChild().getFirstChild()).getLiteral()); assertThat(document.getLastChild(), instanceOf(DashBlock.class)); } + + @Test + public void indentation() { + String given = " - 1 space\n - 3 spaces\n - 5 spaces\n\t - tab + space"; + Parser parser = Parser.builder().build(); + Node document = parser.parse(given); + + assertThat(document.getFirstChild(), instanceOf(BulletList.class)); + + Node list = document.getFirstChild(); // first level list + assertEquals("expect one child", list.getFirstChild(), list.getLastChild()); + assertEquals("1 space", firstText(list.getFirstChild())); + + list = list.getFirstChild().getLastChild(); // second level list + assertEquals("expect one child", list.getFirstChild(), list.getLastChild()); + assertEquals("3 spaces", firstText(list.getFirstChild())); + + list = list.getFirstChild().getLastChild(); // third level list + assertEquals("5 spaces", firstText(list.getFirstChild())); + assertEquals("tab + space", firstText(list.getFirstChild().getNext())); + } + + private String firstText(Node n) { + while (!(n instanceof Text)) { + assertThat(n, notNullValue()); + n = n.getFirstChild(); + } + return ((Text) n).getLiteral(); + } private static class DashBlock extends CustomBlock { }