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