package org.apache.maven.doxia.module.latex;

/*
 * 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 org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.AbstractTextSink;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.apache.maven.doxia.util.DoxiaUtils;
import org.apache.maven.doxia.util.LineBreaker;

import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Stack;

/**
 * Latex Sink implementation.
 * <br>
 * <b>Note</b>: The encoding used is UTF-8.
 *
 * @version $Id$
 * @since 1.0
 */
public class LatexSink
    extends AbstractTextSink
{
    /**
     * Flag that indicates if the document to be written is only a fragment.
     *
     * This implies that <code>\\begin{document}</code>, <code>\\title{..}</code> will not be output.
     */
    private final boolean fragmentDocument;

    private boolean ignoreText;

    private final LineBreaker out;

    private final String sinkCommands;

    private final String preamble;

    private boolean titleFlag;

    private int numberedListNesting;

    private boolean verbatimFlag;

    private boolean figureFlag;

    private boolean tableFlag;

    private boolean gridFlag;

    private int[] cellJustif;

    private int cellCount;

    private boolean isTitle;

    private String title;

    /** Keep track of the closing tags for inline events. */
    protected Stack<List<String>> inlineStack = new Stack<List<String>>();

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /**
     * Constructor, initialize the Writer and the variables.
     *
     * @param out not null writer to write the result. <b>Should</b> be an UTF-8 Writer.
     * You could use <code>newWriter</code> methods from {@link org.codehaus.plexus.util.WriterFactory}.
     */
    protected LatexSink( Writer out )
    {
        this( out, null, null );
    }

    /**
     * Constructor, initialize the Writer and the variables.
     *
     * @param out not null writer to write the result. <b>Should</b> be an UTF-8 Writer.
     * You could use <code>newWriter</code> methods from {@link org.codehaus.plexus.util.WriterFactory}.
     * @param sinkCommands A String representation of commands that go before \documentclass.
     * @param preamble A String representation of commands that go between \documentclass and \begin{document}.
     */
    protected LatexSink( Writer out, String sinkCommands, String preamble )
    {
        this( out, sinkCommands, preamble, false );
    }

    /**
     * Constructor, initialize the Writer and the variables.
     *
     * @param out not null writer to write the result. <b>Should</b> be an UTF-8 Writer.
     * You could use <code>newWriter</code> methods from {@link org.codehaus.plexus.util.WriterFactory}.
     * @param sinkCommands A String representation of commands that go before \documentclass.
     * @param preamble A String representation of commands that go between \documentclass and \begin{document}.
     * @param fragmentDocument If this receives events that that are only part of a document.
     * Typically, headers are omitted if this is true.
     */
    protected LatexSink( Writer out, String sinkCommands, String preamble, boolean fragmentDocument )
    {
        this.out = new LineBreaker( out );

        if ( sinkCommands == null )
        {
            sinkCommands = defaultSinkCommands();
        }
        if ( preamble == null )
        {
            preamble = defaultPreamble();
        }

        this.sinkCommands = sinkCommands;
        this.preamble = preamble;
        this.fragmentDocument = fragmentDocument;

        init();
    }

    // ----------------------------------------------------------------------
    // Overridables
    // ----------------------------------------------------------------------

    /**
     * Returns a default \documentclass declaration.
     *
     * @return String.
     */
    protected String getDocumentStart()
    {
        return "\\documentclass[a4paper]{article}" + EOL + EOL;
    }

    /**
     * Returns a default \begin{document} declaration.
     *
     * @return String.
     */
    protected String getDocumentBegin()
    {
        return "\\begin{document}" + EOL + EOL;
    }

    /**
     * Returns a default \end{document} declaration.
     *
     * @return String.
     */
    protected String getDocumentEnd()
    {
        return "\\end{document}" + EOL;
    }

    // ----------------------------------------------------------------------
    // Sink Implementation
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void head()
    {
        head( null );
    }

    /** {@inheritDoc} */
    public void head( SinkEventAttributes attributes )
    {
        init();

        if ( !fragmentDocument )
        {
            markup( sinkCommands );

            markup( getDocumentStart() );

            markup( preamble );

            markup( getDocumentBegin() );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void body()
    {
        body( null );
    }

    /** {@inheritDoc} */
    public void body( SinkEventAttributes attributes )
    {
        if ( titleFlag )
        {
            if ( fragmentDocument  )
            {
                markup( "\\section" );
            }
            else
            {
                titleFlag = false;
                markup( "\\maketitle" + EOL + EOL );
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void body_()
    {
        if ( !fragmentDocument )
        {
            markup( getDocumentEnd() );
        }

        flush();
    }

    /**
     * {@inheritDoc}
     */
    public void title()
    {
        title( null );
    }

    /** {@inheritDoc} */
    public void title( SinkEventAttributes attributes )
    {
        if ( !fragmentDocument )
        {
            titleFlag = true;
            markup( "\\title{" );
        }
        else
        {
            ignoreText = true;
        }
    }

    /**
     * {@inheritDoc}
     */
    public void title_()
    {
        if ( !fragmentDocument )
        {
            markup( "}" + EOL );
        }
        else
        {
            ignoreText = false;
        }
    }

    /**
     * {@inheritDoc}
     */
    public void author()
    {
        author( null );
    }

    /** {@inheritDoc} */
    public void author( SinkEventAttributes attributes )
    {
        if ( !fragmentDocument )
        {
            markup( "\\author{" );
        }
        else
        {
            ignoreText = true;
        }
    }

    /**
     * {@inheritDoc}
     */
    public void author_()
    {
        if ( !fragmentDocument )
        {
            markup( "}" + EOL );
        }
        else
        {
            ignoreText = false;
        }
    }

    /**
     * {@inheritDoc}
     */
    public void date()
    {
        date( null );
    }

    /** {@inheritDoc} */
    public void date( SinkEventAttributes attributes )
    {
        if ( !fragmentDocument )
        {
            markup( "\\date{" );
        }
        else
        {
            ignoreText = true;
        }
    }

    /**
     * {@inheritDoc}
     */
    public void date_()
    {
        if ( !fragmentDocument )
        {
            markup( "}" + EOL );
        }
        else
        {
            ignoreText = false;
        }
    }

    /** {@inheritDoc} */
    public void sectionTitle( int level, SinkEventAttributes attributes )
    {
        isTitle = true;
    }

    /** {@inheritDoc} */
    public void sectionTitle_( int level )
    {
        String command = "";
        switch ( level )
        {
            case SECTION_LEVEL_1:
                command = "section";
                break;
            case SECTION_LEVEL_2:
                command = "subsection";
                break;
            case SECTION_LEVEL_3:
                command = "subsubsection";
                break;
            case SECTION_LEVEL_4:
                command = "paragraph";
                break;
            case SECTION_LEVEL_5:
                command = "subparagraph";
                break;
            default:
                throw new IllegalArgumentException( "Not a section level: " + level );
        }

        isTitle = false;

        if ( StringUtils.isNotEmpty( title ) )
        {
            markup( EOL + "\\" + command + "{" + title + "}" + EOL );

            title = null;
        }
    }

    // ----------------------------------------------------------------------
    // Section Title 1
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void sectionTitle1()
    {
        sectionTitle( SECTION_LEVEL_1, null );
    }

    /**
     * {@inheritDoc}
     */
    public void sectionTitle1_()
    {
        sectionTitle_( SECTION_LEVEL_1 );
    }

    // ----------------------------------------------------------------------
    // Section Title 2
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void sectionTitle2()
    {
        sectionTitle( SECTION_LEVEL_2, null );
    }

    /**
     * {@inheritDoc}
     */
    public void sectionTitle2_()
    {
        sectionTitle_( SECTION_LEVEL_2 );
    }

    // ----------------------------------------------------------------------
    // Section Title 3
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void sectionTitle3()
    {
        sectionTitle( SECTION_LEVEL_3, null );
    }

    /**
     * {@inheritDoc}
     */
    public void sectionTitle3_()
    {
        sectionTitle_( SECTION_LEVEL_3 );
    }

    // ----------------------------------------------------------------------
    // Section Title 4
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void sectionTitle4()
    {
        sectionTitle( SECTION_LEVEL_4, null );
    }

    /**
     * {@inheritDoc}
     */
    public void sectionTitle4_()
    {
        sectionTitle_( SECTION_LEVEL_4 );
    }

    // ----------------------------------------------------------------------
    // Section Title 5
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void sectionTitle5()
    {
        sectionTitle( SECTION_LEVEL_5, null );
    }

    /**
     * {@inheritDoc}
     */
    public void sectionTitle5_()
    {
        sectionTitle_( SECTION_LEVEL_5 );
    }

    // ----------------------------------------------------------------------
    // List
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void list()
    {
        list( null );
    }

    /** {@inheritDoc} */
    public void list( SinkEventAttributes attributes )
    {
        markup( EOL + "\\begin{itemize}" );
    }

    /**
     * {@inheritDoc}
     */
    public void list_()
    {
        markup( EOL + "\\end{itemize}" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void listItem()
    {
        listItem( null );
    }

    /** {@inheritDoc} */
    public void listItem( SinkEventAttributes attributes )
    {
        markup( EOL + "\\item " );
    }

    /**
     * {@inheritDoc}
     */
    public void numberedList( int numbering )
    {
        numberedList( numbering, null );
    }

    /** {@inheritDoc} */
    public void numberedList( int numbering, SinkEventAttributes attributes )
    {
        ++numberedListNesting;

        String counter;
        switch ( numberedListNesting )
        {
            case 1:
                counter = "enumi";
                break;
            case 2:
                counter = "enumii";
                break;
            case 3:
                counter = "enumiii";
                break;
            case 4:
            default:
                counter = "enumiv";
        }

        String style;
        switch ( numbering )
        {
            case NUMBERING_UPPER_ALPHA:
                style = "Alph";
                break;
            case NUMBERING_LOWER_ALPHA:
                style = "alph";
                break;
            case NUMBERING_UPPER_ROMAN:
                style = "Roman";
                break;
            case NUMBERING_LOWER_ROMAN:
                style = "roman";
                break;
            case NUMBERING_DECIMAL:
            default:
                style = "arabic";
        }

        markup( EOL + "\\begin{enumerate}" + EOL );
        markup( "\\renewcommand{\\the" + counter + "}{\\" + style + "{" + counter + "}}" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void numberedList_()
    {
        markup( EOL + "\\end{enumerate}" + EOL );
        --numberedListNesting;
    }

    /**
     * {@inheritDoc}
     */
    public void numberedListItem()
    {
        numberedListItem( null );
    }

    /** {@inheritDoc} */
    public void numberedListItem( SinkEventAttributes attributes )
    {
        markup( "\\item " );
    }

    /**
     * {@inheritDoc}
     */
    public void definitionList()
    {
        definitionList( null );
    }

    /** {@inheritDoc} */
    public void definitionList( SinkEventAttributes attributes )
    {
        markup( EOL + "\\begin{description}" );
    }

    /**
     * {@inheritDoc}
     */
    public void definitionList_()
    {
        markup( EOL + "\\end{description}" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void definedTerm()
    {
        definedTerm( null );
    }

    /** {@inheritDoc} */
    public void definedTerm( SinkEventAttributes attributes )
    {
        markup( EOL + "\\item[\\mbox{" );
    }

    /**
     * {@inheritDoc}
     */
    public void definedTerm_()
    {
        markup( "}] " );
    }

    /** {@inheritDoc} */
    public void definitionListItem()
    {
        definitionListItem( null );
    }

    /** {@inheritDoc} */
    public void definitionListItem( SinkEventAttributes attributes )
    {
        // nop
    }

    /** {@inheritDoc} */
    public void definitionListItem_()
    {
        // nop
    }

    /** {@inheritDoc} */
    public void definition()
    {
        definition( null );
    }

    /** {@inheritDoc} */
    public void definition( SinkEventAttributes attributes )
    {
        // nop
    }

    /** {@inheritDoc} */
    public void definition_()
    {
        // nop
    }

    // ----------------------------------------------------------------------
    // Figure
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void figure()
    {
        figure( null );
    }

    /** {@inheritDoc} */
    public void figure( SinkEventAttributes attributes )
    {
        figureFlag = true;
        markup( EOL + "\\begin{figure}[htb]" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void figure_()
    {
        markup( "\\end{figure}" + EOL );
        figureFlag = false;
    }

    /**
     * {@inheritDoc}
     */
    public void figureGraphics( String name )
    {
        figureGraphics( name, null );
    }

    /** {@inheritDoc} */
    public void figureGraphics( String src, SinkEventAttributes attributes )
    {
        if ( !src.toLowerCase( Locale.ENGLISH ).endsWith( ".eps" ) )
        {
            getLog().warn( "[Latex Sink] Found non-eps figure graphics!" );
        }

        markup( "\\begin{center}" + EOL );
        markup( "\\includegraphics{" + src + "}" + EOL );
        markup( "\\end{center}" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void figureCaption()
    {
        figureCaption( null );
    }

    /** {@inheritDoc} */
    public void figureCaption( SinkEventAttributes attributes )
    {
        markup( "\\caption{" );
    }

    /**
     * {@inheritDoc}
     */
    public void figureCaption_()
    {
        markup( "}" + EOL );
    }

    // ----------------------------------------------------------------------
    // Table
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void table()
    {
        table( null );
    }

    /** {@inheritDoc} */
    public void table( SinkEventAttributes attributes )
    {
        tableFlag = true;
        markup( EOL + "\\begin{table}[htp]" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void table_()
    {
        markup( "\\end{table}" + EOL );
        tableFlag = false;
    }

    /**
     * {@inheritDoc}
     */
    public void tableRows( int[] justification, boolean grid )

    {
        StringBuilder justif = new StringBuilder();
        for ( int i = 0; i < justification.length; ++i )
        {
            if ( grid )
            {
                justif.append( '|' );
            }
            switch ( justification[i] )
            {
                case Sink.JUSTIFY_CENTER:
                    justif.append( 'c' );
                    break;
                case Sink.JUSTIFY_LEFT:
                    justif.append( 'l' );
                    break;
                case Sink.JUSTIFY_RIGHT:
                    justif.append( 'r' );
                    break;
                default:
                    break;
            }
        }
        if ( grid )
        {
            justif.append( '|' );
        }

        markup( "\\begin{center}" + EOL );
        markup( "\\begin{tabular}{" + justif.toString() + "}" + EOL );
        if ( grid )
        {
            markup( "\\hline" + EOL );
        }
        gridFlag = grid;
        cellJustif = justification;
    }

    /**
     * {@inheritDoc}
     */
    public void tableRows_()
    {
        markup( "\\end{tabular}" + EOL );
        markup( "\\end{center}" + EOL );

        gridFlag = false;
        cellJustif = null;
    }

    /**
     * {@inheritDoc}
     */
    public void tableRow()
    {
        tableRow( null );
    }

    /** {@inheritDoc} */
    public void tableRow( SinkEventAttributes attributes )
    {
        cellCount = 0;
    }

    /**
     * {@inheritDoc}
     */
    public void tableRow_()
    {
        markup( "\\\\" + EOL );
        if ( gridFlag || lastCellWasHeader )
        {
            markup( "\\hline" + EOL );
        }
        cellCount = 0;
        lastCellWasHeader = false;
    }

    /**
     * {@inheritDoc}
     */
    public void tableCell()
    {
        tableCell( (SinkEventAttributes) null );
    }

    /** {@inheritDoc} */
    public void tableCell( String width )
    {
        SinkEventAttributeSet att = new SinkEventAttributeSet();
        att.addAttribute( javax.swing.text.html.HTML.Attribute.WIDTH, width );

        tableCell( att );
    }

    /** {@inheritDoc} */
    public void tableCell( SinkEventAttributes attributes )
    {
        tableCell( false );
    }

    /**
     * {@inheritDoc}
     */
    public void tableCell_()
    {
        markup( "\\end{tabular}" );
        ++cellCount;
    }

    /**
     * {@inheritDoc}
     */
    public void tableHeaderCell()
    {
        tableCell( (SinkEventAttributes) null );
    }

    /** {@inheritDoc} */
    public void tableHeaderCell( String width )
    {
        SinkEventAttributeSet att = new SinkEventAttributeSet();
        att.addAttribute( javax.swing.text.html.HTML.Attribute.WIDTH, width );

        tableHeaderCell( att );
    }

    /** {@inheritDoc} */
    public void tableHeaderCell( SinkEventAttributes attributes )
    {
        tableCell( true );
    }

    /**
     * {@inheritDoc}
     */
    public void tableHeaderCell_()
    {
        tableCell_();
    }

    private boolean lastCellWasHeader = false;

    /**
     * Starts a table cell.
     *
     * @param header True if this is a header cell.
     */
    private void tableCell( boolean header )
    {
        lastCellWasHeader = header;

        if ( cellCount > 0 )
        {
            markup( " &" + EOL );
        }

        char justif;
        switch ( cellJustif[cellCount] )
        {
            case Sink.JUSTIFY_LEFT:
                justif = 'l';
                break;
            case Sink.JUSTIFY_RIGHT:
                justif = 'r';
                break;
            case Sink.JUSTIFY_CENTER:
            default:
                justif = 'c';
                break;
        }
        markup( "\\begin{tabular}[t]{" + justif + "}" );
    }

    /**
     * {@inheritDoc}
     */
    public void tableCaption()
    {
        tableCaption( null );
    }

    /** {@inheritDoc} */
    public void tableCaption( SinkEventAttributes attributes )
    {
        markup( "\\caption{" );
    }

    /**
     * {@inheritDoc}
     */
    public void tableCaption_()
    {
        markup( "}" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void paragraph()
    {
        paragraph( null );
    }

    /** {@inheritDoc} */
    public void paragraph( SinkEventAttributes attributes )
    {
        markup( EOL + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void paragraph_()
    {
        markup( EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void verbatim( boolean boxed )
    {
        verbatim( boxed ? SinkEventAttributeSet.BOXED : null );
    }

    /** {@inheritDoc} */
    public void verbatim( SinkEventAttributes attributes )
    {
        boolean boxed = false;

        if ( attributes != null && attributes.isDefined( SinkEventAttributes.DECORATION ) )
        {
            boxed = "boxed".equals(
                attributes.getAttribute( SinkEventAttributes.DECORATION ) );
        }

        markup( EOL + "\\begin{small}" + EOL );

        if ( boxed )
        {
            markup( "\\begin{Verbatim}[frame=single]" + EOL );
        }
        else
        {
            markup( "\\begin{Verbatim}" + EOL );
        }

        verbatimFlag = true;
    }

    /**
     * {@inheritDoc}
     */
    public void verbatim_()
    {
        markup( EOL + "\\end{Verbatim}" + EOL );
        markup( "\\end{small}" + EOL );

        verbatimFlag = false;
    }

    /**
     * {@inheritDoc}
     */
    public void horizontalRule()
    {
        horizontalRule( null );
    }

    /** {@inheritDoc} */
    public void horizontalRule( SinkEventAttributes attributes )
    {
        markup( EOL + "\\begin{center}\\rule[0.5ex]{\\linewidth}{1pt}\\end{center}" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void pageBreak()
    {
        markup( EOL + "\\newpage" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void anchor( String name )
    {
        anchor( name, null );
    }

    /** {@inheritDoc} */
    public void anchor( String name, SinkEventAttributes attributes )
    {
        markup( "\\hypertarget{" + name + "}{" );
    }

    /**
     * {@inheritDoc}
     */
    public void anchor_()
    {
        markup( "}" );
    }

    /**
     * {@inheritDoc}
     */
    public void link( String name )
    {
        link( name, null );
    }

    /** {@inheritDoc} */
    public void link( String name, SinkEventAttributes attributes )
    {
        // TODO: use \\url for simple links
        if ( DoxiaUtils.isExternalLink( name ) )
        {
            markup( "\\href{" + name + "}{" );
        }
        else
        {
            markup( "\\hyperlink{" + name + "}{" );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void link_()
    {
        markup( "}" );
    }

    /** {@inheritDoc} */
    public void inline()
    {
        inline( null );
    }

    /** {@inheritDoc} */
    public void inline( SinkEventAttributes attributes )
    {
        List<String> tags = new ArrayList<String>();

        if ( attributes != null )
        {

            if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "italic" ) )
            {
                markup( "\\textit{" );
                tags.add( 0, "}" );
            }

            if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "bold" ) )
            {
                markup( "\\textbf{" );
                tags.add( 0, "}" );
            }

            if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "code" ) )
            {
                markup( "\\texttt{\\small " );
                tags.add( 0, "}" );
            }

        }

        inlineStack.push( tags );
    }

    /** {@inheritDoc} */
    public void inline_()
    {
        for ( String tag: inlineStack.pop() )
        {
            markup( tag );
        }
    }

    /**
     * {@inheritDoc}
     */
    public void italic()
    {
        inline( SinkEventAttributeSet.Semantics.ITALIC );
    }

    /**
     * {@inheritDoc}
     */
    public void italic_()
    {
        inline_();
    }

    /**
     * {@inheritDoc}
     */
    public void bold()
    {
        inline( SinkEventAttributeSet.Semantics.BOLD );
    }

    /**
     * {@inheritDoc}
     */
    public void bold_()
    {
        inline_();
    }

    /**
     * {@inheritDoc}
     */
    public void monospaced()
    {
        inline( SinkEventAttributeSet.Semantics.CODE );
    }

    /**
     * {@inheritDoc}
     */
    public void monospaced_()
    {
        inline_();
    }

    /**
     * {@inheritDoc}
     */
    public void lineBreak()
    {
        lineBreak( null );
    }

    /** {@inheritDoc} */
    public void lineBreak( SinkEventAttributes attributes )
    {
        markup( ( figureFlag || tableFlag || titleFlag || verbatimFlag ) ? EOL : "\\newline" + EOL );
    }

    /**
     * {@inheritDoc}
     */
    public void nonBreakingSpace()
    {
        markup( "~" );
    }

    /**
     * {@inheritDoc}
     */
    public void text( String text )
    {
        text( text, null );
    }

    /** {@inheritDoc} */
    public void text( String text, SinkEventAttributes attributes )
    {
        if ( ignoreText )
        {
            return;
        }
        if ( isTitle )
        {
            title = text;
        }
        else if ( verbatimFlag )
        {
            verbatimContent( text );
        }
        else
        {
            content( text );
        }
    }

    /** {@inheritDoc} */
    public void rawText( String text )
    {
        verbatimContent( text );
    }

    /** {@inheritDoc} */
    public void comment( String comment )
    {
        rawText( EOL + "%" + comment );
    }

    /**
     * {@inheritDoc}
     *
     * Unkown events just log a warning message but are ignored otherwise.
     * @see org.apache.maven.doxia.sink.Sink#unknown(String,Object[],SinkEventAttributes)
     */
    public void unknown( String name, Object[] requiredParams, SinkEventAttributes attributes )
    {
        getLog().warn( "[Latex Sink] Unknown Sink event: '" + name + "', ignoring!" );
    }

    // -----------------------------------------------------------------------

    /**
     * Writes the text, preserving whitespace.
     *
     * @param text the text to write.
     */
    protected void markup( String text )
    {
        if ( text != null )
        {
            out.write( text, /*preserveSpace*/ true );
        }
    }

    /**
     * Writes the text, without preserving whitespace.
     *
     * @param text the text to write.
     */
    protected void content( String text )
    {
        out.write( escaped( text ), /*preserveSpace*/ false );
    }

    /**
     * Writes the text, preserving whitespace.
     *
     * @param text the text to write.
     */
    protected void verbatimContent( String text )
    {
        out.write( text, /*preserveSpace*/ true );
    }

    // -----------------------------------------------------------------------

    /**
     * Escapes special characters.
     *
     * @param text The text to escape.
     * @return The text with special characters replaced.
     */
    public static String escaped( String text )
    {
        int length = text.length();
        StringBuilder buffer = new StringBuilder( length );

        for ( int i = 0; i < length; ++i )
        {
            char c = text.charAt( i );
            switch ( c )
            {
                case '-':
                case '<':
                case '>':
                    buffer.append( "\\symbol{" ).append( (int) c ).append( "}" );
                    break;
                case '~':
                    buffer.append( "\\textasciitilde " );
                    break;
                case '^':
                    buffer.append( "\\textasciicircum " );
                    break;
                case '|':
                    buffer.append( "\\textbar " );
                    break;
                case '\\':
                    buffer.append( "\\textbackslash " );
                    break;
                case '$':
                    buffer.append( "\\$" );
                    break;
                case '&':
                    buffer.append( "\\&" );
                    break;
                case '%':
                    buffer.append( "\\%" );
                    break;
                case '#':
                    buffer.append( "\\#" );
                    break;
                case '{':
                    buffer.append( "\\{" );
                    break;
                case '}':
                    buffer.append( "\\}" );
                    break;
                case '_':
                    buffer.append( "\\_" );
                    break;
                default:
                    buffer.append( c );
            }
        }

        return buffer.toString();
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void flush()
    {
        out.flush();
    }

    /**
     * {@inheritDoc}
     */
    public void close()
    {
        out.close();

        init();
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    /**
     * Returns the default sink commands from a resource.
     *
     * @throws java.io.IOException if the resource file cannot be read.
     * @return InputStream
     */
    private static InputStream getDefaultSinkCommands()
        throws IOException
    {
        return LatexSink.class.getResource( "default_sink_commands.tex" ).openStream();
    }

    /**
     * Returns the default preamble from a resource.
     *
     * @return InputStream
     * @throws java.io.IOException if the resource file cannot be read.
     */
    private static InputStream getDefaultPreamble()
        throws IOException
    {
        return LatexSink.class.getResource( "default_preamble.tex" ).openStream();
    }

    /**
     * Returns the default sink commands.
     *
     * @return String.
     */
    protected String defaultSinkCommands()
    {
        try
        {
            return IOUtil.toString( getDefaultSinkCommands() );
        }
        catch ( IOException ioe )
        {
            // this should not happen
            getLog().warn( "Could not read default LaTeX commands, the generated LaTeX file will not compile!" );
            getLog().debug( ioe );

            return "";
        }
    }

    /**
     * Returns the default preamble.
     *
     * @return String.
     */
    protected String defaultPreamble()
    {
        try
        {
            return IOUtil.toString( getDefaultPreamble() );
        }
        catch ( IOException ioe )
        {
            // this should not happen
            getLog().warn( "Could not read default LaTeX preamble, the generated LaTeX file will not compile!" );
            getLog().debug( ioe );

            return "";
        }
    }

    /** {@inheritDoc} */
    protected void init()
    {
        super.init();

        this.ignoreText = false;
        this.titleFlag = false;
        this.numberedListNesting = 0;
        this.verbatimFlag = false;
        this.figureFlag = false;
        this.tableFlag = false;
        this.gridFlag = false;
        this.cellJustif = null;
        this.cellCount = 0;
        this.isTitle = false;
        this.title = null;
    }
}
