<?xml version="1.0" encoding="UTF-8"?>

<!--
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.
-->

<document>
  <properties>
    <title>Doxia FO Module - Usage</title>
    <author email="ltheussl@apache.org">Lukas Theussl</author>
  </properties>

  <body>
    <section name="Usage">

    <macro name="toc">
      <param name="section" value="1"/>
      <param name="fromDepth" value="1"/>
      <param name="toDepth" value="1"/>
    </macro>

    <subsection name="Converting single documents">

      <p>
        Here's an example that converts a single apt input file into a fo document.
        To produce a pdf from the result using Apache FOP, see eg
        <a href="http://xmlgraphics.apache.org/fop/0.93/embedding.html#ExampleFO2PDF">ExampleFO2PDF</a>.
      </p>

      <source>
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.maven.doxia.module.apt.AptParser;
import org.apache.maven.doxia.module.fo.FoSink;
import org.apache.maven.doxia.module.fo.FoSinkFactory;
import org.apache.maven.doxia.parser.ParseException;


public class Apt2FO
{
    public static void main(String[] args)
    {
        try
        {
            // Open input apt document:
            FileReader source = new FileReader(
                new File( "resources", "test.apt" ) );

            // Create FO sink:
            OutputStream out = new FileOutputStream(
                new File( "output", "test.fo" ) );
            FoSinkFactory factory = new FoSinkFactory();
            FoSink fosink = (FoSink) factory.createSink( out );

            // parse apt to fo:
            fosink.beginDocument();
            AptParser parser = new AptParser();
            parser.parse( source, fosink );
            fosink.endDocument();

            // close streams
            fosink.close();
            source.close();
        }
        catch ( ParseException e )
        {
            e.printStackTrace();
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
    }
}</source>

    </subsection>

    <subsection name="Converting multiple documents">

      <p>
        If you want to parse several source documents into a single fo file,
        so you can generate a single pdf from multiple source files, you should
        use the FoAggregateSink. A simple example is outlined below,
        refer to the <a href="apidocs/index.html">API docs</a> for more information.
      </p>

      <source>
    AptParser parser = new AptParser();

    FoAggregateSink fosink = new FoAggregateSink(
        new FileWriter( new File( "out", "aggregate.fo" ) ) );

    // getDocumentModel() should return a DocumentModel object
    fosink.setDocumentModel( getDocumentModel()  );

    fosink.beginDocument();

    fosink.coverPage();

    fosink.toc();

    // first document
    FileReader source1 =
        new FileReader( new File( "resources", "test1.apt" ) );
    fosink.setDocumentName( "doc1" );
    fosink.setDocumentTitle( "Document 1" );
    parser.parse( source1, fosink );

    // second document
    FileReader source2 =
        new FileReader( new File( "resources", "test2.apt" ) );
    fosink.setDocumentName( "doc2" );
    fosink.setDocumentTitle( "Document 2" );
    parser.parse( source2, fosink );

    fosink.endDocument();</source>

    </subsection>

    <subsection name="Embedded use">

      <p>
        To compile and run the following example,
        you need the following dependencies on your classpath
        (tested versions in parentheses).<br/>
        Compile:
        <code>doxia-core (1.1.4)</code>, <code>doxia-module-fo (1.1.1)</code>,
        <code>doxia-sink-api (1.1.4)</code>, <code>doxia-logging-api (1.1.4)</code>.<br/>
        Run:
        <code>commons-configuration (1.10)</code>, <code>commons-lang (2.6)</code>,
        <code>plexus-utils (2.0.5)</code>, <code>commons-collections (3.2.1)</code>,
        <code>commons-logging (1.1.1)</code>.
      </p>

      <source>import java.io.File;
import java.io.IOException;

import org.apache.maven.doxia.module.fo.FoSinkFactory;
import org.apache.maven.doxia.sink.Sink;

public class TestPDF
{
    public static void main( String[] args )
    {
        FoSink sink = null;

        try
        {
            sink = (FoSink) new FoSinkFactory()
                .createSink( new File( "." ), "test.fo" );

            sink.beginDocument();
            populateSink( sink );
            sink.endDocument();
        }
        catch ( IOException ex )
        {
            ex.printStackTrace();
        }
        finally
        {
            if ( sink != null )
            {
                sink.close();
            }
        }
    }

    private static void populateSink( Sink sink )
    {
        sink.head();
        sink.title();
        sink.text( "Title" );
        sink.title_();
        sink.author();
        sink.text( "Author" );
        sink.author_();
        sink.date();
        sink.text( "Date" );
        sink.date_();
        sink.head_();
        sink.body();
        sink.paragraph();
        sink.text( "Hello world!" );
        sink.paragraph_();
        sink.body_();
    }
}</source>
    </subsection>


    </section>

  </body>
</document>