Author: ltheussl Date: Sat Nov 3 13:54:56 2007 New Revision: 591684 URL: http://svn.apache.org/viewvc?rev=591684&view=rev Log: Add some base classes to handle common html events
Added: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java (with props) maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java (with props) Added: 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=591684&view=auto ============================================================================== --- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java (added) +++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java Sat Nov 3 13:54:56 2007 @@ -0,0 +1,668 @@ +package org.apache.maven.doxia.parser; + +/* + * 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 javax.swing.text.html.HTML.Attribute; +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.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * Common base parser for xhtml events. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Jason van Zyl</a> + * @author ltheussl + * @version $Id$ + * @since 1.0 + */ +public class XhtmlBaseParser + extends AbstractXmlParser +{ + /** Used to distinguish <a href=""> from <a name="">. */ + private boolean isLink; + + /** Used to distinguish <a href=""> from <a name="">. */ + private boolean isAnchor; + + /** Used for nested lists. */ + private int orderedListDepth = 0; + + /** For tables. */ + private boolean hasCaption; + + /** Counts section level. */ + private int sectionLevel; + + /** + * <p> + * Goes through a common list of possible html start tags. These include only tags that can go into + * the body of a xhtml document and so should be re-usable by different xhtml-based parsers. + * </p> + * <p> + * The currently handled tags are: + * </p> + * <p> + * <code> + * <h2>, <h3>, <h4>, <h5>, <h6>, <p>, <pre>, + * <ul>, <ol>, <li>, <dl>, <dt>, <dd>, <b>, <strong>, + * <i>, <em>, <code>, <samp>, <tt>, <a>, <table>, <tr>, + * <th>, <td>, <caption>, <br/>, <hr/>, <img/>. + * </code> + * </p> + * + * @param parser A parser. + * @param sink the sink to receive the events. + * @return True if the event has been handled by this method, i.e. the tag was recognized, false otherwise. + */ + public boolean baseStartTag( XmlPullParser parser, Sink sink ) + { + boolean visited = true; + + if ( parser.getName().equals( Tag.H2.toString() ) ) + { + closeOpenSections( Sink.SECTION_LEVEL_1, sink ); + + sink.section1(); + + sink.sectionTitle1(); + } + else if ( parser.getName().equals( Tag.H3.toString() ) ) + { + closeOpenSections( Sink.SECTION_LEVEL_2, sink ); + + sink.section2(); + + sink.sectionTitle2(); + } + else if ( parser.getName().equals( Tag.H4.toString() ) ) + { + closeOpenSections( Sink.SECTION_LEVEL_3, sink ); + + sink.section3(); + + sink.sectionTitle3(); + } + else if ( parser.getName().equals( Tag.H5.toString() ) ) + { + closeOpenSections( Sink.SECTION_LEVEL_4, sink ); + + sink.section4(); + + sink.sectionTitle4(); + } + else if ( parser.getName().equals( Tag.H6.toString() ) ) + { + closeOpenSections( Sink.SECTION_LEVEL_5, sink ); + + sink.section5(); + + sink.sectionTitle5(); + } + else if ( parser.getName().equals( Tag.P.toString() ) ) + { + sink.paragraph(); + } + /* + * The PRE element tells visual user agents that the enclosed text is + * "preformatted". When handling preformatted text, visual user agents: + * - May leave white space intact. + * - May render text with a fixed-pitch font. + * - May disable automatic word wrap. + * - Must not disable bidirectional processing. + * Non-visual user agents are not required to respect extra white space + * in the content of a PRE element. + */ + else if ( parser.getName().equals( Tag.PRE.toString() ) ) + { + sink.verbatim( false ); + } + else if ( parser.getName().equals( Tag.UL.toString() ) ) + { + sink.list(); + } + else if ( parser.getName().equals( Tag.OL.toString() ) ) + { + int numbering = Sink.NUMBERING_DECIMAL; + + // this will have to be generalized if we handle styles + String style = parser.getAttributeValue( null, Attribute.STYLE.toString() ); + + if ( style != null ) + { + if ( "list-style-type: upper-alpha".equals( style ) ) + { + numbering = Sink.NUMBERING_UPPER_ALPHA; + } + else if ( "list-style-type: lower-alpha".equals( style ) ) + { + numbering = Sink.NUMBERING_LOWER_ALPHA; + } + else if ( "list-style-type: upper-roman".equals( style ) ) + { + numbering = Sink.NUMBERING_UPPER_ROMAN; + } + else if ( "list-style-type: lower-roman".equals( style ) ) + { + numbering = Sink.NUMBERING_LOWER_ROMAN; + } + else if ( "list-style-type: decimal".equals( style ) ) + { + numbering = Sink.NUMBERING_DECIMAL; + } + } + + sink.numberedList( numbering ); + orderedListDepth++; + } + else if ( parser.getName().equals( Tag.LI.toString() ) ) + { + if ( orderedListDepth == 0 ) + { + sink.listItem(); + } + else + { + sink.numberedListItem(); + } + } + else if ( parser.getName().equals( Tag.DL.toString() ) ) + { + sink.definitionList(); + } + else if ( parser.getName().equals( Tag.DT.toString() ) ) + { + sink.definitionListItem(); + sink.definedTerm(); + } + else if ( parser.getName().equals( Tag.DD.toString() ) ) + { + sink.definition(); + } + else if ( ( parser.getName().equals( Tag.B.toString() ) ) || ( parser.getName().equals( Tag.STRONG.toString() ) ) ) + { + sink.bold(); + } + else if ( ( parser.getName().equals( Tag.I.toString() ) ) || ( parser.getName().equals( Tag.EM.toString() ) ) ) + { + sink.italic(); + } + else if ( ( parser.getName().equals( Tag.CODE.toString() ) ) || ( parser.getName().equals( Tag.SAMP.toString() ) ) || + ( parser.getName().equals( Tag.TT.toString() ) ) ) + { + sink.monospaced(); + } + else if ( parser.getName().equals( Tag.A.toString() ) ) + { + String href = parser.getAttributeValue( null, Attribute.HREF.toString() ); + + if ( href != null ) + { + String link = href; + + if ( link.startsWith( "#" ) ) + { + link = link.substring( 1 ); + } + + sink.link( link ); + + isLink = true; + } + else + { + String name = parser.getAttributeValue( null, Attribute.NAME.toString() ); + + if ( name != null ) + { + sink.anchor( name ); + + isAnchor = true; + } + else + { + String id = parser.getAttributeValue( null, Attribute.ID.toString() ); + + if ( id != null ) + { + sink.anchor( id ); + + isAnchor = true; + } + } + } + } + + // ---------------------------------------------------------------------- + // Tables + // ---------------------------------------------------------------------- + + else if ( parser.getName().equals( Tag.TABLE.toString() ) ) + { + sink.table(); + + String border = parser.getAttributeValue( null, Attribute.BORDER.toString() ); + + boolean grid = true; + + if ( "0".equals( border ) ) + { + grid = false; + } + + String align = parser.getAttributeValue( null, Attribute.ALIGN.toString() ); + + int[] justif = { JUSTIFY_CENTER }; + + if ( "left".equals( align ) ) + { + justif[0] = JUSTIFY_LEFT; + } + else if ( "right".equals( align ) ) + { + justif[0] = JUSTIFY_RIGHT; + } + + sink.tableRows( justif, grid ); + } + else if ( parser.getName().equals( Tag.TR.toString() ) ) + { + sink.tableRow(); + } + 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 ); + } + } + 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 ); + } + } + else if ( parser.getName().equals( Tag.CAPTION.toString() ) ) + { + sink.tableRows_(); + this.hasCaption = true; + sink.tableCaption(); + } + + // ---------------------------------------------------------------------- + // Empty elements: <br/>, <hr/> and <img /> + // ---------------------------------------------------------------------- + + else if ( parser.getName().equals( Tag.BR.toString() ) ) + { + sink.lineBreak(); + } + else if ( parser.getName().equals( Tag.HR.toString() ) ) + { + sink.horizontalRule(); + } + else if ( parser.getName().equals( Tag.IMG.toString() ) ) + { + String src = parser.getAttributeValue( null, Attribute.SRC.toString() ); + String title = parser.getAttributeValue( null, Attribute.TITLE.toString() ); + String alt = parser.getAttributeValue( null, Attribute.ALT.toString() ); + + sink.figure(); + + if ( src != null ) + { + sink.figureGraphics( src ); + } + + if ( title != null ) + { + sink.figureCaption(); + sink.text( title ); + sink.figureCaption_(); + } + else if ( alt != null ) + { + sink.figureCaption(); + sink.text( alt ); + sink.figureCaption_(); + } + + sink.figure_(); + } + else + { + visited = false; + } + + return visited; + } + + /** + * <p> + * Goes through a common list of possible html end tags. + * These should be re-usable by different xhtml-based parsers. + * The tags handled here are the same as for [EMAIL PROTECTED] #baseStartTag(XmlPullParser,Sink)}, + * except for the empty elements (<code><br/>, <hr/>, <img/><code>). + * </p> + * + * @param parser A parser. + * @param sink the sink to receive the events. + * @return True if the event has been handled by this method, false otherwise. + */ + public boolean baseEndTag( XmlPullParser parser, Sink sink ) + { + boolean visited = true; + + if ( parser.getName().equals( Tag.P.toString() ) ) + { + sink.paragraph_(); + } + else if ( parser.getName().equals( Tag.PRE.toString() ) ) + { + sink.verbatim_(); + } + else if ( parser.getName().equals( Tag.UL.toString() ) ) + { + sink.list_(); + } + else if ( parser.getName().equals( Tag.OL.toString() ) ) + { + sink.numberedList_(); + orderedListDepth--; + } + else if ( parser.getName().equals( Tag.LI.toString() ) ) + { + if ( orderedListDepth == 0 ) + { + sink.listItem_(); + } + else + { + sink.numberedListItem_(); + } + } + else if ( parser.getName().equals( Tag.DL.toString() ) ) + { + sink.definitionList_(); + } + else if ( parser.getName().equals( Tag.DT.toString() ) ) + { + sink.definedTerm_(); + } + else if ( parser.getName().equals( Tag.DD.toString() ) ) + { + sink.definition_(); + sink.definitionListItem_(); + } + else if ( ( parser.getName().equals( Tag.B.toString() ) ) || ( parser.getName().equals( Tag.STRONG.toString() ) ) ) + { + sink.bold_(); + } + else if ( ( parser.getName().equals( Tag.I.toString() ) ) || ( parser.getName().equals( Tag.EM.toString() ) ) ) + { + sink.italic_(); + } + else if ( ( parser.getName().equals( Tag.CODE.toString() ) ) || ( parser.getName().equals( Tag.SAMP.toString() ) ) || + ( parser.getName().equals( Tag.TT.toString() ) ) ) + { + sink.monospaced_(); + } + else if ( parser.getName().equals( Tag.A.toString() ) ) + { + if ( isLink ) + { + sink.link_(); + + isLink = false; + } + else if ( isAnchor ) + { + sink.anchor_(); + + isAnchor = false; + } + } + + // ---------------------------------------------------------------------- + // Tables + // ---------------------------------------------------------------------- + + else if ( parser.getName().equals( Tag.TABLE.toString() ) ) + { + if ( !hasCaption ) + { + sink.tableRows_(); + } + + this.hasCaption = false; + + sink.table_(); + } + else if ( parser.getName().equals( Tag.TR.toString() ) ) + { + sink.tableRow_(); + } + else if ( parser.getName().equals( Tag.TH.toString() ) ) + { + sink.tableHeaderCell_(); + } + else if ( parser.getName().equals( Tag.TD.toString() ) ) + { + sink.tableCell_(); + } + else if ( parser.getName().equals( Tag.CAPTION.toString() ) ) + { + sink.tableCaption_(); + } + else if ( parser.getName().equals( Tag.H2.toString() ) ) + { + sink.sectionTitle1_(); + } + else if ( parser.getName().equals( Tag.H3.toString() ) ) + { + sink.sectionTitle2_(); + } + else if ( parser.getName().equals( Tag.H4.toString() ) ) + { + sink.sectionTitle3_(); + } + else if ( parser.getName().equals( Tag.H5.toString() ) ) + { + sink.sectionTitle4_(); + } + else if ( parser.getName().equals( Tag.H6.toString() ) ) + { + sink.sectionTitle5_(); + } + else + { + visited = false; + } + + return visited; + } + + /** + * [EMAIL PROTECTED] + * + * Just calls [EMAIL PROTECTED] baseStartTag(XmlPullParser,Sink)}, this should be + * overridden by implementing parsers to include additional tags. + */ + protected void handleStartTag( XmlPullParser parser, Sink sink ) + throws XmlPullParserException, MacroExecutionException + { + if ( !baseStartTag( parser, sink ) ) + { + // TODO: log( "Unrecognized start tag!" ); + } + } + + /** + * [EMAIL PROTECTED] + * + * Just calls [EMAIL PROTECTED] baseEndTag(XmlPullParser,Sink)}, this should be + * overridden by implementing parsers to include additional tags. + */ + protected void handleEndTag( XmlPullParser parser, Sink sink ) + throws XmlPullParserException, MacroExecutionException + { + if ( !baseEndTag( parser, sink ) ) + { + // TODO: log( "Unrecognized end tag!" ); + } + } + + /** [EMAIL PROTECTED] */ + protected void handleText( XmlPullParser parser, Sink sink ) + throws XmlPullParserException + { + String text = parser.getText(); + + if ( StringUtils.isNotEmpty( text.trim() ) ) + { + // emit separate text events for different lines + String[] lines = StringUtils.split( text, EOL ); + + for ( int i = 0; i < lines.length; i++ ) + { + sink.text( lines[i] ); + } + } + } + + /** [EMAIL PROTECTED] */ + protected void handleCdsect( XmlPullParser parser, Sink sink ) + throws XmlPullParserException + { + sink.text( parser.getText() ); + } + + /** [EMAIL PROTECTED] */ + protected void handleComment( XmlPullParser parser, Sink sink ) + throws XmlPullParserException + { + String text = parser.getText(); + + if ( "PB".equals( text.trim() ) ) + { + sink.pageBreak(); + } + else + { + sink.comment( text.trim() ); + } + } + + /** [EMAIL PROTECTED] */ + protected void handleEntity( XmlPullParser parser, Sink sink ) + throws XmlPullParserException + { + String text = parser.getText(); + + int[] holder = new int[] {0, 0}; + char[] chars = parser.getTextCharacters( holder ); + String textChars = String.valueOf( chars, holder[0], holder[1] ); + + if ( "#160".equals( textChars ) ) + { + sink.nonBreakingSpace(); + } + else + { + sink.text( text ); + } + } + + /** + * Close open sections. The current level is set to newLevel afterwards. + * + * @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 ) + { + while ( this.sectionLevel >= newLevel ) + { + 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_(); + } + + this.sectionLevel--; + } + + this.sectionLevel = newLevel; + } + + /** + * Return the current section level. + * + * @return the current section level. + */ + protected int getSectionLevel() + { + return this.sectionLevel; + } + + /** + * Set the current section level. + * + * @param newLevel the new section level. + */ + protected void setSectionLevel( int newLevel ) + { + this.sectionLevel = newLevel; + } + +} Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/parser/XhtmlBaseParser.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Added: 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=591684&view=auto ============================================================================== --- maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java (added) +++ maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java Sat Nov 3 13:54:56 2007 @@ -0,0 +1,1218 @@ +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.io.PrintWriter; +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.sink.StructureSink; +import org.apache.maven.doxia.util.HtmlTools; + +/** + * Abstract base xhtml sink implementation. + * + * @author Jason van Zyl + * @author ltheussl + * @version $Id$ + * @since 1.0 + */ +public class XhtmlBaseSink + extends AbstractXmlSink +{ + // ---------------------------------------------------------------------- + // Instance fields + // ---------------------------------------------------------------------- + + /** The PrintWriter to write the result. */ + private PrintWriter writer; + + /** Used to collect text events. */ + private StringBuffer buffer = new StringBuffer(); + + /** An indication on if we're inside a head. */ + private boolean headFlag; + + /** An indication on if we're in verbatim mode. */ + private boolean verbatimFlag; + + /** Justification of table cells. */ + private int[] cellJustif; + + /** Number of cells in a table row. */ + private int cellCount; + + /** Used to style successive table rows differently. */ + private boolean evenTableRow = true; + + // ---------------------------------------------------------------------- + // Constructor + // ---------------------------------------------------------------------- + + /** + * Constructor, initialize the PrintWriter. + * + * @param out The writer to write the result. + */ + public XhtmlBaseSink( Writer out ) + { + this.writer = new PrintWriter( out ); + } + + // ---------------------------------------------------------------------- + // Accessor methods + // ---------------------------------------------------------------------- + + /** + * @return the current buffer. + */ + protected StringBuffer getBuffer() + { + return buffer; + } + + /** + * @param headFlag an header flag. + */ + protected void setHeadFlag( boolean headFlag ) + { + this.headFlag = headFlag; + } + + /** + * @return the current headFlag. + */ + protected boolean isHeadFlag() + { + return this.headFlag ; + } + + /** + * @param verb a verbatim flag. + */ + protected void setVerbatimFlag( boolean verb ) + { + this.verbatimFlag = verb; + } + + /** + * @return the current verbatim flag. + */ + protected boolean isVerbatimFlag() + { + return this.verbatimFlag ; + } + + /** + * @param justif the new cell justification array. + */ + protected void setCellJustif( int[] justif ) + { + this.cellJustif = justif; + } + + /** + * @return the current cell justification array. + */ + protected int[] getCellJustif() + { + return this.cellJustif ; + } + + /** + * @param count the new cell count. + */ + protected void setCellCount( int count ) + { + this.cellCount = count; + } + + /** + * @return the current cell count. + */ + protected int getCellCount() + { + return this.cellCount ; + } + + /** + * @param verb an evenTableRow flag. + */ + protected void setEvenTableRow( boolean even ) + { + this.evenTableRow = even; + } + + /** + * @return the current evenTableRow flag. + */ + protected boolean isEvenTableRow() + { + return this.evenTableRow ; + } + + /** + * Reset all variables. + */ + protected void resetState() + { + resetBuffer(); + headFlag = false; + verbatimFlag = false; + cellJustif = null; + cellCount = 0; + evenTableRow = true; + } + + /** + * Reset the buffer. + */ + protected void resetBuffer() + { + this.buffer = new StringBuffer(); + } + + + // ---------------------------------------------------------------------- + // Sections + // ---------------------------------------------------------------------- + + /** [EMAIL PROTECTED] */ + public void section1() + { + onSection( SECTION_LEVEL_1 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle1() + { + onSectionTitle( SECTION_LEVEL_1 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle1_() + { + onSectionTitle_( SECTION_LEVEL_1 ); + } + + /** [EMAIL PROTECTED] */ + public void section1_() + { + onSection_( SECTION_LEVEL_1 ); + } + + /** [EMAIL PROTECTED] */ + public void section2() + { + onSection( SECTION_LEVEL_2 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle2() + { + onSectionTitle( SECTION_LEVEL_2 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle2_() + { + onSectionTitle_( SECTION_LEVEL_2 ); + } + + /** [EMAIL PROTECTED] */ + public void section2_() + { + onSection_( SECTION_LEVEL_2 ); + } + + /** [EMAIL PROTECTED] */ + public void section3() + { + onSection( SECTION_LEVEL_3 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle3() + { + onSectionTitle( SECTION_LEVEL_3 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle3_() + { + onSectionTitle_( SECTION_LEVEL_3 ); + } + + /** [EMAIL PROTECTED] */ + public void section3_() + { + onSection_( SECTION_LEVEL_3 ); + } + + /** [EMAIL PROTECTED] */ + public void section4() + { + onSection( SECTION_LEVEL_4 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle4() + { + onSectionTitle( SECTION_LEVEL_4 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle4_() + { + onSectionTitle_( SECTION_LEVEL_4 ); + } + + /** [EMAIL PROTECTED] */ + public void section4_() + { + onSection_( SECTION_LEVEL_4 ); + } + + /** [EMAIL PROTECTED] */ + public void section5() + { + onSection( SECTION_LEVEL_5 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle5() + { + onSectionTitle( SECTION_LEVEL_5 ); + } + + /** [EMAIL PROTECTED] */ + public void sectionTitle5_() + { + onSectionTitle_( SECTION_LEVEL_5 ); + } + + /** [EMAIL PROTECTED] */ + public void section5_() + { + onSection_( SECTION_LEVEL_5 ); + } + + /** + * Starts a section. The default class style is <code>section</code>. + * + * @param depth The level of the section. + * @see javax.swing.text.html.HTML.Tag#DIV + */ + protected void onSection( int depth ) + { + if ( depth >= SECTION_LEVEL_1 && depth <= SECTION_LEVEL_5 ) + { + MutableAttributeSet att = new SimpleAttributeSet(); + att.addAttribute( Attribute.CLASS, "section" ); + + writeStartTag( Tag.DIV, att ); + } + } + + /** + * Ends a section. + * + * @param depth The level of the section. + * @see javax.swing.text.html.HTML.Tag#DIV + */ + protected void onSection_( int depth ) + { + if ( depth >= SECTION_LEVEL_1 && depth <= SECTION_LEVEL_5 ) + { + writeEndTag( Tag.DIV ); + } + } + + /** + * Starts a section title. + * + * @param depth The level of the section title. + * @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 ) + { + if ( depth == SECTION_LEVEL_1 ) + { + writeStartTag( Tag.H2 ); + } + else if ( depth == SECTION_LEVEL_2 ) + { + writeStartTag( Tag.H3 ); + } + else if ( depth == SECTION_LEVEL_3 ) + { + writeStartTag( Tag.H4 ); + } + else if ( depth == SECTION_LEVEL_4 ) + { + writeStartTag( Tag.H5 ); + } + else if ( depth == SECTION_LEVEL_5 ) + { + writeStartTag( Tag.H6 ); + } + } + + /** + * Ends a section title. + * + * @param depth The level of the section title. + * @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 ) + { + if ( depth == SECTION_LEVEL_1 ) + { + writeEndTag( Tag.H2 ); + } + else if ( depth == SECTION_LEVEL_2 ) + { + writeEndTag( Tag.H3 ); + } + else if ( depth == SECTION_LEVEL_3 ) + { + writeEndTag( Tag.H4 ); + } + else if ( depth == SECTION_LEVEL_4 ) + { + writeEndTag( Tag.H5 ); + } + else if ( depth == SECTION_LEVEL_5 ) + { + writeEndTag( Tag.H6 ); + } + } + + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#UL + */ + public void list() + { + writeStartTag( Tag.UL ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#UL + */ + public void list_() + { + writeEndTag( Tag.UL ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#LI + */ + public void listItem() + { + writeStartTag( Tag.LI ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#LI + */ + public void listItem_() + { + writeEndTag( Tag.LI ); + } + + /** + * The default list style depends on the numbering. + * + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#OL + */ + public void numberedList( int numbering ) + { + String style; + switch ( numbering ) + { + case NUMBERING_UPPER_ALPHA: + style = "upper-alpha"; + break; + case NUMBERING_LOWER_ALPHA: + style = "lower-alpha"; + break; + case NUMBERING_UPPER_ROMAN: + style = "upper-roman"; + break; + case NUMBERING_LOWER_ROMAN: + style = "lower-roman"; + break; + case NUMBERING_DECIMAL: + default: + style = "decimal"; + } + + MutableAttributeSet att = new SimpleAttributeSet(); + att.addAttribute( Attribute.STYLE, "list-style-type: " + style ); + + writeStartTag( Tag.OL, att ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#OL + */ + public void numberedList_() + { + writeEndTag( Tag.OL ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#LI + */ + public void numberedListItem() + { + writeStartTag( Tag.LI ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#LI + */ + public void numberedListItem_() + { + writeEndTag( Tag.LI ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DL + */ + public void definitionList() + { + writeStartTag( Tag.DL ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DL + */ + public void definitionList_() + { + writeEndTag( Tag.DL ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DT + */ + public void definedTerm() + { + writeStartTag( Tag.DT ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DT + */ + public void definedTerm_() + { + writeEndTag( Tag.DT ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DD + */ + public void definition() + { + writeStartTag( Tag.DD ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DD + */ + public void definition_() + { + writeEndTag( Tag.DD ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#IMG + */ + public void figure() + { + write( String.valueOf( LESS_THAN ) + Tag.IMG ); + } + + /** [EMAIL PROTECTED] */ + public void figure_() + { + write( String.valueOf( SPACE ) + String.valueOf( SLASH ) + String.valueOf( GREATER_THAN ) ); + } + + /** [EMAIL PROTECTED] */ + public void figureGraphics( String name ) + { + write( String.valueOf( SPACE ) + Attribute.SRC + String.valueOf( EQUAL ) + String.valueOf( QUOTE ) + name + + String.valueOf( QUOTE ) ); + } + + /** [EMAIL PROTECTED] */ + public void figureCaption() + { + write( String.valueOf( SPACE ) + Attribute.ALT + String.valueOf( EQUAL ) + String.valueOf( QUOTE ) ); + } + + /** [EMAIL PROTECTED] */ + public void figureCaption_() + { + write( String.valueOf( QUOTE ) ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#P + */ + public void paragraph() + { + writeStartTag( Tag.P ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#P + */ + public void paragraph_() + { + writeEndTag( Tag.P ); + } + + /** + * The default class style for boxed is <code>source</code>. + * + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DIV + * @see javax.swing.text.html.HTML.Tag#PRE + */ + public void verbatim( boolean boxed ) + { + verbatimFlag = true; + + MutableAttributeSet att = new SimpleAttributeSet(); + + if ( boxed ) + { + att.addAttribute( Attribute.CLASS, "source" ); + } + + writeStartTag( Tag.DIV, att ); + writeStartTag( Tag.PRE ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#DIV + * @see javax.swing.text.html.HTML.Tag#PRE + */ + public void verbatim_() + { + writeEndTag( Tag.PRE ); + writeEndTag( Tag.DIV ); + + verbatimFlag = false; + + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#HR + */ + public void horizontalRule() + { + writeSimpleTag( Tag.HR ); + } + + /** [EMAIL PROTECTED] */ + public void table() + { + // start table with tableRows + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#TABLE + */ + public void table_() + { + writeEndTag( Tag.TABLE ); + } + + /** + * The default class style is <code>bodyTable</code>. + * The default align is <code>center</code>. + * + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#TABLE + */ + public void tableRows( int[] justification, boolean grid ) + { + this.cellJustif = justification; + + MutableAttributeSet att = new SimpleAttributeSet(); + att.addAttribute( Attribute.ALIGN, "center" ); + att.addAttribute( Attribute.BORDER, ( grid ? "1" : "0" ) ); + att.addAttribute( Attribute.CLASS, "bodyTable" ); + + writeStartTag( Tag.TABLE, att ); + } + + /** [EMAIL PROTECTED] */ + public void tableRows_() + { + this.cellJustif = null; + + this.evenTableRow = true; + } + + /** + * The default class style is <code>a</code> or <code>b</code> depending the row id. + * + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#TR + */ + public void tableRow() + { + MutableAttributeSet att = new SimpleAttributeSet(); + + if ( evenTableRow ) + { + att.addAttribute( Attribute.CLASS, "a" ); + } + else + { + att.addAttribute( Attribute.CLASS, "b" ); + } + + writeStartTag( Tag.TR, att ); + + evenTableRow = !evenTableRow; + + cellCount = 0; + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#TR + */ + public void tableRow_() + { + writeEndTag( Tag.TR ); + + cellCount = 0; + } + + /** [EMAIL PROTECTED] */ + public void tableCell() + { + tableCell( false ); + } + + /** [EMAIL PROTECTED] */ + public void tableHeaderCell() + { + tableCell( true ); + } + + /** + * 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 ) + { + tableCell( headerRow, null ); + } + + /** [EMAIL PROTECTED] */ + public void tableCell( String width ) + { + tableCell( false, width ); + } + + /** [EMAIL PROTECTED] */ + public void tableHeaderCell( String width ) + { + tableCell( true, width ); + } + + /** + * @param headerRow true if it is an header row + * @param width the cell size + * @see javax.swing.text.html.HTML.Tag#TH + * @see javax.swing.text.html.HTML.Tag#TD + */ + public void tableCell( boolean headerRow, String width ) + { + String justif = null; + + if ( cellJustif != null ) + { + switch ( cellJustif[cellCount] ) + { + case Parser.JUSTIFY_LEFT: + justif = "left"; + break; + case Parser.JUSTIFY_RIGHT: + justif = "right"; + break; + case Parser.JUSTIFY_CENTER: + default: + justif = "center"; + break; + } + } + + + Tag t = ( headerRow ? Tag.TH : Tag.TD ); + + MutableAttributeSet att = new SimpleAttributeSet(); + + if ( width != null ) + { + att.addAttribute( Attribute.WIDTH, width ); + } + + if ( justif != null ) + { + att.addAttribute( Attribute.ALIGN, justif ); + } + + writeStartTag( t, att ); + } + + /** [EMAIL PROTECTED] */ + public void tableCell_() + { + tableCell_( false ); + } + + /** [EMAIL PROTECTED] */ + public void tableHeaderCell_() + { + tableCell_( true ); + } + + /** + * Ends 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 ) + { + Tag t = ( headerRow ? Tag.TH : Tag.TD ); + + writeEndTag( t ); + + ++cellCount; + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#CAPTION + */ + public void tableCaption() + { + // TODO: tableCaption should be written before tableRows + writeStartTag( Tag.CAPTION ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#CAPTION + */ + public void tableCaption_() + { + writeEndTag( Tag.CAPTION ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#A + */ + public void anchor( String name ) + { + if ( !headFlag ) + { + String id = HtmlTools.encodeId( name ); + + MutableAttributeSet att = new SimpleAttributeSet(); + + if ( id != null ) + { + att.addAttribute( Attribute.NAME, id ); + } + + writeStartTag( Tag.A, att ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#A + */ + public void anchor_() + { + if ( !headFlag ) + { + writeEndTag( Tag.A ); + } + } + + /** [EMAIL PROTECTED] */ + public void link( String name ) + { + link( name, null ); + } + + /** + * Adds a link with an optional target. + * The default style class for external link is <code>externalLink</code>. + * + * @param name the link name. + * @param target the link target, may be null. + * @see javax.swing.text.html.HTML.Tag#A + */ + public void link( String name, String target ) + { + if ( headFlag ) + { + return; + } + + MutableAttributeSet att = new SimpleAttributeSet(); + + if ( target != null ) + { + att.addAttribute( Attribute.TARGET, target ); + } + + if ( StructureSink.isExternalLink( name ) || isExternalHtml( name ) ) + { + if ( isExternalLink( name ) ) + { + att.addAttribute( Attribute.CLASS, "externalLink" ); + } + + att.addAttribute( Attribute.HREF, HtmlTools.escapeHTML( name ) ); + } + else + { + att.addAttribute( Attribute.HREF, "#" + HtmlTools.escapeHTML( name ) ); + } + + writeStartTag( Tag.A, att ); + } + + /** + * [EMAIL PROTECTED] StructureSink#isExternalLink(String)} also treats links to other documents as + * external links, those should not have a class="externalLink" attribute. + */ + private boolean isExternalLink( String href ) + { + String text = href.toLowerCase(); + return ( text.indexOf( "http:/" ) == 0 || text.indexOf( "https:/" ) == 0 + || text.indexOf( "ftp:/" ) == 0 || text.indexOf( "mailto:" ) == 0 + || text.indexOf( "file:/" ) == 0 ); + + } + + /** + * Legacy: treat links to other html documents as external links. + * 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 ) + { + String text = href.toLowerCase(); + return ( text.indexOf( ".html#" ) != -1 || text.indexOf( ".htm#" ) != -1 + || text.endsWith( ".htm" ) || text.endsWith( ".html" ) + || !HtmlTools.isId( text ) ); + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#A + */ + public void link_() + { + if ( !headFlag ) + { + writeEndTag( Tag.A ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#I + */ + public void italic() + { + if ( !headFlag ) + { + writeStartTag( Tag.I ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#I + */ + public void italic_() + { + if ( !headFlag ) + { + writeEndTag( Tag.I ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#B + */ + public void bold() + { + if ( !headFlag ) + { + writeStartTag( Tag.B ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#B + */ + public void bold_() + { + if ( !headFlag ) + { + writeEndTag( Tag.B ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#TT + */ + public void monospaced() + { + if ( !headFlag ) + { + writeStartTag( Tag.TT ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#TT + */ + public void monospaced_() + { + if ( !headFlag ) + { + writeEndTag( Tag.TT ); + } + } + + /** + * [EMAIL PROTECTED] + * @see javax.swing.text.html.HTML.Tag#BR + */ + public void lineBreak() + { + if ( headFlag ) + { + getBuffer().append( EOL ); + } + else + { + writeSimpleTag( Tag.BR ); + } + } + + /** [EMAIL PROTECTED] */ + public void pageBreak() + { + comment( "PB" ); + } + + /** [EMAIL PROTECTED] */ + public void nonBreakingSpace() + { + if ( headFlag ) + { + getBuffer().append( ' ' ); + } + else + { + write( " " ); + } + } + + /** [EMAIL PROTECTED] */ + public void text( String text ) + { + if ( headFlag ) + { + getBuffer().append( text ); + } + else if ( verbatimFlag ) + { + verbatimContent( text ); + } + else + { + content( text ); + } + } + + /** [EMAIL PROTECTED] */ + public void rawText( String text ) + { + write( text ); + } + + /** [EMAIL PROTECTED] */ + public void comment( String comment ) + { + StringBuffer buf = new StringBuffer( comment.length() + 9 ); + + buf.append( LESS_THAN ).append( BANG ).append( MINUS ).append( MINUS ).append( SPACE ); + + buf.append( comment ); + + buf.append( SPACE ).append( MINUS ).append( MINUS ).append( GREATER_THAN ); + + rawText( buf.toString() ); + } + + /** [EMAIL PROTECTED] */ + public void flush() + { + writer.flush(); + } + + /** [EMAIL PROTECTED] */ + public void close() + { + writer.close(); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + + /** + * Write HTML escaped text to output. + * + * @param text The text to write. + */ + protected void content( String text ) + { + write( escapeHTML( text ) ); + } + + /** + * Write HTML escaped text to output. + * + * @param text The text to write. + */ + protected void verbatimContent( String text ) + { + write( escapeHTML( text ) ); + } + + /** + * Forward to HtmlTools.escapeHTML( text ). + * + * @param text the String to escape, may be null + * @return the text escaped, "" if null String input + * @see org.apache.maven.doxia.util.HtmlTools#escapeHTML(String) + */ + public static String escapeHTML( String text ) + { + return HtmlTools.escapeHTML( text ); + } + + /** + * @param text + * @return a fragment encoded + * @see #encodeURL(String) + */ + public static String encodeFragment( String text ) + { + return encodeURL( StructureSink.linkToKey( text ) ); + } + + /** + * Forward to HtmlTools.encodeURL( text ). + * + * @param text the String to encode, may be null. + * @return the text encoded, null if null String input. + * @see org.apache.maven.doxia.util.HtmlTools#encodeURL(String) + */ + public static String encodeURL( String text ) + { + return HtmlTools.encodeURL( text ); + } + + /** [EMAIL PROTECTED] */ + protected void write( String text ) + { + writer.write( text ); + } + +} Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/doxia/doxia/trunk/doxia-core/src/main/java/org/apache/maven/doxia/sink/XhtmlBaseSink.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision"