View Javadoc
1   package org.apache.maven.doxia.module.confluence.parser;
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 org.apache.maven.doxia.parser.ParseException;
23  import org.apache.maven.doxia.util.ByLineSource;
24  
25  /**
26   * <p>ParagraphBlockParser class.</p>
27   */
28  public class ParagraphBlockParser
29      implements BlockParser
30  {
31      private BlockParser[] parsers;
32  
33      /**
34       * <p>Constructor for ParagraphBlockParser.</p>
35       *
36       * @param parsers the parsers.
37       */
38      public ParagraphBlockParser( BlockParser[] parsers )
39      {
40          super();
41          this.parsers = parsers;
42      }
43  
44      /** {@inheritDoc} */
45      public boolean accept( String line, ByLineSource source )
46      {
47          return true;
48      }
49  
50      /**
51       * Visit the Block.
52       *
53       * @param line the line to visit.
54       * @param source the source.
55       * @param generateParagraphTags whether to generate a paragraph.
56       * @return the visited Block.
57       * @throws org.apache.maven.doxia.parser.ParseException if any.
58       */
59      public Block visit( String line, ByLineSource source, boolean generateParagraphTags )
60              throws ParseException
61      {
62          if ( generateParagraphTags )
63          {
64              return this.visit( line, source );
65          }
66          else
67          {
68              ChildBlocksBuilder builder = new ChildBlocksBuilder( line );
69              return new ParagraphBlock( builder.getBlocks(), generateParagraphTags );
70          }
71      }
72  
73      /** {@inheritDoc} */
74      public Block visit( String line, ByLineSource source )
75          throws ParseException
76      {
77  
78          ChildBlocksBuilder builder = new ChildBlocksBuilder( appendUntilEmptyLine( line, source ) );
79          return new ParagraphBlock( builder.getBlocks() );
80      }
81  
82      /**
83       * Slurp lines from the source starting with the given line appending them together into a StringBuilder until an
84       * empty line is reached, and while the source contains more lines. The result can be passed to the
85       * {@link #getBlocks(String)} method.
86       *
87       * @param line the first line
88       * @param source the source to read new lines from
89       * @return a StringBuilder appended with lines
90       * @throws ParseException
91       */
92      private String appendUntilEmptyLine( String line, ByLineSource source )
93          throws ParseException
94      {
95          StringBuilder text = new StringBuilder();
96  
97          do
98          {
99  
100             if ( line.trim().length() == 0 )
101             {
102                 break;
103             }
104 
105             boolean accepted = false;
106             for ( BlockParser parser : parsers )
107             {
108                 if ( parser.accept( line, source ) )
109                 {
110                     accepted = true;
111                     break;
112                 }
113             }
114             if ( accepted )
115             {
116                 // Slightly fragile - if any of the parsers need to do this in order to decide whether to accept a line,
117                 // then it will barf because of the contract of ByLineSource
118                 source.ungetLine();
119                 break;
120             }
121 
122             if ( text.length() == 0 )
123             {
124                 text.append( line.trim() );
125             }
126             else
127             {
128                 text.append( " " ).append( line.trim() );
129             }
130 
131         }
132         while ( ( line = source.getNextLine() ) != null );
133 
134         return text.toString();
135     }
136 
137 }