1 package org.apache.maven.doxia.module.confluence.parser.table;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
42
43
44
45
46 public class TableBlockParser
47 implements BlockParser
48 {
49 private static final String EMPTY_STRING = "";
50
51 private static final String ANY_CHARACTER = ".*";
52
53 private static final String ESCAPE_CHARACTER = "\\";
54
55 private BlockParser[] parsers;
56
57
58
59
60 public TableBlockParser()
61 {
62 BlockParser headingParser = new SectionBlockParser();
63 BlockParser figureParser = new FigureBlockParser();
64 BlockParser listParser = new ListBlockParser();
65
66 BlockParser[] subparsers = new BlockParser[] { headingParser, figureParser, listParser };
67 BlockParser paragraphParser = new ParagraphBlockParser( subparsers );
68
69 this.parsers = new BlockParser[] { headingParser, figureParser, listParser, paragraphParser };
70
71 }
72
73
74 public boolean accept( String line, ByLineSource source )
75 {
76 return line.startsWith( "|" );
77 }
78
79
80 public Block visit( String line, ByLineSource source )
81 throws ParseException
82 {
83 if ( !accept( line, source ) )
84 {
85 throw new IllegalAccessError( "call accept before this ;)" );
86 }
87
88 List<Block> rows = new ArrayList<Block>();
89
90 String l = line;
91
92 do
93 {
94 l = l.substring( 0, l.lastIndexOf( "|" ) );
95
96 List<Block> cells = new ArrayList<Block>();
97
98 if ( l.startsWith( "||" ) )
99 {
100 String[] text = StringUtils.split( l, "||" );
101
102 for ( int i = 0; i < text.length; i++ )
103 {
104 List<Block> textBlocks = new ArrayList<Block>();
105
106 textBlocks.add( parseLine( text[i], new ByLineReaderSource( new StringReader( EMPTY_STRING ) ) ) );
107
108 List<Block> blocks = new ArrayList<Block>();
109
110 blocks.add( new BoldBlock( textBlocks ) );
111
112 cells.add( new TableCellHeaderBlock( blocks ) );
113 }
114 }
115 else
116 {
117 int it = 0;
118 String[] text = StringUtils.split( l, "|" );
119 List<String> texts = new LinkedList<String>();
120
121 while ( it < text.length )
122 {
123 if ( text[it].matches( ANY_CHARACTER + ESCAPE_CHARACTER + ConfluenceMarkup.LINK_START_MARKUP
124 + ANY_CHARACTER )
125 && !text[it].matches( ANY_CHARACTER + ESCAPE_CHARACTER + ConfluenceMarkup.LINK_END_MARKUP
126 + ANY_CHARACTER ) )
127 {
128 texts.add( text[it] + ConfluenceMarkup.TABLE_CELL_MARKUP + text[it + 1] );
129 it += 2;
130 continue;
131 }
132 texts.add( text[it] );
133 it++;
134 }
135
136 for ( String pText : texts )
137 {
138 List<Block> blocks = new ArrayList<Block>();
139
140 blocks.add( parseLine( pText, new ByLineReaderSource( new StringReader( EMPTY_STRING ) ) ) );
141
142 cells.add( new TableCellBlock( blocks ) );
143 }
144 }
145
146 rows.add( new TableRowBlock( cells ) );
147 }
148 while ( ( l = source.getNextLine() ) != null && accept( l, source ) );
149
150 assert rows.size() >= 1;
151
152 return new TableBlock( rows );
153 }
154
155 private Block parseLine( String text, ByLineSource source )
156 throws ParseException
157 {
158 if ( text.length() > 0 )
159 {
160 for ( BlockParser parser : parsers )
161 {
162 if ( parser.accept( text, source ) )
163 {
164 if ( parser instanceof ParagraphBlockParser )
165 {
166 return ( (ParagraphBlockParser) parser ).visit( text, source, false );
167 }
168 else
169 {
170 return parser.visit( text, source );
171 }
172 }
173 }
174 }
175 return null;
176 }
177 }