462086: correct defect in Markdown DocumentBuilder sublist handling
Change-Id: Iefbddfa5ca263e80d7edec37cae61f265ffb5eb3
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=462086
diff --git a/org.eclipse.mylyn.wikitext.markdown.core/src/org/eclipse/mylyn/internal/wikitext/markdown/core/MarkdownDocumentBuilder.java b/org.eclipse.mylyn.wikitext.markdown.core/src/org/eclipse/mylyn/internal/wikitext/markdown/core/MarkdownDocumentBuilder.java
index b7a101d..2f9a6eb 100644
--- a/org.eclipse.mylyn.wikitext.markdown.core/src/org/eclipse/mylyn/internal/wikitext/markdown/core/MarkdownDocumentBuilder.java
+++ b/org.eclipse.mylyn.wikitext.markdown.core/src/org/eclipse/mylyn/internal/wikitext/markdown/core/MarkdownDocumentBuilder.java
@@ -54,20 +54,20 @@
}
- private class ContentBlock extends Block implements MarkdownBlock {
+ private class ContentBlock extends NewlineDelimitedBlock implements MarkdownBlock {
protected String prefix;
protected String suffix;
- ContentBlock(BlockType blockType, String prefix, String suffix) {
- super(blockType);
+ ContentBlock(BlockType blockType, String prefix, String suffix, int leadingNewlines, int trailingNewlines) {
+ super(blockType, leadingNewlines, trailingNewlines);
this.prefix = prefix;
this.suffix = suffix;
}
- ContentBlock(String prefix, String suffix) {
- this(null, prefix, suffix);
+ ContentBlock(String prefix, String suffix, int leadingNewlines, int trailingNewlines) {
+ this(null, prefix, suffix, leadingNewlines, trailingNewlines);
}
@Override
@@ -112,7 +112,7 @@
private class ImplicitParagraphBlock extends ContentBlock {
ImplicitParagraphBlock() {
- super(BlockType.PARAGRAPH, "", "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ super(BlockType.PARAGRAPH, "", "", 2, 2); //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
@@ -124,8 +124,9 @@
private class PrefixedLineContentBlock extends ContentBlock {
- PrefixedLineContentBlock(BlockType blockType, String prefix, String suffix) {
- super(blockType, prefix, suffix);
+ PrefixedLineContentBlock(BlockType blockType, String prefix, String suffix, int leadingNewlines,
+ int trailingNewlines) {
+ super(blockType, prefix, suffix, leadingNewlines, trailingNewlines);
}
@Override
@@ -159,8 +160,8 @@
private int count = 0;
- ListBlock(BlockType blockType, String prefix, String suffix) {
- super(blockType, prefix, suffix);
+ ListBlock(BlockType blockType, int leadingNewlines) {
+ super(blockType, "", "", leadingNewlines, 1); //$NON-NLS-1$//$NON-NLS-2$
}
@Override
@@ -187,8 +188,8 @@
private int count;
- private ListItemBlock(String prefix, String suffix) {
- super(BlockType.LIST_ITEM, prefix, suffix);
+ private ListItemBlock(String prefix) {
+ super(BlockType.LIST_ITEM, prefix, "", 1, 1); //$NON-NLS-1$
}
@Override
@@ -206,6 +207,8 @@
if (getPreviousBlock().getBlockType() == BlockType.NUMERIC_LIST) {
prefix = count + ". "; //$NON-NLS-1$
}
+ String indent = Strings.repeat(" ", prefix.length()); //$NON-NLS-1$
+
MarkdownDocumentBuilder.this.emitContent(prefix);
// split out content by line
Matcher matcher = PATTERN_LINE_BREAK.matcher(content);
@@ -214,7 +217,7 @@
// indent each line hanging past the initial line item
String line = matcher.group(0);
if (lines > 0 && !line.trim().isEmpty()) {
- line = " " + line; //$NON-NLS-1$
+ line = indent + line;
}
MarkdownDocumentBuilder.this.emitContent(line);
lines++;
@@ -232,7 +235,7 @@
private final LinkAttributes attributes;
LinkBlock(LinkAttributes attributes) {
- super("", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ super("", "", 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
this.attributes = attributes;
}
@@ -259,7 +262,7 @@
private class CodeSpan extends ContentBlock {
private CodeSpan() {
- super("`", "`"); //$NON-NLS-1$ //$NON-NLS-2$
+ super("`", "`", 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
@@ -282,22 +285,29 @@
protected Block computeBlock(BlockType type, Attributes attributes) {
switch (type) {
case PARAGRAPH:
- return new ContentBlock(type, "", "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock(type, "", "", 2, 2); //$NON-NLS-1$ //$NON-NLS-2$
case QUOTE:
- return new PrefixedLineContentBlock(type, "> ", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new PrefixedLineContentBlock(type, "> ", "", 1, 1); //$NON-NLS-1$ //$NON-NLS-2$
case BULLETED_LIST:
case NUMERIC_LIST:
- return new ListBlock(type, "", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (currentBlock != null) {
+ BlockType currentBlockType = currentBlock.getBlockType();
+ if (currentBlockType == BlockType.LIST_ITEM || currentBlockType == BlockType.DEFINITION_ITEM
+ || currentBlockType == BlockType.DEFINITION_TERM) {
+ return new ListBlock(type, 1);
+ }
+ }
+ return new ListBlock(type, 2);
case LIST_ITEM:
if (computeCurrentListType() == BlockType.NUMERIC_LIST) {
- return new ListItemBlock("1. ", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ListItemBlock("1. "); //$NON-NLS-1$
}
- return new ListItemBlock("* ", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ListItemBlock("* "); //$NON-NLS-1$
case CODE:
- return new PrefixedLineContentBlock(type, " ", "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new PrefixedLineContentBlock(type, " ", "", 1, 2); //$NON-NLS-1$ //$NON-NLS-2$
default:
Logger.getLogger(getClass().getName()).warning("Unexpected block type: " + type); //$NON-NLS-1$
- return new ContentBlock(type, "", "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock(type, "", "", 2, 2); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@@ -308,24 +318,24 @@
if (attributes instanceof LinkAttributes) {
return new LinkBlock((LinkAttributes) attributes);
}
- return new ContentBlock("<", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock("<", ">", 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
case ITALIC:
case EMPHASIS:
- return new ContentBlock("*", "*"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock("*", "*", 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
case BOLD:
case STRONG:
- return new ContentBlock("**", "**"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock("**", "**", 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
case CODE:
return new CodeSpan();
default:
Logger.getLogger(getClass().getName()).warning("Unexpected block type: " + type); //$NON-NLS-1$
- return new ContentBlock("", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock("", "", 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@Override
protected Block computeHeading(int level, Attributes attributes) {
- return new ContentBlock(computePrefix('#', level) + " ", "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new ContentBlock(computePrefix('#', level) + " ", "", 1, 2); //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
diff --git a/org.eclipse.mylyn.wikitext.markdown.tests/src/org/eclipse/mylyn/internal/wikitext/markdown/tests/MarkdownDocumentBuilderTest.java b/org.eclipse.mylyn.wikitext.markdown.tests/src/org/eclipse/mylyn/internal/wikitext/markdown/tests/MarkdownDocumentBuilderTest.java
index db493c4..ce2d6de 100644
--- a/org.eclipse.mylyn.wikitext.markdown.tests/src/org/eclipse/mylyn/internal/wikitext/markdown/tests/MarkdownDocumentBuilderTest.java
+++ b/org.eclipse.mylyn.wikitext.markdown.tests/src/org/eclipse/mylyn/internal/wikitext/markdown/tests/MarkdownDocumentBuilderTest.java
@@ -322,7 +322,7 @@
builder.endBlock();
builder.endBlock();
builder.endDocument();
- assertMarkup("* X\n* Y\n* Z\n\n");
+ assertMarkup("* X\n* Y\n* Z\n");
}
public void testListNumeric() {
@@ -339,7 +339,7 @@
builder.endBlock();
builder.endBlock();
builder.endDocument();
- assertMarkup("1. One\n2. Two\n3. Three\n\n");
+ assertMarkup("1. One\n2. Two\n3. Three\n");
}
public void testListConsecutive() {
@@ -355,7 +355,7 @@
builder.endBlock();
builder.endBlock();
builder.endDocument();
- assertMarkup("* Food\n\n1. Drink\n\n");
+ assertMarkup("* Food\n\n1. Drink\n");
}
public void testListWithParagraphs() {
@@ -397,7 +397,7 @@
builder.endBlock();
builder.endBlock();
builder.endDocument();
- assertMarkup("* List item with two paragraphs.\n\n Second paragraph.\n\n* Simple list item.\n\n");
+ assertMarkup("* List item with two paragraphs.\n\n Second paragraph.\n\n* Simple list item.\n");
}
public void testListItemWithBlockQuote() {
@@ -415,7 +415,7 @@
builder.endBlock();
builder.endBlock();
builder.endDocument();
- assertMarkup("* A list item with a blockquote:\n\n > This is a blockquote \n > inside a list item.\n\n");
+ assertMarkup("* A list item with a blockquote:\n\n > This is a blockquote \n > inside a list item.\n");
}
public void testListItemWithCodeBlock() {
@@ -431,7 +431,7 @@
builder.endBlock();
builder.endBlock();
builder.endDocument();
- assertMarkup("* A list item with a code block:\n\n code goes here\n\n");
+ assertMarkup("* A list item with a code block:\n\n code goes here\n\n");
}
public void testCodeBlock() {
@@ -783,6 +783,58 @@
assertMarkup("© XY&Z 2014\n\n");
}
+ public void testBulletedListWithNestedSublist2() {
+ builder.beginDocument();
+
+ builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
+
+ emitListItem("first");
+
+ builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
+ builder.characters("second");
+
+ builder.beginBlock(BlockType.BULLETED_LIST, new Attributes());
+ emitListItem("second.1");
+ builder.endBlock(); // list
+ builder.endBlock(); // list item
+ builder.endBlock(); // list
+
+ builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes());
+ emitListItem("third");
+
+ builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
+ builder.characters("fourth");
+ builder.beginBlock(BlockType.NUMERIC_LIST, new Attributes());
+ emitListItem("fourth.1");
+
+ builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
+ builder.characters("fourth.2");
+ builder.lineBreak();
+ builder.characters("fourth.2 line 2");
+ builder.endBlock(); // list item
+
+ builder.endBlock(); // list
+ builder.endBlock(); // list item
+
+ builder.endBlock(); // list
+
+ builder.endDocument();
+
+ String markup = out.toString();
+
+ TestUtil.println(markup);
+
+ assertEquals(
+ "* first\n* second\n * second.1\n\n1. third\n2. fourth\n 1. fourth.1\n 2. fourth.2 \n fourth.2 line 2\n",
+ markup);
+ }
+
+ private void emitListItem(String text) {
+ builder.beginBlock(BlockType.LIST_ITEM, new Attributes());
+ builder.characters(text);
+ builder.endBlock();
+ }
+
private void assertMarkup(String expected) {
String markup = out.toString();
TestUtil.println(markup);