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 */ 028public class ParagraphBlockParser 029 implements BlockParser 030{ 031 private BlockParser[] parsers; 032 033 /** 034 * <p>Constructor for ParagraphBlockParser.</p> 035 * 036 * @param parsers the parsers. 037 */ 038 public ParagraphBlockParser( BlockParser[] parsers ) 039 { 040 super(); 041 this.parsers = parsers; 042 } 043 044 /** {@inheritDoc} */ 045 public boolean accept( String line, ByLineSource source ) 046 { 047 return true; 048 } 049 050 /** 051 * Visit the Block. 052 * 053 * @param line the line to visit. 054 * @param source the source. 055 * @param generateParagraphTags whether to generate a paragraph. 056 * @return the visited Block. 057 * @throws org.apache.maven.doxia.parser.ParseException if any. 058 */ 059 public Block visit( String line, ByLineSource source, boolean generateParagraphTags ) 060 throws ParseException 061 { 062 if ( generateParagraphTags ) 063 { 064 return this.visit( line, source ); 065 } 066 else 067 { 068 ChildBlocksBuilder builder = new ChildBlocksBuilder( line ); 069 return new ParagraphBlock( builder.getBlocks(), generateParagraphTags ); 070 } 071 } 072 073 /** {@inheritDoc} */ 074 public Block visit( String line, ByLineSource source ) 075 throws ParseException 076 { 077 078 ChildBlocksBuilder builder = new ChildBlocksBuilder( appendUntilEmptyLine( line, source ) ); 079 return new ParagraphBlock( builder.getBlocks() ); 080 } 081 082 /** 083 * Slurp lines from the source starting with the given line appending them together into a StringBuilder until an 084 * empty line is reached, and while the source contains more lines. The result can be passed to the 085 * {@link #getBlocks(String)} method. 086 * 087 * @param line the first line 088 * @param source the source to read new lines from 089 * @return a StringBuilder appended with lines 090 * @throws ParseException 091 */ 092 private String appendUntilEmptyLine( String line, ByLineSource source ) 093 throws ParseException 094 { 095 StringBuilder text = new StringBuilder(); 096 097 do 098 { 099 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}