1 package org.apache.maven.doxia.module.fo;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.StringReader;
24 import java.io.Writer;
25
26 import org.apache.maven.doxia.document.DocumentMeta;
27 import org.apache.maven.doxia.document.DocumentModel;
28 import org.apache.maven.doxia.document.DocumentTOC;
29 import org.apache.maven.doxia.document.DocumentTOCItem;
30 import org.apache.maven.doxia.parser.XhtmlBaseParser;
31 import org.apache.maven.doxia.sink.Sink;
32 import org.apache.maven.doxia.sink.impl.AbstractSinkTest;
33 import org.apache.maven.doxia.sink.impl.SinkTestDocument;
34
35 import static org.apache.maven.doxia.util.HtmlTools.escapeHTML;
36
37
38
39
40 public class FoSinkTest
41 extends AbstractSinkTest
42 {
43 private FoConfiguration config;
44
45
46
47
48
49 @Override
50 protected String wrapXml( String xmlFragment )
51 {
52 return "<fo:fo xmlns:fo=\"" + FoMarkup.FO_NAMESPACE + "\">" + xmlFragment + "</fo:fo>";
53 }
54
55
56
57
58
59 public void testConvertFO2PDF()
60 throws Exception
61 {
62 String fileName = "test";
63
64 FoSink fosink = new FoSink( getTestWriter( fileName ) );
65 fosink.beginDocument();
66 SinkTestDocument.generate( fosink );
67 fosink.endDocument();
68 fosink.close();
69
70
71 fo2pdf( fileName );
72 }
73
74
75
76
77
78 public void testAggregateMode()
79 throws Exception
80 {
81 FoAggregateSink fosink = new FoAggregateSink( getTestWriter( "aggregate" ) );
82
83 fosink.setDocumentModel( getModel() );
84
85 fosink.beginDocument();
86
87 fosink.coverPage();
88
89 fosink.toc();
90
91 fosink.setDocumentName( "doc1" );
92 fosink.setDocumentTitle( "Document 1" );
93 SinkTestDocument.generate( fosink );
94
95
96 fosink.setDocumentName( "doc2" );
97 fosink.setDocumentTitle( "Document 2" );
98 SinkTestDocument.generate( fosink );
99
100 fosink.endDocument();
101
102
103 fo2pdf( "aggregate" );
104 }
105
106 private DocumentModel getModel()
107 {
108 DocumentModel model = new DocumentModel();
109 model.setToc( getToc() );
110 model.setMeta( getMeta() );
111 return model;
112 }
113
114 private DocumentMeta getMeta()
115 {
116 DocumentMeta meta = new DocumentMeta();
117 meta.setAuthor( "The Apache Maven Project" );
118 meta.setTitle( "Doxia FO Sink" );
119 return meta;
120 }
121
122 private DocumentTOC getToc()
123 {
124 DocumentTOCItem item1 = new DocumentTOCItem();
125 item1.setName( "First document" );
126 item1.setRef( "doc1.apt" );
127
128 DocumentTOCItem item2 = new DocumentTOCItem();
129 item2.setName( "Second document" );
130 item2.setRef( "doc2.xml" );
131
132 DocumentTOC toc = new DocumentTOC();
133 toc.setName( "What's in here" );
134 toc.addItem( item1 );
135 toc.addItem( item2 );
136
137 return toc;
138 }
139
140
141
142
143
144
145 protected String outputExtension()
146 {
147 return "fo";
148 }
149
150
151 protected Sink createSink( Writer writer )
152 {
153 return new FoSink( writer );
154 }
155
156
157 protected boolean isXmlSink()
158 {
159 return true;
160 }
161
162
163 protected String getTitleBlock( String title )
164 {
165 String attribs = getConfig().getAttributeString( "doc.header.title" );
166 return EOL + "<fo:block" + attribs + ">" + title + "</fo:block>" + EOL;
167 }
168
169
170 protected String getAuthorBlock( String author )
171 {
172 String attribs = getConfig().getAttributeString( "doc.header.author" );
173 return EOL + "<fo:block" + attribs + ">" + author + "</fo:block>" + EOL;
174 }
175
176
177 protected String getDateBlock( String date )
178 {
179 String attribs = getConfig().getAttributeString( "doc.header.date" );
180 return EOL + "<fo:block" + attribs + ">" + date + "</fo:block>" + EOL;
181 }
182
183
184 protected String getHeadBlock()
185 {
186 return "";
187 }
188
189
190 public void testHead()
191 {
192 String expected = "";
193 assertEquals( "Wrong head!", expected, getHeadBlock() );
194 }
195
196
197 protected String getBodyBlock()
198 {
199 return EOL + "</fo:flow>" + EOL + "</fo:page-sequence>" + EOL + "</fo:root>" + EOL;
200 }
201
202 protected String getArticleBlock()
203 {
204 return "";
205 }
206
207 protected String getNavigationBlock()
208 {
209 return "";
210 }
211
212 protected String getSidebarBlock()
213 {
214 return "";
215 }
216
217
218 protected String getSectionTitleBlock( String title )
219 {
220 return title;
221 }
222
223
224 protected String getSection1Block( String title )
225 {
226 String attribs = getConfig().getAttributeString( "body.text" );
227 String attrib2 = getConfig().getAttributeString( "body.h1" );
228 return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">1 " + title
229 + "</fo:block>" + EOL + "</fo:block>" + EOL;
230 }
231
232
233 protected String getSection2Block( String title )
234 {
235 String attribs = getConfig().getAttributeString( "body.text" );
236 String attrib2 = getConfig().getAttributeString( "body.h2" );
237 return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">0.1 " + title
238 + "</fo:block>" + EOL + "</fo:block>" + EOL;
239 }
240
241
242 protected String getSection3Block( String title )
243 {
244 String attribs = getConfig().getAttributeString( "body.text" );
245 String attrib2 = getConfig().getAttributeString( "body.h3" );
246 return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">0.0.1 " + title
247 + "</fo:block>" + EOL + "</fo:block>" + EOL;
248 }
249
250
251 protected String getSection4Block( String title )
252 {
253 String attribs = getConfig().getAttributeString( "body.text" );
254 String attrib2 = getConfig().getAttributeString( "body.h4" );
255 return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">" + title
256 + "</fo:block>" + EOL + "</fo:block>" + EOL;
257 }
258
259
260 protected String getSection5Block( String title )
261 {
262 String attribs = getConfig().getAttributeString( "body.text" );
263 String attrib2 = getConfig().getAttributeString( "body.h5" );
264 return EOL + EOL + "<fo:block" + attribs + ">" + EOL + EOL + "<fo:block" + attrib2 + ">" + title
265 + "</fo:block>" + EOL + "</fo:block>" + EOL;
266 }
267
268 protected String getHeaderBlock()
269 {
270 return "";
271 }
272
273
274 protected String getContentBlock()
275 {
276 return "";
277 }
278
279 protected String getFooterBlock()
280 {
281 return "";
282 }
283
284
285 protected String getListBlock( String item )
286 {
287 String attribs = getConfig().getAttributeString( "list" );
288 String itemAttribs = getConfig().getAttributeString( "list.item" );
289 return EOL + EOL + "<fo:list-block" + attribs + ">" + EOL + "<fo:list-item" + itemAttribs
290 + "><fo:list-item-label><fo:block>•</fo:block></fo:list-item-label>" + EOL + EOL
291 + "<fo:list-item-body" + itemAttribs + ">" + EOL + "<fo:block>" + item + "</fo:block>" + EOL
292 + "</fo:list-item-body>" + EOL + "</fo:list-item>" + EOL + "</fo:list-block>" + EOL;
293 }
294
295
296 protected String getNumberedListBlock( String item )
297 {
298 String attribs = getConfig().getAttributeString( "list" );
299 String itemAttribs = getConfig().getAttributeString( "list.item" );
300 return EOL + EOL + "<fo:list-block" + attribs + ">" + EOL + "<fo:list-item" + itemAttribs + ">" + EOL
301 + "<fo:list-item-label>" + EOL + "<fo:block>i.</fo:block>" + EOL + "</fo:list-item-label>" + EOL + EOL
302 + "<fo:list-item-body" + itemAttribs + ">" + EOL + "<fo:block>" + item + "</fo:block>" + EOL
303 + "</fo:list-item-body>" + EOL + "</fo:list-item>" + EOL + "</fo:list-block>" + EOL;
304 }
305
306
307 protected String getDefinitionListBlock( String definum, String definition )
308 {
309 String dlAtts = getConfig().getAttributeString( "dl" );
310 String dtAtts = getConfig().getAttributeString( "dt" );
311 String ddAtts = getConfig().getAttributeString( "dd" );
312 return EOL + EOL + "<fo:block" + dlAtts + ">" + EOL + "<fo:block" + dtAtts + ">" + definum + "</fo:block>"
313 + EOL + EOL + EOL + "<fo:block" + ddAtts + ">" + definition + "</fo:block>" + EOL + "</fo:block>"
314 + EOL;
315 }
316
317
318 protected String getFigureBlock( String source, String caption )
319 {
320 String dlAtts = getConfig().getAttributeString( "figure.display" );
321 String dtAtts = getConfig().getAttributeString( "figure.graphics" );
322 String ddAtts = getConfig().getAttributeString( "figure.caption" );
323
324 String figureBlock = EOL + EOL + "<fo:block" + dlAtts + ">" +
325 "<fo:external-graphic" + " src=\"" + escapeHTML( source ) + "\"" + dtAtts + "/>" + EOL;
326 if ( caption != null )
327 {
328 figureBlock += EOL + "<fo:block" + ddAtts + ">" + caption + "</fo:block>" + EOL;
329 }
330 figureBlock += "</fo:block>" + EOL;
331
332
333 return figureBlock;
334 }
335
336
337 protected String getTableBlock( String cell, String caption )
338 {
339 String dlAtts = getConfig().getAttributeString( "table.padding" );
340 String dtAtts = getConfig().getAttributeString( "table.layout" );
341 String ddAtts = getConfig().getAttributeString( "table.body.row" );
342
343
344 return EOL + EOL + "<fo:block" + dlAtts + ">" + EOL + "<fo:table" + dtAtts + ">" + EOL
345 + "<fo:table-column column-width=\"proportional-column-width(1)\"/>" + EOL + EOL + "<fo:table-body>"
346 + EOL + "<fo:table-row" + ddAtts
347 + "><fo:table-cell column-number=\"1\" padding-after=\"1.5pt\" padding-end=\"5pt\" "
348 + "keep-together.within-column=\"always\" padding-start=\"2.5pt\" "
349 + "background-color=\"#eeeeee\" padding-before=\"4pt\">" + EOL + "<fo:block line-height=\"1.2em\" "
350 + "text-align=\"center\" font-family=\"Helvetica,sans-serif\" font-size=\"9pt\">" + EOL + cell
351 + "</fo:block>" + EOL + "</fo:table-cell>" + EOL + "</fo:table-row>" + EOL + "</fo:table-body>" + EOL
352 + "</fo:table>" + EOL + "</fo:block>" + EOL + EOL
353 + "<fo:block white-space-collapse=\"true\" space-after=\"6pt\" space-before=\"3pt\" "
354 + "font-family=\"Garamond,serif\" line-height=\"12pt\" text-align=\"center\" font-size=\"11pt\">"
355 + "Table_caption</fo:block>" + EOL;
356 }
357
358
359 protected String getParagraphBlock( String text )
360 {
361 String attribs = getConfig().getAttributeString( "normal.paragraph" );
362 return EOL + "<fo:block" + attribs + ">" + text + "</fo:block>" + EOL;
363 }
364
365
366 protected String getDataBlock( String value, String text )
367 {
368 return text;
369 }
370
371
372 protected String getTimeBlock( String datetime, String text )
373 {
374 return text;
375 }
376
377
378 protected String getAddressBlock( String text )
379 {
380 return text;
381 }
382
383
384 protected String getBlockquoteBlock( String text )
385 {
386 return text;
387 }
388
389
390 protected String getDivisionBlock( String text )
391 {
392 return text;
393 }
394
395
396 protected String getVerbatimBlock( String text )
397 {
398 String attribs = getConfig().getAttributeString( "body.source" );
399 return EOL + "<fo:block" + attribs + ">" + text + "</fo:block>" + EOL;
400 }
401
402
403 protected String getHorizontalRuleBlock()
404 {
405 String attribs = getConfig().getAttributeString( "body.rule" );
406 return EOL + EOL + "<fo:block>" + EOL + "<fo:leader" + attribs + " /></fo:block>" + EOL;
407 }
408
409
410 protected String getPageBreakBlock()
411 {
412 return EOL + "<fo:block break-before=\"page\" />" + EOL;
413 }
414
415
416 protected String getAnchorBlock( String anchor )
417 {
418
419 return EOL + "<fo:inline id=\"#" + anchor + "\">" + anchor + "</fo:inline>";
420 }
421
422
423 protected String getLinkBlock( String link, String text )
424 {
425 String attribs = getConfig().getAttributeString( "href.internal" );
426 return EOL + "<fo:basic-link internal-destination=\"" + link + "\">" + EOL + "<fo:inline" + attribs + ">"
427 + text + "</fo:inline></fo:basic-link>";
428 }
429
430
431 protected String getInlineBlock( String text )
432 {
433 return text;
434 }
435
436
437 protected String getInlineItalicBlock( String text )
438 {
439 String attribs = getConfig().getAttributeString( "italic" );
440 return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
441 }
442
443
444 protected String getInlineBoldBlock( String text )
445 {
446 String attribs = getConfig().getAttributeString( "bold" );
447 return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
448 }
449
450
451 protected String getInlineCodeBlock( String text )
452 {
453 String attribs = getConfig().getAttributeString( "monospace" );
454 return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
455 }
456
457
458 protected String getItalicBlock( String text )
459 {
460 String attribs = getConfig().getAttributeString( "italic" );
461 return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
462 }
463
464
465 protected String getBoldBlock( String text )
466 {
467 String attribs = getConfig().getAttributeString( "bold" );
468 return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
469 }
470
471
472 protected String getMonospacedBlock( String text )
473 {
474 String attribs = getConfig().getAttributeString( "monospace" );
475 return EOL + "<fo:inline" + attribs + ">" + text + "</fo:inline>";
476 }
477
478
479 protected String getLineBreakBlock()
480 {
481 return EOL + EOL + "<fo:block />";
482 }
483
484
485 protected String getLineBreakOpportunityBlock()
486 {
487 return "";
488 }
489
490
491 protected String getNonBreakingSpaceBlock()
492 {
493 return " ";
494 }
495
496
497 protected String getTextBlock( String text )
498 {
499 return FoSink.escaped( text, false );
500 }
501
502
503 protected String getRawTextBlock( String text )
504 {
505 return text;
506 }
507
508
509
510
511
512 private void fo2pdf( String baseName )
513 throws Exception
514 {
515
516 File outputDirectory = new File( getBasedir(), outputBaseDir() + getOutputDir() );
517 File resourceDirectory = new File( getBasedirFile(), "target/test-classes" );
518 File foFile = new File( outputDirectory, baseName + "." + outputExtension() );
519 File pdfFile = new File( outputDirectory, baseName + ".pdf" );
520 FoUtils.convertFO2PDF( foFile, pdfFile, resourceDirectory.getCanonicalPath() );
521 }
522
523 private FoConfiguration getConfig()
524 {
525 if ( config == null )
526 {
527 config = ( (FoSink) getSink() ).getFoConfiguration();
528 }
529
530 return config;
531 }
532
533
534 protected String getCommentBlock( String text )
535 {
536 return "<!--" + toXmlComment( text ) + "-->";
537 }
538
539
540
541
542
543
544 public void testTableCaption()
545 throws Exception
546 {
547 StringBuilder html = new StringBuilder();
548 html.append( "<table>" ).append( EOL );
549 html.append( "<caption>caption table</caption>" ).append( EOL );
550 html.append( "<tr>" ).append( EOL );
551 html.append( "<td>foo</td>" ).append( EOL );
552 html.append( "</tr>" ).append( EOL );
553 html.append( "<tr>" ).append( EOL );
554 html.append( "<td>bar</td>" ).append( EOL );
555 html.append( "</tr>" ).append( EOL );
556 html.append( "</table>" ).append( EOL );
557
558 String fileName = "testTableCaption";
559
560
561 FoSink fosink = new FoSink( getTestWriter( fileName ) );
562 fosink.beginDocument();
563 SinkTestDocument.generateHead( fosink );
564
565 fosink.body();
566 XhtmlBaseParser parser = new XhtmlBaseParser();
567 parser.parse( new StringReader( html.toString() ), fosink );
568 fosink.body_();
569
570 fosink.endDocument();
571 fosink.close();
572
573
574 fo2pdf( fileName );
575 }
576
577
578
579
580 public void testNestedTables()
581 throws Exception
582 {
583 StringBuilder html = new StringBuilder();
584 html.append( "<table>" ).append( EOL );
585 html.append( "<caption>first caption</caption>" ).append( EOL );
586 html.append( "<tr>" ).append( EOL );
587 html.append( "<td>foo</td>" ).append( EOL );
588 html.append( "</tr>" ).append( EOL );
589 html.append( "<tr>" ).append( EOL );
590 html.append( "<td>" ).append( EOL );
591
592 html.append( "<table>" ).append( EOL );
593 html.append( "<caption>second caption</caption>" ).append( EOL );
594 html.append( "<tr>" ).append( EOL );
595 html.append( "<td>foo</td>" ).append( EOL );
596 html.append( "<td>bar</td>" ).append( EOL );
597 html.append( "</tr>" ).append( EOL );
598 html.append( "<tr>" ).append( EOL );
599 html.append( "<td>foo1</td>" ).append( EOL );
600 html.append( "<td>" ).append( EOL );
601
602 html.append( "<table>" ).append( EOL );
603 html.append( "<caption>third caption</caption>" ).append( EOL );
604 html.append( "<tr>" ).append( EOL );
605 html.append( "<td>foo1</td>" ).append( EOL );
606 html.append( "<td>bar1</td>" ).append( EOL );
607 html.append( "</tr>" ).append( EOL );
608 html.append( "</table>" ).append( EOL );
609 html.append( "</td>" ).append( EOL );
610
611 html.append( "</tr>" ).append( EOL );
612 html.append( "</table>" ).append( EOL );
613
614 html.append( "</td>" ).append( EOL );
615 html.append( "</tr>" ).append( EOL );
616 html.append( "</table>" ).append( EOL );
617
618 String fileName = "testNestedTables";
619
620
621 FoSink fosink = new FoSink( getTestWriter( fileName ) );
622 fosink.beginDocument();
623 SinkTestDocument.generateHead( fosink );
624
625 fosink.body();
626 XhtmlBaseParser parser = new XhtmlBaseParser();
627 parser.parse( new StringReader( html.toString() ), fosink );
628 fosink.body_();
629
630 fosink.endDocument();
631 fosink.close();
632
633
634 fo2pdf( fileName );
635 }
636 }