1 package org.apache.maven.doxia.module.itext;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.lowagie.text.BadElementException;
23 import com.lowagie.text.ElementTags;
24 import com.lowagie.text.Image;
25
26 import java.awt.Color;
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.LineNumberReader;
30 import java.io.StringReader;
31 import java.io.StringWriter;
32 import java.io.Writer;
33 import java.net.MalformedURLException;
34 import java.net.URL;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Locale;
39 import java.util.Map;
40 import java.util.Set;
41 import java.util.Stack;
42 import java.util.TreeSet;
43
44 import org.apache.maven.doxia.sink.Sink;
45 import org.apache.maven.doxia.sink.SinkEventAttributes;
46 import org.apache.maven.doxia.sink.impl.AbstractXmlSink;
47 import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
48 import org.apache.maven.doxia.util.DoxiaUtils;
49 import org.apache.maven.doxia.util.HtmlTools;
50
51 import org.codehaus.plexus.util.IOUtil;
52 import org.codehaus.plexus.util.StringUtils;
53 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
54 import org.codehaus.plexus.util.xml.XMLWriter;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class ITextSink
74 extends AbstractXmlSink
75 {
76
77 public static final String DTD = "http://itext.sourceforge.net/itext.dtd";
78
79
80 public static final String DOCTYPE = "ITEXT SYSTEM \"" + DTD + "\"";
81
82
83 public static final String DEFAULT_CHAPTER_TITLE_LEADING = "36.0";
84
85
86 public static final String DEFAULT_SECTION_TITLE_LEADING = "24.0";
87
88
89 private ClassLoader currentClassLoader;
90
91
92 private SinkActionContext actionContext;
93
94
95 private Writer writer;
96
97
98 private final XMLWriter xmlWriter;
99
100 private boolean writeStart;
101
102
103 private ITextHeader header;
104
105
106 private ITextFont font;
107
108 private int numberDepth = 1;
109
110 private int depth = 0;
111
112 private StringWriter tableCaptionWriter = null;
113
114 private XMLWriter tableCaptionXMLWriter = null;
115
116
117
118 private boolean anchorDefined = false;
119
120
121 private boolean figureDefined = false;
122
123
124 protected Stack<List<String>> inlineStack = new Stack<>();
125
126
127
128 private Map<String, Set<String>> warnMessages;
129
130
131
132
133
134
135 protected ITextSink( Writer writer )
136 {
137 this( writer, "UTF-8" );
138 }
139
140
141
142
143
144
145
146
147 protected ITextSink( Writer writer, String encoding )
148 {
149
150 this( new PrettyPrintXMLWriter( writer, encoding, null ) );
151
152 this.writer = writer;
153 this.writeStart = true;
154 }
155
156
157
158
159
160
161 protected ITextSink( PrettyPrintXMLWriter xmlWriter )
162 {
163 this.xmlWriter = xmlWriter;
164
165 this.writeStart = false;
166
167 init();
168 }
169
170
171
172
173
174
175 public ClassLoader getClassLoader()
176 {
177 return currentClassLoader;
178 }
179
180
181
182
183
184
185 public void setClassLoader( ClassLoader cl )
186 {
187 currentClassLoader = cl;
188 }
189
190
191
192
193
194
195
196
197 public void close()
198 {
199 IOUtil.close( writer );
200
201 init();
202 }
203
204
205
206
207 public void flush()
208 {
209 if ( getLog().isWarnEnabled() && this.warnMessages != null )
210 {
211 for ( Map.Entry<String, Set<String>> entry : this.warnMessages.entrySet() )
212 {
213 for ( String msg : entry.getValue() )
214 {
215 getLog().warn( msg );
216 }
217 }
218 }
219
220 this.warnMessages = null;
221 }
222
223
224
225
226
227
228
229
230 public void head_()
231 {
232 actionContext.release();
233 }
234
235
236
237
238 public void head()
239 {
240
241
242 actionContext.setAction( SinkActionContext.HEAD );
243 }
244
245
246
247
248 public void author_()
249 {
250 actionContext.release();
251 }
252
253
254
255
256 public void author()
257 {
258 actionContext.setAction( SinkActionContext.AUTHOR );
259 }
260
261
262
263
264 public void date_()
265 {
266 actionContext.release();
267 }
268
269
270
271
272 public void date()
273 {
274 actionContext.setAction( SinkActionContext.DATE );
275 }
276
277
278
279
280 public void title_()
281 {
282 actionContext.release();
283 }
284
285
286
287
288 public void title()
289 {
290 actionContext.setAction( SinkActionContext.TITLE );
291 }
292
293
294
295
296
297
298
299
300 public void body_()
301 {
302 if ( writeStart )
303 {
304 writeEndElement();
305
306 writeEndElement();
307 }
308
309 actionContext.release();
310 }
311
312
313
314
315 public void body()
316 {
317 if ( writeStart )
318 {
319 writeStartElement( ElementTags.ITEXT );
320 writeAddAttribute( ElementTags.TITLE, header.getTitle() );
321 writeAddAttribute( ElementTags.AUTHOR, header.getAuthors() );
322 writeAddAttribute( ElementTags.CREATIONDATE, header.getDate() );
323 writeAddAttribute( ElementTags.SUBJECT, header.getTitle() );
324 writeAddAttribute( ElementTags.KEYWORDS, "" );
325 writeAddAttribute( ElementTags.PRODUCER, "Generated with Doxia by " + System.getProperty( "user.name" ) );
326 writeAddAttribute( ElementTags.PAGE_SIZE, ITextUtil.getPageSize( ITextUtil.getDefaultPageSize() ) );
327
328 writeStartElement( ElementTags.CHAPTER );
329 writeAddAttribute( ElementTags.NUMBERDEPTH, numberDepth );
330 writeAddAttribute( ElementTags.DEPTH, depth );
331 writeAddAttribute( ElementTags.INDENT, "0.0" );
332
333 writeStartElement( ElementTags.TITLE );
334 writeAddAttribute( ElementTags.LEADING, DEFAULT_CHAPTER_TITLE_LEADING );
335 writeAddAttribute( ElementTags.FONT, ITextFont.DEFAULT_FONT_NAME );
336 writeAddAttribute( ElementTags.SIZE, ITextFont.getSectionFontSize( 0 ) );
337 writeAddAttribute( ElementTags.STYLE, ITextFont.BOLD );
338 writeAddAttribute( ElementTags.BLUE, ITextFont.DEFAULT_FONT_COLOR_BLUE );
339 writeAddAttribute( ElementTags.GREEN, ITextFont.DEFAULT_FONT_COLOR_GREEN );
340 writeAddAttribute( ElementTags.RED, ITextFont.DEFAULT_FONT_COLOR_RED );
341 writeAddAttribute( ElementTags.ALIGN, ElementTags.ALIGN_CENTER );
342
343
344
345
346
347 writeStartElement( ElementTags.CHUNK );
348 writeAddAttribute( ElementTags.FONT, ITextFont.DEFAULT_FONT_NAME );
349 writeAddAttribute( ElementTags.SIZE, ITextFont.getSectionFontSize( 0 ) );
350 writeAddAttribute( ElementTags.STYLE, ITextFont.BOLD );
351 writeAddAttribute( ElementTags.BLUE, ITextFont.DEFAULT_FONT_COLOR_BLUE );
352 writeAddAttribute( ElementTags.GREEN, ITextFont.DEFAULT_FONT_COLOR_GREEN );
353 writeAddAttribute( ElementTags.RED, ITextFont.DEFAULT_FONT_COLOR_RED );
354
355
356 write( header.getTitle() );
357
358 writeEndElement();
359
360 writeEndElement();
361 }
362
363 actionContext.setAction( SinkActionContext.BODY );
364 }
365
366
367
368
369
370
371
372
373 public void sectionTitle()
374 {
375 actionContext.release();
376 }
377
378
379
380
381 public void sectionTitle_()
382 {
383 actionContext.setAction( SinkActionContext.SECTION_TITLE );
384 }
385
386
387
388
389 public void section1_()
390 {
391 writeEndElement();
392
393 numberDepth--;
394 depth = 0;
395
396 actionContext.release();
397 }
398
399
400
401
402 public void section1()
403 {
404 numberDepth++;
405 depth = 1;
406
407 writeStartElement( ElementTags.SECTION );
408 writeAddAttribute( ElementTags.NUMBERDEPTH, numberDepth );
409 writeAddAttribute( ElementTags.DEPTH, depth );
410 writeAddAttribute( ElementTags.INDENT, "0.0" );
411
412 lineBreak();
413
414 actionContext.setAction( SinkActionContext.SECTION_1 );
415 }
416
417
418
419
420 public void sectionTitle1_()
421 {
422 writeEndElement();
423
424 font.setSize( ITextFont.DEFAULT_FONT_SIZE );
425 bold_();
426
427 actionContext.release();
428 }
429
430
431
432
433 public void sectionTitle1()
434 {
435 font.setSize( ITextFont.getSectionFontSize( 1 ) );
436 font.setColor( Color.BLACK );
437 bold();
438
439 writeStartElement( ElementTags.TITLE );
440 writeAddAttribute( ElementTags.LEADING, DEFAULT_SECTION_TITLE_LEADING );
441 writeAddAttribute( ElementTags.FONT, font.getFontName() );
442 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
443 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
444 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
445 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
446 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
447
448
449 actionContext.setAction( SinkActionContext.SECTION_TITLE_1 );
450 }
451
452
453
454
455 public void section2_()
456 {
457 writeEndElement();
458
459 numberDepth--;
460 depth = 0;
461
462 actionContext.release();
463 }
464
465
466
467
468 public void section2()
469 {
470 numberDepth++;
471 depth = 1;
472
473 writeStartElement( ElementTags.SECTION );
474 writeAddAttribute( ElementTags.NUMBERDEPTH, numberDepth );
475 writeAddAttribute( ElementTags.DEPTH, depth );
476 writeAddAttribute( ElementTags.INDENT, "0.0" );
477
478 lineBreak();
479
480 actionContext.setAction( SinkActionContext.SECTION_2 );
481 }
482
483
484
485
486 public void sectionTitle2_()
487 {
488 writeEndElement();
489
490 font.setSize( ITextFont.DEFAULT_FONT_SIZE );
491 bold_();
492
493 actionContext.release();
494 }
495
496
497
498
499 public void sectionTitle2()
500 {
501 font.setSize( ITextFont.getSectionFontSize( 2 ) );
502 font.setColor( Color.BLACK );
503 bold();
504
505 writeStartElement( ElementTags.TITLE );
506 writeAddAttribute( ElementTags.LEADING, DEFAULT_SECTION_TITLE_LEADING );
507 writeAddAttribute( ElementTags.FONT, font.getFontName() );
508 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
509 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
510 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
511 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
512 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
513
514
515 actionContext.setAction( SinkActionContext.SECTION_TITLE_2 );
516 }
517
518
519
520
521 public void section3_()
522 {
523 writeEndElement();
524
525 numberDepth--;
526 depth = 1;
527
528 actionContext.release();
529 }
530
531
532
533
534 public void section3()
535 {
536 numberDepth++;
537 depth = 1;
538
539 writeStartElement( ElementTags.SECTION );
540 writeAddAttribute( ElementTags.NUMBERDEPTH, numberDepth );
541 writeAddAttribute( ElementTags.DEPTH, depth );
542 writeAddAttribute( ElementTags.INDENT, "0.0" );
543
544 lineBreak();
545
546 actionContext.setAction( SinkActionContext.SECTION_3 );
547 }
548
549
550
551
552 public void sectionTitle3_()
553 {
554 writeEndElement();
555
556 font.setSize( ITextFont.DEFAULT_FONT_SIZE );
557 bold_();
558
559 actionContext.release();
560 }
561
562
563
564
565 public void sectionTitle3()
566 {
567 font.setSize( ITextFont.getSectionFontSize( 3 ) );
568 font.setColor( Color.BLACK );
569 bold();
570
571 writeStartElement( ElementTags.TITLE );
572 writeAddAttribute( ElementTags.LEADING, DEFAULT_SECTION_TITLE_LEADING );
573 writeAddAttribute( ElementTags.FONT, font.getFontName() );
574 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
575 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
576 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
577 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
578 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
579
580
581 actionContext.setAction( SinkActionContext.SECTION_TITLE_3 );
582 }
583
584
585
586
587 public void section4_()
588 {
589 writeEndElement();
590
591 numberDepth--;
592 depth = 1;
593
594 actionContext.release();
595 }
596
597
598
599
600 public void section4()
601 {
602 numberDepth++;
603 depth = 1;
604
605 writeStartElement( ElementTags.SECTION );
606 writeAddAttribute( ElementTags.NUMBERDEPTH, numberDepth );
607 writeAddAttribute( ElementTags.DEPTH, depth );
608 writeAddAttribute( ElementTags.INDENT, "0.0" );
609
610 lineBreak();
611
612 actionContext.setAction( SinkActionContext.SECTION_4 );
613 }
614
615
616
617
618 public void sectionTitle4_()
619 {
620 writeEndElement();
621
622 font.setSize( ITextFont.DEFAULT_FONT_SIZE );
623 bold_();
624
625 actionContext.release();
626 }
627
628
629
630
631 public void sectionTitle4()
632 {
633 font.setSize( ITextFont.getSectionFontSize( 4 ) );
634 font.setColor( Color.BLACK );
635 bold();
636
637 writeStartElement( ElementTags.TITLE );
638 writeAddAttribute( ElementTags.LEADING, DEFAULT_SECTION_TITLE_LEADING );
639 writeAddAttribute( ElementTags.FONT, font.getFontName() );
640 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
641 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
642 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
643 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
644 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
645
646
647 actionContext.setAction( SinkActionContext.SECTION_TITLE_4 );
648 }
649
650
651
652
653 public void section5_()
654 {
655 writeEndElement();
656
657 numberDepth--;
658 depth = 1;
659
660 actionContext.release();
661 }
662
663
664
665
666 public void section5()
667 {
668 numberDepth++;
669 depth = 1;
670
671 writeStartElement( ElementTags.SECTION );
672 writeAddAttribute( ElementTags.NUMBERDEPTH, numberDepth );
673 writeAddAttribute( ElementTags.DEPTH, depth );
674 writeAddAttribute( ElementTags.INDENT, "0.0" );
675
676 lineBreak();
677
678 actionContext.setAction( SinkActionContext.SECTION_5 );
679 }
680
681
682
683
684 public void sectionTitle5_()
685 {
686 writeEndElement();
687
688 font.setSize( ITextFont.DEFAULT_FONT_SIZE );
689 bold_();
690
691 actionContext.release();
692 }
693
694
695
696
697 public void sectionTitle5()
698 {
699 font.setSize( ITextFont.getSectionFontSize( 5 ) );
700 font.setColor( Color.BLACK );
701 bold();
702
703 writeStartElement( ElementTags.TITLE );
704 writeAddAttribute( ElementTags.LEADING, DEFAULT_SECTION_TITLE_LEADING );
705 writeAddAttribute( ElementTags.FONT, font.getFontName() );
706 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
707 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
708 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
709 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
710 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
711
712
713 actionContext.setAction( SinkActionContext.SECTION_TITLE_5 );
714 }
715
716
717
718
719
720
721
722
723 public void paragraph_()
724 {
725
726 if ( ( actionContext.getCurrentAction() == SinkActionContext.LIST_ITEM )
727 || ( actionContext.getCurrentAction() == SinkActionContext.NUMBERED_LIST_ITEM )
728 || ( actionContext.getCurrentAction() == SinkActionContext.DEFINITION ) )
729 {
730 return;
731 }
732
733 writeEndElement();
734
735 actionContext.release();
736 }
737
738
739
740
741 public void paragraph()
742 {
743
744 if ( ( actionContext.getCurrentAction() == SinkActionContext.LIST_ITEM )
745 || ( actionContext.getCurrentAction() == SinkActionContext.NUMBERED_LIST_ITEM )
746 || ( actionContext.getCurrentAction() == SinkActionContext.DEFINITION ) )
747 {
748 return;
749 }
750
751 writeStartElement( ElementTags.PARAGRAPH );
752 writeStartElement( ElementTags.NEWLINE );
753 writeEndElement();
754
755 actionContext.setAction( SinkActionContext.PARAGRAPH );
756 }
757
758
759
760
761
762
763
764
765 public void list_()
766 {
767 writeEndElement();
768
769 writeEndElement();
770
771 actionContext.release();
772 }
773
774
775
776
777 public void list()
778 {
779 writeStartElement( ElementTags.CHUNK );
780 writeAddAttribute( ElementTags.FONT, font.getFontName() );
781 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
782 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
783 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
784 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
785 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
786
787 writeStartElement( ElementTags.LIST );
788 writeAddAttribute( ElementTags.NUMBERED, Boolean.FALSE.toString() );
789 writeAddAttribute( ElementTags.SYMBOLINDENT, "15" );
790
791 actionContext.setAction( SinkActionContext.LIST );
792 }
793
794
795
796
797 public void listItem_()
798 {
799 writeEndElement();
800
801 actionContext.release();
802 }
803
804
805
806
807 public void listItem()
808 {
809 writeStartElement( ElementTags.LISTITEM );
810 writeAddAttribute( ElementTags.INDENTATIONLEFT, "20.0" );
811
812 actionContext.setAction( SinkActionContext.LIST_ITEM );
813 }
814
815
816
817
818 public void numberedList_()
819 {
820 writeEndElement();
821
822 writeEndElement();
823
824 actionContext.release();
825 }
826
827
828 public void numberedList( int numbering )
829 {
830 writeStartElement( ElementTags.CHUNK );
831 writeAddAttribute( ElementTags.FONT, font.getFontName() );
832 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
833 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
834 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
835 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
836 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
837
838 writeStartElement( ElementTags.LIST );
839 writeAddAttribute( ElementTags.NUMBERED, Boolean.TRUE.toString() );
840 writeAddAttribute( ElementTags.SYMBOLINDENT, "20" );
841
842 switch ( numbering )
843 {
844 case Sink.NUMBERING_UPPER_ALPHA:
845 writeAddAttribute( ElementTags.LETTERED, Boolean.TRUE.toString() );
846 writeAddAttribute( ElementTags.FIRST, 'A' );
847 break;
848
849 case Sink.NUMBERING_LOWER_ALPHA:
850 writeAddAttribute( ElementTags.LETTERED, Boolean.TRUE.toString() );
851 writeAddAttribute( ElementTags.FIRST, 'a' );
852 break;
853
854
855 case Sink.NUMBERING_UPPER_ROMAN:
856 writeAddAttribute( ElementTags.LETTERED, Boolean.TRUE.toString() );
857 writeAddAttribute( ElementTags.FIRST, 'I' );
858 break;
859
860 case Sink.NUMBERING_LOWER_ROMAN:
861 writeAddAttribute( ElementTags.LETTERED, Boolean.TRUE.toString() );
862 writeAddAttribute( ElementTags.FIRST, 'i' );
863 break;
864
865 case Sink.NUMBERING_DECIMAL:
866 default:
867 writeAddAttribute( ElementTags.LETTERED, Boolean.FALSE.toString() );
868 }
869
870 actionContext.setAction( SinkActionContext.NUMBERED_LIST );
871 }
872
873
874
875
876 public void numberedListItem_()
877 {
878 writeEndElement();
879
880 actionContext.release();
881 }
882
883
884
885
886 public void numberedListItem()
887 {
888 writeStartElement( ElementTags.LISTITEM );
889 writeAddAttribute( ElementTags.INDENTATIONLEFT, "20" );
890
891 actionContext.setAction( SinkActionContext.NUMBERED_LIST_ITEM );
892 }
893
894
895
896
897 public void definitionList_()
898 {
899 actionContext.release();
900 }
901
902
903
904
905 public void definitionList()
906 {
907 lineBreak();
908
909 actionContext.setAction( SinkActionContext.DEFINITION_LIST );
910 }
911
912
913
914
915 public void definedTerm_()
916 {
917 font.setSize( ITextFont.DEFAULT_FONT_SIZE );
918 bold_();
919
920 writeEndElement();
921
922 actionContext.release();
923
924 lineBreak();
925 }
926
927
928
929
930 public void definedTerm()
931 {
932 font.setSize( ITextFont.DEFAULT_FONT_SIZE + 2 );
933 bold();
934
935 writeStartElement( ElementTags.CHUNK );
936 writeAddAttribute( ElementTags.FONT, font.getFontName() );
937 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
938 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
939 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
940 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
941 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
942
943 actionContext.setAction( SinkActionContext.DEFINED_TERM );
944 }
945
946
947
948
949 public void definition_()
950 {
951 writeEndElement();
952
953 actionContext.release();
954
955 lineBreak();
956 }
957
958
959
960
961 public void definition()
962 {
963 writeStartElement( ElementTags.CHUNK );
964 writeAddAttribute( ElementTags.FONT, font.getFontName() );
965 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
966 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
967 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
968 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
969 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
970
971
972 writeStartElement( ElementTags.CHUNK );
973 writeAddAttribute( ElementTags.FONT, font.getFontName() );
974 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
975 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
976 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
977 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
978 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
979
980
981 write( "\u00A0" + StringUtils.repeat( " ", 16 ), false, false );
982
983 writeEndElement();
984
985 actionContext.setAction( SinkActionContext.DEFINITION );
986 }
987
988
989
990
991 public void definitionListItem_()
992 {
993 actionContext.release();
994 }
995
996
997
998
999 public void definitionListItem()
1000 {
1001 actionContext.setAction( SinkActionContext.DEFINITION_LIST_ITEM );
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011 public void table_()
1012 {
1013 if ( tableCaptionXMLWriter != null )
1014 {
1015 tableCaptionXMLWriter = null;
1016
1017 writeEndElement();
1018
1019 writeEndElement();
1020
1021 writeStartElement( ElementTags.PARAGRAPH );
1022 writeAddAttribute( ElementTags.ALIGN, ElementTags.ALIGN_CENTER );
1023
1024 write( tableCaptionWriter.toString(), true );
1025
1026 writeEndElement();
1027
1028 tableCaptionWriter = null;
1029 }
1030 else
1031 {
1032 writeEndElement();
1033
1034 writeEndElement();
1035 }
1036 actionContext.release();
1037 }
1038
1039
1040
1041
1042 public void table()
1043 {
1044 writeStartElement( ElementTags.CHUNK );
1045 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1046 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1047 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1048 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1049 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1050 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1051
1052 writeStartElement( ElementTags.TABLE );
1053 writeAddAttribute( ElementTags.LEFT, Boolean.TRUE.toString() );
1054 writeAddAttribute( ElementTags.RIGHT, Boolean.TRUE.toString() );
1055 writeAddAttribute( ElementTags.TOP, Boolean.TRUE.toString() );
1056 writeAddAttribute( ElementTags.BOTTOM, Boolean.TRUE.toString() );
1057 writeAddAttribute( ElementTags.ALIGN, ElementTags.ALIGN_CENTER );
1058 writeAddAttribute( ElementTags.WIDTH, "100.0%" );
1059 writeAddAttribute( ElementTags.TABLEFITSPAGE, Boolean.TRUE.toString() );
1060 writeAddAttribute( ElementTags.CELLSFITPAGE, Boolean.TRUE.toString() );
1061 writeAddAttribute( ElementTags.CELLPADDING, "10" );
1062
1063
1064 actionContext.setAction( SinkActionContext.TABLE );
1065 }
1066
1067
1068
1069
1070 public void tableCaption_()
1071 {
1072 actionContext.release();
1073 }
1074
1075
1076
1077
1078 public void tableCaption()
1079 {
1080 tableCaptionWriter = new StringWriter();
1081 tableCaptionXMLWriter = new PrettyPrintXMLWriter( tableCaptionWriter );
1082 actionContext.setAction( SinkActionContext.TABLE_CAPTION );
1083 }
1084
1085
1086
1087
1088 public void tableCell_()
1089 {
1090 writeEndElement();
1091
1092 actionContext.release();
1093 }
1094
1095
1096
1097
1098 public void tableCell()
1099 {
1100 writeStartElement( ElementTags.CELL );
1101 writeAddAttribute( ElementTags.LEFT, Boolean.TRUE.toString() );
1102 writeAddAttribute( ElementTags.RIGHT, Boolean.TRUE.toString() );
1103 writeAddAttribute( ElementTags.TOP, Boolean.TRUE.toString() );
1104 writeAddAttribute( ElementTags.BOTTOM, Boolean.TRUE.toString() );
1105 writeAddAttribute( ElementTags.HORIZONTALALIGN, ElementTags.ALIGN_LEFT );
1106
1107 actionContext.setAction( SinkActionContext.TABLE_CELL );
1108 }
1109
1110
1111 public void tableCell( String width )
1112 {
1113 actionContext.setAction( SinkActionContext.TABLE_CELL );
1114 }
1115
1116
1117
1118
1119 public void tableHeaderCell_()
1120 {
1121 writeEndElement();
1122
1123 actionContext.release();
1124 }
1125
1126
1127
1128
1129 public void tableHeaderCell()
1130 {
1131 writeStartElement( ElementTags.CELL );
1132 writeAddAttribute( ElementTags.LEFT, Boolean.TRUE.toString() );
1133 writeAddAttribute( ElementTags.RIGHT, Boolean.TRUE.toString() );
1134 writeAddAttribute( ElementTags.TOP, Boolean.TRUE.toString() );
1135 writeAddAttribute( ElementTags.BOTTOM, Boolean.TRUE.toString() );
1136 writeAddAttribute( ElementTags.HEADER, Boolean.TRUE.toString() );
1137 writeAddAttribute( ElementTags.BGRED, Color.GRAY.getRed() );
1138 writeAddAttribute( ElementTags.BGBLUE, Color.GRAY.getBlue() );
1139 writeAddAttribute( ElementTags.BGGREEN, Color.GRAY.getGreen() );
1140 writeAddAttribute( ElementTags.HORIZONTALALIGN, ElementTags.ALIGN_CENTER );
1141
1142 actionContext.setAction( SinkActionContext.TABLE_HEADER_CELL );
1143 }
1144
1145
1146 public void tableHeaderCell( String width )
1147 {
1148 actionContext.setAction( SinkActionContext.TABLE_HEADER_CELL );
1149 }
1150
1151
1152
1153
1154 public void tableRow_()
1155 {
1156 writeEndElement();
1157
1158 actionContext.release();
1159 }
1160
1161
1162
1163
1164 public void tableRow()
1165 {
1166 writeStartElement( ElementTags.ROW );
1167
1168 actionContext.setAction( SinkActionContext.TABLE_ROW );
1169 }
1170
1171
1172
1173
1174 public void tableRows_()
1175 {
1176
1177
1178 actionContext.release();
1179 }
1180
1181
1182 public void tableRows( int[] justification, boolean grid )
1183 {
1184
1185 writeAddAttribute( ElementTags.COLUMNS, justification.length );
1186
1187 actionContext.setAction( SinkActionContext.TABLE_ROWS );
1188 }
1189
1190
1191
1192
1193
1194
1195
1196
1197 public void verbatim_()
1198 {
1199 writeEndElement();
1200
1201 writeEndElement();
1202
1203 writeEndElement();
1204
1205 writeEndElement();
1206
1207 actionContext.release();
1208 }
1209
1210
1211 public void verbatim( boolean boxed )
1212 {
1213
1214 writeStartElement( ElementTags.CHUNK );
1215 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1216 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1217 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1218 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1219 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1220 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1221
1222 writeStartElement( ElementTags.TABLE );
1223 writeAddAttribute( ElementTags.COLUMNS, "1" );
1224 writeAddAttribute( ElementTags.LEFT, Boolean.TRUE.toString() );
1225 writeAddAttribute( ElementTags.RIGHT, Boolean.TRUE.toString() );
1226 writeAddAttribute( ElementTags.TOP, Boolean.TRUE.toString() );
1227 writeAddAttribute( ElementTags.BOTTOM, Boolean.TRUE.toString() );
1228 writeAddAttribute( ElementTags.ALIGN, ElementTags.ALIGN_CENTER );
1229 writeAddAttribute( ElementTags.TABLEFITSPAGE, Boolean.TRUE.toString() );
1230 writeAddAttribute( ElementTags.CELLSFITPAGE, Boolean.TRUE.toString() );
1231 writeAddAttribute( ElementTags.CELLPADDING, "10" );
1232 writeAddAttribute( ElementTags.WIDTH, "100.0%" );
1233
1234 writeStartElement( ElementTags.ROW );
1235
1236 writeStartElement( ElementTags.CELL );
1237 writeAddAttribute( ElementTags.LEFT, Boolean.TRUE.toString() );
1238 writeAddAttribute( ElementTags.RIGHT, Boolean.TRUE.toString() );
1239 writeAddAttribute( ElementTags.TOP, Boolean.TRUE.toString() );
1240 writeAddAttribute( ElementTags.BOTTOM, Boolean.TRUE.toString() );
1241
1242 actionContext.setAction( SinkActionContext.VERBATIM );
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252 public void figure_()
1253 {
1254 writeEndElement();
1255
1256 writeEndElement();
1257
1258 actionContext.release();
1259
1260 figureDefined = false;
1261 }
1262
1263
1264
1265
1266 public void figure()
1267 {
1268 figureDefined = true;
1269
1270 writeStartElement( ElementTags.CHUNK );
1271 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1272 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1273 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1274 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1275 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1276 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1277
1278 writeStartElement( ElementTags.IMAGE );
1279
1280 actionContext.setAction( SinkActionContext.FIGURE );
1281 }
1282
1283
1284
1285
1286 public void figureCaption_()
1287 {
1288 actionContext.release();
1289 }
1290
1291
1292
1293
1294 public void figureCaption()
1295 {
1296 actionContext.setAction( SinkActionContext.FIGURE_CAPTION );
1297 }
1298
1299
1300
1301
1302
1303
1304 public void figureGraphics( String name )
1305 {
1306 String urlName = null;
1307 File nameFile = null;
1308 if ( ( name.toLowerCase( Locale.ENGLISH ).startsWith( "http://" ) )
1309 || ( name.toLowerCase( Locale.ENGLISH ).startsWith( "https://" ) ) )
1310 {
1311 urlName = name;
1312 }
1313 else
1314 {
1315 if ( System.getProperty( "itext.basedir" ) != null )
1316 {
1317 try
1318 {
1319 nameFile = new File( System.getProperty( "itext.basedir" ), name );
1320 urlName = nameFile.toURI().toURL().toString();
1321 }
1322 catch ( MalformedURLException e )
1323 {
1324 getLog().error( "MalformedURLException: " + e.getMessage(), e );
1325 }
1326 }
1327 else
1328 {
1329 if ( getClassLoader() != null )
1330 {
1331 if ( getClassLoader().getResource( name ) != null )
1332 {
1333 urlName = getClassLoader().getResource( name ).toString();
1334 }
1335 }
1336 else
1337 {
1338 if ( ITextSink.class.getClassLoader().getResource( name ) != null )
1339 {
1340 urlName = ITextSink.class.getClassLoader().getResource( name ).toString();
1341 }
1342 }
1343 }
1344 }
1345
1346 if ( urlName == null )
1347 {
1348 String msg =
1349 "No image '" + name
1350 + "' found in the class loader. Try to call setClassLoader(ClassLoader) before.";
1351 logMessage( "imageNotFound", msg );
1352
1353 return;
1354 }
1355
1356 if ( nameFile != null && !nameFile.exists() )
1357 {
1358 String msg = "No image '" + nameFile + "' found in your system, check the path.";
1359 logMessage( "imageNotFound", msg );
1360
1361 return;
1362 }
1363
1364 boolean figureCalled = figureDefined;
1365 if ( !figureCalled )
1366 {
1367 figure();
1368 }
1369
1370 float width = 0;
1371 float height = 0;
1372 try
1373 {
1374 Image image = Image.getInstance( new URL( urlName ) );
1375 image.scaleToFit( ITextUtil.getDefaultPageSize().width() / 2, ITextUtil.getDefaultPageSize().height() / 2 );
1376 width = image.plainWidth();
1377 height = image.plainHeight();
1378 }
1379 catch ( BadElementException e )
1380 {
1381 getLog().error( "BadElementException: " + e.getMessage(), e );
1382 }
1383 catch ( MalformedURLException e )
1384 {
1385 getLog().error( "MalformedURLException: " + e.getMessage(), e );
1386 }
1387 catch ( IOException e )
1388 {
1389 getLog().error( "IOException: " + e.getMessage(), e );
1390 }
1391
1392 writeAddAttribute( ElementTags.URL, urlName );
1393 writeAddAttribute( ElementTags.ALIGN, ElementTags.ALIGN_MIDDLE );
1394 writeAddAttribute( ElementTags.PLAINWIDTH, String.valueOf( width ) );
1395 writeAddAttribute( ElementTags.PLAINHEIGHT, String.valueOf( height ) );
1396
1397 actionContext.setAction( SinkActionContext.FIGURE_GRAPHICS );
1398
1399 if ( !figureCalled )
1400 {
1401 figure_();
1402 }
1403 }
1404
1405
1406
1407
1408
1409
1410
1411
1412 public void inline()
1413 {
1414 inline( null );
1415 }
1416
1417
1418 public void inline( SinkEventAttributes attributes )
1419 {
1420 List<String> tags = new ArrayList<>();
1421
1422 if ( attributes != null )
1423 {
1424
1425 if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "italic" ) )
1426 {
1427 font.addItalic();
1428 tags.add( 0, "italic" );
1429 }
1430
1431 if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "bold" ) )
1432 {
1433 font.addBold();
1434 tags.add( 0, "bold" );
1435 }
1436
1437 if ( attributes.containsAttribute( SinkEventAttributes.SEMANTICS, "code" ) )
1438 {
1439 font.setMonoSpaced( true );
1440 tags.add( 0, "code" );
1441 }
1442
1443 }
1444
1445 inlineStack.push( tags );
1446 }
1447
1448
1449
1450
1451 public void inline_()
1452 {
1453 for ( String tag: inlineStack.pop() )
1454 {
1455 if ( "italic".equals( tag ) )
1456 {
1457 font.removeItalic();
1458 }
1459 else if ( "bold".equals( tag ) )
1460 {
1461 font.removeBold();
1462 }
1463 else if ( "code".equals( tag ) )
1464 {
1465 font.setMonoSpaced( false );
1466 }
1467 }
1468 }
1469
1470
1471
1472
1473 public void bold_()
1474 {
1475 inline_();
1476 }
1477
1478
1479
1480
1481 public void bold()
1482 {
1483 inline( SinkEventAttributeSet.Semantics.BOLD );
1484 }
1485
1486
1487
1488
1489 public void italic_()
1490 {
1491 inline_();
1492 }
1493
1494
1495
1496
1497 public void italic()
1498 {
1499 inline( SinkEventAttributeSet.Semantics.ITALIC );
1500 }
1501
1502
1503
1504
1505 public void monospaced_()
1506 {
1507 inline_();
1508 }
1509
1510
1511
1512
1513 public void monospaced()
1514 {
1515 inline( SinkEventAttributeSet.Semantics.CODE );
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525 public void link_()
1526 {
1527 writeEndElement();
1528
1529 font.setColor( Color.BLACK );
1530 font.removeUnderlined();
1531
1532 actionContext.release();
1533 }
1534
1535
1536 public void link( String name )
1537 {
1538 if ( name == null )
1539 {
1540 throw new NullPointerException( "Link name cannot be null!" );
1541 }
1542
1543 font.setColor( Color.BLUE );
1544 font.addUnderlined();
1545
1546 writeStartElement( ElementTags.ANCHOR );
1547 if ( StringUtils.isNotEmpty( name ) && name.startsWith( "#" ) && StringUtils.isNotEmpty( header.getTitle() ) )
1548 {
1549 name = "#" + DoxiaUtils.encodeId( header.getTitle(), true ) + "_" + name.substring( 1 );
1550 }
1551 writeAddAttribute( ElementTags.REFERENCE, HtmlTools.escapeHTML( name ) );
1552 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1553 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1554 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1555 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1556 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1557 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1558
1559 actionContext.setAction( SinkActionContext.LINK );
1560 }
1561
1562
1563
1564
1565 public void anchor_()
1566 {
1567 if ( !anchorDefined )
1568 {
1569
1570 writeAddAttribute( ElementTags.BLUE, "255" );
1571 writeAddAttribute( ElementTags.GREEN, "255" );
1572 writeAddAttribute( ElementTags.RED, "255" );
1573
1574 write( "_" );
1575 }
1576
1577 anchorDefined = false;
1578
1579 writeEndElement();
1580
1581 actionContext.release();
1582 }
1583
1584
1585 public void anchor( String name )
1586 {
1587 if ( name == null )
1588 {
1589 throw new NullPointerException( "Anchor name cannot be null!" );
1590 }
1591
1592 if ( StringUtils.isNotEmpty( header.getTitle() ) )
1593 {
1594 name = header.getTitle() + "_" + name;
1595 }
1596 String id = name;
1597
1598 if ( !DoxiaUtils.isValidId( id ) )
1599 {
1600 id = DoxiaUtils.encodeId( name, true );
1601
1602 String msg = "Modified invalid link: '" + name + "' to '" + id + "'";
1603 logMessage( "modifiedLink", msg );
1604 }
1605
1606 writeStartElement( ElementTags.ANCHOR );
1607 writeAddAttribute( ElementTags.NAME, id );
1608 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1609 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1610 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1611
1612 actionContext.setAction( SinkActionContext.ANCHOR );
1613 }
1614
1615
1616
1617
1618
1619
1620
1621
1622 public void lineBreak()
1623 {
1624
1625 if ( ( actionContext.getCurrentAction() == SinkActionContext.AUTHOR )
1626 || ( actionContext.getCurrentAction() == SinkActionContext.DATE )
1627 || ( actionContext.getCurrentAction() == SinkActionContext.TITLE ) )
1628 {
1629 return;
1630 }
1631
1632 writeStartElement( ElementTags.NEWLINE );
1633 writeEndElement();
1634 }
1635
1636
1637
1638
1639 public void nonBreakingSpace()
1640 {
1641 write( " " );
1642 }
1643
1644
1645
1646
1647 public void pageBreak()
1648 {
1649 writeStartElement( ElementTags.NEWPAGE );
1650 writeEndElement();
1651 }
1652
1653
1654
1655
1656 public void horizontalRule()
1657 {
1658 writeStartElement( ElementTags.PARAGRAPH );
1659 writeAddAttribute( ElementTags.BLUE, "255" );
1660 writeAddAttribute( ElementTags.GREEN, "255" );
1661 writeAddAttribute( ElementTags.RED, "255" );
1662 write( "_" );
1663 writeEndElement();
1664
1665 writeStartElement( ElementTags.PARAGRAPH );
1666 writeStartElement( ElementTags.HORIZONTALRULE );
1667 writeEndElement();
1668 writeEndElement();
1669 }
1670
1671
1672
1673
1674
1675
1676 public void rawText( String text )
1677 {
1678 writeStartElement( ElementTags.CHUNK );
1679 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1680 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1681 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1682 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1683 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1684 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1685
1686 write( text, false );
1687
1688 writeEndElement();
1689 }
1690
1691
1692 public void text( String text )
1693 {
1694 if ( StringUtils.isEmpty( text ) )
1695 {
1696 return;
1697 }
1698
1699 switch ( actionContext.getCurrentAction() )
1700 {
1701 case SinkActionContext.AUTHOR:
1702 header.addAuthor( text );
1703 break;
1704
1705 case SinkActionContext.DATE:
1706 header.setDate( text );
1707 break;
1708
1709 case SinkActionContext.TITLE:
1710 header.setTitle( text );
1711 break;
1712
1713 case SinkActionContext.TABLE_CAPTION:
1714 this.tableCaptionXMLWriter.writeText( text );
1715 break;
1716
1717 case SinkActionContext.VERBATIM:
1718
1719 LineNumberReader lnr = new LineNumberReader( new StringReader( text ) );
1720 String line;
1721 try
1722 {
1723 while ( ( line = lnr.readLine() ) != null )
1724 {
1725 writeStartElement( ElementTags.CHUNK );
1726 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1727 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1728 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1729 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1730 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1731 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1732
1733 write( "<![CDATA[", true );
1734
1735 line = StringUtils.replace( line, "<![CDATA[", "< ![CDATA[" );
1736 line = StringUtils.replace( line, "]]>", "]] >" );
1737 write( line, true, false );
1738 write( "]]>", true );
1739
1740 writeEndElement();
1741 lineBreak();
1742 }
1743 }
1744 catch ( IOException e )
1745 {
1746 throw new RuntimeException( "IOException: ", e );
1747 }
1748 break;
1749
1750 case SinkActionContext.FIGURE_CAPTION:
1751 writeAddAttribute( ElementTags.ALT, text );
1752 break;
1753
1754 case SinkActionContext.SECTION_TITLE:
1755 case SinkActionContext.SECTION_1:
1756 case SinkActionContext.SECTION_2:
1757 case SinkActionContext.SECTION_3:
1758 case SinkActionContext.SECTION_4:
1759 case SinkActionContext.SECTION_5:
1760 case SinkActionContext.FIGURE:
1761 case SinkActionContext.FIGURE_GRAPHICS:
1762 case SinkActionContext.TABLE_ROW:
1763 case SinkActionContext.TABLE:
1764 case SinkActionContext.HEAD:
1765 case SinkActionContext.UNDEFINED:
1766 break;
1767
1768 case SinkActionContext.ANCHOR:
1769 anchorDefined = true;
1770 case SinkActionContext.PARAGRAPH:
1771 case SinkActionContext.LINK:
1772 case SinkActionContext.TABLE_CELL:
1773 case SinkActionContext.TABLE_HEADER_CELL:
1774 case SinkActionContext.DEFINITION:
1775 case SinkActionContext.DEFINED_TERM:
1776 case SinkActionContext.NUMBERED_LIST_ITEM:
1777 case SinkActionContext.LIST_ITEM:
1778 case SinkActionContext.SECTION_TITLE_5:
1779 case SinkActionContext.SECTION_TITLE_4:
1780 case SinkActionContext.SECTION_TITLE_3:
1781 case SinkActionContext.SECTION_TITLE_2:
1782 case SinkActionContext.SECTION_TITLE_1:
1783 default:
1784 writeStartElement( ElementTags.CHUNK );
1785 writeAddAttribute( ElementTags.FONT, font.getFontName() );
1786 writeAddAttribute( ElementTags.SIZE, font.getFontSize() );
1787 writeAddAttribute( ElementTags.STYLE, font.getFontStyle() );
1788 writeAddAttribute( ElementTags.BLUE, font.getFontColorBlue() );
1789 writeAddAttribute( ElementTags.GREEN, font.getFontColorGreen() );
1790 writeAddAttribute( ElementTags.RED, font.getFontColorRed() );
1791
1792 write( text );
1793
1794 writeEndElement();
1795 }
1796 }
1797
1798
1799
1800
1801
1802
1803
1804 public void unknown( String name, Object[] requiredParams, SinkEventAttributes attributes )
1805 {
1806 String msg = "Unknown Sink event: '" + name + "', ignoring!";
1807 logMessage( "unknownEvent", msg );
1808 }
1809
1810
1811
1812
1813 protected void init()
1814 {
1815 super.init();
1816
1817 this.actionContext = new SinkActionContext();
1818 this.font = new ITextFont();
1819 this.header = new ITextHeader();
1820
1821 this.numberDepth = 1;
1822 this.depth = 0;
1823 this.tableCaptionWriter = null;
1824 this.tableCaptionXMLWriter = null;
1825 this.anchorDefined = false;
1826 this.figureDefined = false;
1827 this.warnMessages = null;
1828 }
1829
1830
1831
1832
1833
1834
1835 private void writeStartElement( String tag )
1836 {
1837 if ( tableCaptionXMLWriter == null )
1838 {
1839 xmlWriter.startElement( tag );
1840 }
1841 else
1842 {
1843 tableCaptionXMLWriter.startElement( tag );
1844 }
1845 }
1846
1847
1848
1849
1850
1851
1852
1853 private void writeAddAttribute( String key, String value )
1854 {
1855 if ( tableCaptionXMLWriter == null )
1856 {
1857 xmlWriter.addAttribute( key, value );
1858 }
1859 else
1860 {
1861 tableCaptionXMLWriter.addAttribute( key, value );
1862 }
1863 }
1864
1865
1866
1867
1868
1869
1870
1871 private void writeAddAttribute( String key, int value )
1872 {
1873 if ( tableCaptionXMLWriter == null )
1874 {
1875 xmlWriter.addAttribute( key, String.valueOf( value ) );
1876 }
1877 else
1878 {
1879 tableCaptionXMLWriter.addAttribute( key, String.valueOf( value ) );
1880 }
1881 }
1882
1883
1884
1885
1886 private void writeEndElement()
1887 {
1888 if ( tableCaptionXMLWriter == null )
1889 {
1890 xmlWriter.endElement();
1891 }
1892 else
1893 {
1894 tableCaptionXMLWriter.endElement();
1895 }
1896 }
1897
1898
1899
1900
1901
1902
1903 protected void write( String aString )
1904 {
1905 write( aString, false );
1906 }
1907
1908
1909
1910
1911
1912
1913
1914 private void write( String aString, boolean escapeHtml )
1915 {
1916 write( aString, escapeHtml, true );
1917 }
1918
1919
1920
1921
1922
1923
1924
1925
1926 private void write( String aString, boolean escapeHtml, boolean trim )
1927 {
1928 if ( aString == null )
1929 {
1930 return;
1931 }
1932
1933 if ( trim )
1934 {
1935 aString = StringUtils.replace( aString, "\n", "" );
1936
1937 LineNumberReader lnr = new LineNumberReader( new StringReader( aString ) );
1938 StringBuilder sb = new StringBuilder();
1939 String line;
1940 try
1941 {
1942 while ( ( line = lnr.readLine() ) != null )
1943 {
1944 sb.append( beautifyPhrase( line.trim() ) );
1945 sb.append( " " );
1946 }
1947
1948 aString = sb.toString();
1949 }
1950 catch ( IOException e )
1951 {
1952
1953 }
1954 if ( aString.trim().length() == 0 )
1955 {
1956 return;
1957 }
1958 }
1959 if ( escapeHtml )
1960 {
1961 if ( tableCaptionXMLWriter == null )
1962 {
1963 xmlWriter.writeMarkup( aString );
1964 }
1965 else
1966 {
1967 tableCaptionXMLWriter.writeMarkup( aString );
1968 }
1969 }
1970 else
1971 {
1972 if ( tableCaptionXMLWriter == null )
1973 {
1974 xmlWriter.writeText( aString );
1975 }
1976 else
1977 {
1978 tableCaptionXMLWriter.writeText( aString );
1979 }
1980 }
1981 }
1982
1983
1984
1985
1986
1987
1988
1989 private static String beautifyPhrase( String aString )
1990 {
1991 String[] strings = StringUtils.split( aString, " " );
1992 StringBuilder sb = new StringBuilder();
1993 for ( String string : strings )
1994 {
1995 if ( string.trim().length() != 0 )
1996 {
1997 sb.append( string.trim() );
1998 sb.append( " " );
1999 }
2000 }
2001
2002 return sb.toString().trim();
2003 }
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013 private void logMessage( String key, String msg )
2014 {
2015 msg = "[iText Sink] " + msg;
2016 if ( getLog().isDebugEnabled() )
2017 {
2018 getLog().debug( msg );
2019
2020 return;
2021 }
2022
2023 if ( warnMessages == null )
2024 {
2025 warnMessages = new HashMap<>();
2026 }
2027
2028 Set<String> set = warnMessages.get( key );
2029 if ( set == null )
2030 {
2031 set = new TreeSet<>();
2032 }
2033 set.add( msg );
2034 warnMessages.put( key, set );
2035 }
2036 }