summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremie Bresson2012-09-05 16:46:24 (EDT)
committerDavid Green2012-09-05 16:46:24 (EDT)
commit7cac0792730a2a6985ea873589bf527e16e164c4 (patch)
treed6016750b1cde6097407932c6e8cd0becfeb7210
parentb4943d28d911e14b25a3582f740bc90a04ad6e98 (diff)
downloadorg.eclipse.mylyn.docs-7cac0792730a2a6985ea873589bf527e16e164c4.zip
org.eclipse.mylyn.docs-7cac0792730a2a6985ea873589bf527e16e164c4.tar.gz
org.eclipse.mylyn.docs-7cac0792730a2a6985ea873589bf527e16e164c4.tar.bz2
bug 381912: [MediaWiki] support for nested blocks in table cells.refs/changes/87/6287/9
Add the possibility to have more complex cell content in tables. - Add the nesting protocol to TableBlock - Add the cases described in the bug to the test suite - Correction of the JavaDoc of Block.canResume(String, int) Bugzilla: https://bugs.eclipse.org/bugs/show_bug.cgi?id=381912 Change-Id: Iecd139af2cfd6d358b86aa4fc2b380c00a168567
-rw-r--r--org.eclipse.mylyn.wikitext.core/src/org/eclipse/mylyn/wikitext/core/parser/markup/Block.java12
-rw-r--r--org.eclipse.mylyn.wikitext.mediawiki.core/src/org/eclipse/mylyn/internal/wikitext/mediawiki/core/block/TableBlock.java103
-rw-r--r--org.eclipse.mylyn.wikitext.tests/src/org/eclipse/mylyn/wikitext/mediawiki/core/MediaWikiLanguageTest.java91
3 files changed, 179 insertions, 27 deletions
diff --git a/org.eclipse.mylyn.wikitext.core/src/org/eclipse/mylyn/wikitext/core/parser/markup/Block.java b/org.eclipse.mylyn.wikitext.core/src/org/eclipse/mylyn/wikitext/core/parser/markup/Block.java
index cec28ec..f478101 100644
--- a/org.eclipse.mylyn.wikitext.core/src/org/eclipse/mylyn/wikitext/core/parser/markup/Block.java
+++ b/org.eclipse.mylyn.wikitext.core/src/org/eclipse/mylyn/wikitext/core/parser/markup/Block.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 David Green and others.
+ * Copyright (c) 2007, 2012 David Green and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* David Green - initial API and implementation
+ * Jeremie Bresson - Bug 381912
*******************************************************************************/
package org.eclipse.mylyn.wikitext.core.parser.markup;
@@ -95,16 +96,17 @@ public abstract class Block extends Processor implements Cloneable {
}
/**
- * Indicate if the block can continue on the given line at the given offset. blocks that implement a nesting
- * protocol should implement this method.
+ * Indicates if the block can resume with the given markup line at the provided offset. Resuming a block, means that
+ * the nested children blocks are closed. Blocks that implement a nesting protocol should implement this method.
*
* @param line
* the line of content
* @param lineOffset
* the 0-based offset into the line
- * @return the 0-based offset where the close will occur, or -1 if the block should not close on this line.
+ * @return <code>true</code> if the block can resume <code>false</code> if nested block needs to handle the content
+ * further.
* @see #beginNesting()
- * @see #canResume(String, int)
+ * @see #findCloseOffset(String, int)
* @since 1.6
*/
public boolean canResume(String line, int lineOffset) {
diff --git a/org.eclipse.mylyn.wikitext.mediawiki.core/src/org/eclipse/mylyn/internal/wikitext/mediawiki/core/block/TableBlock.java b/org.eclipse.mylyn.wikitext.mediawiki.core/src/org/eclipse/mylyn/internal/wikitext/mediawiki/core/block/TableBlock.java
index d2dd5c2..7f1105d 100644
--- a/org.eclipse.mylyn.wikitext.mediawiki.core/src/org/eclipse/mylyn/internal/wikitext/mediawiki/core/block/TableBlock.java
+++ b/org.eclipse.mylyn.wikitext.mediawiki.core/src/org/eclipse/mylyn/internal/wikitext/mediawiki/core/block/TableBlock.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2011 David Green and others.
+ * Copyright (c) 2007, 2012 David Green and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,13 +7,13 @@
*
* Contributors:
* David Green - initial API and implementation
+ * Jeremie Bresson - Bug 381912
*******************************************************************************/
package org.eclipse.mylyn.internal.wikitext.mediawiki.core.block;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.eclipse.mylyn.wikitext.core.parser.Attributes;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder.BlockType;
import org.eclipse.mylyn.wikitext.core.parser.TableAttributes;
import org.eclipse.mylyn.wikitext.core.parser.TableCellAttributes;
@@ -49,6 +49,8 @@ public class TableBlock extends Block {
private boolean openRow;
+ private boolean openCell;
+
@Override
public int processLineContent(String line, int offset) {
if (blockLineCount++ == 0) {
@@ -130,22 +132,22 @@ public class TableBlock extends Block {
Matcher cellMatcher = cellPattern.matcher(line);
if (cellMatcher.matches()) {
String kind = cellMatcher.group(1);
+ BlockType type = ("!".equals(kind)) ? BlockType.TABLE_CELL_HEADER : BlockType.TABLE_CELL_NORMAL; //$NON-NLS-1$
+
String contents = cellMatcher.group(2);
if (contents == null) {
- // likely an incomplete line
+ //cell was just opened, no cell options.
+ openCell(cellMatcher.start(), type, new TableCellAttributes());
return -1;
}
- int contentsStart = cellMatcher.start(2);
- BlockType type = ("!".equals(kind)) ? BlockType.TABLE_CELL_HEADER : BlockType.TABLE_CELL_NORMAL; //$NON-NLS-1$
- if (!openRow) {
- openRow(cellMatcher.start(), new Attributes());
- }
+ int contentsStart = cellMatcher.start(2);
emitCells(contentsStart, type, contents);
return -1;
} else {
// ignore, bad formatting or unsupported syntax (caption)
+ // in case of cells this will be handled with NestedBlocks
return -1;
}
}
@@ -188,13 +190,6 @@ public class TableBlock extends Block {
throw new IllegalStateException();
}
String cellOptions = cellSplitterMatcher.group(1);
- String cellContents = cellSplitterMatcher.group(2);
- if (cellContents == null) {
- // probably invalid syntax
- return;
- }
-
- int contentsStart = cellSplitterMatcher.start(2);
TableCellAttributes attributes = new TableCellAttributes();
@@ -224,15 +219,19 @@ public class TableBlock extends Block {
}
}
}
- state.setLineCharacterOffset(lineCharacterOffset);
- builder.beginBlock(type, attributes);
-
- markupLanguage.emitMarkupLine(parser, state, lineCharacterOffset + contentsStart, cellContents, 0);
- builder.endBlock();
+ String cellContents = cellSplitterMatcher.group(2);
+ if (cellContents == null) {
+ //cell was opened, no content on this line
+ openCell(lineCharacterOffset + cellSplitterMatcher.end(), type, attributes);
+ } else {
+ int contentsStart = cellSplitterMatcher.start(2);
+ openCell(lineCharacterOffset, type, attributes);
+ markupLanguage.emitMarkupLine(parser, state, lineCharacterOffset + contentsStart, cellContents, 0);
+ }
}
- private void openRow(int lineOffset, Attributes attributes) {
+ private void openRow(int lineOffset, TableRowAttributes attributes) {
closeRow();
state.setLineCharacterOffset(lineOffset);
builder.beginBlock(BlockType.TABLE_ROW, attributes);
@@ -240,12 +239,43 @@ public class TableBlock extends Block {
}
private void closeRow() {
+ closeCell();
if (openRow) {
builder.endBlock();
openRow = false;
}
}
+ /**
+ * Open a cell block.
+ *
+ * @param lineOffset
+ * line offset
+ * @param type
+ * type of cell (expecting {@link BlockType#TABLE_CELL_HEADER} or {@link BlockType#TABLE_CELL_NORMAL}).
+ * @param attributes
+ * attributes of the cell
+ */
+ private void openCell(int lineOffset, BlockType type, TableCellAttributes attributes) {
+ closeCell();
+ if (!openRow) {
+ openRow(lineOffset, new TableRowAttributes());
+ }
+ state.setLineCharacterOffset(lineOffset);
+ builder.beginBlock(type, attributes);
+ openCell = true;
+ }
+
+ /**
+ * Close a cell block if it was opened.
+ */
+ private void closeCell() {
+ if (openCell) {
+ builder.endBlock();
+ openCell = false;
+ }
+ }
+
@Override
public boolean canStart(String line, int lineOffset) {
blockLineCount = 0;
@@ -262,10 +292,41 @@ public class TableBlock extends Block {
@Override
public void setClosed(boolean closed) {
if (closed && !isClosed()) {
+ closeCell();
closeRow();
builder.endBlock();
}
super.setClosed(closed);
}
+ @Override
+ public boolean beginNesting() {
+ return openCell;
+ }
+
+ @Override
+ public int findCloseOffset(String line, int lineOffset) {
+ if (openCell) {
+ if (!checkAtNewTableRow(line, lineOffset)) {
+ return -1;
+ }
+ }
+ return lineOffset; //Close here.
+ }
+
+ private boolean checkAtNewTableRow(String line, int lineOffset) {
+ if (lineOffset < line.length()) {
+ char startChar = line.charAt(lineOffset);
+ if (startChar == '|' || startChar == '!') {
+ //new line, a new cell or a new header cell
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canResume(String line, int lineOffset) {
+ return checkAtNewTableRow(line, lineOffset);
+ }
}
diff --git a/org.eclipse.mylyn.wikitext.tests/src/org/eclipse/mylyn/wikitext/mediawiki/core/MediaWikiLanguageTest.java b/org.eclipse.mylyn.wikitext.tests/src/org/eclipse/mylyn/wikitext/mediawiki/core/MediaWikiLanguageTest.java
index 6a4ed94..e52f2f6 100644
--- a/org.eclipse.mylyn.wikitext.tests/src/org/eclipse/mylyn/wikitext/mediawiki/core/MediaWikiLanguageTest.java
+++ b/org.eclipse.mylyn.wikitext.tests/src/org/eclipse/mylyn/wikitext/mediawiki/core/MediaWikiLanguageTest.java
@@ -7,7 +7,7 @@
*
* Contributors:
* David Green - initial API and implementation
- * Jeremie Bresson - Bug 381506
+ * Jeremie Bresson - Bug 381506, 381912
*******************************************************************************/
package org.eclipse.mylyn.wikitext.mediawiki.core;
@@ -718,6 +718,95 @@ public class MediaWikiLanguageTest extends TestCase {
assertTrue(html.contains("<table class=\"foo\"><tr><td>Some text</td></tr></table>"));
}
+ public void testTableWithParagraphs() {
+ //BUG 381912:
+ StringBuilder sb = new StringBuilder();
+ sb.append("{|border=\"1\"\n");
+ sb.append("|\n");
+ sb.append("A paragraph with '''Bold text''' in a cell.\n");
+ sb.append("|\n");
+ sb.append("A cell ''containing'' more...\n");
+ sb.append("\n");
+ sb.append("Than one paragraph.\n");
+ sb.append("|}\n");
+
+ String html = parser.parseToHtml(sb.toString());
+ TestUtil.println("HTML: \n" + html);
+ Pattern pattern = Pattern.compile("<table border=\"1\">\\s*<tr>\\s*<td>\\s*<p>\\s*A paragraph with \\s*<b>\\s*Bold text\\s*</b>\\s* in a cell.\\s*</p>\\s*</td>\\s*<td>\\s*<p>\\s*A cell \\s*<i>\\s*containing\\s*</i>\\s* more...\\s*</p>\\s*<p>\\s*Than one paragraph.\\s*</p>\\s*</td>\\s*</tr>\\s*</table>");
+ assertContainsPattern(html, pattern);
+ }
+
+ public void testTableWithLongerText() {
+ //BUG 381912:
+ //See: http://www.mediawiki.org/wiki/Help:Tables "longer text and more complex wiki syntax inside table cells".
+ StringBuilder sb = new StringBuilder();
+ sb.append("{|border=\"1\"\n");
+ sb.append("|Sxto mesto kusoks ti sam, \n");
+ sb.append("Da skandalis studentis bezopasostif tut, \n");
+ sb.append("dost takai vcxera na mne\n");
+ sb.append("Mai na zxen problem zembulbas, \n");
+ sb.append("dost vozduh dusxijm kai te. \n");
+ sb.append("\n");
+ sb.append("Oliv slozxju informacias bi bez\n");
+ sb.append("om gde detes komnat,\n");
+ sb.append("To divaj neskolk pridijt ili\n");
+ sb.append("Ktor zapalka bezopasostif es tot. \n");
+ sb.append("|\n");
+ sb.append("* Sxto mesto kusoks ti sam\n");
+ sb.append("* Vi edat zaspatit zapomnitlubovijm sol\n");
+ sb.append("* dost takai vcxera na mne\n");
+ sb.append("|}\n");
+
+ String html = parser.parseToHtml(sb.toString());
+ TestUtil.println("HTML: \n" + html);
+ Pattern pattern = Pattern.compile("<table border=\"1\">\\s*<tr>\\s*<td>\\s*Sxto mesto kusoks ti sam,\\s*<p>\\s*Da skandalis studentis bezopasostif tut,\\s+dost takai vcxera na mne\\s+Mai na zxen problem zembulbas,\\s+dost vozduh dusxijm kai te.\\s*</p>\\s*<p>\\s*Oliv slozxju informacias bi bez\\s*om gde detes komnat,\\s*To divaj neskolk pridijt ili\\s*Ktor zapalka bezopasostif es tot.\\s*</p>\\s*</td>\\s*<td>\\s*<ul>\\s*<li>\\s*Sxto mesto kusoks ti sam\\s*</li>\\s*<li>\\s*Vi edat zaspatit zapomnitlubovijm sol\\s*</li>\\s*<li>\\s*dost takai vcxera na mne\\s*</li>\\s*</ul>\\s*</td>\\s*</tr>\\s*</table>");
+ assertContainsPattern(html, pattern);
+ }
+
+ public void testTableWithCodeInCellAndOptions() {
+ //BUG 381912:
+ StringBuilder sb = new StringBuilder();
+ sb.append("{|border=\"1\"\n");
+ sb.append("|\n");
+ sb.append(" some\n");
+ sb.append("|\n");
+ sb.append(" code\n");
+ sb.append(" multiline\n");
+ sb.append("|style=\"background-color:#FFFF00;\"|\n");
+ sb.append(" this is code in an highlighted cell\n");
+ sb.append("|}\n");
+
+ String html = parser.parseToHtml(sb.toString());
+ TestUtil.println("HTML: \n" + html);
+ Pattern pattern = Pattern.compile("<table border=\"1\">\\s*<tr>\\s*<td>\\s*<pre>\\s*some\n</pre>\\s*</td>\\s*<td>\\s*<pre>\\s*code\n multiline\n</pre>\\s*</td>\\s*<td style=\"background-color:#FFFF00;\">\\s*<pre>\\s*this is code in an highlighted cell\n</pre>\\s*</td>\\s*</tr>\\s*</table>");
+ assertContainsPattern(html, pattern);
+ }
+
+ public void testTableWithExplicitFirstRowAndRowSpan() {
+ //BUG 381912:
+ StringBuilder sb = new StringBuilder();
+ sb.append("{|border=\"1\"\n");
+ sb.append("|-\n");
+ sb.append("!colspan=\"6\"|XYZ uv\n");
+ sb.append("|-\n");
+ sb.append("|rowspan=\"2\"|X1 & X2\n");
+ sb.append("|y1\n");
+ sb.append("|y2\n");
+ sb.append("|y3\n");
+ sb.append("|colspan=\"2\"|Z9\n");
+ sb.append("|-\n");
+ sb.append("|z8\n");
+ sb.append("|colspan=\"2\"|T6\n");
+ sb.append("|u4\n");
+ sb.append("|U6\n");
+ sb.append("|}\n");
+
+ String html = parser.parseToHtml(sb.toString());
+ TestUtil.println("HTML: \n" + html);
+ Pattern pattern = Pattern.compile("<table border=\"1\">\\s*<tr>\\s*<th colspan=\"6\">\\s*XYZ uv\\s*</th>\\s*</tr>\\s*<tr>\\s*<td rowspan=\"2\">\\s*X1 &amp; X2\\s*</td>\\s*<td>\\s*y1\\s*</td>\\s*<td>\\s*y2\\s*</td>\\s*<td>\\s*y3\\s*</td>\\s*<td colspan=\"2\">\\s*Z9\\s*</td>\\s*</tr>\\s*<tr>\\s*<td>\\s*z8\\s*</td>\\s*<td colspan=\"2\">\\s*T6\\s*</td>\\s*<td>\\s*u4\\s*</td>\\s*<td>\\s*U6\\s*</td>\\s*</tr>\\s*</table>");
+ assertContainsPattern(html, pattern);
+ }
+
public void testEntityReference() {
String tests = "&Agrave; &Aacute; &Acirc; &Atilde; &Auml; &Aring; &AElig; &Ccedil; &Egrave; &Eacute; &Ecirc; &Euml; &Igrave; &Iacute; &Icirc; &Iuml; &Ntilde; &Ograve; &Oacute; &Ocirc; &Otilde; &Ouml; &Oslash; &Ugrave; &Uacute; &Ucirc; &Uuml; &szlig; &agrave; &aacute; &acirc; &atilde; &auml; &aring; &aelig; &ccedil; &egrave; &eacute; &ecirc; &euml; &igrave; &iacute; &icirc; &iuml; &ntilde; &ograve; &oacute; &ocirc; &oelig; &otilde; &ouml; &oslash; &ugrave; &uacute; &ucirc; &uuml; &yuml; &iquest; &iexcl; &sect; &para; &dagger; &Dagger; &bull; &ndash; &mdash; &lsaquo; &rsaquo; &laquo; &raquo; &lsquo; &rsquo; &ldquo; &rdquo; &trade; &copy; &reg; &cent; &euro; &yen; &pound; &curren; &#8304; &sup1; &sup2; &sup3; &#8308; &int; &sum; &prod; &radic; &minus; &plusmn; &infin; &asymp; &prop; &equiv; &ne; &le; &ge; &times; &middot; &divide; &part; &prime; &Prime; &nabla; &permil; &deg; &there4; &alefsym; &oslash; &isin; &notin; &cap; &cup; &sub; &sup; &sube; &supe; &not; &and; &or; &exist; &forall; &rArr; &lArr; &dArr; &uArr; &hArr; &rarr; &darr; &uarr; &larr; &harr; &mdash; &ndash;";
final String[] allEntities = tests.split("\\s+");