1 package org.apache.maven.doxia.module.apt;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.PrintWriter;
23 import java.io.Writer;
24 import java.util.Stack;
25
26 import org.apache.maven.doxia.sink.SinkEventAttributes;
27 import org.apache.maven.doxia.sink.impl.AbstractTextSink;
28 import org.codehaus.plexus.util.StringUtils;
29
30
31
32
33
34
35
36
37
38
39 public class AptSink
40 extends AbstractTextSink
41 implements AptMarkup
42 {
43
44
45
46
47
48 private StringBuffer buffer;
49
50
51 private StringBuilder tableCaptionBuffer;
52
53
54 private String author;
55
56
57 private String title;
58
59
60 private String date;
61
62
63 private boolean startFlag;
64
65
66 private boolean tableCaptionFlag;
67
68
69 private boolean headerFlag;
70
71
72 private boolean bufferFlag;
73
74
75 private boolean itemFlag;
76
77
78 private boolean verbatimFlag;
79
80
81 private boolean isBoxed;
82
83
84 private boolean gridFlag;
85
86
87 private int cellCount;
88
89
90 private final PrintWriter writer;
91
92
93 private int cellJustif[];
94
95
96 private String rowLine;
97
98
99 private String listNestingIndent;
100
101
102 private final Stack<String> listStyles;
103
104
105
106
107
108
109
110
111
112
113
114 protected AptSink( Writer writer )
115 {
116 this.writer = new PrintWriter( writer );
117 this.listStyles = new Stack<String>();
118
119 init();
120 }
121
122
123
124
125
126
127 protected StringBuffer getBuffer()
128 {
129 return buffer;
130 }
131
132
133
134
135
136
137 protected void setHeadFlag( boolean headFlag )
138 {
139 this.headerFlag = headFlag;
140 }
141
142
143
144
145
146
147 protected void resetState()
148 {
149 init();
150 }
151
152
153 protected void init()
154 {
155 super.init();
156
157 resetBuffer();
158
159 this.tableCaptionBuffer = new StringBuilder();
160 this.listNestingIndent = "";
161
162 this.author = null;
163 this.title = null;
164 this.date = null;
165 this.startFlag = true;
166 this.tableCaptionFlag = false;
167 this.headerFlag = false;
168 this.bufferFlag = false;
169 this.itemFlag = false;
170 this.verbatimFlag = false;
171 this.isBoxed = false;
172 this.gridFlag = false;
173 this.cellCount = 0;
174 this.cellJustif = null;
175 this.rowLine = null;
176 this.listStyles.clear();
177 }
178
179
180
181
182 protected void resetBuffer()
183 {
184 buffer = new StringBuffer();
185 }
186
187
188
189
190 protected void resetTableCaptionBuffer()
191 {
192 tableCaptionBuffer = new StringBuilder();
193 }
194
195
196 public void head()
197 {
198 boolean startFlag = this.startFlag;
199
200 init();
201
202 headerFlag = true;
203 this.startFlag = startFlag;
204 }
205
206
207 public void head_()
208 {
209 headerFlag = false;
210
211 if ( ! startFlag )
212 {
213 write( EOL );
214 }
215 write( HEADER_START_MARKUP + EOL );
216 if ( title != null )
217 {
218 write( " " + title + EOL );
219 }
220 write( HEADER_START_MARKUP + EOL );
221 if ( author != null )
222 {
223 write( " " + author + EOL );
224 }
225 write( HEADER_START_MARKUP + EOL );
226 if ( date != null )
227 {
228 write( " " + date + EOL );
229 }
230 write( HEADER_START_MARKUP + EOL );
231 }
232
233
234 public void title_()
235 {
236 if ( buffer.length() > 0 )
237 {
238 title = buffer.toString();
239 resetBuffer();
240 }
241 }
242
243
244 public void author_()
245 {
246 if ( buffer.length() > 0 )
247 {
248 author = buffer.toString();
249 resetBuffer();
250 }
251 }
252
253
254 public void date_()
255 {
256 if ( buffer.length() > 0 )
257 {
258 date = buffer.toString();
259 resetBuffer();
260 }
261 }
262
263
264 public void section1_()
265 {
266 write( EOL );
267 }
268
269
270 public void section2_()
271 {
272 write( EOL );
273 }
274
275
276 public void section3_()
277 {
278 write( EOL );
279 }
280
281
282 public void section4_()
283 {
284 write( EOL );
285 }
286
287
288 public void section5_()
289 {
290 write( EOL );
291 }
292
293
294 public void sectionTitle1()
295 {
296 write( EOL );
297 }
298
299
300 public void sectionTitle1_()
301 {
302 write( EOL + EOL );
303 }
304
305
306 public void sectionTitle2()
307 {
308 write( EOL + SECTION_TITLE_START_MARKUP );
309 }
310
311
312 public void sectionTitle2_()
313 {
314 write( EOL + EOL );
315 }
316
317
318 public void sectionTitle3()
319 {
320 write( EOL + StringUtils.repeat( SECTION_TITLE_START_MARKUP, 2 ) );
321 }
322
323
324 public void sectionTitle3_()
325 {
326 write( EOL + EOL );
327 }
328
329
330 public void sectionTitle4()
331 {
332 write( EOL + StringUtils.repeat( SECTION_TITLE_START_MARKUP, 3 ) );
333 }
334
335
336 public void sectionTitle4_()
337 {
338 write( EOL + EOL );
339 }
340
341
342 public void sectionTitle5()
343 {
344 write( EOL + StringUtils.repeat( SECTION_TITLE_START_MARKUP, 4 ) );
345 }
346
347
348 public void sectionTitle5_()
349 {
350 write( EOL + EOL );
351 }
352
353
354 public void list()
355 {
356 listNestingIndent += " ";
357 listStyles.push( LIST_START_MARKUP );
358 write( EOL );
359 }
360
361
362 public void list_()
363 {
364 if ( listNestingIndent.length() <= 1 )
365 {
366 write( EOL + listNestingIndent + LIST_END_MARKUP + EOL );
367 }
368 else
369 {
370 write( EOL );
371 }
372 listNestingIndent = StringUtils.chomp( listNestingIndent, " " );
373 listStyles.pop();
374 itemFlag = false;
375 }
376
377
378 public void listItem()
379 {
380
381
382
383 numberedListItem();
384 itemFlag = true;
385 }
386
387
388 public void listItem_()
389 {
390 write( EOL );
391 itemFlag = false;
392 }
393
394
395 public void numberedList( int numbering )
396 {
397 listNestingIndent += " ";
398 write( EOL );
399
400 String style;
401 switch ( numbering )
402 {
403 case NUMBERING_UPPER_ALPHA:
404 style = String.valueOf( NUMBERING_UPPER_ALPHA_CHAR );
405 break;
406 case NUMBERING_LOWER_ALPHA:
407 style = String.valueOf( NUMBERING_LOWER_ALPHA_CHAR );
408 break;
409 case NUMBERING_UPPER_ROMAN:
410 style = String.valueOf( NUMBERING_UPPER_ROMAN_CHAR );
411 break;
412 case NUMBERING_LOWER_ROMAN:
413 style = String.valueOf( NUMBERING_LOWER_ROMAN_CHAR );
414 break;
415 case NUMBERING_DECIMAL:
416 default:
417 style = String.valueOf( NUMBERING );
418 }
419
420 listStyles.push( style );
421 }
422
423
424 public void numberedList_()
425 {
426 if ( listNestingIndent.length() <= 1 )
427 {
428 write( EOL + listNestingIndent + LIST_END_MARKUP + EOL );
429 }
430 else
431 {
432 write( EOL );
433 }
434 listNestingIndent = StringUtils.chomp( listNestingIndent, " " );
435 listStyles.pop();
436 itemFlag = false;
437 }
438
439
440 public void numberedListItem()
441 {
442 String style = listStyles.peek();
443 if ( style.equals( String.valueOf( STAR ) ) )
444 {
445 write( EOL + listNestingIndent + String.valueOf( STAR ) + String.valueOf( SPACE ) );
446 }
447 else
448 {
449 write( EOL + listNestingIndent + String.valueOf( LEFT_SQUARE_BRACKET )
450 + String.valueOf( LEFT_SQUARE_BRACKET ) + style + String.valueOf( RIGHT_SQUARE_BRACKET )
451 + String.valueOf( RIGHT_SQUARE_BRACKET ) + String.valueOf( SPACE ) );
452 }
453 itemFlag = true;
454 }
455
456
457 public void numberedListItem_()
458 {
459 write( EOL );
460 itemFlag = false;
461 }
462
463
464 public void definitionList()
465 {
466 listNestingIndent += " ";
467 listStyles.push( "" );
468 write( EOL );
469 }
470
471
472 public void definitionList_()
473 {
474 if ( listNestingIndent.length() <= 1 )
475 {
476 write( EOL + listNestingIndent + LIST_END_MARKUP + EOL );
477 }
478 else
479 {
480 write( EOL );
481 }
482 listNestingIndent = StringUtils.chomp( listNestingIndent, " " );
483 listStyles.pop();
484 itemFlag = false;
485 }
486
487
488 public void definedTerm()
489 {
490 write( EOL + " [" );
491 }
492
493
494 public void definedTerm_()
495 {
496 write( "] " );
497 }
498
499
500 public void definition()
501 {
502 itemFlag = true;
503 }
504
505
506 public void definition_()
507 {
508 write( EOL );
509 itemFlag = false;
510 }
511
512
513 public void pageBreak()
514 {
515 write( EOL + PAGE_BREAK + EOL );
516 }
517
518
519 public void paragraph()
520 {
521 if ( itemFlag )
522 {
523 write( EOL + EOL + " " + listNestingIndent );
524 }
525 else
526 {
527 write( EOL + " " );
528 }
529 }
530
531
532 public void paragraph_()
533 {
534 write( EOL + EOL );
535 }
536
537
538 public void verbatim( boolean boxed )
539 {
540 verbatimFlag = true;
541 this.isBoxed = boxed;
542 write( EOL );
543 if ( boxed )
544 {
545 write( EOL + BOXED_VERBATIM_START_MARKUP + EOL );
546 }
547 else
548 {
549 write( EOL + NON_BOXED_VERBATIM_START_MARKUP + EOL );
550 }
551 }
552
553
554 public void verbatim_()
555 {
556 if ( isBoxed )
557 {
558 write( EOL + BOXED_VERBATIM_END_MARKUP + EOL );
559 }
560 else
561 {
562 write( EOL + NON_BOXED_VERBATIM_END_MARKUP + EOL );
563 }
564 isBoxed = false;
565 verbatimFlag = false;
566 }
567
568
569 public void horizontalRule()
570 {
571 write( EOL + HORIZONTAL_RULE_MARKUP + EOL );
572 }
573
574
575 public void table()
576 {
577 write( EOL );
578 }
579
580
581 public void table_()
582 {
583 if ( rowLine != null )
584 {
585 write( rowLine );
586 }
587 rowLine = null;
588
589 if ( tableCaptionBuffer.length() > 0 )
590 {
591 text( tableCaptionBuffer.toString() + EOL );
592 }
593
594 resetTableCaptionBuffer();
595 }
596
597
598 public void tableRows( int justification[], boolean grid )
599 {
600 cellJustif = justification;
601 gridFlag = grid;
602 }
603
604
605 public void tableRows_()
606 {
607 cellJustif = null;
608 gridFlag = false;
609 }
610
611
612 public void tableRow()
613 {
614 bufferFlag = true;
615 cellCount = 0;
616 }
617
618
619 public void tableRow_()
620 {
621 bufferFlag = false;
622
623
624 buildRowLine();
625
626 write( rowLine );
627
628
629 if ( gridFlag )
630 {
631 write( TABLE_ROW_SEPARATOR_MARKUP );
632 }
633
634 write( buffer.toString() );
635
636 resetBuffer();
637
638 write( EOL );
639
640
641 cellCount = 0;
642 }
643
644
645 private void buildRowLine()
646 {
647 StringBuilder rLine = new StringBuilder();
648 rLine.append( TABLE_ROW_START_MARKUP );
649
650 for ( int i = 0; i < cellCount; i++ )
651 {
652 if ( cellJustif != null )
653 {
654 switch ( cellJustif[i] )
655 {
656 case 1:
657 rLine.append( TABLE_COL_LEFT_ALIGNED_MARKUP );
658 break;
659 case 2:
660 rLine.append( TABLE_COL_RIGHT_ALIGNED_MARKUP );
661 break;
662 default:
663 rLine.append( TABLE_COL_CENTERED_ALIGNED_MARKUP );
664 }
665 }
666 else
667 {
668 rLine.append( TABLE_COL_CENTERED_ALIGNED_MARKUP );
669 }
670 }
671 rLine.append( EOL );
672
673 this.rowLine = rLine.toString();
674 }
675
676
677 public void tableCell()
678 {
679 tableCell( false );
680 }
681
682
683 public void tableHeaderCell()
684 {
685 tableCell( true );
686 }
687
688
689
690
691
692
693 public void tableCell( boolean headerRow )
694 {
695 if ( headerRow )
696 {
697 buffer.append( TABLE_CELL_SEPARATOR_MARKUP );
698 }
699 }
700
701
702 public void tableCell_()
703 {
704 endTableCell();
705 }
706
707
708 public void tableHeaderCell_()
709 {
710 endTableCell();
711 }
712
713
714
715
716 private void endTableCell()
717 {
718 buffer.append( TABLE_CELL_SEPARATOR_MARKUP );
719 cellCount++;
720 }
721
722
723 public void tableCaption()
724 {
725 tableCaptionFlag = true;
726 }
727
728
729 public void tableCaption_()
730 {
731 tableCaptionFlag = false;
732 }
733
734
735 public void figureCaption_()
736 {
737 write( EOL );
738 }
739
740
741 public void figureGraphics( String name )
742 {
743 write( EOL + "[" + name + "] " );
744 }
745
746
747 public void anchor( String name )
748 {
749 write( ANCHOR_START_MARKUP );
750 }
751
752
753 public void anchor_()
754 {
755 write( ANCHOR_END_MARKUP );
756 }
757
758
759 public void link( String name )
760 {
761 if ( !headerFlag )
762 {
763 write( LINK_START_1_MARKUP );
764 text( name.startsWith( "#" ) ? name.substring( 1 ) : name );
765 write( LINK_START_2_MARKUP );
766 }
767 }
768
769
770 public void link_()
771 {
772 if ( !headerFlag )
773 {
774 write( LINK_END_MARKUP );
775 }
776 }
777
778
779
780
781
782
783
784 public void link( String name, String target )
785 {
786 if ( !headerFlag )
787 {
788 write( LINK_START_1_MARKUP );
789 text( target );
790 write( LINK_START_2_MARKUP );
791 text( name );
792 }
793 }
794
795
796 public void italic()
797 {
798 if ( !headerFlag )
799 {
800 write( ITALIC_START_MARKUP );
801 }
802 }
803
804
805 public void italic_()
806 {
807 if ( !headerFlag )
808 {
809 write( ITALIC_END_MARKUP );
810 }
811 }
812
813
814 public void bold()
815 {
816 if ( !headerFlag )
817 {
818 write( BOLD_START_MARKUP );
819 }
820 }
821
822
823 public void bold_()
824 {
825 if ( !headerFlag )
826 {
827 write( BOLD_END_MARKUP );
828 }
829 }
830
831
832 public void monospaced()
833 {
834 if ( !headerFlag )
835 {
836 write( MONOSPACED_START_MARKUP );
837 }
838 }
839
840
841 public void monospaced_()
842 {
843 if ( !headerFlag )
844 {
845 write( MONOSPACED_END_MARKUP );
846 }
847 }
848
849
850 public void lineBreak()
851 {
852 if ( headerFlag || bufferFlag )
853 {
854 buffer.append( EOL );
855 }
856 else if ( verbatimFlag )
857 {
858 write( EOL );
859 }
860 else
861 {
862 write( "\\" + EOL );
863 }
864 }
865
866
867 public void nonBreakingSpace()
868 {
869 if ( headerFlag || bufferFlag )
870 {
871 buffer.append( NON_BREAKING_SPACE_MARKUP );
872 }
873 else
874 {
875 write( NON_BREAKING_SPACE_MARKUP );
876 }
877 }
878
879
880 public void text( String text )
881 {
882 if ( tableCaptionFlag )
883 {
884 tableCaptionBuffer.append( text );
885 }
886 else if ( headerFlag || bufferFlag )
887 {
888 buffer.append( text );
889 }
890 else if ( verbatimFlag )
891 {
892 verbatimContent( text );
893 }
894 else
895 {
896 content( text );
897 }
898 }
899
900
901 public void rawText( String text )
902 {
903 write( text );
904 }
905
906
907 public void comment( String comment )
908 {
909 rawText( ( startFlag ? "" : EOL ) + COMMENT + COMMENT + comment );
910 }
911
912
913
914
915
916
917
918 public void unknown( String name, Object[] requiredParams, SinkEventAttributes attributes )
919 {
920 getLog().warn( "[Apt Sink] Unknown Sink event: '" + name + "', ignoring!" );
921 }
922
923
924
925
926
927
928 protected void write( String text )
929 {
930 startFlag = false;
931 writer.write( unifyEOLs( text ) );
932 }
933
934
935
936
937
938
939 protected void content( String text )
940 {
941 write( escapeAPT( text ) );
942 }
943
944
945
946
947
948
949 protected void verbatimContent( String text )
950 {
951 write( escapeAPT( text ) );
952 }
953
954
955 public void flush()
956 {
957 writer.flush();
958 }
959
960
961 public void close()
962 {
963 writer.close();
964
965 init();
966 }
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982 private static String escapeAPT( String text )
983 {
984 if ( text == null )
985 {
986 return "";
987 }
988
989 int length = text.length();
990 StringBuilder buffer = new StringBuilder( length );
991
992 for ( int i = 0; i < length; ++i )
993 {
994 char c = text.charAt( i );
995 switch ( c )
996 {
997 case '\\':
998 case '~':
999 case '=':
1000 case '-':
1001 case '+':
1002 case '*':
1003 case '[':
1004 case ']':
1005 case '<':
1006 case '>':
1007 case '{':
1008 case '}':
1009 buffer.append( '\\' );
1010 buffer.append( c );
1011 break;
1012 default:
1013 buffer.append( c );
1014 }
1015 }
1016
1017 return buffer.toString();
1018 }
1019 }