1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.cms.core.pdf;
17
18 import java.io.IOException;
19 import java.io.Reader;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22
23 import com.lowagie.text.Chunk;
24 import com.lowagie.text.DocListener;
25 import com.lowagie.text.Element;
26 import com.lowagie.text.ExceptionConverter;
27 import com.lowagie.text.ListItem;
28 import com.lowagie.text.Paragraph;
29 import com.lowagie.text.Phrase;
30 import com.lowagie.text.TextElementArray;
31 import com.lowagie.text.html.simpleparser.HTMLWorker;
32 import com.lowagie.text.html.simpleparser.IncCell;
33 import com.lowagie.text.html.simpleparser.IncTable;
34 import com.lowagie.text.html.simpleparser.StyleSheet;
35 import com.lowagie.text.pdf.PdfPTable;
36
37
38 /***
39 * Extends HTMLWorker to use CJKFactoryProperties instead of
40 * FactoryProperties while parsing.
41 *
42 * @author someda
43 */
44 public class CJKHTMLWorker extends HTMLWorker {
45
46 public CJKHTMLWorker(DocListener doc){
47 super(doc);
48 }
49
50 public static ArrayList parseToList(Reader reader, StyleSheet style) throws IOException {
51 CJKHTMLWorker worker = new CJKHTMLWorker(null);
52 if (style != null)
53 worker.style = style;
54 worker.document = worker;
55 worker.objectList = new ArrayList();
56 worker.parse(reader);
57 return worker.objectList;
58 }
59
60 public void startElement(String tag, HashMap h) {
61 if (!tagsSupported.containsKey(tag))
62 return;
63 style.applyStyle(tag, h);
64 String follow = (String)CJKFactoryProperties.followTags.get(tag);
65 if (follow != null) {
66 HashMap prop = new HashMap();
67 prop.put(follow, null);
68 cprops.addToChain(follow, prop);
69 return;
70 }
71 if (tag.equals("a")) {
72 cprops.addToChain(tag, h);
73 if (currentParagraph == null)
74 currentParagraph = new Paragraph();
75 stack.push(currentParagraph);
76 currentParagraph = new Paragraph();
77 return;
78 }
79 if (tag.equals("br")) {
80 if (currentParagraph == null)
81 currentParagraph = new Paragraph();
82 currentParagraph.add(CJKFactoryProperties.createChunk("\n", cprops));
83 return;
84 }
85 if (tag.equals("font") || tag.equals("span")) {
86 cprops.addToChain(tag, h);
87 return;
88 }
89 endElement("p");
90 if (tag.equals("h1") || tag.equals("h2") || tag.equals("h3") || tag.equals("h4") || tag.equals("h5") || tag.equals("h6")) {
91 if (!h.containsKey("size"))
92 h.put("size", tag.substring(1));
93 cprops.addToChain(tag, h);
94 return;
95 }
96 if (tag.equals("ul")) {
97 if (pendingLI)
98 endElement("li");
99 skipText = true;
100 cprops.addToChain(tag, h);
101 com.lowagie.text.List list = new com.lowagie.text.List(false, 10);
102 list.setListSymbol("\u2022");
103 stack.push(list);
104 return;
105 }
106 if (tag.equals("ol")) {
107 if (pendingLI)
108 endElement("li");
109 skipText = true;
110 cprops.addToChain(tag, h);
111 com.lowagie.text.List list = new com.lowagie.text.List(true, 10);
112 stack.push(list);
113 return;
114 }
115 if (tag.equals("li")) {
116 if (pendingLI)
117 endElement("li");
118 skipText = false;
119 pendingLI = true;
120 cprops.addToChain(tag, h);
121 stack.push(new com.lowagie.text.ListItem());
122 return;
123 }
124 if (tag.equals("div") || tag.equals("body")) {
125 cprops.addToChain(tag, h);
126 return;
127 }
128 if (tag.equals("pre")) {
129 if (!h.containsKey("face")) {
130 h.put("face", "Courier");
131 }
132 cprops.addToChain(tag, h);
133 isPRE = true;
134 return;
135 }
136 if (tag.equals("p")) {
137 cprops.addToChain(tag, h);
138 currentParagraph = CJKFactoryProperties.createParagraph(h);
139 return;
140 }
141 if (tag.equals("tr")) {
142 if (pendingTR)
143 endElement("tr");
144 skipText = true;
145 pendingTR = true;
146 cprops.addToChain("tr", h);
147 return;
148 }
149 if (tag.equals("td") || tag.equals("th")) {
150 if (pendingTD)
151 endElement(tag);
152 skipText = false;
153 pendingTD = true;
154 cprops.addToChain("td", h);
155 stack.push(new IncCell(tag, cprops));
156 return;
157 }
158 if (tag.equals("table")) {
159 cprops.addToChain("table", h);
160 IncTable table = new IncTable(h);
161 stack.push(table);
162 tableState.push(new boolean[]{pendingTR, pendingTD});
163 pendingTR = pendingTD = false;
164 skipText = true;
165 return;
166 }
167 }
168
169 public void endElement(String tag) {
170 if (!tagsSupported.containsKey(tag))
171 return;
172 try {
173 String follow = (String)CJKFactoryProperties.followTags.get(tag);
174 if (follow != null) {
175 cprops.removeChain(follow);
176 return;
177 }
178 if (tag.equals("font") || tag.equals("span")) {
179 cprops.removeChain(tag);
180 return;
181 }
182 if (tag.equals("a")) {
183 String href = cprops.getProperty("href");
184 if (currentParagraph == null)
185 currentParagraph = new Paragraph();
186 if (href != null) {
187 ArrayList chunks = currentParagraph.getChunks();
188 for (int k = 0; k < chunks.size(); ++k) {
189 Chunk ck = (Chunk)chunks.get(k);
190 ck.setAnchor(href);
191 }
192 }
193 Paragraph tmp = (Paragraph)stack.pop();
194 Phrase tmp2 = new Phrase();
195 tmp2.add(currentParagraph);
196 tmp.add(tmp2);
197 currentParagraph = tmp;
198 cprops.removeChain("a");
199 return;
200 }
201 if (tag.equals("br")) {
202 return;
203 }
204 if (currentParagraph != null) {
205 if (stack.empty())
206 document.add(currentParagraph);
207 else {
208 Object obj = stack.pop();;
209 if (obj instanceof TextElementArray) {
210 TextElementArray current = (TextElementArray)obj;
211 current.add(currentParagraph);
212 }
213 stack.push(obj);
214 }
215 }
216 currentParagraph = null;
217 if (tag.equals("ul") || tag.equals("ol")) {
218 if (pendingLI)
219 endElement("li");
220 skipText = false;
221 cprops.removeChain(tag);
222 if (stack.empty())
223 return;
224 Object obj = stack.pop();
225 if (!(obj instanceof com.lowagie.text.List)) {
226 stack.push(obj);
227 return;
228 }
229 if (stack.empty())
230 document.add((Element)obj);
231 else
232 ((TextElementArray)stack.peek()).add(obj);
233 return;
234 }
235 if (tag.equals("li")) {
236 pendingLI = false;
237 skipText = true;
238 cprops.removeChain(tag);
239 if (stack.empty())
240 return;
241 Object obj = stack.pop();
242 if (!(obj instanceof ListItem)) {
243 stack.push(obj);
244 return;
245 }
246 if (stack.empty()) {
247 document.add((Element)obj);
248 return;
249 }
250 Object list = stack.pop();
251 if (!(list instanceof com.lowagie.text.List)) {
252 stack.push(list);
253 return;
254 }
255 ListItem item = (ListItem)obj;
256 ((com.lowagie.text.List)list).add(item);
257 ArrayList cks = item.getChunks();
258 if (cks.size() > 0)
259 item.listSymbol().setFont(((Chunk)cks.get(0)).font());
260 stack.push(list);
261 return;
262 }
263 if (tag.equals("div") || tag.equals("body")) {
264 cprops.removeChain(tag);
265 return;
266 }
267 if (tag.equals("pre")) {
268 cprops.removeChain(tag);
269 isPRE = false;
270 return;
271 }
272 if (tag.equals("p")) {
273 cprops.removeChain(tag);
274 pendingP = false;
275 return;
276 }
277 if (tag.equals("h1") || tag.equals("h2") || tag.equals("h3") || tag.equals("h4") || tag.equals("h5") || tag.equals("h6")) {
278 cprops.removeChain(tag);
279 return;
280 }
281 if (tag.equals("table")) {
282 if (pendingTR)
283 endElement("tr");
284 cprops.removeChain("table");
285 IncTable table = (IncTable) stack.pop();
286 PdfPTable tb = table.buildTable();
287 tb.setSplitRows(true);
288 if (stack.empty())
289 document.add(tb);
290 else
291 ((TextElementArray)stack.peek()).add(tb);
292 boolean state[] = (boolean[])tableState.pop();
293 pendingTR = state[0];
294 pendingTD = state[1];
295 skipText = false;
296 return;
297 }
298 if (tag.equals("tr")) {
299 if (pendingTD)
300 endElement("td");
301 pendingTR = false;
302 cprops.removeChain("tr");
303 ArrayList cells = new ArrayList();
304 IncTable table = null;
305 while (true) {
306 Object obj = stack.pop();
307 if (obj instanceof IncCell) {
308 cells.add(((IncCell)obj).getCell());
309 }
310 if (obj instanceof IncTable) {
311 table = (IncTable)obj;
312 break;
313 }
314 }
315 table.addCols(cells);
316 table.endRow();
317 stack.push(table);
318 skipText = true;
319 return;
320 }
321 if (tag.equals("td") || tag.equals("th")) {
322 pendingTD = false;
323 cprops.removeChain("td");
324 skipText = true;
325 return;
326 }
327 }
328 catch (Exception e) {
329 throw new ExceptionConverter(e);
330 }
331 }
332
333 public void text(String str) {
334 if (skipText)
335 return;
336 String content = str;
337 if (isPRE) {
338 if (currentParagraph == null)
339 currentParagraph = new Paragraph();
340 currentParagraph.add(CJKFactoryProperties.createChunk(content, cprops));
341 return;
342 }
343 if (content.trim().length() == 0 && content.indexOf(' ') < 0) {
344 return;
345 }
346
347 StringBuffer buf = new StringBuffer();
348 int len = content.length();
349 char character;
350 boolean newline = false;
351 for (int i = 0; i < len; i++) {
352 switch(character = content.charAt(i)) {
353 case ' ':
354 if (!newline) {
355 buf.append(character);
356 }
357 break;
358 case '\n':
359 if (i > 0) {
360 newline = true;
361 buf.append(' ');
362 }
363 break;
364 case '\r':
365 break;
366 case '\t':
367 break;
368 default:
369 newline = false;
370 buf.append(character);
371 }
372 }
373 if (currentParagraph == null)
374 currentParagraph = CJKFactoryProperties.createParagraph(cprops);
375 currentParagraph.add(CJKFactoryProperties.createChunk(buf.toString(), cprops));
376 }
377
378 }