509055: [asciidoc] add quote support for csv tables

Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=509055
Change-Id: If9897dbd15d1e374e26788f8bc279924a4a8c210
Signed-off-by: Jeremie Bresson <dev@jmini.fr>
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/main/java/org/eclipse/mylyn/wikitext/asciidoc/internal/block/TableBlock.java b/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/main/java/org/eclipse/mylyn/wikitext/asciidoc/internal/block/TableBlock.java
index 315882d..f1f8f67 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/main/java/org/eclipse/mylyn/wikitext/asciidoc/internal/block/TableBlock.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/main/java/org/eclipse/mylyn/wikitext/asciidoc/internal/block/TableBlock.java
@@ -130,7 +130,7 @@
 
 	private Iterable<String> createRowCellSplitter(String line) {
 		if (format == TableFormat.COMMA_SEPARATED_VALUES) {
-			return Splitter.on(",").split(line); //$NON-NLS-1$
+			return Splitter.on(Pattern.compile(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")).split(line); //$NON-NLS-1$
 		}
 		String delimiter = getCellSeparator();
 		return Splitter.on(Pattern.compile("(?<!\\\\)" + Pattern.quote(delimiter))).split(line); //$NON-NLS-1$
@@ -152,11 +152,15 @@
 		closeCellBlockIfNeeded();
 
 		String blockContent;
-		if (format != TableFormat.COMMA_SEPARATED_VALUES) {
+		if (format == TableFormat.COMMA_SEPARATED_VALUES) {
+			if (cellContent.startsWith("\"") && cellContent.endsWith("\"")) {
+				blockContent = cellContent.substring(1, cellContent.length() - 1).replaceAll("\"\"", "\"");
+			} else {
+				blockContent = cellContent;
+			}
+		} else {
 			String delimiter = getCellSeparator();
 			blockContent = cellContent.replaceAll("\\\\" + Pattern.quote(delimiter), delimiter);//$NON-NLS-1$
-		} else {
-			blockContent = cellContent;
 		}
 
 		if (!colsAttribute.isEmpty() && cellsCount % colsAttribute.size() == 0) {
diff --git a/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/test/java/org/eclipse/mylyn/internal/wikitext/asciidoc/tests/AsciiDocLanguageTableTest.java b/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/test/java/org/eclipse/mylyn/internal/wikitext/asciidoc/tests/AsciiDocLanguageTableTest.java
index af0006f..130b507 100644
--- a/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/test/java/org/eclipse/mylyn/internal/wikitext/asciidoc/tests/AsciiDocLanguageTableTest.java
+++ b/wikitext/core/org.eclipse.mylyn.wikitext.asciidoc/src/test/java/org/eclipse/mylyn/internal/wikitext/asciidoc/tests/AsciiDocLanguageTableTest.java
@@ -494,6 +494,171 @@
 	}
 
 	@Test
+	public void testTableCSVWithQuotes() {
+		String html = parseToHtml("" //
+				+ "[format=\"csv\"]\n" //
+				+ "|===\n" //
+				+ "\"first\",second,third\n" //
+				+ "first,\"second\",third\n" //
+				+ "first,second,\"third\"\n" //
+				+ "\"foo,bar\",second,third\n" //
+				+ "first,\"foo,bar\",third\n" //
+				+ "first,second,\"foo,bar\"\n" //
+				+ "|===\n" //
+				+ "Some Text");
+		assertEquals("<table>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>foo,bar</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>foo,bar</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>foo,bar</td>" //
+				+ "</tr>" //
+				+ "</table>" //
+				+ "<p>Some Text</p>\n", html);
+	}
+
+	@Test
+	public void testTableCSVWithWrongQuotes() {
+		String html = parseToHtml("" //
+				+ "[format=\"csv\"]\n" //
+				+ "|===\n" //
+				+ "xxx\"first\"xxx,second,third\n" //
+				+ "first,xxx\"second\"xxx,third\n" //
+				+ "first,second,xxx\"third\"xxx\n" //
+				+ "\n" //
+				+ "xxx \" fi rst \" xxx,second,third\n" //
+				+ "first,xxx \"sec ond\" xxx,third\n" //
+				+ "first,second,xxx \" third \" xxx\n" //
+				+ "|===\n" //
+				+ "Some Text");
+		assertEquals("<table>" //
+				+ "<tr>" //
+				+ "<td>xxx\"first\"xxx</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>xxx\"second\"xxx</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>xxx\"third\"xxx</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>xxx \" fi rst \" xxx</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>xxx \"sec ond\" xxx</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>xxx \" third \" xxx</td>" //
+				+ "</tr>" //
+				+ "</table>" //
+				+ "<p>Some Text</p>\n", html);
+	}
+
+	@Test
+	public void testTableCSVWithQuotesAndEscaped() {
+		String html = parseToHtml("" //
+				+ "[format=\"csv\"]\n" //
+				+ "|===\n" //
+				+ "\"lorem \"\"a\"\" ipsum\",second,third\n" //
+				+ "first,\"lorem \"\"a\"\" ipsum\",third\n" //
+				+ "first,second,\"lorem \"\"a\"\" ipsum\"\n" //
+				+ "\n" //
+				+ "\"\"\"a\"\" ipsum\",second,third\n" //
+				+ "first,\"\"\"a\"\" ipsum\",third\n" //
+				+ "first,second,\"\"\"a\"\" ipsum\"\n" //
+				+ "\n" //
+				+ "\"lorem \"\"a\"\"\",second,third\n" //
+				+ "first,\"lorem \"\"a\"\"\",third\n" //
+				+ "first,second,\"lorem \"\"a\"\"\"\n" //
+				+ "|===\n" //
+				+ "Some Text");
+		assertEquals("<table>" //
+				+ "<tr>" //
+				+ "<td>lorem \"a\" ipsum</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>lorem \"a\" ipsum</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>lorem \"a\" ipsum</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>\"a\" ipsum</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>\"a\" ipsum</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>\"a\" ipsum</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>lorem \"a\"</td>" //
+				+ "<td>second</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>lorem \"a\"</td>" //
+				+ "<td>third</td>" //
+				+ "</tr>" //
+				+ "<tr>" //
+				+ "<td>first</td>" //
+				+ "<td>second</td>" //
+				+ "<td>lorem \"a\"</td>" //
+				+ "</tr>" //
+				+ "</table>" //
+				+ "<p>Some Text</p>\n", html);
+	}
+
+	@Test
 	public void testTableDSV() {
 		String html = parseToHtml("" //
 				+ "[format=\"dsv\", options=\"header\"]\n" //