You are viewing a plain text version of this content. The canonical link for it is here.
Posted to doxia-commits@maven.apache.org by vs...@apache.org on 2009/08/21 13:58:39 UTC
svn commit: r806515 - in /maven/doxia/doxia/trunk/doxia-core/src:
main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java
test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java
Author: vsiveton
Date: Fri Aug 21 11:58:39 2009
New Revision: 806515
URL: http://svn.apache.org/viewvc?rev=806515&view=rev
Log:
o be sure that nested tables are correctly handle
o improved also table caption (DOXIA-177)
Modified:
maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java
Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java?rev=806515&r1=806514&r2=806515&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java Fri Aug 21 11:58:39 2009
@@ -25,6 +25,7 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
@@ -39,6 +40,7 @@
import org.apache.maven.doxia.util.HtmlTools;
import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
/**
* Abstract base xhtml sink implementation.
@@ -59,10 +61,6 @@
/** The PrintWriter to write the result. */
private PrintWriter writer;
- /** The StringWriter to write the result temporary, so we could play with the output and fix XHTML
- * like DOXIA-177. Calling the method {@link #close()} is needed to perform the changes in the {@link #writer}. */
- private StringWriter tempWriter;
-
/** Used to collect text events mainly for the head events. */
private StringBuffer textBuffer = new StringBuffer();
@@ -78,18 +76,28 @@
/** An indication on if we're in verbatim mode. */
private boolean verbatimFlag;
- /** Alignment of table cells. */
- private int[] cellJustif;
+ /** Stack of alignment int[] of table cells. */
+ private final LinkedList cellJustifStack;
- /** Justification of table cells. */
- private boolean isCellJustif;
+ /** Stack of justification of table cells. */
+ private final LinkedList isCellJustifStack;
- /** Number of cells in a table row. */
- private int cellCount;
+ /** Stack of current table cell. */
+ private final LinkedList cellCountStack;
/** Used to style successive table rows differently. */
private boolean evenTableRow = true;
+ /** The stack of StringWriter to write the table result temporary, so we could play with the output DOXIA-177. */
+ private final LinkedList tableContentWriterStack;
+
+ private final LinkedList tableCaptionWriterStack;
+
+ private final LinkedList tableCaptionXMLWriterStack;
+
+ /** The stack of table caption */
+ private final LinkedList tableCaptionStack;
+
/** used to store attributes passed to table(). */
protected MutableAttributeSet tableAttributes;
@@ -133,7 +141,14 @@
public XhtmlBaseSink( Writer out )
{
this.writer = new PrintWriter( out );
- this.tempWriter = new StringWriter();
+
+ this.cellJustifStack = new LinkedList();
+ this.isCellJustifStack = new LinkedList();
+ this.cellCountStack = new LinkedList();
+ this.tableContentWriterStack = new LinkedList();
+ this.tableCaptionWriterStack = new LinkedList();
+ this.tableCaptionXMLWriterStack = new LinkedList();
+ this.tableCaptionStack = new LinkedList();
}
// ----------------------------------------------------------------------
@@ -197,8 +212,8 @@
*/
protected void setCellJustif( int[] justif )
{
- this.cellJustif = justif;
- this.isCellJustif = true;
+ this.cellJustifStack.addLast( justif );
+ this.isCellJustifStack.addLast( Boolean.TRUE );
}
/**
@@ -208,7 +223,7 @@
*/
protected int[] getCellJustif()
{
- return this.cellJustif ;
+ return (int[])this.cellJustifStack.getLast();
}
/**
@@ -218,7 +233,7 @@
*/
protected void setCellCount( int count )
{
- this.cellCount = count;
+ this.cellCountStack.addLast( Integer.valueOf( count ) );
}
/**
@@ -228,7 +243,7 @@
*/
protected int getCellCount()
{
- return this.cellCount ;
+ return Integer.parseInt( this.cellCountStack.getLast().toString() );
}
/**
@@ -239,9 +254,9 @@
resetTextBuffer();
headFlag = false;
verbatimFlag = false;
- cellJustif = null;
- isCellJustif = false;
- cellCount = 0;
+ cellJustifStack.clear();
+ isCellJustifStack.clear();
+ cellCountStack.clear();
evenTableRow = true;
}
@@ -1091,6 +1106,7 @@
/** {@inheritDoc} */
public void table( SinkEventAttributes attributes )
{
+ this.tableContentWriterStack.addLast( new StringWriter() );
this.tableRows = false;
if ( paragraphFlag )
@@ -1102,7 +1118,7 @@
}
// start table with tableRows
- if ( attributes == null )
+ if ( this.tableAttributes == null )
{
this.tableAttributes = new SinkEventAttributeSet( 0 );
}
@@ -1123,49 +1139,41 @@
writeEndTag( HtmlMarkup.TABLE );
- String content = tempWriter.toString();
-
- String startTable =
- new StringBuffer().append( Markup.LESS_THAN ).append( HtmlMarkup.TABLE.toString() ).toString();
-
- if ( content.lastIndexOf( startTable ) == -1 )
+ if ( this.tableContentWriterStack.isEmpty() )
{
- if ( getLog().isDebugEnabled() )
+ if ( getLog().isWarnEnabled() )
{
- getLog().debug( "table() NOT call firstly" );
+ getLog().warn( "No table content." );
}
return;
}
- content = content.substring( content.lastIndexOf( startTable ) );
+ String tableContent = this.tableContentWriterStack.removeLast().toString();
- String startCaption =
- new StringBuffer().append( Markup.LESS_THAN ).append( HtmlMarkup.CAPTION.toString() )
- .append( Markup.GREATER_THAN ).toString();
- String endCaption =
- new StringBuffer().append( Markup.LESS_THAN ).append( Markup.SLASH ).append( HtmlMarkup.CAPTION.toString() )
- .append( Markup.GREATER_THAN ).toString();
+ String tableCaption = null;
+ if ( !this.tableCaptionStack.isEmpty() && this.tableCaptionStack.getLast() != null )
+ {
+ tableCaption = this.tableCaptionStack.removeLast().toString();
+ }
- if ( content.indexOf( startCaption ) != -1 && content.indexOf( endCaption ) != -1 )
+ if ( tableCaption != null )
{
// DOXIA-177
- int iStartCaption = content.indexOf( startCaption );
- int iEndCaption = content.indexOf( endCaption ) + endCaption.length();
-
- String captionTag = content.substring( iStartCaption, iEndCaption );
- String contentWithoutCaption = StringUtils.replace( content, captionTag, "" );
+ StringBuffer sb = new StringBuffer();
+ sb.append( tableContent.substring( 0, tableContent.indexOf( Markup.GREATER_THAN ) + 1 ) );
+ sb.append( tableCaption );
+ sb.append( tableContent.substring( tableContent.indexOf( Markup.GREATER_THAN ) + 1 ) );
- String startTr =
- new StringBuffer().append( Markup.LESS_THAN ).append( HtmlMarkup.TR.toString() ).toString();
+ write( sb.toString() );
+ }
+ else
+ {
+ write( tableContent );
+ }
- StringBuffer text = new StringBuffer();
- text.append( contentWithoutCaption.substring( 0, contentWithoutCaption.indexOf( startTr ) ) );
- text.append( captionTag );
- text.append( contentWithoutCaption.substring( contentWithoutCaption.indexOf( startTr ) ) );
-
- String contentWithCaption = tempWriter.toString();
- tempWriter = new StringWriter();
- tempWriter.write( StringUtils.replace( contentWithCaption, content, text.toString() ) );
+ if ( !this.cellCountStack.isEmpty() )
+ {
+ this.cellCountStack.removeLast().toString();
}
}
@@ -1188,35 +1196,41 @@
}
MutableAttributeSet att = new SinkEventAttributeSet();
-
- if ( !tableAttributes.isDefined( Attribute.ALIGN.toString() ) )
+ if ( !this.tableAttributes.isDefined( Attribute.ALIGN.toString() ) )
{
att.addAttribute( Attribute.ALIGN, "center" );
}
- if ( !tableAttributes.isDefined( Attribute.BORDER.toString() ) )
+ if ( !this.tableAttributes.isDefined( Attribute.BORDER.toString() ) )
{
att.addAttribute( Attribute.BORDER, ( grid ? "1" : "0" ) );
}
- if ( !tableAttributes.isDefined( Attribute.CLASS.toString() ) )
+ if ( !this.tableAttributes.isDefined( Attribute.CLASS.toString() ) )
{
att.addAttribute( Attribute.CLASS, "bodyTable" );
}
- att.addAttributes( tableAttributes );
-
- tableAttributes.removeAttributes( tableAttributes );
+ att.addAttributes( this.tableAttributes );
+ this.tableAttributes.removeAttributes( this.tableAttributes );
writeStartTag( HtmlMarkup.TABLE, att );
+
+ this.cellCountStack.addLast( new Integer( 0 ) );
}
/** {@inheritDoc} */
public void tableRows_()
{
this.tableRows = false;
- this.cellJustif = null;
- this.isCellJustif = false;
+ if ( !this.cellJustifStack.isEmpty() )
+ {
+ this.cellJustifStack.removeLast();
+ }
+ if ( !this.isCellJustifStack.isEmpty() )
+ {
+ this.isCellJustifStack.removeLast();
+ }
this.evenTableRow = true;
}
@@ -1263,7 +1277,11 @@
evenTableRow = !evenTableRow;
- cellCount = 0;
+ if ( !this.cellCountStack.isEmpty() )
+ {
+ this.cellCountStack.removeLast();
+ this.cellCountStack.addLast( new Integer( 0 ) );
+ }
}
/**
@@ -1273,8 +1291,6 @@
public void tableRow_()
{
writeEndTag( HtmlMarkup.TR );
-
- cellCount = 0;
}
/** {@inheritDoc} */
@@ -1342,19 +1358,25 @@
justif = attributes.getAttribute( Attribute.ALIGN.toString() ).toString();
}
- if ( justif == null && cellJustif != null && cellJustif.length > 0 && isCellJustif )
+ if ( !this.cellCountStack.isEmpty() )
{
- switch ( cellJustif[Math.min( cellCount, cellJustif.length - 1 )] )
+ int cellCount = Integer.parseInt( this.cellCountStack.getLast().toString() );
+ int[] cellJustif = (int[]) this.cellJustifStack.getLast();
+ if ( justif == null && cellJustif != null && cellJustif.length > 0
+ && this.isCellJustifStack.getLast().equals( Boolean.TRUE ) )
{
- case JUSTIFY_LEFT:
- justif = "left";
- break;
- case JUSTIFY_RIGHT:
- justif = "right";
- break;
- case JUSTIFY_CENTER:
- default:
- justif = "center";
+ switch ( cellJustif[Math.min( cellCount, cellJustif.length - 1 )] )
+ {
+ case JUSTIFY_LEFT:
+ justif = "left";
+ break;
+ case JUSTIFY_RIGHT:
+ justif = "right";
+ break;
+ case JUSTIFY_CENTER:
+ default:
+ justif = "center";
+ }
}
}
@@ -1394,9 +1416,11 @@
writeEndTag( t );
- if ( isCellJustif )
+ if ( !this.isCellJustifStack.isEmpty() && this.isCellJustifStack.getLast().equals( Boolean.TRUE )
+ && !this.cellCountStack.isEmpty() )
{
- ++cellCount;
+ int cellCount = Integer.parseInt( this.cellCountStack.removeLast().toString() );
+ this.cellCountStack.addLast( new Integer( ++cellCount ) );
}
}
@@ -1415,6 +1439,10 @@
*/
public void tableCaption( SinkEventAttributes attributes )
{
+ StringWriter sw = new StringWriter();
+ this.tableCaptionWriterStack.addLast( sw );
+ this.tableCaptionXMLWriterStack.addLast( new PrettyPrintXMLWriter( sw ) );
+
// TODO: tableCaption should be written before tableRows (DOXIA-177)
MutableAttributeSet atts = SinkUtils.filterAttributes(
attributes, SinkUtils.SINK_SECTION_ATTRIBUTES );
@@ -1429,6 +1457,12 @@
public void tableCaption_()
{
writeEndTag( HtmlMarkup.CAPTION );
+
+ if ( !this.tableCaptionXMLWriterStack.isEmpty() && this.tableCaptionXMLWriterStack.getLast() != null )
+ {
+ this.tableCaptionStack.addLast( this.tableCaptionWriterStack.removeLast().toString() );
+ this.tableCaptionXMLWriterStack.removeLast();
+ }
}
/**
@@ -1877,8 +1911,6 @@
/** {@inheritDoc} */
public void close()
{
- writer.write( tempWriter.toString() );
- tempWriter = new StringWriter();
writer.close();
if ( getLog().isWarnEnabled() && this.warnMessages != null )
@@ -1955,7 +1987,62 @@
/** {@inheritDoc} */
protected void write( String text )
{
- tempWriter.write( unifyEOLs( text ) );
+ if ( !this.tableCaptionXMLWriterStack.isEmpty() && this.tableCaptionXMLWriterStack.getLast() != null )
+ {
+ ( (PrettyPrintXMLWriter) this.tableCaptionXMLWriterStack.getLast() ).writeText( unifyEOLs( text ) );
+ }
+ else if ( !this.tableContentWriterStack.isEmpty() && this.tableContentWriterStack.getLast() != null )
+ {
+ ( (StringWriter) this.tableContentWriterStack.getLast() ).write( unifyEOLs( text ) );
+ }
+ else
+ {
+ writer.write( unifyEOLs( text ) );
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void writeStartTag( Tag t, MutableAttributeSet att, boolean isSimpleTag )
+ {
+ if ( this.tableCaptionXMLWriterStack.isEmpty() )
+ {
+ super.writeStartTag ( t, att, isSimpleTag );
+ }
+ else
+ {
+ String tag = ( getNameSpace() != null ? getNameSpace() + ":" : "" ) + t.toString();
+ ( (PrettyPrintXMLWriter) this.tableCaptionXMLWriterStack.getLast() ).startElement( tag );
+
+ if ( att != null )
+ {
+ Enumeration names = att.getAttributeNames();
+ while ( names.hasMoreElements() )
+ {
+ Object key = names.nextElement();
+ Object value = att.getAttribute( key );
+
+ ( (PrettyPrintXMLWriter) this.tableCaptionXMLWriterStack.getLast() ).addAttribute( key.toString(), value.toString() );
+ }
+ }
+
+ if ( isSimpleTag )
+ {
+ ( (PrettyPrintXMLWriter) this.tableCaptionXMLWriterStack.getLast() ).endElement();
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void writeEndTag( Tag t )
+ {
+ if ( this.tableCaptionXMLWriterStack.isEmpty() )
+ {
+ super.writeEndTag( t );
+ }
+ else
+ {
+ ( (PrettyPrintXMLWriter) this.tableCaptionXMLWriterStack.getLast() ).endElement();
+ }
}
/**
Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java?rev=806515&r1=806514&r2=806515&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/XhtmlBaseSinkTest.java Fri Aug 21 11:58:39 2009
@@ -82,28 +82,70 @@
assertEquals( expected, actual );
}
- /** @throws Exception */
+ /**
+ * @throws Exception if any
+ */
public void testNestedTables()
throws Exception
{
// DOXIA-177
-
try
{
sink = new XhtmlBaseSink( writer );
sink.table();
- sink.tableRows( new int[] {0}, false );
- sink.tableCaption();
- sink.text( "caption1" );
- sink.tableCaption_();
+ sink.tableRows( new int[] { Sink.JUSTIFY_CENTER }, false );
sink.tableRow();
sink.tableCell();
- sink.table();
- sink.tableRows( new int[] {0}, false );
+ sink.text( "cell11" );
+ sink.tableCell_();
+ sink.tableCell();
+ sink.text( "cell12" );
+ sink.tableCell_();
+ sink.tableRow_();
+
sink.tableRow();
sink.tableCell();
- sink.text( "nestedTableCell" );
+ sink.table( SinkEventAttributeSet.LEFT );
+ sink.tableRows( new int[] { Sink.JUSTIFY_LEFT }, false );
+ sink.tableRow();
+ sink.tableCell();
+ sink.text( "nestedTable1Cell11" );
+ sink.tableCell_();
+ sink.tableCell();
+ sink.text( "nestedTable1Cell12" );
+ sink.tableCell_();
+ sink.tableRow_();
+ sink.tableRow();
+ sink.tableCell();
+
+ sink.table( SinkEventAttributeSet.RIGHT );
+ sink.tableRows( new int[] { Sink.JUSTIFY_RIGHT }, false );
+ sink.tableRow();
+ sink.tableCell();
+ sink.text( "nestedTable2Cell11" );
+ sink.tableCell_();
+ sink.tableCell();
+ sink.text( "nestedTable2Cell12" );
+ sink.tableCell_();
+ sink.tableRow_();
+ sink.tableRow();
+ sink.tableCell();
+ sink.text( "nestedTable2Cell21" );
+ sink.tableCell_();
+ sink.tableCell();
+ sink.text( "nestedTable2Cell22" );
+ sink.tableCell_();
+ sink.tableRow_();
+ sink.tableRows_();
+ sink.tableCaption();
+ sink.text( "caption3" );
+ sink.tableCaption_();
+ sink.table_();
+
+ sink.tableCell_();
+ sink.tableCell();
+ sink.text( "nestedTable1Cell22" );
sink.tableCell_();
sink.tableRow_();
sink.tableRows_();
@@ -111,9 +153,16 @@
sink.text( "caption2" );
sink.tableCaption_();
sink.table_();
+
+ sink.tableCell_();
+ sink.tableCell();
+ sink.text( "cell22" );
sink.tableCell_();
sink.tableRow_();
sink.tableRows_();
+ sink.tableCaption();
+ sink.text( "caption1" );
+ sink.tableCaption_();
sink.table_();
}
finally
@@ -122,9 +171,18 @@
}
String actual = writer.toString();
- assertTrue( actual.indexOf( "nestedTableCell" ) != 1 );
- assertTrue( actual.indexOf( "class=\"bodyTable\"><caption>caption1</caption><tr" ) != 1 );
- assertTrue( actual.indexOf( "class=\"bodyTable\"><caption>caption2</caption><tr" ) != 1 );
+ assertTrue( actual.indexOf( "<table align=\"center\" border=\"0\" class=\"bodyTable\">"
+ + "<caption>caption1</caption>" ) != 1 );
+ assertTrue( actual.indexOf( "<table border=\"0\" class=\"bodyTable\" align=\"left\">"
+ + "<caption>caption2</caption>" ) != 1 );
+ assertTrue( actual.indexOf( "<table align=\"center\" border=\"0\" class=\"bodyTable\">"
+ + "<caption>caption3</caption>" ) != 1 );
+
+ assertTrue( actual.indexOf( "<td align=\"center\">cell11</td>" ) != 1 );
+ assertTrue( actual.indexOf( "<td align=\"left\">nestedTable1Cell11</td>" ) != 1 );
+ assertTrue( actual.indexOf( "<td align=\"right\">nestedTable2Cell11</td>" ) != 1 );
+ assertTrue( actual.indexOf( "<td align=\"left\">nestedTable1Cell22</td>" ) != 1 );
+ assertTrue( actual.indexOf( "<td align=\"center\">cell22</td>" ) != 1 );
}
/**
@@ -643,15 +701,21 @@
{
sink = new XhtmlBaseSink( writer );
+ sink.table();
+ sink.tableRows( null, false );
sink.tableCaption( attributes );
+ sink.text( "caption" );
sink.tableCaption_();
+ sink.tableRows_();
+ sink.table_();
}
finally
{
sink.close();
}
- assertEquals( "<caption style=\"bold\"></caption>", writer.toString() );
+ assertEquals( "<table align=\"center\" border=\"0\" class=\"bodyTable\">" +
+ "<caption style=\"bold\">caption</caption></table>", writer.toString() );
}
/**