1 package org.apache.maven.doxia.module.twiki;
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.StringWriter;
24 import java.io.Writer;
25 import java.util.Stack;
26
27 import javax.swing.text.MutableAttributeSet;
28 import javax.swing.text.html.HTML.Attribute;
29 import javax.swing.text.html.HTML.Tag;
30
31 import org.apache.maven.doxia.sink.AbstractTextSink;
32 import org.apache.maven.doxia.sink.SinkEventAttributeSet;
33 import org.apache.maven.doxia.sink.SinkEventAttributes;
34 import org.apache.maven.doxia.sink.SinkUtils;
35 import org.apache.maven.doxia.util.HtmlTools;
36 import org.codehaus.plexus.util.StringUtils;
37
38
39
40
41
42
43
44
45
46
47 public class TWikiSink
48 extends AbstractTextSink
49 implements TWikiMarkup
50 {
51
52 private final PrintWriter out;
53
54
55 private StringWriter writer;
56
57
58 private boolean boldFlag;
59
60
61 private boolean boldItalicOrMonodpacedFlag;
62
63
64 private boolean headFlag;
65
66 private int levelList = 0;
67
68
69 private final Stack<String> listStyles;
70
71
72
73
74
75
76
77 protected TWikiSink( Writer writer )
78 {
79 this.out = new PrintWriter( writer );
80 this.listStyles = new Stack<String>();
81
82 init();
83 }
84
85
86 public void anchor( String name )
87 {
88 write( EOL );
89 write( ANCHOR_MARKUP + name );
90 }
91
92
93 public void anchor( String name, SinkEventAttributes attributes )
94 {
95 anchor( name );
96 }
97
98
99
100
101
102 public void anchor_()
103 {
104
105 }
106
107
108
109
110
111 public void author()
112 {
113
114 }
115
116
117 public void author( SinkEventAttributes attributes )
118 {
119 author();
120 }
121
122
123
124
125
126 public void author_()
127 {
128
129 }
130
131
132
133
134
135 public void body()
136 {
137
138 }
139
140
141 public void body( SinkEventAttributes attributes )
142 {
143 body();
144 }
145
146
147
148
149
150 public void body_()
151 {
152
153 }
154
155
156 public void bold()
157 {
158 boldFlag = true;
159 write( BOLD_START_MARKUP );
160 }
161
162
163 public void bold_()
164 {
165 boldFlag = false;
166 if ( !boldItalicOrMonodpacedFlag )
167 {
168 write( BOLD_END_MARKUP );
169 }
170 boldItalicOrMonodpacedFlag = false;
171 }
172
173
174
175
176
177 public void comment( String comment )
178 {
179
180 }
181
182
183 public void close()
184 {
185 out.write( writer.toString() );
186 out.close();
187
188 init();
189 }
190
191
192
193
194
195 public void date()
196 {
197
198 }
199
200
201 public void date( SinkEventAttributes attributes )
202 {
203 date();
204 }
205
206
207
208
209
210 public void date_()
211 {
212
213 }
214
215
216
217
218
219 public void definedTerm()
220 {
221
222 }
223
224
225 public void definedTerm( SinkEventAttributes attributes )
226 {
227 definedTerm();
228 }
229
230
231
232
233
234 public void definedTerm_()
235 {
236
237 }
238
239
240 public void definition()
241 {
242 write( DEFINITION_LIST_DEFINITION_MARKUP );
243 }
244
245
246 public void definition( SinkEventAttributes attributes )
247 {
248 definition();
249 }
250
251
252 public void definition_()
253 {
254 writeEOL();
255 }
256
257
258
259
260
261 public void definitionList()
262 {
263
264 }
265
266
267 public void definitionList( SinkEventAttributes attributes )
268 {
269 definitionList();
270 }
271
272
273
274
275
276 public void definitionList_()
277 {
278
279 }
280
281
282 public void definitionListItem()
283 {
284 write( DEFINITION_LIST_ITEM_MARKUP );
285 }
286
287
288 public void definitionListItem( SinkEventAttributes attributes )
289 {
290 definitionListItem();
291 }
292
293
294
295
296
297 public void definitionListItem_()
298 {
299
300 }
301
302
303 public void figure()
304 {
305 write( String.valueOf( LESS_THAN ) + Tag.IMG.toString() + SPACE );
306 }
307
308
309 public void figure( SinkEventAttributes attributes )
310 {
311 figure();
312 }
313
314
315
316
317
318 public void figure_()
319 {
320 write( SLASH + String.valueOf( GREATER_THAN ) );
321 }
322
323
324
325
326
327 public void figureCaption()
328 {
329 write( Attribute.ALT.toString() + EQUAL + QUOTE );
330 }
331
332
333 public void figureCaption( SinkEventAttributes attributes )
334 {
335 figureCaption();
336 }
337
338
339
340
341
342 public void figureCaption_()
343 {
344 write( QUOTE + String.valueOf( SPACE ) );
345 }
346
347
348 public void figureGraphics( String name )
349 {
350 write( Attribute.SRC.toString() + EQUAL + QUOTE + name + QUOTE + String.valueOf( SPACE ) );
351 }
352
353
354 public void figureGraphics( String src, SinkEventAttributes attributes )
355 {
356 figureGraphics( src );
357 }
358
359
360 public void flush()
361 {
362 close();
363 writer.flush();
364 }
365
366
367 public void head()
368 {
369 init();
370
371 headFlag = true;
372 }
373
374
375 public void head( SinkEventAttributes attributes )
376 {
377 head();
378 }
379
380
381 public void head_()
382 {
383 headFlag = false;
384 }
385
386
387 public void horizontalRule()
388 {
389 writeEOL( true );
390 write( HORIZONTAL_RULE_MARKUP );
391 writeEOL( true );
392 }
393
394
395 public void horizontalRule( SinkEventAttributes attributes )
396 {
397 horizontalRule();
398 }
399
400
401 public void italic()
402 {
403 if ( boldFlag )
404 {
405 boldItalicOrMonodpacedFlag = true;
406
407 String tmp = writer.toString();
408 writer = new StringWriter();
409 writer.write( tmp.substring( 0, tmp.length() - 1 ) );
410 write( BOLD_ITALIC_START_MARKUP );
411 }
412 else
413 {
414 write( ITALIC_START_MARKUP );
415 }
416 }
417
418
419 public void italic_()
420 {
421 if ( boldFlag )
422 {
423 write( BOLD_ITALIC_END_MARKUP );
424 }
425 else
426 {
427 write( ITALIC_END_MARKUP );
428 }
429 }
430
431
432
433
434
435 public void lineBreak()
436 {
437
438 }
439
440
441 public void lineBreak( SinkEventAttributes attributes )
442 {
443 lineBreak();
444 }
445
446
447 public void link( String name )
448 {
449 write( LINK_START_MARKUP + name + LINK_MIDDLE_MARKUP );
450 }
451
452
453 public void link( String name, SinkEventAttributes attributes )
454 {
455 link( name );
456 }
457
458
459 public void link_()
460 {
461 write( LINK_END_MARKUP );
462 }
463
464
465 public void list()
466 {
467 if ( !writer.toString().endsWith( EOL + EOL ) )
468 {
469 writeEOL( true );
470 }
471
472 levelList++;
473 }
474
475
476 public void list( SinkEventAttributes attributes )
477 {
478 list();
479 }
480
481
482 public void list_()
483 {
484 levelList--;
485 }
486
487
488 public void listItem()
489 {
490 String indent = StringUtils.repeat( THREE_SPACES_MARKUP, levelList );
491 write( indent + LIST_ITEM_MARKUP );
492 }
493
494
495 public void listItem( SinkEventAttributes attributes )
496 {
497 listItem();
498 }
499
500
501 public void listItem_()
502 {
503 writeEOL( true );
504 }
505
506
507 public void monospaced()
508 {
509 if ( boldFlag )
510 {
511 boldItalicOrMonodpacedFlag = true;
512
513 String tmp = writer.toString();
514 writer = new StringWriter();
515 writer.write( tmp.substring( 0, tmp.length() - 1 ) );
516 write( BOLD_MONOSPACED_START_MARKUP );
517 }
518 else
519 {
520 write( MONOSPACED_START_MARKUP );
521 }
522 }
523
524
525 public void monospaced_()
526 {
527 if ( boldFlag )
528 {
529 write( BOLD_MONOSPACED_END_MARKUP );
530 }
531 else
532 {
533 write( MONOSPACED_END_MARKUP );
534 }
535 }
536
537
538
539
540
541 public void nonBreakingSpace()
542 {
543
544 }
545
546
547 public void numberedList( int numbering )
548 {
549 levelList++;
550
551 String style;
552 switch ( numbering )
553 {
554 case NUMBERING_UPPER_ALPHA:
555 style = NUMBERING_UPPER_ALPHA_MARKUP;
556 break;
557 case NUMBERING_LOWER_ALPHA:
558 style = NUMBERING_LOWER_ALPHA_MARKUP;
559 break;
560 case NUMBERING_UPPER_ROMAN:
561 style = NUMBERING_UPPER_ROMAN_MARKUP;
562 break;
563 case NUMBERING_LOWER_ROMAN:
564 style = NUMBERING_LOWER_ROMAN_MARKUP;
565 break;
566 case NUMBERING_DECIMAL:
567 default:
568 style = NUMBERING_MARKUP;
569 }
570
571 listStyles.push( style );
572 }
573
574
575 public void numberedList( int numbering, SinkEventAttributes attributes )
576 {
577 numberedList( numbering );
578 }
579
580
581 public void numberedList_()
582 {
583 levelList--;
584 listStyles.pop();
585 }
586
587
588 public void numberedListItem()
589 {
590 writeEOL( true );
591 String style = (String) listStyles.peek();
592 String indent = StringUtils.repeat( THREE_SPACES_MARKUP, levelList );
593 write( indent + style + SPACE );
594 }
595
596
597 public void numberedListItem( SinkEventAttributes attributes )
598 {
599 numberedListItem();
600 }
601
602
603 public void numberedListItem_()
604 {
605 writeEOL( true );
606 }
607
608
609
610
611
612 public void pageBreak()
613 {
614
615 }
616
617
618
619
620
621 public void paragraph()
622 {
623
624 }
625
626
627 public void paragraph( SinkEventAttributes attributes )
628 {
629 paragraph();
630 }
631
632
633 public void paragraph_()
634 {
635 writeEOL( true );
636 writeEOL();
637 }
638
639
640
641
642
643 public void rawText( String text )
644 {
645
646 }
647
648
649
650
651
652 public void section( int level, SinkEventAttributes attributes )
653 {
654
655 }
656
657
658
659
660
661 public void section1()
662 {
663
664 }
665
666
667
668
669
670 public void section1_()
671 {
672
673 }
674
675
676
677
678
679 public void section2()
680 {
681
682 }
683
684
685
686
687
688 public void section2_()
689 {
690
691 }
692
693
694
695
696
697 public void section3()
698 {
699
700 }
701
702
703
704
705
706 public void section3_()
707 {
708
709 }
710
711
712
713
714
715 public void section4()
716 {
717
718 }
719
720
721
722
723
724 public void section4_()
725 {
726
727 }
728
729
730
731
732
733 public void section5()
734 {
735
736 }
737
738
739
740
741
742 public void section5_()
743 {
744
745 }
746
747
748
749
750
751 public void section_( int level )
752 {
753
754 }
755
756
757
758
759
760 public void sectionTitle()
761 {
762
763 }
764
765
766 public void sectionTitle( int level, SinkEventAttributes attributes )
767 {
768 if ( level > 0 && level < 6 )
769 {
770 write( StringUtils.repeat( "-", 3 ) + StringUtils.repeat( "+", level ) );
771 }
772 }
773
774
775 public void sectionTitle1()
776 {
777 sectionTitle( 1, null );
778 }
779
780
781 public void sectionTitle1_()
782 {
783 sectionTitle_( 1 );
784 }
785
786
787 public void sectionTitle2()
788 {
789 sectionTitle( 2, null );
790 }
791
792
793 public void sectionTitle2_()
794 {
795 sectionTitle_( 2 );
796 }
797
798
799 public void sectionTitle3()
800 {
801 sectionTitle( 3, null );
802 }
803
804
805 public void sectionTitle3_()
806 {
807 sectionTitle_( 3 );
808 }
809
810
811 public void sectionTitle4()
812 {
813 sectionTitle( 4, null );
814 }
815
816
817 public void sectionTitle4_()
818 {
819 sectionTitle_( 4 );
820 }
821
822
823 public void sectionTitle5()
824 {
825 sectionTitle( 5, null );
826 }
827
828
829 public void sectionTitle5_()
830 {
831 sectionTitle_( 5 );
832 }
833
834
835
836
837
838 public void sectionTitle_()
839 {
840
841 }
842
843
844 public void sectionTitle_( int level )
845 {
846 writeEOL( true );
847 writeEOL();
848 }
849
850
851
852
853
854 public void table()
855 {
856
857 }
858
859
860 public void table( SinkEventAttributes attributes )
861 {
862 table();
863 }
864
865
866
867
868
869 public void table_()
870 {
871
872 }
873
874
875
876
877
878 public void tableCaption()
879 {
880
881 }
882
883
884 public void tableCaption( SinkEventAttributes attributes )
885 {
886 tableCaption();
887 }
888
889
890
891
892
893 public void tableCaption_()
894 {
895
896 }
897
898
899 public void tableCell()
900 {
901 write( " " );
902 }
903
904
905 public void tableCell( SinkEventAttributes attributes )
906 {
907 tableCell();
908 }
909
910
911 public void tableCell( String width )
912 {
913 tableCell();
914 }
915
916
917 public void tableCell_()
918 {
919 write( TABLE_CELL_MARKUP );
920 }
921
922
923 public void tableHeaderCell()
924 {
925 write( TABLE_CELL_HEADER_START_MARKUP );
926 }
927
928
929 public void tableHeaderCell( SinkEventAttributes attributes )
930 {
931 tableHeaderCell();
932 }
933
934
935 public void tableHeaderCell( String width )
936 {
937 tableHeaderCell();
938 }
939
940
941 public void tableHeaderCell_()
942 {
943 write( TABLE_CELL_HEADER_END_MARKUP );
944 }
945
946
947 public void tableRow()
948 {
949 write( TABLE_ROW_MARKUP );
950 }
951
952
953 public void tableRow( SinkEventAttributes attributes )
954 {
955 tableRow();
956 }
957
958
959 public void tableRow_()
960 {
961 writeEOL( true );
962 }
963
964
965
966
967
968 public void tableRows( int[] justification, boolean grid )
969 {
970
971 }
972
973
974
975
976
977 public void tableRows_()
978 {
979
980 }
981
982
983 public void text( String text )
984 {
985 if ( headFlag )
986 {
987 return;
988 }
989
990 content( text );
991 }
992
993
994 public void text( String text, SinkEventAttributes attributes )
995 {
996 if ( attributes == null )
997 {
998 text( text );
999 }
1000 else
1001 {
1002 if ( attributes.containsAttribute( SinkEventAttributes.DECORATION, "underline" ) )
1003 {
1004 writeStartTag( Tag.U );
1005 }
1006 if ( attributes.containsAttribute( SinkEventAttributes.DECORATION, "line-through" ) )
1007 {
1008 writeStartTag( Tag.S );
1009 }
1010 if ( attributes.containsAttribute( SinkEventAttributes.VALIGN, "sub" ) )
1011 {
1012 writeStartTag( Tag.SUB );
1013 }
1014 if ( attributes.containsAttribute( SinkEventAttributes.VALIGN, "sup" ) )
1015 {
1016 writeStartTag( Tag.SUP );
1017 }
1018
1019 text( text );
1020
1021 if ( attributes.containsAttribute( SinkEventAttributes.VALIGN, "sup" ) )
1022 {
1023 writeEndTag( Tag.SUP );
1024 }
1025 if ( attributes.containsAttribute( SinkEventAttributes.VALIGN, "sub" ) )
1026 {
1027 writeEndTag( Tag.SUB );
1028 }
1029 if ( attributes.containsAttribute( SinkEventAttributes.DECORATION, "line-through" ) )
1030 {
1031 writeEndTag( Tag.S );
1032 }
1033 if ( attributes.containsAttribute( SinkEventAttributes.DECORATION, "underline" ) )
1034 {
1035 writeEndTag( Tag.U );
1036 }
1037 }
1038 }
1039
1040
1041
1042
1043
1044 public void title()
1045 {
1046
1047 }
1048
1049
1050 public void title( SinkEventAttributes attributes )
1051 {
1052 title();
1053 }
1054
1055
1056
1057
1058
1059 public void title_()
1060 {
1061
1062 }
1063
1064
1065
1066
1067
1068 public void unknown( String name, Object[] requiredParams, SinkEventAttributes attributes )
1069 {
1070
1071 }
1072
1073
1074 public void verbatim( boolean boxed )
1075 {
1076 SinkEventAttributeSet att = new SinkEventAttributeSet();
1077
1078 if ( boxed )
1079 {
1080 att.addAttribute( SinkEventAttributes.DECORATION, "boxed" );
1081 }
1082
1083 verbatim( att );
1084 }
1085
1086
1087 public void verbatim( SinkEventAttributes attributes )
1088 {
1089 MutableAttributeSet atts = SinkUtils.filterAttributes( attributes, SinkUtils.SINK_VERBATIM_ATTRIBUTES );
1090
1091 if ( atts == null )
1092 {
1093 atts = new SinkEventAttributeSet();
1094 }
1095
1096 boolean boxed = false;
1097
1098 if ( atts.isDefined( SinkEventAttributes.DECORATION ) )
1099 {
1100 boxed = "boxed".equals( atts.getAttribute( SinkEventAttributes.DECORATION ).toString() );
1101 }
1102
1103 if ( boxed )
1104 {
1105 atts.addAttribute( Attribute.CLASS, "source" );
1106 }
1107
1108 atts.removeAttribute( SinkEventAttributes.DECORATION );
1109
1110 String width = (String) atts.getAttribute( Attribute.WIDTH.toString() );
1111 atts.removeAttribute( Attribute.WIDTH.toString() );
1112
1113 writeStartTag( Tag.DIV, atts );
1114 writeEOL( true );
1115
1116 if ( width != null )
1117 {
1118 atts.addAttribute( Attribute.WIDTH.toString(), width );
1119 }
1120
1121 atts.removeAttribute( Attribute.ALIGN.toString() );
1122 atts.removeAttribute( Attribute.CLASS.toString() );
1123
1124 writeStartTag( VERBATIM_TAG, atts );
1125 }
1126
1127
1128 public void verbatim_()
1129 {
1130 writeEndTag( VERBATIM_TAG );
1131 writeEOL( true );
1132 writeEndTag( Tag.DIV );
1133 writeEOL( true );
1134 }
1135
1136
1137
1138
1139
1140 private void write( String text )
1141 {
1142 writer.write( unifyEOLs( text ) );
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 private void writeStartTag( Tag t )
1157 {
1158 writeStartTag( t, null );
1159 }
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174 private void writeStartTag( Tag t, MutableAttributeSet att )
1175 {
1176 writeStartTag( t, att, false );
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 private void writeStartTag( Tag t, MutableAttributeSet att, boolean isSimpleTag )
1193 {
1194 if ( t == null )
1195 {
1196 throw new IllegalArgumentException( "A tag is required" );
1197 }
1198
1199 StringBuffer sb = new StringBuffer();
1200 sb.append( LESS_THAN );
1201
1202 sb.append( t.toString() );
1203
1204 sb.append( SinkUtils.getAttributeString( att ) );
1205
1206 if ( isSimpleTag )
1207 {
1208 sb.append( SPACE ).append( SLASH );
1209 }
1210
1211 sb.append( GREATER_THAN );
1212
1213 write( sb.toString() );
1214 }
1215
1216
1217
1218
1219 private void writeEOL()
1220 {
1221 write( EOL );
1222 }
1223
1224
1225
1226
1227 private void writeEOL( boolean trim )
1228 {
1229 if ( !trim )
1230 {
1231 writeEOL();
1232 return;
1233 }
1234
1235 String tmp = writer.toString().trim();
1236 writer = new StringWriter();
1237 writer.write( tmp );
1238 write( EOL );
1239 }
1240
1241
1242
1243
1244
1245
1246
1247
1248 private void writeEndTag( Tag t )
1249 {
1250 StringBuffer sb = new StringBuffer();
1251 sb.append( LESS_THAN );
1252 sb.append( SLASH );
1253
1254 sb.append( t.toString() );
1255 sb.append( GREATER_THAN );
1256
1257 write( sb.toString() );
1258 }
1259
1260
1261
1262
1263
1264
1265 protected void content( String text )
1266 {
1267 write( escapeHTML( text ) );
1268 }
1269
1270
1271 protected void init()
1272 {
1273 super.init();
1274
1275 this.writer = new StringWriter();
1276 this.headFlag = false;
1277 this.levelList = 0;
1278 this.listStyles.clear();
1279 this.boldFlag = false;
1280 this.boldItalicOrMonodpacedFlag = false;
1281 }
1282
1283
1284
1285
1286
1287
1288
1289
1290 protected static String escapeHTML( String text )
1291 {
1292 return HtmlTools.escapeHTML( text );
1293 }
1294 }