View Javadoc
1   package org.apache.maven.doxia.module.confluence.parser.table;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.StringReader;
23  import java.util.ArrayList;
24  import java.util.LinkedList;
25  import java.util.List;
26  
27  import org.apache.maven.doxia.module.confluence.ConfluenceMarkup;
28  import org.apache.maven.doxia.module.confluence.parser.Block;
29  import org.apache.maven.doxia.module.confluence.parser.BlockParser;
30  import org.apache.maven.doxia.module.confluence.parser.BoldBlock;
31  import org.apache.maven.doxia.module.confluence.parser.FigureBlockParser;
32  import org.apache.maven.doxia.module.confluence.parser.ParagraphBlockParser;
33  import org.apache.maven.doxia.module.confluence.parser.SectionBlockParser;
34  import org.apache.maven.doxia.module.confluence.parser.list.ListBlockParser;
35  import org.apache.maven.doxia.parser.ParseException;
36  import org.apache.maven.doxia.util.ByLineReaderSource;
37  import org.apache.maven.doxia.util.ByLineSource;
38  import org.codehaus.plexus.util.StringUtils;
39  
40  /**
41   * Parse tables
42   *
43   * @author Juan F. Codagnone
44   */
45  public class TableBlockParser
46      implements BlockParser
47  {
48      private static final String EMPTY_STRING = "";
49  
50      private static final String ANY_CHARACTER = ".*";
51  
52      private static final String ESCAPE_CHARACTER = "\\";
53  
54      private BlockParser[] parsers;
55  
56      /**
57       * Default constructor TableBlockParser.
58       */
59      public TableBlockParser()
60      {
61          BlockParser headingParser = new SectionBlockParser();
62          BlockParser figureParser = new FigureBlockParser();
63          BlockParser listParser = new ListBlockParser();
64  
65          BlockParser[] subparsers = new BlockParser[] { headingParser, figureParser, listParser };
66          BlockParser paragraphParser = new ParagraphBlockParser( subparsers );
67  
68          this.parsers = new BlockParser[] { headingParser, figureParser, listParser, paragraphParser };
69  
70      }
71  
72      /** {@inheritDoc} */
73      public boolean accept( String line, ByLineSource source )
74      {
75          return line.startsWith( "|" );
76      }
77  
78      /** {@inheritDoc} */
79      public Block visit( String line, ByLineSource source )
80          throws ParseException
81      {
82          if ( !accept( line, source ) )
83          {
84              throw new IllegalAccessError( "call accept before this ;)" );
85          }
86  
87          List<Block> rows = new ArrayList<>();
88  
89          String l = line;
90  
91          do
92          {
93              l = l.substring( 0, l.lastIndexOf( "|" ) );
94  
95              List<Block> cells = new ArrayList<>();
96  
97              if ( l.startsWith( "||" ) )
98              {
99                  String[] text = StringUtils.split( l, "||" );
100 
101                 for ( String s : text )
102                 {
103                     List<Block> textBlocks = new ArrayList<>();
104 
105                     textBlocks.add( parseLine( s, new ByLineReaderSource( new StringReader( EMPTY_STRING ) ) ) );
106 
107                     List<Block> blocks = new ArrayList<>();
108 
109                     blocks.add( new BoldBlock( textBlocks ) );
110 
111                     cells.add( new TableCellHeaderBlock( blocks ) );
112                 }
113             }
114             else
115             {
116                 int it = 0;
117                 String[] text = StringUtils.split( l, "|" );
118                 List<String> texts = new LinkedList<>();
119 
120                 while ( it < text.length )
121                 {
122                     if ( text[it].matches( ANY_CHARACTER + ESCAPE_CHARACTER + ConfluenceMarkup.LINK_START_MARKUP
123                         + ANY_CHARACTER )
124                         && !text[it].matches( ANY_CHARACTER + ESCAPE_CHARACTER + ConfluenceMarkup.LINK_END_MARKUP
125                             + ANY_CHARACTER ) )
126                     {
127                         texts.add( text[it] + ConfluenceMarkup.TABLE_CELL_MARKUP + text[it + 1] );
128                         it += 2;
129                         continue;
130                     }
131                     texts.add( text[it] );
132                     it++;
133                 }
134 
135                 for ( String pText : texts )
136                 {
137                     List<Block> blocks = new ArrayList<>();
138 
139                     blocks.add( parseLine( pText, new ByLineReaderSource( new StringReader( EMPTY_STRING ) ) ) );
140 
141                     cells.add( new TableCellBlock( blocks ) );
142                 }
143             }
144 
145             rows.add( new TableRowBlock( cells ) );
146         }
147         while ( ( l = source.getNextLine() ) != null && accept( l, source ) );
148 
149         assert rows.size() >= 1;
150 
151         return new TableBlock( rows );
152     }
153 
154     private Block parseLine( String text, ByLineSource source )
155         throws ParseException
156     {
157         if ( text.length() > 0 )
158         {
159             for ( BlockParser parser : parsers )
160             {
161                 if ( parser.accept( text, source ) )
162                 {
163                     if ( parser instanceof ParagraphBlockParser )
164                     {
165                         return ( (ParagraphBlockParser) parser ).visit( text, source, false );
166                     }
167                     else
168                     {
169                         return parser.visit( text, source );
170                     }
171                 }
172             }
173         }
174         return null;
175     }
176 }