| package org.apache.maven.doxia.module.fo; |
| |
| /* |
| * 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.File; |
| import java.io.StringReader; |
| import java.io.Writer; |
| |
| import org.apache.maven.doxia.document.DocumentMeta; |
| import org.apache.maven.doxia.document.DocumentModel; |
| import org.apache.maven.doxia.document.DocumentTOC; |
| import org.apache.maven.doxia.document.DocumentTOCItem; |
| import org.apache.maven.doxia.parser.XhtmlBaseParser; |
| import org.apache.maven.doxia.sink.Sink; |
| import org.apache.maven.doxia.sink.impl.AbstractSinkTest; |
| import org.apache.maven.doxia.sink.impl.SinkTestDocument; |
| |
| import static org.apache.maven.doxia.util.HtmlTools.escapeHTML; |
| |
| /** |
| * <code>FO Sink</code> Test case. |
| * |
| * @version $Id$ |
| */ |
| public class FoSinkTest |
| extends AbstractSinkTest |
| { |
| private FoConfiguration config; |
| |
| // ---------------------------------------------------------------------- |
| // Specific test methods |
| // ---------------------------------------------------------------------- |
| |
| @Override |
| protected String wrapXml( String xmlFragment ) |
| { |
| return "<fo:fo xmlns:fo=\"" + FoMarkup.FO_NAMESPACE + "\">" + xmlFragment + "</fo:fo>"; |
| } |
| |
| /** |
| * Uses fop to generate a pdf from a test document. |
| * @throws Exception If the conversion fails. |
| */ |
| public void testConvertFO2PDF() |
| throws Exception |
| { |
| String fileName = "test"; |
| // first create fo |
| FoSink fosink = new FoSink( getTestWriter( fileName ) ); |
| fosink.beginDocument(); |
| SinkTestDocument.generate( fosink ); |
| fosink.endDocument(); |
| fosink.close(); |
| |
| // then generate PDF |
| fo2pdf( fileName ); |
| } |
| |
| /** |
| * Uses fop to generate an aggregated pdf from two test documents. |
| * @throws Exception If the conversion fails. |
| */ |
| public void testAggregateMode() |
| throws Exception |
| { |
| FoAggregateSink fosink = new FoAggregateSink( getTestWriter( "aggregate" ) ); |
| |
| fosink.setDocumentModel( getModel() ); |
| |
| fosink.beginDocument(); |
| |
| fosink.coverPage(); |
| |
| fosink.toc(); |
| |
| fosink.setDocumentName( "doc1" ); |
| fosink.setDocumentTitle( "Document 1" ); |
| SinkTestDocument.generate( fosink ); |
| |
| // re-use the same source |
| fosink.setDocumentName( "doc2" ); |
| fosink.setDocumentTitle( "Document 2" ); |
| SinkTestDocument.generate( fosink ); |
| |
| fosink.endDocument(); |
| |
| // then generate PDF |
| fo2pdf( "aggregate" ); |
| } |
| |
| private DocumentModel getModel() |
| { |
| DocumentModel model = new DocumentModel(); |
| model.setToc( getToc() ); |
| model.setMeta( getMeta() ); |
| return model; |
| } |
| |
| private DocumentMeta getMeta() |
| { |
| DocumentMeta meta = new DocumentMeta(); |
| meta.setAuthor( "The Apache Maven Project" ); |
| meta.setTitle( "Doxia FO Sink" ); |
| return meta; |
| } |
| |
| private DocumentTOC getToc() |
| { |
| DocumentTOCItem item1 = new DocumentTOCItem(); |
| item1.setName( "First document" ); |
| item1.setRef( "doc1.apt" ); |
| |
| DocumentTOCItem item2 = new DocumentTOCItem(); |
| item2.setName( "Second document" ); |
| item2.setRef( "doc2.xml" ); |
| |
| DocumentTOC toc = new DocumentTOC(); |
| toc.setName( "What's in here" ); |
| toc.addItem( item1 ); |
| toc.addItem( item2 ); |
| |
| return toc; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Abstract methods the individual SinkTests must provide |
| // ---------------------------------------------------------------------- |
| |
| /** {@inheritDoc} */ |
| protected String outputExtension() |
| { |
| return "fo"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected Sink createSink( Writer writer ) |
| { |
| return new FoSink( writer ); |
| } |
| |
| /** {@inheritDoc} */ |
| protected boolean isXmlSink() |
| { |
| return true; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getTitleBlock( String title ) |
| { |
| String attribs = getConfig().getAttributeString( "doc.header.title" ); |
| return EOL + "<fo:block" + attribs + ">" + title + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getAuthorBlock( String author ) |
| { |
| String attribs = getConfig().getAttributeString( "doc.header.author" ); |
| return EOL + "<fo:block" + attribs + ">" + author + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getDateBlock( String date ) |
| { |
| String attribs = getConfig().getAttributeString( "doc.header.date" ); |
| return EOL + "<fo:block" + attribs + ">" + date + "</fo:block>" + EOL; |
| } |
| |
| // TODO |
| protected String getHeadBlock() |
| { |
| return ""; |
| } |
| |
| // TODO: remove |
| public void testHead() |
| { |
| String expected = ""; |
| assertEquals( "Wrong head!", expected, getHeadBlock() ); |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getBodyBlock() |
| { |
| return EOL + "</fo:flow>" + EOL + "</fo:page-sequence>" + EOL + "</fo:root>" + EOL; |
| } |
| |
| protected String getArticleBlock() |
| { |
| return ""; |
| } |
| |
| protected String getNavigationBlock() |
| { |
| return ""; |
| } |
| |
| protected String getSidebarBlock() |
| { |
| return ""; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getSectionTitleBlock( String title ) |
| { |
| return title; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getSection1Block( String title ) |
| { |
| String attribs = getConfig().getAttributeString( "body.text" ); |
| String attrib2 = getConfig().getAttributeString( "body.h1" ); |
| return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">1 " + title |
| + "</fo:block>" + EOL + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getSection2Block( String title ) |
| { |
| String attribs = getConfig().getAttributeString( "body.text" ); |
| String attrib2 = getConfig().getAttributeString( "body.h2" ); |
| return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">0.1 " + title |
| + "</fo:block>" + EOL + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getSection3Block( String title ) |
| { |
| String attribs = getConfig().getAttributeString( "body.text" ); |
| String attrib2 = getConfig().getAttributeString( "body.h3" ); |
| return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">0.0.1 " + title |
| + "</fo:block>" + EOL + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getSection4Block( String title ) |
| { |
| String attribs = getConfig().getAttributeString( "body.text" ); |
| String attrib2 = getConfig().getAttributeString( "body.h4" ); |
| return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">" + title |
| + "</fo:block>" + EOL + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getSection5Block( String title ) |
| { |
| String attribs = getConfig().getAttributeString( "body.text" ); |
| String attrib2 = getConfig().getAttributeString( "body.h5" ); |
| return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">" + title |
| + "</fo:block>" + EOL + "</fo:block>" + EOL; |
| } |
| |
| protected String getHeaderBlock() |
| { |
| return ""; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getContentBlock() |
| { |
| return ""; |
| } |
| |
| protected String getFooterBlock() |
| { |
| return ""; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getListBlock( String item ) |
| { |
| String attribs = getConfig().getAttributeString( "list" ); |
| String itemAttribs = getConfig().getAttributeString( "list.item" ); |
| return EOL + EOL + "<fo:list-block" + attribs + ">" + EOL + "<fo:list-item" + itemAttribs |
| + "><fo:list-item-label><fo:block>•</fo:block></fo:list-item-label>" + EOL + EOL |
| + "<fo:list-item-body" + itemAttribs + ">" + EOL + "<fo:block>" + item + "</fo:block>" + EOL |
| + "</fo:list-item-body>" + EOL + "</fo:list-item>" + EOL + "</fo:list-block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getNumberedListBlock( String item ) |
| { |
| String attribs = getConfig().getAttributeString( "list" ); |
| String itemAttribs = getConfig().getAttributeString( "list.item" ); |
| return EOL + EOL + "<fo:list-block" + attribs + ">" + EOL + "<fo:list-item" + itemAttribs + ">" + EOL |
| + "<fo:list-item-label>" + EOL + "<fo:block>i.</fo:block>" + EOL + "</fo:list-item-label>" + EOL + EOL |
| + "<fo:list-item-body" + itemAttribs + ">" + EOL + "<fo:block>" + item + "</fo:block>" + EOL |
| + "</fo:list-item-body>" + EOL + "</fo:list-item>" + EOL + "</fo:list-block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getDefinitionListBlock( String definum, String definition ) |
| { |
| String dlAtts = getConfig().getAttributeString( "dl" ); |
| String dtAtts = getConfig().getAttributeString( "dt" ); |
| String ddAtts = getConfig().getAttributeString( "dd" ); |
| return EOL + EOL + "<fo:block" + dlAtts + ">" + EOL + "<fo:block" + dtAtts + ">" + definum + "</fo:block>" |
| + EOL + EOL + EOL + "<fo:block" + ddAtts + ">" + definition + "</fo:block>" + EOL + "</fo:block>" |
| + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getFigureBlock( String source, String caption ) |
| { |
| String dlAtts = getConfig().getAttributeString( "figure.display" ); |
| String dtAtts = getConfig().getAttributeString( "figure.graphics" ); |
| String ddAtts = getConfig().getAttributeString( "figure.caption" ); |
| |
| String figureBlock = EOL + EOL + "<fo:block" + dlAtts + ">" + |
| "<fo:external-graphic" + " src=\"" + escapeHTML( source ) + "\"" + dtAtts + "/>" + EOL; |
| if ( caption != null ) |
| { |
| figureBlock += EOL + "<fo:block" + ddAtts + ">" + caption + "</fo:block>" + EOL; |
| } |
| figureBlock += "</fo:block>" + EOL; |
| |
| |
| return figureBlock; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getTableBlock( String cell, String caption ) |
| { |
| String dlAtts = getConfig().getAttributeString( "table.padding" ); |
| String dtAtts = getConfig().getAttributeString( "table.layout" ); |
| String ddAtts = getConfig().getAttributeString( "table.body.row" ); |
| // String deAtts = getConfig().getAttributeString( "table.body.cell" ); |
| |
| return EOL + EOL + "<fo:block" + dlAtts + ">" + EOL + "<fo:table" + dtAtts + ">" + EOL |
| + "<fo:table-column column-width=\"proportional-column-width(1)\"/>" + EOL + EOL + "<fo:table-body>" |
| + EOL + "<fo:table-row" + ddAtts |
| + "><fo:table-cell column-number=\"1\" padding-after=\"1.5pt\" padding-end=\"5pt\" " |
| + "keep-together.within-column=\"always\" padding-start=\"2.5pt\" " |
| + "background-color=\"#eeeeee\" padding-before=\"4pt\">" + EOL + "<fo:block line-height=\"1.2em\" " |
| + "text-align=\"center\" font-family=\"Helvetica,sans-serif\" font-size=\"9pt\">" + EOL + cell |
| + "</fo:block>" + EOL + "</fo:table-cell>" + EOL + "</fo:table-row>" + EOL + "</fo:table-body>" + EOL |
| + "</fo:table>" + EOL + "</fo:block>" + EOL + EOL |
| + "<fo:block white-space-collapse=\"true\" space-after=\"6pt\" space-before=\"3pt\" " |
| + "font-family=\"Garamond,serif\" line-height=\"12pt\" text-align=\"center\" font-size=\"11pt\">" |
| + "Table_caption</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getParagraphBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "normal.paragraph" ); |
| return EOL + "<fo:block" + attribs + ">" + text + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getDataBlock( String value, String text ) |
| { |
| return text; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getTimeBlock( String datetime, String text ) |
| { |
| return text; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getAddressBlock( String text ) |
| { |
| return text; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getBlockquoteBlock( String text ) |
| { |
| return text; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getDivisionBlock( String text ) |
| { |
| return text; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getVerbatimBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "body.source" ); |
| return EOL + "<fo:block" + attribs + ">" + text + "</fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getHorizontalRuleBlock() |
| { |
| String attribs = getConfig().getAttributeString( "body.rule" ); |
| return EOL + EOL + "<fo:block>" + EOL + "<fo:leader" + attribs + " /></fo:block>" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getPageBreakBlock() |
| { |
| return EOL + "<fo:block break-before=\"page\" />" + EOL; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getAnchorBlock( String anchor ) |
| { |
| // all anchors get '#' pre-pended |
| return EOL + "<fo:inline id=\"#" + anchor + "\">" + anchor + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getLinkBlock( String link, String text ) |
| { |
| String attribs = getConfig().getAttributeString( "href.internal" ); |
| return EOL + "<fo:basic-link internal-destination=\"" + link + "\">" + EOL + "<fo:inline" + attribs + ">" |
| + text + "</fo:inline></fo:basic-link>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getInlineBlock( String text ) |
| { |
| return text; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getInlineItalicBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "italic" ); |
| return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getInlineBoldBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "bold" ); |
| return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getInlineCodeBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "monospace" ); |
| return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getItalicBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "italic" ); |
| return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getBoldBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "bold" ); |
| return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getMonospacedBlock( String text ) |
| { |
| String attribs = getConfig().getAttributeString( "monospace" ); |
| return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getLineBreakBlock() |
| { |
| return EOL + EOL + "<fo:block />"; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getLineBreakOpportunityBlock() |
| { |
| return ""; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getNonBreakingSpaceBlock() |
| { |
| return " "; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getTextBlock( String text ) |
| { |
| return FoSink.escaped( text, false ); |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getRawTextBlock( String text ) |
| { |
| return text; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Auxiliary methods |
| // ---------------------------------------------------------------------- |
| |
| private void fo2pdf( String baseName ) |
| throws Exception |
| { |
| // File outputDirectory = new File( getBasedirFile(), getOutputDir() ); |
| File outputDirectory = new File( getBasedir(), outputBaseDir() + getOutputDir() ); |
| File resourceDirectory = new File( getBasedirFile(), "target/test-classes" ); |
| File foFile = new File( outputDirectory, baseName + "." + outputExtension() ); |
| File pdfFile = new File( outputDirectory, baseName + ".pdf" ); |
| FoUtils.convertFO2PDF( foFile, pdfFile, resourceDirectory.getCanonicalPath() ); |
| } |
| |
| private FoConfiguration getConfig() |
| { |
| if ( config == null ) |
| { |
| config = ( (FoSink) getSink() ).getFoConfiguration(); |
| } |
| |
| return config; |
| } |
| |
| /** {@inheritDoc} */ |
| protected String getCommentBlock( String text ) |
| { |
| return "<!--" + toXmlComment( text ) + "-->"; |
| } |
| |
| /** |
| * DOXIA-357 |
| * |
| * @throws Exception if any |
| */ |
| public void testTableCaption() |
| throws Exception |
| { |
| StringBuilder html = new StringBuilder(); |
| html.append( "<table>" ).append( EOL ); |
| html.append( "<caption>caption table</caption>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>foo</td>" ).append( EOL ); |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>bar</td>" ).append( EOL ); |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "</table>" ).append( EOL ); |
| |
| String fileName = "testTableCaption"; |
| |
| // first create fo |
| FoSink fosink = new FoSink( getTestWriter( fileName ) ); |
| fosink.beginDocument(); |
| SinkTestDocument.generateHead( fosink ); |
| |
| fosink.body(); |
| XhtmlBaseParser parser = new XhtmlBaseParser(); |
| parser.parse( new StringReader( html.toString() ), fosink ); |
| fosink.body_(); |
| |
| fosink.endDocument(); |
| fosink.close(); |
| |
| // then generate PDF |
| fo2pdf( fileName ); |
| } |
| |
| /** |
| * @throws Exception if any |
| */ |
| public void testNestedTables() |
| throws Exception |
| { |
| StringBuilder html = new StringBuilder(); |
| html.append( "<table>" ).append( EOL ); |
| html.append( "<caption>first caption</caption>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>foo</td>" ).append( EOL ); |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>" ).append( EOL ); |
| |
| html.append( "<table>" ).append( EOL ); |
| html.append( "<caption>second caption</caption>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>foo</td>" ).append( EOL ); |
| html.append( "<td>bar</td>" ).append( EOL ); |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>foo1</td>" ).append( EOL ); |
| html.append( "<td>" ).append( EOL ); |
| |
| html.append( "<table>" ).append( EOL ); |
| html.append( "<caption>third caption</caption>" ).append( EOL ); |
| html.append( "<tr>" ).append( EOL ); |
| html.append( "<td>foo1</td>" ).append( EOL ); |
| html.append( "<td>bar1</td>" ).append( EOL ); |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "</table>" ).append( EOL ); |
| html.append( "</td>" ).append( EOL ); |
| |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "</table>" ).append( EOL ); |
| |
| html.append( "</td>" ).append( EOL ); |
| html.append( "</tr>" ).append( EOL ); |
| html.append( "</table>" ).append( EOL ); |
| |
| String fileName = "testNestedTables"; |
| |
| // first create fo |
| FoSink fosink = new FoSink( getTestWriter( fileName ) ); |
| fosink.beginDocument(); |
| SinkTestDocument.generateHead( fosink ); |
| |
| fosink.body(); |
| XhtmlBaseParser parser = new XhtmlBaseParser(); |
| parser.parse( new StringReader( html.toString() ), fosink ); |
| fosink.body_(); |
| |
| fosink.endDocument(); |
| fosink.close(); |
| |
| // then generate PDF |
| fo2pdf( fileName ); |
| } |
| } |