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 lt...@apache.org on 2008/03/07 14:27:16 UTC

svn commit: r634662 [1/2] - in /maven/doxia/doxia/trunk: doxia-core/src/main/java/org/apache/maven/doxia/parser/ doxia-core/src/main/java/org/apache/maven/doxia/sink/ doxia-core/src/main/java/org/apache/maven/doxia/util/ doxia-core/src/test/java/org/ap...

Author: ltheussl
Date: Fri Mar  7 05:27:15 2008
New Revision: 634662

URL: http://svn.apache.org/viewvc?rev=634662&view=rev
Log:
[DOXIA-204] Add generic parameter support to Sink events

Added:
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java   (with props)
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java   (with props)
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/WellformednessCheckingSink.java
      - copied, changed from r632557, maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/WellformednessCheckingSink.java
    maven/doxia/doxia/trunk/doxia-sink-api/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributes.java   (with props)
Removed:
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/WellformednessCheckingSink.java
Modified:
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/AbstractXmlSink.java
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkAdapter.java
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java
    maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/util/HtmlTools.java
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventTestingSink.java
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkTestDocument.java
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/TextSink.java
    maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/util/StructureSinkUtilsTest.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-fo/src/main/java/org/apache/maven/doxia/module/fo/FoConfiguration.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocParser.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocSink.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocSinkTest.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlParser.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlSink.java
    maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/test/java/org/apache/maven/doxia/module/xhtml/XhtmlParserTest.java
    maven/doxia/doxia/trunk/doxia-sink-api/src/main/java/org/apache/maven/doxia/sink/Sink.java

Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/AbstractXmlParser.java Fri Mar  7 05:27:15 2008
@@ -25,6 +25,8 @@
 import org.apache.maven.doxia.macro.MacroExecutionException;
 import org.apache.maven.doxia.markup.XmlMarkup;
 import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.doxia.sink.SinkEventAttributeSet;
+
 import org.codehaus.plexus.util.xml.pull.MXParser;
 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
@@ -83,6 +85,32 @@
     {
         return XML_TYPE;
     }
+
+    /**
+     * Converts the attributes of the current start tag of the given parser to a SinkEventAttributeSet.
+     *
+     * @param parser A parser.
+     * @param return a SinkEventAttributeSet or null if the current parser event is not a start tag.
+     */
+    protected SinkEventAttributeSet getAttributesFromParser( XmlPullParser parser )
+    {
+        int count = parser.getAttributeCount();
+
+        if ( count < 0 )
+        {
+            return null;
+        }
+
+        SinkEventAttributeSet atts = new SinkEventAttributeSet( count );
+
+        for ( int i = 0; i < count; i++ )
+        {
+            atts.addAttribute( parser.getAttributeName( i ), parser.getAttributeValue( i ) );
+        }
+
+        return atts;
+    }
+
 
     /**
      * Parse the model from the XmlPullParser into the given sink.

Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java Fri Mar  7 05:27:15 2008
@@ -23,8 +23,8 @@
 import javax.swing.text.html.HTML.Tag;
 
 import org.apache.maven.doxia.macro.MacroExecutionException;
-import org.apache.maven.doxia.parser.AbstractXmlParser;
 import org.apache.maven.doxia.sink.Sink;
+import org.apache.maven.doxia.sink.SinkEventAttributeSet;
 
 import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
@@ -84,49 +84,51 @@
     {
         boolean visited = true;
 
+        SinkEventAttributeSet attribs = getAttributesFromParser( parser );
+
         if ( parser.getName().equals( Tag.H2.toString() ) )
         {
             closeOpenSections( Sink.SECTION_LEVEL_1, sink );
 
-            sink.section1();
+            sink.section( Sink.SECTION_LEVEL_1, attribs );
 
-            sink.sectionTitle1();
+            sink.sectionTitle( Sink.SECTION_LEVEL_1, attribs );
         }
         else if ( parser.getName().equals( Tag.H3.toString() ) )
         {
             closeOpenSections( Sink.SECTION_LEVEL_2, sink );
 
-            sink.section2();
+            sink.section( Sink.SECTION_LEVEL_2, attribs );
 
-            sink.sectionTitle2();
+            sink.sectionTitle( Sink.SECTION_LEVEL_2, attribs );
         }
         else if ( parser.getName().equals( Tag.H4.toString() ) )
         {
             closeOpenSections( Sink.SECTION_LEVEL_3, sink );
 
-            sink.section3();
+            sink.section( Sink.SECTION_LEVEL_3, attribs );
 
-            sink.sectionTitle3();
+            sink.sectionTitle( Sink.SECTION_LEVEL_3, attribs );
         }
         else if ( parser.getName().equals( Tag.H5.toString() ) )
         {
             closeOpenSections( Sink.SECTION_LEVEL_4, sink );
 
-            sink.section4();
+            sink.section( Sink.SECTION_LEVEL_4, attribs );
 
-            sink.sectionTitle4();
+            sink.sectionTitle( Sink.SECTION_LEVEL_4, attribs );
         }
         else if ( parser.getName().equals( Tag.H6.toString() ) )
         {
             closeOpenSections( Sink.SECTION_LEVEL_5, sink );
 
-            sink.section5();
+            sink.section( Sink.SECTION_LEVEL_5, attribs );
 
-            sink.sectionTitle5();
+            sink.sectionTitle( Sink.SECTION_LEVEL_5, attribs );
         }
         else if ( parser.getName().equals( Tag.P.toString() ) )
         {
-            sink.paragraph();
+            sink.paragraph( attribs );
         }
         /*
          * The PRE element tells visual user agents that the enclosed text is
@@ -142,11 +144,13 @@
         {
             verbatim();
 
-            sink.verbatim( false );
+            attribs.addAttribute( "boxed", "false");
+
+            sink.verbatim( attribs );
         }
         else if ( parser.getName().equals( Tag.UL.toString() ) )
         {
-            sink.list();
+            sink.list( attribs );
         }
         else if ( parser.getName().equals( Tag.OL.toString() ) )
         {
@@ -179,48 +183,48 @@
                 }
             }
 
-            sink.numberedList( numbering );
+            sink.numberedList( numbering, attribs );
             orderedListDepth++;
         }
         else if ( parser.getName().equals( Tag.LI.toString() ) )
         {
             if ( orderedListDepth == 0 )
             {
-                sink.listItem();
+                sink.listItem( attribs );
             }
             else
             {
-                sink.numberedListItem();
+                sink.numberedListItem( attribs );
             }
         }
         else if ( parser.getName().equals( Tag.DL.toString() ) )
         {
-            sink.definitionList();
+            sink.definitionList( attribs );
         }
         else if ( parser.getName().equals( Tag.DT.toString() ) )
         {
-            sink.definitionListItem();
-            sink.definedTerm();
+            sink.definitionListItem( attribs );
+            sink.definedTerm( attribs );
         }
         else if ( parser.getName().equals( Tag.DD.toString() ) )
         {
-            sink.definition();
+            sink.definition( attribs );
         }
         else if ( ( parser.getName().equals( Tag.B.toString() ) )
                 || ( parser.getName().equals( Tag.STRONG.toString() ) ) )
         {
-            sink.bold();
+            sink.bold( attribs );
         }
         else if ( ( parser.getName().equals( Tag.I.toString() ) )
                 || ( parser.getName().equals( Tag.EM.toString() ) ) )
         {
-            sink.italic();
+            sink.italic( attribs );
         }
         else if ( ( parser.getName().equals( Tag.CODE.toString() ) )
                 || ( parser.getName().equals( Tag.SAMP.toString() ) )
                 || ( parser.getName().equals( Tag.TT.toString() ) ) )
         {
-            sink.monospaced();
+            sink.monospaced( attribs );
         }
         else if ( parser.getName().equals( Tag.A.toString() ) )
         {
@@ -235,7 +239,7 @@
                     link = link.substring( 1 );
                 }
 
-                sink.link( link );
+                sink.link( link, attribs  );
 
                 isLink = true;
             }
@@ -245,7 +249,7 @@
 
                 if ( name != null )
                 {
-                    sink.anchor( name );
+                    sink.anchor( name, attribs  );
 
                     isAnchor = true;
                 }
@@ -255,7 +259,7 @@
 
                     if ( id != null )
                     {
-                        sink.anchor( id );
+                        sink.anchor( id, attribs  );
 
                         isAnchor = true;
                     }
@@ -269,7 +273,7 @@
 
         else if ( parser.getName().equals( Tag.TABLE.toString() ) )
         {
-            sink.table();
+            sink.table( attribs );
 
             String border = parser.getAttributeValue( null, Attribute.BORDER.toString() );
 
@@ -297,39 +301,21 @@
         }
         else if ( parser.getName().equals( Tag.TR.toString() ) )
         {
-            sink.tableRow();
+            sink.tableRow( attribs );
         }
         else if ( parser.getName().equals( Tag.TH.toString() ) )
         {
-            String width = parser.getAttributeValue( null, Attribute.WIDTH.toString() );
-
-            if ( width ==  null )
-            {
-                sink.tableHeaderCell();
-            }
-            else
-            {
-                sink.tableHeaderCell( width );
-            }
+            sink.tableHeaderCell( attribs );
         }
         else if ( parser.getName().equals( Tag.TD.toString() ) )
         {
-            String width = parser.getAttributeValue( null, Attribute.WIDTH.toString() );
-
-            if ( width ==  null )
-            {
-                sink.tableCell();
-            }
-            else
-            {
-                sink.tableCell( width );
-            }
+            sink.tableCell( attribs );
         }
         else if ( parser.getName().equals( Tag.CAPTION.toString() ) )
         {
             sink.tableRows_();
             this.hasCaption = true;
-            sink.tableCaption();
+            sink.tableCaption( attribs );
         }
 
         // ----------------------------------------------------------------------
@@ -338,11 +324,11 @@
 
         else if ( parser.getName().equals( Tag.BR.toString() ) )
         {
-            sink.lineBreak();
+            sink.lineBreak( attribs );
         }
         else if ( parser.getName().equals( Tag.HR.toString() ) )
         {
-            sink.horizontalRule();
+            sink.horizontalRule( attribs );
         }
         else if ( parser.getName().equals( Tag.IMG.toString() ) )
         {
@@ -354,9 +340,10 @@
 
             if ( src != null )
             {
-                sink.figureGraphics( src );
+                sink.figureGraphics( src, attribs );
             }
 
+            // TODO: remove, see DOXIA-75
             if ( title != null )
             {
                 sink.figureCaption();
@@ -576,10 +563,10 @@
         /*
          * NOTE: Don't do any whitespace trimming here. Whitespace normalization has already been performed by the
          * parser so any whitespace that makes it here is significant.
-         */ 
+         */
         if ( StringUtils.isNotEmpty( text ) )
         {
-            // Emit separate text events for different lines, e.g. the input 
+            // Emit separate text events for different lines, e.g. the input
             // "\nLine1\n\nLine2\n\n" should deliver the event sequence "\n", "Line1\n", "\n", "Line2\n", "\n".
             // In other words, the concatenation of the text events must deliver the input sequence.
             // (according to section 2.11 of the XML spec, parsers must normalize line breaks to "\n")

Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/AbstractXmlSink.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/AbstractXmlSink.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/AbstractXmlSink.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/AbstractXmlSink.java Fri Mar  7 05:27:15 2008
@@ -19,9 +19,6 @@
  * under the License.
  */
 
-import java.util.Enumeration;
-
-import javax.swing.text.AttributeSet;
 import javax.swing.text.MutableAttributeSet;
 import javax.swing.text.html.HTML.Tag;
 
@@ -62,37 +59,6 @@
     }
 
     /**
-     * Utility method to get an AttributeSet as a String.
-     *
-     * @param att The AttributeSet.
-     * @return String
-     */
-    public static String getAttributeString( MutableAttributeSet att )
-    {
-        StringBuffer sb = new StringBuffer();
-
-        if ( att != null )
-        {
-            Enumeration names = att.getAttributeNames();
-
-            while ( names.hasMoreElements() )
-            {
-                Object key = names.nextElement();
-                Object value = att.getAttribute( key );
-
-                // AttributeSets are ignored
-                if ( !(value instanceof AttributeSet) )
-                {
-                    sb.append( SPACE ).append( key.toString() ).append( EQUAL )
-                        .append( QUOTE ).append( value.toString() ).append( QUOTE );
-                }
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
      * Starts a Tag. For instance:
      * <pre>
      * &lt;tag&gt;
@@ -148,7 +114,7 @@
 
         sb.append( t.toString() );
 
-        sb.append( getAttributeString( att ) );
+        sb.append( SinkUtils.getAttributeString( att ) );
 
         if ( isSimpleTag )
         {
@@ -220,7 +186,7 @@
     }
 
     /**
-     * TODO DOXIA-59 Need to uniform writing
+     * Write a text to the sink.
      *
      * @param text the given text to write
      */

Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkAdapter.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkAdapter.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkAdapter.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkAdapter.java Fri Mar  7 05:27:15 2008
@@ -569,4 +569,297 @@
     {
         // nop
     }
+    /** {@inheritDoc} */
+    public void head( SinkEventAttributes attributes )
+    {
+        head();
+    }
+
+    /** {@inheritDoc} */
+    public void title( SinkEventAttributes attributes )
+    {
+        title();
+    }
+
+    /** {@inheritDoc} */
+    public void author( SinkEventAttributes attributes )
+    {
+        author();
+    }
+
+    /** {@inheritDoc} */
+    public void date( SinkEventAttributes attributes )
+    {
+        date();
+    }
+
+    /** {@inheritDoc} */
+    public void body( SinkEventAttributes attributes )
+    {
+        body();
+    }
+
+    /** {@inheritDoc} */
+    public void section( int level, SinkEventAttributes attributes )
+    {
+        if ( level == SECTION_LEVEL_1 )
+        {
+            section1();
+        }
+        else if ( level == SECTION_LEVEL_2 )
+        {
+            section2();
+        }
+        else if ( level == SECTION_LEVEL_3 )
+        {
+            section3();
+        }
+        else if ( level == SECTION_LEVEL_4 )
+        {
+            section4();
+        }
+        else if ( level == SECTION_LEVEL_5 )
+        {
+            section5();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void section_( int level )
+    {
+        if ( level == SECTION_LEVEL_1 )
+        {
+            section1_();
+        }
+        else if ( level == SECTION_LEVEL_2 )
+        {
+            section2_();
+        }
+        else if ( level == SECTION_LEVEL_3 )
+        {
+            section3_();
+        }
+        else if ( level == SECTION_LEVEL_4 )
+        {
+            section4_();
+        }
+        else if ( level == SECTION_LEVEL_5 )
+        {
+            section5_();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle( int level, SinkEventAttributes attributes )
+    {
+        if ( level == SECTION_LEVEL_1 )
+        {
+            sectionTitle1();
+        }
+        else if ( level == SECTION_LEVEL_2 )
+        {
+            sectionTitle2();
+        }
+        else if ( level == SECTION_LEVEL_3 )
+        {
+            sectionTitle3();
+        }
+        else if ( level == SECTION_LEVEL_4 )
+        {
+            sectionTitle4();
+        }
+        else if ( level == SECTION_LEVEL_5 )
+        {
+            sectionTitle5();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle_( int level )
+    {
+        if ( level == SECTION_LEVEL_1 )
+        {
+            sectionTitle1_();
+        }
+        else if ( level == SECTION_LEVEL_2 )
+        {
+            sectionTitle2_();
+        }
+        else if ( level == SECTION_LEVEL_3 )
+        {
+            sectionTitle3_();
+        }
+        else if ( level == SECTION_LEVEL_4 )
+        {
+            sectionTitle4_();
+        }
+        else if ( level == SECTION_LEVEL_5 )
+        {
+            sectionTitle5_();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void list( SinkEventAttributes attributes )
+    {
+        list();
+    }
+
+    /** {@inheritDoc} */
+    public void listItem( SinkEventAttributes attributes )
+    {
+        listItem();
+    }
+
+    /** {@inheritDoc} */
+    public void numberedList( int numbering, SinkEventAttributes attributes )
+    {
+        numberedList( numbering );
+    }
+
+    /** {@inheritDoc} */
+    public void numberedListItem( SinkEventAttributes attributes )
+    {
+        numberedListItem();
+    }
+
+    /** {@inheritDoc} */
+    public void definitionList( SinkEventAttributes attributes )
+    {
+        definitionList();
+    }
+
+    /** {@inheritDoc} */
+    public void definitionListItem( SinkEventAttributes attributes )
+    {
+        definitionListItem();
+    }
+
+    /** {@inheritDoc} */
+    public void definition( SinkEventAttributes attributes )
+    {
+        definition();
+    }
+
+    /** {@inheritDoc} */
+    public void definedTerm( SinkEventAttributes attributes )
+    {
+        definedTerm();
+    }
+
+    /** {@inheritDoc} */
+    public void figure( SinkEventAttributes attributes )
+    {
+        figure();
+    }
+
+    /** {@inheritDoc} */
+    public void figureCaption( SinkEventAttributes attributes )
+    {
+        figureCaption();
+    }
+
+    /** {@inheritDoc} */
+    public void figureGraphics( String src, SinkEventAttributes attributes )
+    {
+        figureGraphics( src );
+    }
+
+    /** {@inheritDoc} */
+    public void table( SinkEventAttributes attributes )
+    {
+        table();
+    }
+
+    /** {@inheritDoc} */
+    public void tableRow( SinkEventAttributes attributes )
+    {
+        tableRow();
+    }
+
+    /** {@inheritDoc} */
+    public void tableCell( SinkEventAttributes attributes )
+    {
+        tableCell();
+    }
+
+    /** {@inheritDoc} */
+    public void tableHeaderCell( SinkEventAttributes attributes )
+    {
+        tableHeaderCell();
+    }
+
+    /** {@inheritDoc} */
+    public void tableCaption( SinkEventAttributes attributes )
+    {
+        tableCaption();
+    }
+
+    /** {@inheritDoc} */
+    public void paragraph( SinkEventAttributes attributes )
+    {
+        paragraph();
+    }
+
+    /** {@inheritDoc} */
+    public void verbatim( SinkEventAttributes attributes )
+    {
+        boolean boxed = false;
+
+        if ( attributes != null && attributes.isDefined( "boxed" ) )
+        {
+            boxed = Boolean.valueOf(
+                (String) attributes.getAttribute( "boxed" ) ).booleanValue();
+        }
+
+        verbatim( boxed );
+    }
+
+    /** {@inheritDoc} */
+    public void horizontalRule( SinkEventAttributes attributes )
+    {
+        horizontalRule();
+    }
+
+    /** {@inheritDoc} */
+    public void anchor( String name, SinkEventAttributes attributes )
+    {
+        anchor( name );
+    }
+
+    /** {@inheritDoc} */
+    public void link( String name, SinkEventAttributes attributes )
+    {
+        link( name );
+    }
+
+    /** {@inheritDoc} */
+    public void italic( SinkEventAttributes attributes )
+    {
+        italic();
+    }
+
+    /** {@inheritDoc} */
+    public void bold( SinkEventAttributes attributes )
+    {
+        bold();
+    }
+
+    /** {@inheritDoc} */
+    public void monospaced( SinkEventAttributes attributes )
+    {
+        monospaced();
+    }
+
+    /** {@inheritDoc} */
+    public void lineBreak( SinkEventAttributes attributes )
+    {
+        lineBreak();
+    }
+
+    /** {@inheritDoc} */
+    public void text( String text, SinkEventAttributes attributes )
+    {
+        text( text );
+    }
 }

Added: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java?rev=634662&view=auto
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java (added)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java Fri Mar  7 05:27:15 2008
@@ -0,0 +1,326 @@
+package org.apache.maven.doxia.sink;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+
+import javax.swing.text.AttributeSet;
+
+/**
+ * Implementation of MutableAttributeSet using a LinkedHashMap.
+ *
+ * @author ltheussl
+ * @version $Id$
+ * @since 1.0-beta-1
+ */
+public class SinkEventAttributeSet
+    implements SinkEventAttributes
+{
+    private LinkedHashMap attribs;
+
+    private AttributeSet resolveParent;
+
+    /**
+     * Constructs a new, empty SinkEventAttributeSet with default size 5.
+     */
+    public SinkEventAttributeSet()
+    {
+        this( 5 );
+    }
+
+    /**
+     * Constructs a new, empty SinkEventAttributeSet with the specified initial size.
+     *
+     * @param size the initial number of attribs.
+     */
+    public SinkEventAttributeSet( int size )
+    {
+        attribs = new LinkedHashMap( size );
+    }
+
+    /**
+     * Constructs a new SinkEventAttributeSet with the attribute name-value
+     * mappings as given by the specified String array.
+     *
+     * @param attributes the specified String array. If the length of this array
+     * is not an even number, an IllegalArgumentException is thrown.
+     */
+    public SinkEventAttributeSet( String[] attributes )
+    {
+        int n = attributes.length;
+        
+        if ( ( n % 2 ) != 0 )
+        {
+            throw new IllegalArgumentException( "Missing attribute!" );
+        }
+        
+        attribs = new LinkedHashMap( n / 2 );
+        
+        for ( int i = 0; i < n; i = i + 2 )
+        {
+            attribs.put( attributes[i], attributes[i + 1] );
+        }
+    }
+
+    /**
+     * Constructs a new SinkEventAttributeSet with the same attribute name-value
+     * mappings as in the specified AttributeSet.
+     *
+     * @param attributes the specified AttributeSet.
+     */
+    public SinkEventAttributeSet( AttributeSet attributes )
+    {
+        attribs = new LinkedHashMap( attributes.getAttributeCount() );
+
+        Enumeration names = attributes.getAttributeNames();
+
+        while ( names.hasMoreElements() )
+        {
+            Object name = names.nextElement();
+
+            attribs.put( name, attributes.getAttribute( name ) );
+        }
+    }
+
+    /**
+     * Checks whether the set of attribs is empty.
+     *
+     * @return true if the set is empty.
+     */
+    public boolean isEmpty()
+    {
+        return attribs.isEmpty();
+    }
+
+    /** {@inheritDoc} */
+    public int getAttributeCount()
+    {
+        return attribs.size();
+    }
+
+    /** {@inheritDoc} */
+    public boolean isDefined( Object attrName )
+    {
+        return attribs.containsKey( attrName );
+    }
+
+    /** {@inheritDoc} */
+    public boolean isEqual( AttributeSet attr )
+    {
+        return ( ( getAttributeCount() == attr.getAttributeCount() )
+                && containsAttributes( attr ) );
+    }
+
+    /** {@inheritDoc} */
+    public AttributeSet copyAttributes()
+    {
+        return ( (AttributeSet) clone() );
+    }
+
+    /** {@inheritDoc} */
+    public Enumeration getAttributeNames()
+    {
+        return Collections.enumeration( attribs.keySet() );
+    }
+
+    /** {@inheritDoc} */
+    public Object getAttribute( Object key  )
+    {
+        Object value = attribs.get( key  );
+
+        if ( value == null )
+        {
+            AttributeSet parent = getResolveParent();
+
+            if ( parent != null )
+            {
+                value = parent.getAttribute( key  );
+            }
+        }
+
+        return value;
+    }
+
+    /** {@inheritDoc} */
+    public boolean containsAttribute( Object name, Object value )
+    {
+        return value.equals( getAttribute( name ) );
+    }
+
+    /** {@inheritDoc} */
+    public boolean containsAttributes( AttributeSet attributes )
+    {
+        boolean result = true;
+
+        Enumeration names = attributes.getAttributeNames();
+
+        while ( result && names.hasMoreElements() )
+        {
+            Object name = names.nextElement();
+            result = attributes.getAttribute( name ).equals( getAttribute( name ) );
+        }
+
+        return result;
+    }
+
+    /**
+     * Adds an attribute with the given name and value.
+     *
+     * @param name the name.
+     * @param value the value.
+     */
+    public void addAttribute( Object name, Object value )
+    {
+        attribs.put( name.toString(), value.toString() );
+    }
+
+    /** {@inheritDoc} */
+    public void addAttributes( AttributeSet attributes  )
+    {
+        if ( attributes == null || attributes.getAttributeCount() == 0 )
+        {
+            return;
+        }
+
+        Enumeration names = attributes.getAttributeNames();
+
+        while ( names.hasMoreElements() )
+        {
+            Object name = names.nextElement();
+
+            addAttribute( name, attributes.getAttribute( name ) );
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void removeAttribute( Object name )
+    {
+        attribs.remove( name );
+    }
+
+    /** {@inheritDoc} */
+    public void removeAttributes( Enumeration names )
+    {
+        while ( names.hasMoreElements() )
+        {
+            removeAttribute( names.nextElement() );
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void removeAttributes( AttributeSet attributes  )
+    {
+        if ( attributes == null )
+        {
+            return;
+        }
+        else if ( attributes == this )
+        {
+            attribs.clear();
+        }
+        else
+        {
+            Enumeration names = attributes.getAttributeNames();
+
+            while ( names.hasMoreElements() )
+            {
+                Object name = names.nextElement();
+                Object value = attributes.getAttribute( name );
+
+                if ( value.equals( getAttribute( name ) ) )
+                {
+                    removeAttribute( name );
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    public AttributeSet getResolveParent()
+    {
+        return this.resolveParent;
+    }
+
+    /** {@inheritDoc} */
+    public void setResolveParent( AttributeSet parent )
+    {
+        this.resolveParent = parent;
+    }
+
+    /** {@inheritDoc} */
+    public Object clone()
+    {
+        SinkEventAttributeSet attr;
+
+        try
+        {
+            attr = (SinkEventAttributeSet) super.clone();
+            attr.attribs = (LinkedHashMap) attribs.clone();
+            attr.resolveParent = resolveParent.copyAttributes();
+        }
+        catch ( CloneNotSupportedException e )
+        {
+            attr = null;
+        }
+
+        return attr;
+    }
+
+    /** {@inheritDoc} */
+    public int hashCode()
+    {
+        return attribs.hashCode() + resolveParent.hashCode();
+    }
+
+    /** {@inheritDoc} */
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+
+        if ( obj instanceof SinkEventAttributeSet )
+        {
+            return isEqual( (SinkEventAttributeSet) obj  );
+        }
+
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public String toString() {
+        StringBuffer s = new StringBuffer();
+        Enumeration names = getAttributeNames();
+
+        while ( names.hasMoreElements() )
+        {
+            String key = names.nextElement().toString();
+            String value = getAttribute( key ).toString();
+
+            s.append( ' ' ).append( key ).append( '=' ).append( value );
+        }
+
+        return s.toString();
+    }
+
+}

Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkEventAttributeSet.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java?rev=634662&view=auto
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java (added)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java Fri Mar  7 05:27:15 2008
@@ -0,0 +1,241 @@
+package org.apache.maven.doxia.sink;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.util.Enumeration;
+import java.util.Arrays;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.MutableAttributeSet;
+
+import org.apache.maven.doxia.markup.Markup;
+
+/**
+ * Collection of common utility methods for sinks.
+ *
+ * @author ltheussl
+ * @version $Id$
+ * @since 1.0-beta-1
+ */
+public class SinkUtils
+{
+
+    /** Do not instantiate. */
+    private SinkUtils()
+    {
+    }
+
+    /**
+     * The set of base attributes.
+     */
+    public static final String[] SINK_BASE_ATTRIBUTES =
+    {
+        SinkEventAttributes.CLASS, SinkEventAttributes.ID, SinkEventAttributes.LANG,
+        SinkEventAttributes.STYLE, SinkEventAttributes.TITLE
+    };
+
+    /**
+     * The attributes that are supported for the br tag.
+     */
+    public static final String[] SINK_BR_ATTRIBUTES =
+    {
+        SinkEventAttributes.CLASS, SinkEventAttributes.ID,
+        SinkEventAttributes.STYLE, SinkEventAttributes.TITLE
+    };
+
+    /**
+     * The attributes that are supported for the &lt;img&gt; tag.
+     */
+    public static final String[] SINK_IMG_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the section tags, like &lt;p&gt;, &lt;h2&gt;, &lt;div&gt;.
+     */
+    public static final String[] SINK_SECTION_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the &lt;div&gt; and &lt;pre&gt; tags.
+     */
+    public static final String[] SINK_VERBATIM_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the &lt;hr&gt; tag.
+     */
+    public static final String[] SINK_HR_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the &lt;a&gt; tag.
+     */
+    public static final String[] SINK_LINK_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the &lt;table&gt; tag.
+     */
+    public static final String[] SINK_TABLE_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the &lt;td&gt; and &lt;th&gt; tags.
+     */
+    public static final String[] SINK_TD_ATTRIBUTES;
+
+    /**
+     * The attributes that are supported for the &lt;tr&gt; tag.
+     */
+    public static final String[] SINK_TR_ATTRIBUTES;
+
+    private static final String[] IMG_ATTRIBUTES =
+    {
+        SinkEventAttributes.ALIGN, SinkEventAttributes.ALT, SinkEventAttributes.BORDER,
+        SinkEventAttributes.HEIGHT, SinkEventAttributes.HSPACE, SinkEventAttributes.ISMAP,
+        SinkEventAttributes.SRC, SinkEventAttributes.USEMAP, SinkEventAttributes.VSPACE,
+        SinkEventAttributes.WIDTH
+    };
+
+    private static final String[] HR_ATTRIBUTES =
+    {
+        SinkEventAttributes.ALIGN, SinkEventAttributes.NOSHADE, SinkEventAttributes.SIZE,
+        SinkEventAttributes.WIDTH
+    };
+
+    private static final String[] LINK_ATTRIBUTES =
+    {
+        SinkEventAttributes.CHARSET, SinkEventAttributes.COORDS, SinkEventAttributes.HREF,
+        SinkEventAttributes.HREFLANG, SinkEventAttributes.REL, SinkEventAttributes.REV,
+        SinkEventAttributes.SHAPE, SinkEventAttributes.TARGET, SinkEventAttributes.TYPE
+    };
+
+    private static final String[] TABLE_ATTRIBUTES =
+    {
+        SinkEventAttributes.ALIGN, SinkEventAttributes.BGCOLOR, SinkEventAttributes.BORDER,
+        SinkEventAttributes.CELLPADDING, SinkEventAttributes.CELLSPACING, SinkEventAttributes.FRAME,
+        SinkEventAttributes.RULES, SinkEventAttributes.SUMMARY, SinkEventAttributes.WIDTH
+    };
+
+    private static final String[] TABLE_CELL_ATTRIBUTES =
+    {
+        SinkEventAttributes.ABBRV, SinkEventAttributes.ALIGN, SinkEventAttributes.AXIS,
+        SinkEventAttributes.BGCOLOR, SinkEventAttributes.COLSPAN, SinkEventAttributes.HEADERS,
+        SinkEventAttributes.HEIGHT, SinkEventAttributes.NOWRAP, SinkEventAttributes.ROWSPAN,
+        SinkEventAttributes.SCOPE, SinkEventAttributes.VALIGN, SinkEventAttributes.WIDTH
+    };
+
+    static
+    {
+        SINK_IMG_ATTRIBUTES = join( SINK_BASE_ATTRIBUTES, IMG_ATTRIBUTES  );
+        SINK_SECTION_ATTRIBUTES =
+                join( SINK_BASE_ATTRIBUTES, new String[] {SinkEventAttributes.ALIGN}  );
+        SINK_VERBATIM_ATTRIBUTES =
+                join( SINK_BASE_ATTRIBUTES,
+                new String[] {SinkEventAttributes.ALIGN, SinkEventAttributes.BOXED, SinkEventAttributes.WIDTH}  );
+        SINK_HR_ATTRIBUTES = join( SINK_BASE_ATTRIBUTES, HR_ATTRIBUTES  );
+        SINK_LINK_ATTRIBUTES = join( SINK_BASE_ATTRIBUTES, LINK_ATTRIBUTES  );
+        SINK_TABLE_ATTRIBUTES = join( SINK_BASE_ATTRIBUTES, TABLE_ATTRIBUTES  );
+        SINK_TR_ATTRIBUTES =
+                join( SINK_BASE_ATTRIBUTES,
+                new String[] {SinkEventAttributes.ALIGN, SinkEventAttributes.BGCOLOR, SinkEventAttributes.VALIGN}  );
+        SINK_TD_ATTRIBUTES = join( SINK_BASE_ATTRIBUTES, TABLE_CELL_ATTRIBUTES  );
+    }
+
+    private static String[] join( String[] a, String[] b )
+    {
+        String[] temp = new String[a.length + b.length];
+        System.arraycopy( a, 0, temp, 0, a.length );
+        System.arraycopy( b, 0, temp, a.length, b.length);
+
+        Arrays.sort( temp ); // necessary for binary searches in filterAttributes()
+
+        return temp;
+    }
+
+    /**
+     * Utility method to get an AttributeSet as a String.
+     * The resulting String is in the form ' name1="value1" name2="value2" ...',
+     * ie it can be appended directly to an xml start tag. Attribute values that are itself
+     * AttributeSets are ignored, all other keys and values are written as Strings.
+     *
+     * @param att The AttributeSet.
+     * @return the AttributeSet as a String in a form that can be appended to an xml start tag.
+     */
+    public static String getAttributeString( AttributeSet att )
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( att != null )
+        {
+            Enumeration names = att.getAttributeNames();
+
+            while ( names.hasMoreElements() )
+            {
+                Object key = names.nextElement();
+                Object value = att.getAttribute( key );
+
+                // AttributeSets are ignored
+                if ( !(value instanceof AttributeSet) )
+                {
+                    sb.append( Markup.SPACE ).append( key.toString() ).append( Markup.EQUAL )
+                        .append( Markup.QUOTE ).append( value.toString() ).append( Markup.QUOTE );
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Filters the given AttributeSet.
+     * Removes all attributes whose name (key) is not contained in the sorted array valids.
+     *
+     * @param attributes The AttributeSet to filter. The String values of Attribute names
+     * are compared to the elements of the valids array.
+     * @param valids a sorted array of attribute names that are to be kept in the resulting AttributeSet.
+     *      <b>Note:</b> a binary search is employed, so the array has to be sorted for correct results.
+     * @return A filtered MutableAttributeSet object. Returns null if the input AttributeSet is null.
+     *      If the array of valids is either null or empty, an empty AttributeSet is returned.
+     */
+    public static MutableAttributeSet filterAttributes( AttributeSet attributes, String[] valids )
+    {
+        if ( attributes == null )
+        {
+            return null;
+        }
+
+        if ( valids == null || valids.length == 0 )
+        {
+            return new SinkEventAttributeSet( 0 );
+        }
+
+        MutableAttributeSet atts = new SinkEventAttributeSet( attributes.getAttributeCount() );
+
+        Enumeration names = attributes.getAttributeNames();
+
+        while ( names.hasMoreElements() )
+        {
+            String key = names.nextElement().toString();
+
+            if ( Arrays.binarySearch( valids, key ) >= 0 )
+            {
+                atts.addAttribute( key, attributes.getAttribute( key ) );
+            }
+        }
+
+        return atts;
+    }
+}

Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/SinkUtils.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

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=634662&r1=634661&r2=634662&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 Mar  7 05:27:15 2008
@@ -23,12 +23,10 @@
 import java.io.Writer;
 
 import javax.swing.text.MutableAttributeSet;
-import javax.swing.text.SimpleAttributeSet;
 import javax.swing.text.html.HTML.Attribute;
 import javax.swing.text.html.HTML.Tag;
 
 import org.apache.maven.doxia.parser.Parser;
-import org.apache.maven.doxia.sink.AbstractXmlSink;
 import org.apache.maven.doxia.util.HtmlTools;
 import org.apache.maven.doxia.util.StructureSinkUtils;
 
@@ -71,6 +69,9 @@
     /** Used to style successive table rows differently. */
     private boolean evenTableRow = true;
 
+    /** used to store attributes passed to table(). */
+    private MutableAttributeSet tableAttributes;
+
     // ----------------------------------------------------------------------
     // Constructor
     // ----------------------------------------------------------------------
@@ -206,15 +207,37 @@
     // ----------------------------------------------------------------------
 
     /** {@inheritDoc} */
+    public void section( int level, SinkEventAttributes attributes )
+    {
+        onSection( level, attributes );
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle( int level, SinkEventAttributes attributes )
+    {
+        onSectionTitle( level, attributes );
+    }
+
+    public void sectionTitle_( int level )
+    {
+        onSectionTitle_( level );
+    }
+
+    public void section_( int level )
+    {
+        onSection_( level );
+    }
+
+    /** {@inheritDoc} */
     public void section1()
     {
-        onSection( SECTION_LEVEL_1 );
+        onSection( SECTION_LEVEL_1, null );
     }
 
     /** {@inheritDoc} */
     public void sectionTitle1()
     {
-        onSectionTitle( SECTION_LEVEL_1 );
+        onSectionTitle( SECTION_LEVEL_1, null );
     }
 
     /** {@inheritDoc} */
@@ -232,13 +255,13 @@
     /** {@inheritDoc} */
     public void section2()
     {
-        onSection( SECTION_LEVEL_2 );
+        onSection( SECTION_LEVEL_2, null );
     }
 
     /** {@inheritDoc} */
     public void sectionTitle2()
     {
-        onSectionTitle( SECTION_LEVEL_2 );
+        onSectionTitle( SECTION_LEVEL_2, null );
     }
 
     /** {@inheritDoc} */
@@ -256,13 +279,13 @@
     /** {@inheritDoc} */
     public void section3()
     {
-        onSection( SECTION_LEVEL_3 );
+        onSection( SECTION_LEVEL_3, null );
     }
 
     /** {@inheritDoc} */
     public void sectionTitle3()
     {
-        onSectionTitle( SECTION_LEVEL_3 );
+        onSectionTitle( SECTION_LEVEL_3, null );
     }
 
     /** {@inheritDoc} */
@@ -280,13 +303,13 @@
     /** {@inheritDoc} */
     public void section4()
     {
-        onSection( SECTION_LEVEL_4 );
+        onSection( SECTION_LEVEL_4, null );
     }
 
     /** {@inheritDoc} */
     public void sectionTitle4()
     {
-        onSectionTitle( SECTION_LEVEL_4 );
+        onSectionTitle( SECTION_LEVEL_4, null );
     }
 
     /** {@inheritDoc} */
@@ -304,13 +327,13 @@
     /** {@inheritDoc} */
     public void section5()
     {
-        onSection( SECTION_LEVEL_5 );
+        onSection( SECTION_LEVEL_5, null );
     }
 
     /** {@inheritDoc} */
     public void sectionTitle5()
     {
-        onSectionTitle( SECTION_LEVEL_5 );
+        onSectionTitle( SECTION_LEVEL_5, null );
     }
 
     /** {@inheritDoc} */
@@ -329,14 +352,18 @@
      * Starts a section. The default class style is <code>section</code>.
      *
      * @param depth The level of the section.
+     * @param attributes some attributes.
      * @see javax.swing.text.html.HTML.Tag#DIV
      */
-    protected void onSection( int depth )
+    protected void onSection( int depth, SinkEventAttributes attributes )
     {
         if ( depth >= SECTION_LEVEL_1 && depth <= SECTION_LEVEL_5 )
         {
-            MutableAttributeSet att = new SimpleAttributeSet();
+            MutableAttributeSet att = new SinkEventAttributeSet();
             att.addAttribute( Attribute.CLASS, "section" );
+            // NOTE: any class entry in attributes will overwrite the above
+            att.addAttributes( SinkUtils.filterAttributes(
+                    attributes, SinkUtils.SINK_BASE_ATTRIBUTES  ) );
 
             writeStartTag( Tag.DIV, att );
         }
@@ -360,33 +387,37 @@
      * Starts a section title.
      *
      * @param depth The level of the section title.
+     * @param attributes some attributes.
      * @see javax.swing.text.html.HTML.Tag#H2
      * @see javax.swing.text.html.HTML.Tag#H3
      * @see javax.swing.text.html.HTML.Tag#H4
      * @see javax.swing.text.html.HTML.Tag#H5
      * @see javax.swing.text.html.HTML.Tag#H6
      */
-    protected void onSectionTitle( int depth )
+    protected void onSectionTitle( int depth, SinkEventAttributes attributes )
     {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_SECTION_ATTRIBUTES  );
+
         if ( depth == SECTION_LEVEL_1 )
         {
-            writeStartTag( Tag.H2 );
+            writeStartTag( Tag.H2, atts );
         }
         else if ( depth == SECTION_LEVEL_2 )
         {
-            writeStartTag( Tag.H3 );
+            writeStartTag( Tag.H3, atts );
         }
         else if ( depth == SECTION_LEVEL_3 )
         {
-            writeStartTag( Tag.H4 );
+            writeStartTag( Tag.H4, atts );
         }
         else if ( depth == SECTION_LEVEL_4 )
         {
-            writeStartTag( Tag.H5 );
+            writeStartTag( Tag.H5, atts );
         }
         else if ( depth == SECTION_LEVEL_5 )
         {
-            writeStartTag( Tag.H6 );
+            writeStartTag( Tag.H6, atts );
         }
     }
 
@@ -441,6 +472,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#UL
      */
+    public void list( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        writeStartTag( Tag.UL, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#UL
+     */
     public void list_()
     {
         writeEndTag( Tag.UL );
@@ -459,6 +502,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#LI
      */
+    public void listItem( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        writeStartTag( Tag.LI, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#LI
+     */
     public void listItem_()
     {
         writeEndTag( Tag.LI );
@@ -472,6 +527,17 @@
      */
     public void numberedList( int numbering )
     {
+        numberedList( numbering, null );
+    }
+
+    /**
+     * The default list style depends on the numbering.
+     *
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#OL
+     */
+    public void numberedList( int numbering, SinkEventAttributes attributes )
+    {
         String style;
         switch ( numbering )
         {
@@ -492,10 +558,17 @@
                 style = "decimal";
         }
 
-        MutableAttributeSet att = new SimpleAttributeSet();
-        att.addAttribute( Attribute.STYLE, "list-style-type: " + style );
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_SECTION_ATTRIBUTES  );
+
+        if ( atts == null )
+        {
+            atts = new SinkEventAttributeSet( 1 );
+        }
 
-        writeStartTag( Tag.OL, att );
+        atts.addAttribute( Attribute.STYLE, "list-style-type: " + style );
+
+        writeStartTag( Tag.OL, atts );
     }
 
     /**
@@ -520,6 +593,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#LI
      */
+    public void numberedListItem( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        writeStartTag( Tag.LI, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#LI
+     */
     public void numberedListItem_()
     {
         writeEndTag( Tag.LI );
@@ -538,6 +623,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#DL
      */
+    public void definitionList( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        writeStartTag( Tag.DL, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#DL
+     */
     public void definitionList_()
     {
         writeEndTag( Tag.DL );
@@ -547,6 +644,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#DT
      */
+    public void definedTerm( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        writeStartTag( Tag.DT, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#DT
+     */
     public void definedTerm()
     {
         writeStartTag( Tag.DT );
@@ -574,6 +683,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#DD
      */
+    public void definition( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        writeStartTag( Tag.DD, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#DD
+     */
     public void definition_()
     {
         writeEndTag( Tag.DD );
@@ -588,6 +709,18 @@
         write( String.valueOf( LESS_THAN ) + Tag.IMG );
     }
 
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#IMG
+     */
+    public void figure( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+        write( String.valueOf( LESS_THAN ) + Tag.IMG + SinkUtils.getAttributeString( atts ) );
+    }
+
     /** {@inheritDoc} */
     public void figure_()
     {
@@ -601,12 +734,33 @@
     }
 
     /** {@inheritDoc} */
+    public void figureGraphics( String src, SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_IMG_ATTRIBUTES  );
+        // TODO: remove, see DOXIA-75
+        atts.removeAttribute( Attribute.ALT.toString() );
+        atts.removeAttribute( Attribute.TITLE.toString() );
+        atts.removeAttribute( Attribute.SRC.toString() );
+
+        write( String.valueOf( SPACE ) + Attribute.SRC + EQUAL
+                + QUOTE + src + QUOTE + SinkUtils.getAttributeString( atts ) );
+    }
+
+    /** {@inheritDoc} */
     public void figureCaption()
     {
         write( String.valueOf( SPACE ) + Attribute.ALT + EQUAL + QUOTE );
     }
 
     /** {@inheritDoc} */
+    public void figureCaption( SinkEventAttributes attributes )
+    {
+        // TODO: see DOXIA-75
+        write( String.valueOf( SPACE ) + Attribute.ALT + EQUAL + QUOTE );
+    }
+
+    /** {@inheritDoc} */
     public void figureCaption_()
     {
         write( String.valueOf( QUOTE ) );
@@ -625,6 +779,18 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#P
      */
+    public void paragraph( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_SECTION_ATTRIBUTES  );
+
+        writeStartTag( Tag.P, atts );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#P
+     */
     public void paragraph_()
     {
         writeEndTag( Tag.P );
@@ -639,17 +805,60 @@
      */
     public void verbatim( boolean boxed )
     {
+        SinkEventAttributeSet att = new SinkEventAttributeSet();
+        att.addAttribute( "boxed", Boolean.toString( boxed ) );
+
+        verbatim( att );
+    }
+
+    /**
+     * The default class style for boxed is <code>source</code>.
+     *
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#DIV
+     * @see javax.swing.text.html.HTML.Tag#PRE
+     */
+    public void verbatim( SinkEventAttributes attributes )
+    {
         verbatimFlag = true;
 
-        MutableAttributeSet att = new SimpleAttributeSet();
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_VERBATIM_ATTRIBUTES  );
+
+        if ( atts == null )
+        {
+            atts = new SinkEventAttributeSet();
+        }
+
+        boolean boxed = false;
+
+        if ( atts.isDefined( "boxed" ) )
+        {
+            boxed = Boolean.valueOf(
+                (String) atts.getAttribute( "boxed" ) ).booleanValue();
+        }
 
         if ( boxed )
         {
-            att.addAttribute( Attribute.CLASS, "source" );
+            atts.addAttribute( Attribute.CLASS, "source" );
         }
 
-        writeStartTag( Tag.DIV, att );
-        writeStartTag( Tag.PRE );
+        atts.removeAttribute( "boxed" );
+
+        String width = (String) atts.getAttribute( Attribute.WIDTH.toString() );
+        atts.removeAttribute( Attribute.WIDTH.toString() );
+
+        writeStartTag( Tag.DIV, atts );
+
+        if ( width != null )
+        {
+            atts.addAttribute( Attribute.WIDTH.toString(), width);
+        }
+
+        atts.removeAttribute( Attribute.ALIGN.toString() );
+        atts.removeAttribute( Attribute.CLASS.toString() );
+
+        writeStartTag( Tag.PRE, atts );
     }
 
     /**
@@ -675,10 +884,38 @@
         writeSimpleTag( Tag.HR );
     }
 
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#HR
+     */
+    public void horizontalRule( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_HR_ATTRIBUTES  );
+
+        writeSimpleTag( Tag.HR, atts );
+    }
+
     /** {@inheritDoc} */
     public void table()
     {
         // start table with tableRows
+        table( null );
+    }
+
+    /** {@inheritDoc} */
+    public void table( SinkEventAttributes attributes )
+    {
+        // start table with tableRows
+        if ( attributes == null )
+        {
+            this.tableAttributes = new SinkEventAttributeSet( 0 );
+        }
+        else
+        {
+            this.tableAttributes = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_TABLE_ATTRIBUTES  );
+        }
     }
 
     /**
@@ -702,10 +939,31 @@
         this.cellJustif = justification;
         this.isCellJustif = true;
 
-        MutableAttributeSet att = new SimpleAttributeSet();
-        att.addAttribute( Attribute.ALIGN, "center" );
-        att.addAttribute( Attribute.BORDER, ( grid ? "1" : "0" ) );
-        att.addAttribute( Attribute.CLASS, "bodyTable" );
+        if ( this.tableAttributes == null )
+        {
+            this.tableAttributes = new SinkEventAttributeSet( 0 );
+        }
+
+        MutableAttributeSet att = new SinkEventAttributeSet();
+
+        if ( !tableAttributes.isDefined( Attribute.ALIGN.toString() ) )
+        {
+            att.addAttribute( Attribute.ALIGN, "center" );
+        }
+
+        if ( !tableAttributes.isDefined( Attribute.BORDER.toString() ) )
+        {
+            att.addAttribute( Attribute.BORDER, ( grid ? "1" : "0" ) );
+        }
+
+        if ( !tableAttributes.isDefined( Attribute.CLASS.toString() ) )
+        {
+            att.addAttribute( Attribute.CLASS, "bodyTable" );
+        }
+
+        att.addAttributes( tableAttributes );
+
+        tableAttributes.removeAttributes( tableAttributes );
 
         writeStartTag( Tag.TABLE, att );
     }
@@ -727,7 +985,18 @@
      */
     public void tableRow()
     {
-        MutableAttributeSet att = new SimpleAttributeSet();
+        tableRow( null );
+    }
+
+    /**
+     * The default class style is <code>a</code> or <code>b</code> depending the row id.
+     *
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#TR
+     */
+    public void tableRow( SinkEventAttributes attributes )
+    {
+        MutableAttributeSet att = new SinkEventAttributeSet();
 
         if ( evenTableRow )
         {
@@ -738,6 +1007,9 @@
             att.addAttribute( Attribute.CLASS, "b" );
         }
 
+        att.addAttributes( SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_TR_ATTRIBUTES  ) );
+
         writeStartTag( Tag.TR, att );
 
         evenTableRow = !evenTableRow;
@@ -759,37 +1031,43 @@
     /** {@inheritDoc} */
     public void tableCell()
     {
-        tableCell( false );
+        tableCell( false, null );
     }
 
     /** {@inheritDoc} */
     public void tableHeaderCell()
     {
-        tableCell( true );
+        tableCell( true, null );
     }
 
-    /**
-     * Starts a table cell.
-     *
-     * @param headerRow true if it is an header row
-     * @see javax.swing.text.html.HTML.Tag#TH
-     * @see javax.swing.text.html.HTML.Tag#TD
-     */
-    public void tableCell( boolean headerRow )
+    /** {@inheritDoc} */
+    public void tableCell( String width )
     {
-        tableCell( headerRow, null );
+        MutableAttributeSet att = new SinkEventAttributeSet();
+        att.addAttribute( Attribute.WIDTH, width );
+
+        tableCell( false, att );
     }
 
     /** {@inheritDoc} */
-    public void tableCell( String width )
+    public void tableHeaderCell( String width )
     {
-        tableCell( false, width );
+        MutableAttributeSet att = new SinkEventAttributeSet();
+        att.addAttribute( Attribute.WIDTH, width );
+
+        tableCell( true, att );
     }
 
     /** {@inheritDoc} */
-    public void tableHeaderCell( String width )
+    public void tableCell( SinkEventAttributes attributes )
+    {
+        tableCell( false, attributes );
+    }
+
+    /** {@inheritDoc} */
+    public void tableHeaderCell( SinkEventAttributes attributes )
     {
-        tableCell( true, width );
+        tableCell( true, attributes );
     }
 
     /**
@@ -798,7 +1076,7 @@
      * @see javax.swing.text.html.HTML.Tag#TH
      * @see javax.swing.text.html.HTML.Tag#TD
      */
-    public void tableCell( boolean headerRow, String width )
+    private void tableCell( boolean headerRow, MutableAttributeSet attributes )
     {
         String justif = null;
 
@@ -822,18 +1100,16 @@
 
         Tag t = ( headerRow ? Tag.TH : Tag.TD );
 
-        MutableAttributeSet att = new SimpleAttributeSet();
-
-        if ( width != null )
-        {
-            att.addAttribute( Attribute.WIDTH, width );
-        }
+        MutableAttributeSet att = new SinkEventAttributeSet();
 
         if ( justif != null )
         {
             att.addAttribute( Attribute.ALIGN, justif );
         }
 
+        att.addAttributes( SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_TD_ATTRIBUTES  ) );
+
         writeStartTag( t, att );
     }
 
@@ -874,8 +1150,20 @@
      */
     public void tableCaption()
     {
+        tableCaption( null );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#CAPTION
+     */
+    public void tableCaption( SinkEventAttributes attributes )
+    {
         // TODO: tableCaption should be written before tableRows
-        writeStartTag( Tag.CAPTION );
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_SECTION_ATTRIBUTES  );
+
+        writeStartTag( Tag.CAPTION, atts );
     }
 
     /**
@@ -893,17 +1181,31 @@
      */
     public void anchor( String name )
     {
+        anchor( name, null );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#A
+     */
+    public void anchor( String name, SinkEventAttributes attributes )
+    {
         if ( !headFlag )
         {
+            MutableAttributeSet atts = SinkUtils.filterAttributes(
+                    attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
             String id = HtmlTools.encodeId( name );
 
-            MutableAttributeSet att = new SimpleAttributeSet();
+            MutableAttributeSet att = new SinkEventAttributeSet();
 
             if ( id != null )
             {
                 att.addAttribute( Attribute.NAME, id );
             }
 
+            att.addAttributes( atts );
+
             writeStartTag( Tag.A, att );
         }
     }
@@ -923,43 +1225,62 @@
     /** {@inheritDoc} */
     public void link( String name )
     {
-        link( name, null );
+        link( name, null, null );
+    }
+
+    /** {@inheritDoc} */
+    public void link( String name, SinkEventAttributes attributes )
+    {
+        String target = (String) attributes.getAttribute( Attribute.TARGET.toString() );
+        MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_LINK_ATTRIBUTES  );
+
+        link( name, target, atts );
     }
 
     /**
      * Adds a link with an optional target.
      * The default style class for external link is <code>externalLink</code>.
      *
-     * @param name the link name.
+     * @param href the link href.
      * @param target the link target, may be null.
+     * @param attributes an AttributeSet, may be null.
+     *      This is supposed to be filtered already.
      * @see javax.swing.text.html.HTML.Tag#A
      */
-    public void link( String name, String target )
+    private void link( String href, String target, MutableAttributeSet attributes )
     {
         if ( headFlag )
         {
             return;
         }
 
-        MutableAttributeSet att = new SimpleAttributeSet();
-
-        if ( target != null )
-        {
-            att.addAttribute( Attribute.TARGET, target );
-        }
+        MutableAttributeSet att = new SinkEventAttributeSet();
 
-        if ( StructureSinkUtils.isExternalLink( name ) || isExternalHtml( name ) )
+        if ( StructureSinkUtils.isExternalLink( href  ) || isExternalHtml( href  ) )
         {
-            if ( isExternalLink( name ) )
+            if ( isExternalLink( href  ) )
             {
                 att.addAttribute( Attribute.CLASS, "externalLink" );
             }
 
-            att.addAttribute( Attribute.HREF, HtmlTools.escapeHTML( name ) );
+            att.addAttribute( Attribute.HREF, HtmlTools.escapeHTML( href  ) );
         }
         else
         {
-            att.addAttribute( Attribute.HREF, "#" + HtmlTools.escapeHTML( name ) );
+            att.addAttribute( Attribute.HREF, "#" + HtmlTools.escapeHTML( href  ) );
+        }
+
+        if ( target != null )
+        {
+            att.addAttribute( Attribute.TARGET, target );
+        }
+
+        if ( attributes != null )
+        {
+            attributes.removeAttribute( Attribute.HREF.toString() );
+            attributes.removeAttribute( Attribute.TARGET.toString() );
+            att.addAttributes( attributes );
         }
 
         writeStartTag( Tag.A, att );
@@ -969,7 +1290,7 @@
      * {@link StructureSinkUtils#isExternalLink(String)} also treats links to other documents as
      * external links, those should not have a class="externalLink" attribute.
      */
-    private boolean isExternalLink( String href )
+    protected boolean isExternalLink( String href )
     {
         String text = href.toLowerCase();
         return ( text.indexOf( "http:/" ) == 0 || text.indexOf( "https:/" ) == 0
@@ -983,7 +1304,7 @@
      * Note that links to other file formats (images, pdf) will still be broken,
      * links to other documents should always start with "./" or "../".
      */
-    private boolean isExternalHtml( String href )
+    protected boolean isExternalHtml( String href )
     {
         String text = href.toLowerCase();
         return ( text.indexOf( ".html#" ) != -1 || text.indexOf( ".htm#" ) != -1
@@ -1019,6 +1340,21 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#I
      */
+    public void italic( SinkEventAttributes attributes )
+    {
+        if ( !headFlag )
+        {
+            MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+            writeStartTag( Tag.I, atts );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#I
+     */
     public void italic_()
     {
         if ( !headFlag )
@@ -1043,6 +1379,21 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#B
      */
+    public void bold( SinkEventAttributes attributes )
+    {
+        if ( !headFlag )
+        {
+            MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+            writeStartTag( Tag.B, atts );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#B
+     */
     public void bold_()
     {
         if ( !headFlag )
@@ -1067,6 +1418,21 @@
      * {@inheritDoc}
      * @see javax.swing.text.html.HTML.Tag#TT
      */
+    public void monospaced( SinkEventAttributes attributes )
+    {
+        if ( !headFlag )
+        {
+            MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BASE_ATTRIBUTES  );
+
+            writeStartTag( Tag.TT, atts );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#TT
+     */
     public void monospaced_()
     {
         if ( !headFlag )
@@ -1088,6 +1454,25 @@
         else
         {
             writeSimpleTag( Tag.BR );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see javax.swing.text.html.HTML.Tag#BR
+     */
+    public void lineBreak( SinkEventAttributes attributes )
+    {
+        if ( headFlag )
+        {
+            getBuffer().append( EOL );
+        }
+        else
+        {
+            MutableAttributeSet atts = SinkUtils.filterAttributes(
+                attributes, SinkUtils.SINK_BR_ATTRIBUTES  );
+
+            writeSimpleTag( Tag.BR, atts );
         }
     }
 

Modified: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/util/HtmlTools.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/util/HtmlTools.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/util/HtmlTools.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/util/HtmlTools.java Fri Mar  7 05:27:15 2008
@@ -253,7 +253,7 @@
      * <p>
      * For letters, the case is preserved in the conversion.
      * </p>
-     * 
+     *
      * <p>
      * Here are some examples:
      * </p>

Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/AbstractParserTest.java Fri Mar  7 05:27:15 2008
@@ -20,11 +20,10 @@
  */
 
 import org.apache.maven.doxia.AbstractModuleTest;
-import org.apache.maven.doxia.WellformednessCheckingSink;
+import org.apache.maven.doxia.sink.WellformednessCheckingSink;
 
 import org.apache.maven.doxia.sink.Sink;
 import org.apache.maven.doxia.sink.TextSink;
-import org.apache.maven.doxia.parser.ParseException;
 
 import java.io.IOException;
 import java.io.Reader;

Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.java Fri Mar  7 05:27:15 2008
@@ -21,12 +21,10 @@
 
 import java.util.Iterator;
 
-import org.apache.maven.doxia.sink.Sink;
 import org.apache.maven.doxia.sink.SinkEventElement;
 import org.apache.maven.doxia.sink.SinkEventTestingSink;
 
 import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.util.xml.pull.MXParser;
 
 /**
  * Test for XhtmlBaseParser.
@@ -58,8 +56,6 @@
     {
         String text = "<p><h2></h2><h3></h3><h4></h4><h5></h5><h6></h6><h2></h2></p>";
 
-        SinkEventTestingSink sink = new SinkEventTestingSink();
-
         parser.parse( text, sink );
 
         Iterator it = sink.getEventList().iterator();
@@ -98,8 +94,6 @@
     {
         String text = "<img src=\"source\" title=\"caption\" />";
 
-        SinkEventTestingSink sink = new SinkEventTestingSink();
-
         parser.parse( text, sink );
 
         Iterator it = sink.getEventList().iterator();
@@ -121,8 +115,6 @@
 
         String text = "<table align=\"center\"><tr><th>Header</th></tr><tr><td>cell</td></tr></table>";
 
-        SinkEventTestingSink sink = new SinkEventTestingSink();
-
         parser.parse( text, sink );
 
         Iterator it = sink.getEventList().iterator();
@@ -141,7 +133,7 @@
         assertEquals( "tableRow_", ( (SinkEventElement) it.next() ).getName() );
         assertEquals( "tableRows_", ( (SinkEventElement) it.next() ).getName() );
         assertEquals( "table_", ( (SinkEventElement) it.next() ).getName() );
-        
+
         assertFalse( it.hasNext() );
     }
 
@@ -151,8 +143,6 @@
     {
         // NOTE significant white space
         String text = "<p><b>word</b> <i>word</i></p>";
-
-        SinkEventTestingSink sink = new SinkEventTestingSink();
 
         parser.parse( text, sink );
 

Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventTestingSink.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventTestingSink.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventTestingSink.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkEventTestingSink.java Fri Mar  7 05:27:15 2008
@@ -19,8 +19,6 @@
  * under the License.
  */
 
-import org.apache.maven.doxia.sink.AbstractSink;
-
 import java.util.LinkedList;
 import java.util.List;
 
@@ -596,6 +594,217 @@
     public void close()
     {
         addEvent( "close" );
+    }
+
+    /** {@inheritDoc} */
+    public void head( SinkEventAttributes attributes )
+    {
+        head();
+    }
+
+    /** {@inheritDoc} */
+    public void title( SinkEventAttributes attributes )
+    {
+        title();
+    }
+
+    /** {@inheritDoc} */
+    public void author( SinkEventAttributes attributes )
+    {
+        author();
+    }
+
+    /** {@inheritDoc} */
+    public void date( SinkEventAttributes attributes )
+    {
+        date();
+    }
+
+    /** {@inheritDoc} */
+    public void body( SinkEventAttributes attributes )
+    {
+        body();
+    }
+
+    /** {@inheritDoc} */
+    public void section( int level, SinkEventAttributes attributes )
+    {
+        addEvent( "section" + level );
+    }
+
+    /** {@inheritDoc} */
+    public void section_( int level )
+    {
+        addEvent( "section" + level + "_" );
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle( int level, SinkEventAttributes attributes )
+    {
+        addEvent( "sectionTitle" + level );
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle_( int level )
+    {
+
+        addEvent( "sectionTitle" + level + "_" );
+    }
+
+    /** {@inheritDoc} */
+    public void list( SinkEventAttributes attributes )
+    {
+        list();
+    }
+
+    /** {@inheritDoc} */
+    public void listItem( SinkEventAttributes attributes )
+    {
+        listItem();
+    }
+
+    /** {@inheritDoc} */
+    public void numberedList( int numbering, SinkEventAttributes attributes )
+    {
+        numberedList( numbering );
+    }
+
+    /** {@inheritDoc} */
+    public void numberedListItem( SinkEventAttributes attributes )
+    {
+        numberedListItem();
+    }
+
+    /** {@inheritDoc} */
+    public void definitionList( SinkEventAttributes attributes )
+    {
+        definitionList();
+    }
+
+    /** {@inheritDoc} */
+    public void definitionListItem( SinkEventAttributes attributes )
+    {
+        definitionListItem();
+    }
+
+    /** {@inheritDoc} */
+    public void definition( SinkEventAttributes attributes )
+    {
+        definition();
+    }
+
+    /** {@inheritDoc} */
+    public void definedTerm( SinkEventAttributes attributes )
+    {
+        definedTerm();
+    }
+
+    /** {@inheritDoc} */
+    public void figure( SinkEventAttributes attributes )
+    {
+        addEvent( "figure", new Object[] {attributes} );
+    }
+
+    /** {@inheritDoc} */
+    public void figureCaption( SinkEventAttributes attributes )
+    {
+        figureCaption();
+    }
+
+    /** {@inheritDoc} */
+    public void figureGraphics( String src, SinkEventAttributes attributes )
+    {
+        figureGraphics( src );
+    }
+
+    /** {@inheritDoc} */
+    public void table( SinkEventAttributes attributes )
+    {
+        table();
+    }
+
+    /** {@inheritDoc} */
+    public void tableRow( SinkEventAttributes attributes )
+    {
+        tableRow();
+    }
+
+    /** {@inheritDoc} */
+    public void tableCell( SinkEventAttributes attributes )
+    {
+        tableCell();
+    }
+
+    /** {@inheritDoc} */
+    public void tableHeaderCell( SinkEventAttributes attributes )
+    {
+        tableHeaderCell();
+    }
+
+    /** {@inheritDoc} */
+    public void tableCaption( SinkEventAttributes attributes )
+    {
+        tableCaption();
+    }
+
+    /** {@inheritDoc} */
+    public void paragraph( SinkEventAttributes attributes )
+    {
+        paragraph();
+    }
+
+    /** {@inheritDoc} */
+    public void verbatim( SinkEventAttributes attributes )
+    {
+        verbatim( false );
+    }
+
+    /** {@inheritDoc} */
+    public void horizontalRule( SinkEventAttributes attributes )
+    {
+        horizontalRule();
+    }
+
+    /** {@inheritDoc} */
+    public void anchor( String name, SinkEventAttributes attributes )
+    {
+        anchor( name );
+    }
+
+    /** {@inheritDoc} */
+    public void link( String name, SinkEventAttributes attributes )
+    {
+        link( name );
+    }
+
+    /** {@inheritDoc} */
+    public void italic( SinkEventAttributes attributes )
+    {
+        italic();
+    }
+
+    /** {@inheritDoc} */
+    public void bold( SinkEventAttributes attributes )
+    {
+        bold();
+    }
+
+    /** {@inheritDoc} */
+    public void monospaced( SinkEventAttributes attributes )
+    {
+        monospaced();
+    }
+
+    /** {@inheritDoc} */
+    public void lineBreak( SinkEventAttributes attributes )
+    {
+        lineBreak();
+    }
+
+    /** {@inheritDoc} */
+    public void text( String text, SinkEventAttributes attributes )
+    {
+        text( text );
     }
 
       //

Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkTestDocument.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkTestDocument.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkTestDocument.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/SinkTestDocument.java Fri Mar  7 05:27:15 2008
@@ -19,10 +19,8 @@
  * under the License.
  */
 
-import java.io.UnsupportedEncodingException;
 
 import org.apache.maven.doxia.parser.Parser;
-import org.apache.maven.doxia.sink.Sink;
 
 /**
  * Static methods to generate standard Doxia sink events.

Modified: maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/TextSink.java
URL: http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/TextSink.java?rev=634662&r1=634661&r2=634662&view=diff
==============================================================================
--- maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/TextSink.java (original)
+++ maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/sink/TextSink.java Fri Mar  7 05:27:15 2008
@@ -30,9 +30,6 @@
     extends AbstractSink
 {
 
-    /** System-dependent end-of-line string. */
-    private static final String EOL = System.getProperty( "line.separator" );
-
     /** For writing the result. */
     private final Writer out;
 
@@ -599,6 +596,223 @@
         }
     }
 
+    /** {@inheritDoc} */
+    public void head( SinkEventAttributes attributes )
+    {
+        head();
+    }
+
+    /** {@inheritDoc} */
+    public void title( SinkEventAttributes attributes )
+    {
+        title();
+    }
+
+    /** {@inheritDoc} */
+    public void author( SinkEventAttributes attributes )
+    {
+        author();
+    }
+
+    /** {@inheritDoc} */
+    public void date( SinkEventAttributes attributes )
+    {
+        date();
+    }
+
+    /** {@inheritDoc} */
+    public void body( SinkEventAttributes attributes )
+    {
+        body();
+    }
+
+    /** {@inheritDoc} */
+    public void section( int level, SinkEventAttributes attributes )
+    {
+        write( "begin:section" + level );
+    }
+
+    /** {@inheritDoc} */
+    public void section_( int level )
+    {
+        writeln( "end:section" + level );
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle( int level, SinkEventAttributes attributes )
+    {
+        write( "begin:sectionTitle" + level );
+    }
+
+    /** {@inheritDoc} */
+    public void sectionTitle_( int level )
+    {
+        writeln( "end:sectionTitle" + level );
+    }
+
+    /** {@inheritDoc} */
+    public void list( SinkEventAttributes attributes )
+    {
+        list();
+    }
+
+    /** {@inheritDoc} */
+    public void listItem( SinkEventAttributes attributes )
+    {
+        listItem();
+    }
+
+    /** {@inheritDoc} */
+    public void numberedList( int numbering, SinkEventAttributes attributes )
+    {
+        numberedList( numbering );
+    }
+
+    /** {@inheritDoc} */
+    public void numberedListItem( SinkEventAttributes attributes )
+    {
+        numberedListItem();
+    }
+
+    /** {@inheritDoc} */
+    public void definitionList( SinkEventAttributes attributes )
+    {
+        definitionList();
+    }
+
+    /** {@inheritDoc} */
+    public void definitionListItem( SinkEventAttributes attributes )
+    {
+        definitionListItem();
+    }
+
+    /** {@inheritDoc} */
+    public void definition( SinkEventAttributes attributes )
+    {
+        definition();
+    }
+
+    /** {@inheritDoc} */
+    public void definedTerm( SinkEventAttributes attributes )
+    {
+        definedTerm();
+    }
+
+    /** {@inheritDoc} */
+    public void figure( SinkEventAttributes attributes )
+    {
+        write( "begin:figure" + SinkUtils.getAttributeString( attributes ) );
+    }
+
+    /** {@inheritDoc} */
+    public void figureCaption( SinkEventAttributes attributes )
+    {
+        figureCaption();
+    }
+
+    /** {@inheritDoc} */
+    public void figureGraphics( String src, SinkEventAttributes attributes )
+    {
+        figureGraphics( src );
+    }
+
+    /** {@inheritDoc} */
+    public void table( SinkEventAttributes attributes )
+    {
+        table();
+    }
+
+    /** {@inheritDoc} */
+    public void tableRow( SinkEventAttributes attributes )
+    {
+        tableRow();
+    }
+
+    /** {@inheritDoc} */
+    public void tableCell( SinkEventAttributes attributes )
+    {
+        tableCell();
+    }
+
+    /** {@inheritDoc} */
+    public void tableHeaderCell( SinkEventAttributes attributes )
+    {
+        tableHeaderCell();
+    }
+
+    /** {@inheritDoc} */
+    public void tableCaption( SinkEventAttributes attributes )
+    {
+        tableCaption();
+    }
+
+    /** {@inheritDoc} */
+    public void paragraph( SinkEventAttributes attributes )
+    {
+        paragraph();
+    }
+
+    /** {@inheritDoc} */
+    public void verbatim( SinkEventAttributes attributes )
+    {
+        boolean boxed = false;
+
+        if ( attributes != null && attributes.isDefined( "boxed" ) )
+        {
+            boxed = Boolean.valueOf(
+                (String) attributes.getAttribute( "boxed" ) ).booleanValue();
+        }
+
+        verbatim( boxed );
+    }
+
+    /** {@inheritDoc} */
+    public void horizontalRule( SinkEventAttributes attributes )
+    {
+        horizontalRule();
+    }
+
+    /** {@inheritDoc} */
+    public void anchor( String name, SinkEventAttributes attributes )
+    {
+        anchor( name );
+    }
+
+    /** {@inheritDoc} */
+    public void link( String name, SinkEventAttributes attributes )
+    {
+        link( name );
+    }
+
+    /** {@inheritDoc} */
+    public void italic( SinkEventAttributes attributes )
+    {
+        italic();
+    }
+
+    /** {@inheritDoc} */
+    public void bold( SinkEventAttributes attributes )
+    {
+        bold();
+    }
+
+    /** {@inheritDoc} */
+    public void monospaced( SinkEventAttributes attributes )
+    {
+        monospaced();
+    }
+
+    /** {@inheritDoc} */
+    public void lineBreak( SinkEventAttributes attributes )
+    {
+        lineBreak();
+    }
+
+    /** {@inheritDoc} */
+    public void text( String text, SinkEventAttributes attributes )
+    {
+        text( text );
+    }
 
     /**
      * Writes the given string + EOL.