001package org.apache.maven.doxia.module.confluence;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.Reader;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.maven.doxia.module.confluence.parser.Block;
027import org.apache.maven.doxia.module.confluence.parser.BlockParser;
028import org.apache.maven.doxia.module.confluence.parser.DefinitionListBlockParser;
029import org.apache.maven.doxia.module.confluence.parser.FigureBlockParser;
030import org.apache.maven.doxia.module.confluence.parser.HorizontalRuleBlockParser;
031import org.apache.maven.doxia.module.confluence.parser.ParagraphBlockParser;
032import org.apache.maven.doxia.module.confluence.parser.SectionBlockParser;
033import org.apache.maven.doxia.module.confluence.parser.VerbatimBlockParser;
034import org.apache.maven.doxia.module.confluence.parser.list.ListBlockParser;
035import org.apache.maven.doxia.module.confluence.parser.table.TableBlockParser;
036import org.apache.maven.doxia.parser.AbstractTextParser;
037import org.apache.maven.doxia.parser.ParseException;
038import org.apache.maven.doxia.parser.Parser;
039import org.apache.maven.doxia.sink.Sink;
040import org.apache.maven.doxia.util.ByLineReaderSource;
041import org.apache.maven.doxia.util.ByLineSource;
042import org.codehaus.plexus.component.annotations.Component;
043
044/**
045 * Parse the <a href="http://www.atlassian.com/software/confluence/">Confluence</a>.
046 * See <a href="http://confluence.atlassian.com/display/CONF25/Confluence+Notation+Guide+Overview">
047 * Confluence Notation Guide Overview</a>
048 *
049 * @version $Id: ConfluenceParser.html 979316 2016-02-02 21:51:43Z hboutemy $
050 * @since 1.0
051 */
052@Component( role = Parser.class, hint = "confluence" )
053public class ConfluenceParser
054    extends AbstractTextParser
055{
056    private BlockParser[] parsers;
057
058    /**
059     * <p>Constructor for ConfluenceParser.</p>
060     */
061    public ConfluenceParser()
062    {
063        init();
064    }
065
066    private List<Block> parse( ByLineSource source )
067        throws ParseException
068    {
069        init();
070
071        List<Block> blocks = new ArrayList<Block>();
072
073        String line;
074
075        while ( ( line = source.getNextLine() ) != null )
076        {
077            //boolean accepted = false;
078
079            for ( BlockParser parser : parsers )
080            {
081                if ( line.trim().length() == 0 )
082                {
083                    continue;
084                }
085
086                if ( parser.accept( line, source ) )
087                {
088                    //accepted = true;
089
090                    blocks.add( parser.visit( line, source ) );
091
092                    break;
093                }
094            }
095
096/*
097            if ( !accepted )
098            {
099                throw new ParseException( "don't know how to handle line: " + source.getLineNumber() + ": " + line );
100            }
101*/
102        }
103
104        return blocks;
105    }
106
107    @Override
108    public void parse( Reader source, Sink sink )
109        throws ParseException
110    {
111        parse( source, sink, "" );
112    }
113
114    @Override
115    public synchronized void parse( Reader source, Sink sink, String reference )
116        throws ParseException
117    {
118        ByLineSource src = new ByLineReaderSource( source, reference );
119
120        try
121        {
122            List<Block> blocks = parse( src );
123
124            sink.head();
125
126            sink.head_();
127
128            sink.body();
129
130            for ( Block block : blocks )
131            {
132                block.traverse( sink );
133            }
134
135            sink.body_();
136        }
137        catch ( Exception e )
138        {
139            // TODO handle column number
140            throw new ParseException( e, src.getName(), src.getLineNumber(), -1 );
141        }
142        finally
143        {
144            setSecondParsing( false );
145            init();
146        }
147    }
148
149    /** {@inheritDoc} */
150    protected void init()
151    {
152        super.init();
153
154        BlockParser headingParser = new SectionBlockParser();
155        BlockParser figureParser = new FigureBlockParser();
156        BlockParser verbatimParser = new VerbatimBlockParser();
157        BlockParser definitionParser = new DefinitionListBlockParser();
158        BlockParser horizontalRuleParser = new HorizontalRuleBlockParser();
159        BlockParser listParser = new ListBlockParser();
160        BlockParser tableParser = new TableBlockParser();
161
162        BlockParser[] subparsers =
163                new BlockParser[] { headingParser, figureParser, listParser, tableParser, verbatimParser };
164        BlockParser paragraphParser = new ParagraphBlockParser( subparsers );
165
166        this.parsers =
167            new BlockParser[] { headingParser, figureParser, verbatimParser, definitionParser, horizontalRuleParser,
168                listParser, tableParser, paragraphParser };
169    }
170}