001package org.apache.maven.doxia.module.confluence.parser.table; 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.StringReader; 023import java.util.ArrayList; 024import java.util.LinkedList; 025import java.util.List; 026 027import org.apache.maven.doxia.module.confluence.ConfluenceMarkup; 028import org.apache.maven.doxia.module.confluence.parser.Block; 029import org.apache.maven.doxia.module.confluence.parser.BlockParser; 030import org.apache.maven.doxia.module.confluence.parser.BoldBlock; 031import org.apache.maven.doxia.module.confluence.parser.FigureBlockParser; 032import org.apache.maven.doxia.module.confluence.parser.ParagraphBlockParser; 033import org.apache.maven.doxia.module.confluence.parser.SectionBlockParser; 034import org.apache.maven.doxia.module.confluence.parser.list.ListBlockParser; 035import org.apache.maven.doxia.parser.ParseException; 036import org.apache.maven.doxia.util.ByLineReaderSource; 037import org.apache.maven.doxia.util.ByLineSource; 038import org.codehaus.plexus.util.StringUtils; 039 040/** 041 * Parse tables 042 * 043 * @author Juan F. Codagnone 044 */ 045public class TableBlockParser 046 implements BlockParser 047{ 048 private static final String EMPTY_STRING = ""; 049 050 private static final String ANY_CHARACTER = ".*"; 051 052 private static final String ESCAPE_CHARACTER = "\\"; 053 054 private BlockParser[] parsers; 055 056 /** 057 * Default constructor TableBlockParser. 058 */ 059 public TableBlockParser() 060 { 061 BlockParser headingParser = new SectionBlockParser(); 062 BlockParser figureParser = new FigureBlockParser(); 063 BlockParser listParser = new ListBlockParser(); 064 065 BlockParser[] subparsers = new BlockParser[] { headingParser, figureParser, listParser }; 066 BlockParser paragraphParser = new ParagraphBlockParser( subparsers ); 067 068 this.parsers = new BlockParser[] { headingParser, figureParser, listParser, paragraphParser }; 069 070 } 071 072 /** {@inheritDoc} */ 073 public boolean accept( String line, ByLineSource source ) 074 { 075 return line.startsWith( "|" ); 076 } 077 078 /** {@inheritDoc} */ 079 public Block visit( String line, ByLineSource source ) 080 throws ParseException 081 { 082 if ( !accept( line, source ) ) 083 { 084 throw new IllegalAccessError( "call accept before this ;)" ); 085 } 086 087 List<Block> rows = new ArrayList<>(); 088 089 String l = line; 090 091 do 092 { 093 l = l.substring( 0, l.lastIndexOf( "|" ) ); 094 095 List<Block> cells = new ArrayList<>(); 096 097 if ( l.startsWith( "||" ) ) 098 { 099 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}