Author: ltheussl
Date: Mon Mar 2 10:54:56 2009
New Revision: 749267
URL: http://svn.apache.org/viewvc?rev=749267&view=rev
Log:
[DOXIA-241] Xdoc/XhtmlBaseParser doesn't close sections properly
Modified:
maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java
maven/doxia/doxia/trunk/doxia-core/src/test/java/org/apache/maven/doxia/parser/XhtmlBaseParserTest.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/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlParser.java
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=749267&r1=749266&r2=749267&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
Mon Mar 2 10:54:56 2009
@@ -507,12 +507,48 @@
}
/**
- * Close open sections. The current level is set to newLevel afterwards.
+ * Make sure sections are nested consecutively.
+ *
+ * <p>
+ * HTML doesn't have any sections, only sectionTitles (<h2>, etc),
that means we have to
+ * open close any sections that are missing in between.
+ * </p>
+ *
+ * <p>
+ * For instance, if the following sequence is parsed:
+ * <pre>
+ * <h3></h3>
+ * <h6></h6>
+ * </pre>
+ * we have to insert two section starts before we open the
<code><h6></code>.
+ * In the following sequence
+ * <pre>
+ * <h6></h6>
+ * <h3></h3>
+ * </pre>
+ * we have to close two sections before we open the
<code><h3></code>.
+ * </p>
+ *
+ * <p>The current level is set to newLevel afterwards.</p>
*
* @param newLevel the new section level, all upper levels have to be
closed.
* @param sink the sink to receive the events.
*/
- protected void closeOpenSections( int newLevel, Sink sink )
+ protected void consecutiveSections( int newLevel, Sink sink )
+ {
+ closeOpenSections( newLevel, sink );
+ openMissingSections( newLevel, sink );
+
+ this.sectionLevel = newLevel;
+ }
+
+ /**
+ * Close open sections.
+ *
+ * @param newLevel the new section level, all upper levels have to be
closed.
+ * @param sink the sink to receive the events.
+ */
+ private void closeOpenSections( int newLevel, Sink sink )
{
while ( this.sectionLevel >= newLevel )
{
@@ -539,8 +575,41 @@
this.sectionLevel--;
}
+ }
- this.sectionLevel = newLevel;
+ /**
+ * Open missing sections.
+ *
+ * @param newLevel the new section level, all lower levels have to be
opened.
+ * @param sink the sink to receive the events.
+ */
+ private void openMissingSections( int newLevel, Sink sink )
+ {
+ while ( this.sectionLevel < newLevel - 1 )
+ {
+ this.sectionLevel++;
+
+ if ( sectionLevel == Sink.SECTION_LEVEL_5 )
+ {
+ sink.section5();
+ }
+ else if ( sectionLevel == Sink.SECTION_LEVEL_4 )
+ {
+ sink.section4();
+ }
+ else if ( sectionLevel == Sink.SECTION_LEVEL_3 )
+ {
+ sink.section3();
+ }
+ else if ( sectionLevel == Sink.SECTION_LEVEL_2 )
+ {
+ sink.section2();
+ }
+ else if ( sectionLevel == Sink.SECTION_LEVEL_1 )
+ {
+ sink.section1();
+ }
+ }
}
/**
@@ -793,7 +862,7 @@
private void handleSectionStart( Sink sink, int sectionLevel,
SinkEventAttributeSet attribs )
{
- closeOpenSections( sectionLevel, sink );
+ consecutiveSections( sectionLevel, sink );
sink.section( sectionLevel, attribs );
sink.sectionTitle( sectionLevel, attribs );
}
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=749267&r1=749266&r2=749267&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
Mon Mar 2 10:54:56 2009
@@ -88,6 +88,49 @@
assertEquals( "section1", ( (SinkEventElement) it.next() ).getName() );
assertEquals( "sectionTitle1", ( (SinkEventElement) it.next()
).getName() );
assertEquals( "sectionTitle1_", ( (SinkEventElement) it.next()
).getName() );
+ // this one is missing because we enclose everything in <p> which is
not valid xhtml,
+ // needs to be tested in overriding parser, eg XhtmlParser, XdocParser.
+ //assertEquals( "section1_", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "paragraph_", ( (SinkEventElement) it.next() ).getName()
);
+ assertFalse( it.hasNext() );
+ }
+
+ /** @throws Exception */
+ public void testNestedHeadingEventsList()
+ throws Exception
+ {
+ // DOXIA-241
+ String text = "<p><h2></h2><h6></h6><h3></h3></p>";
+
+ parser.parse( text, sink );
+
+ Iterator it = sink.getEventList().iterator();
+
+ assertEquals( "paragraph", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section1", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle1", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "sectionTitle1_", ( (SinkEventElement) it.next()
).getName() );
+
+ assertEquals( "section2", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "section3", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "section4", ( (SinkEventElement) it.next() ).getName() );
+
+ assertEquals( "section5", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle5", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "sectionTitle5_", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "section5_", ( (SinkEventElement) it.next() ).getName()
);
+
+ assertEquals( "section4_", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section3_", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section2_", ( (SinkEventElement) it.next() ).getName()
);
+
+ assertEquals( "section2", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle2", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "sectionTitle2_", ( (SinkEventElement) it.next()
).getName() );
+ // these two are missing because we enclose everything in <p> which is
not valid xhtml,
+ // needs to be tested in overriding parser, eg XhtmlParser, XdocParser.
+ //assertEquals( "section2_", ( (SinkEventElement) it.next()
).getName() );
+ //assertEquals( "section1_", ( (SinkEventElement) it.next()
).getName() );
assertEquals( "paragraph_", ( (SinkEventElement) it.next() ).getName()
);
assertFalse( it.hasNext() );
}
Modified:
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocParser.java
URL:
http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocParser.java?rev=749267&r1=749266&r2=749267&view=diff
==============================================================================
---
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocParser.java
(original)
+++
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/main/java/org/apache/maven/doxia/module/xdoc/XdocParser.java
Mon Mar 2 10:54:56 2009
@@ -141,7 +141,7 @@
}
else if ( parser.getName().equals( SECTION_TAG.toString() ) )
{
- closeOpenSections( Sink.SECTION_LEVEL_1, sink );
+ consecutiveSections( Sink.SECTION_LEVEL_1, sink );
Object id = attribs.getAttribute( Attribute.ID.toString() );
if ( id != null )
@@ -160,7 +160,7 @@
}
else if ( parser.getName().equals( SUBSECTION_TAG.toString() ) )
{
- closeOpenSections( Sink.SECTION_LEVEL_2, sink );
+ consecutiveSections( Sink.SECTION_LEVEL_2, sink );
Object id = attribs.getAttribute( Attribute.ID.toString() );
if ( id != null )
@@ -300,7 +300,7 @@
}
else if ( parser.getName().equals( Tag.BODY.toString() ) )
{
- closeOpenSections( 0, sink );
+ consecutiveSections( 0, sink );
sink.body_();
}
@@ -370,15 +370,13 @@
}
else if ( parser.getName().equals( SECTION_TAG.toString() ) )
{
- closeOpenSections( 0, sink );
+ consecutiveSections( 0, sink );
sink.section1_();
}
else if ( parser.getName().equals( SUBSECTION_TAG.toString() ) )
{
- closeOpenSections( Sink.SECTION_LEVEL_1, sink );
-
- sink.section2_();
+ consecutiveSections( Sink.SECTION_LEVEL_1, sink );
}
else if ( parser.getName().equals( Tag.SCRIPT.toString() ) )
{
@@ -413,12 +411,19 @@
}
}
+ /** {...@inheritdoc} */
+ protected void consecutiveSections( int newLevel, Sink sink )
+ {
+ closeOpenSections( newLevel, sink );
+ openMissingSections( newLevel, sink );
+
+ setSectionLevel( newLevel );
+ }
+
/**
- * {...@inheritdoc}
- *
- * Close open h4, h5, h6 sections. The current level is set to newLevel
afterwards.
+ * Close open h4, h5, h6 sections.
*/
- protected void closeOpenSections( int newLevel, Sink sink )
+ private void closeOpenSections( int newLevel, Sink sink )
{
while ( getSectionLevel() >= newLevel )
{
@@ -434,10 +439,40 @@
{
sink.section3_();
}
+ else if ( getSectionLevel() == Sink.SECTION_LEVEL_2 )
+ {
+ sink.section2_();
+ }
setSectionLevel( getSectionLevel() - 1 );
}
+ }
- setSectionLevel( newLevel );
+ /**
+ * Open missing h4, h5, h6 sections.
+ */
+ private void openMissingSections( int newLevel, Sink sink )
+ {
+ while ( getSectionLevel() < newLevel - 1 )
+ {
+ setSectionLevel( getSectionLevel() + 1 );
+
+ if ( getSectionLevel() == Sink.SECTION_LEVEL_5 )
+ {
+ sink.section5();
+ }
+ else if ( getSectionLevel() == Sink.SECTION_LEVEL_4 )
+ {
+ sink.section4();
+ }
+ else if ( getSectionLevel() == Sink.SECTION_LEVEL_3 )
+ {
+ sink.section3();
+ }
+ else if ( getSectionLevel() == Sink.SECTION_LEVEL_2 )
+ {
+ sink.section2();
+ }
+ }
}
}
Modified:
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java
URL:
http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java?rev=749267&r1=749266&r2=749267&view=diff
==============================================================================
---
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java
(original)
+++
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xdoc/src/test/java/org/apache/maven/doxia/module/xdoc/XdocParserTest.java
Mon Mar 2 10:54:56 2009
@@ -213,6 +213,44 @@
}
/** @throws Exception */
+ public void testNestedSectionsEventsList()
+ throws Exception
+ {
+ // DOXIA-241
+ String text = "<section name=\"section\"><h6>h6</h6><subsection
name=\"subsection\"></subsection></section>";
+
+ SinkEventTestingSink sink = new SinkEventTestingSink();
+
+ parser.parse( text, sink );
+
+ Iterator it = sink.getEventList().iterator();
+
+ assertEquals( "section1", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle1", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "text", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle1_", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "section2", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "section3", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "section4", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "section5", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle5", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "text", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle5_", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "section5_", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section4_", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section3_", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section2_", ( (SinkEventElement) it.next() ).getName()
);
+
+ assertEquals( "section2", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle2", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "text", ( (SinkEventElement) it.next() ).getName() );
+ assertEquals( "sectionTitle2_", ( (SinkEventElement) it.next()
).getName() );
+ assertEquals( "section2_", ( (SinkEventElement) it.next() ).getName()
);
+ assertEquals( "section1_", ( (SinkEventElement) it.next() ).getName()
);
+ assertFalse( it.hasNext() );
+ }
+
+ /** @throws Exception */
public void testSourceEventsList()
throws Exception
{
Modified:
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlParser.java
URL:
http://svn.apache.org/viewvc/maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlParser.java?rev=749267&r1=749266&r2=749267&view=diff
==============================================================================
---
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlParser.java
(original)
+++
maven/doxia/doxia/trunk/doxia-modules/doxia-module-xhtml/src/main/java/org/apache/maven/doxia/module/xhtml/XhtmlParser.java
Mon Mar 2 10:54:56 2009
@@ -210,7 +210,7 @@
}
else if ( parser.getName().equals( Tag.BODY.toString() ) )
{
- closeOpenSections( 0, sink );
+ consecutiveSections( 0, sink );
sink.body_();
}