001package org.apache.maven.doxia.module.confluence.parser; 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 org.apache.maven.doxia.parser.ParseException; 023import org.apache.maven.doxia.util.ByLineSource; 024 025/** 026 * <p>ParagraphBlockParser class.</p> 027 * 028 * @version $Id$ 029 */ 030public class ParagraphBlockParser 031 implements BlockParser 032{ 033 private BlockParser[] parsers; 034 035 /** 036 * <p>Constructor for ParagraphBlockParser.</p> 037 * 038 * @param parsers the parsers. 039 */ 040 public ParagraphBlockParser( BlockParser[] parsers ) 041 { 042 super(); 043 this.parsers = parsers; 044 } 045 046 /** {@inheritDoc} */ 047 public boolean accept( String line, ByLineSource source ) 048 { 049 return true; 050 } 051 052 /** 053 * Visit the Block. 054 * 055 * @param line the line to visit. 056 * @param source the source. 057 * @param generateParagraphTags whether to generate a paragraph. 058 * @return the visited Block. 059 * 060 * @throws org.apache.maven.doxia.parser.ParseException if any 061 */ 062 public Block visit( String line, ByLineSource source, boolean generateParagraphTags ) 063 throws ParseException 064 { 065 if ( generateParagraphTags ) 066 { 067 return this.visit( line, source ); 068 } 069 else 070 { 071 ChildBlocksBuilder builder = new ChildBlocksBuilder( line ); 072 return new ParagraphBlock( builder.getBlocks(), generateParagraphTags ); 073 } 074 } 075 076 /** {@inheritDoc} */ 077 public Block visit( String line, ByLineSource source ) 078 throws ParseException 079 { 080 081 ChildBlocksBuilder builder = new ChildBlocksBuilder( appendUntilEmptyLine( line, source ) ); 082 return new ParagraphBlock( builder.getBlocks() ); 083 } 084 085 /** 086 * Slurp lines from the source starting with the given line appending them together into a StringBuilder until an 087 * empty line is reached, and while the source contains more lines. The result can be passed to the 088 * {@link #getBlocks(String)} method. 089 * 090 * @param line the first line 091 * @param source the source to read new lines from 092 * @return a StringBuilder appended with lines 093 * @throws ParseException 094 */ 095 private String appendUntilEmptyLine( String line, ByLineSource source ) 096 throws ParseException 097 { 098 StringBuilder text = new StringBuilder(); 099 100 do 101 { 102 103 if ( line.trim().length() == 0 ) 104 { 105 break; 106 } 107 108 boolean accepted = false; 109 for ( int i = 0; i < parsers.length; i++ ) 110 { 111 BlockParser parser = parsers[i]; 112 if ( parser.accept( line, source ) ) 113 { 114 accepted = true; 115 break; 116 } 117 } 118 if ( accepted ) 119 { 120 // Slightly fragile - if any of the parsers need to do this in order to decide whether to accept a line, 121 // then it will barf because of the contract of ByLineSource 122 source.ungetLine(); 123 break; 124 } 125 126 if ( text.length() == 0 ) 127 { 128 text.append( line.trim() ); 129 } 130 else 131 { 132 text.append( " " + line.trim() ); 133 } 134 135 } 136 while ( ( line = source.getNextLine() ) != null ); 137 138 return text.toString(); 139 } 140 141}