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 public class TableBlockParser
46 implements BlockParser
47 {
48 private static final String EMPTY_STRING = "";
49
50 private static final String ANY_CHARACTER = ".*";
51
52 private static final String ESCAPE_CHARACTER = "\\";
53
54 private BlockParser[] parsers;
55
56
57
58
59 public TableBlockParser()
60 {
61 BlockParser headingParser = new SectionBlockParser();
62 BlockParser figureParser = new FigureBlockParser();
63 BlockParser listParser = new ListBlockParser();
64
65 BlockParser[] subparsers = new BlockParser[] { headingParser, figureParser, listParser };
66 BlockParser paragraphParser = new ParagraphBlockParser( subparsers );
67
68 this.parsers = new BlockParser[] { headingParser, figureParser, listParser, paragraphParser };
69
70 }
71
72
73 public boolean accept( String line, ByLineSource source )
74 {
75 return line.startsWith( "|" );
76 }
77
78
79 public Block visit( String line, ByLineSource source )
80 throws ParseException
81 {
82 if ( !accept( line, source ) )
83 {
84 throw new IllegalAccessError( "call accept before this ;)" );
85 }
86
87 List<Block> rows = new ArrayList<>();
88
89 String l = line;
90
91 do
92 {
93 l = l.substring( 0, l.lastIndexOf( "|" ) );
94
95 List<Block> cells = new ArrayList<>();
96
97 if ( l.startsWith( "||" ) )
98 {
99 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 }