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 org.apache.maven.doxia.macro.MacroExecutionException; |
23 | |
import org.apache.maven.doxia.macro.MacroRequest; |
24 | |
import org.apache.maven.doxia.macro.manager.MacroNotFoundException; |
25 | |
import org.apache.maven.doxia.parser.AbstractTextParser; |
26 | |
import org.apache.maven.doxia.parser.ParseException; |
27 | |
import org.apache.maven.doxia.sink.Sink; |
28 | |
import org.apache.maven.doxia.sink.SinkAdapter; |
29 | |
import org.apache.maven.doxia.sink.SinkEventAttributeSet; |
30 | |
import org.apache.maven.doxia.sink.SinkEventAttributes; |
31 | |
import org.apache.maven.doxia.util.DoxiaUtils; |
32 | |
|
33 | |
import org.codehaus.plexus.util.IOUtil; |
34 | |
import org.codehaus.plexus.util.StringUtils; |
35 | |
|
36 | |
import java.io.IOException; |
37 | |
import java.io.Reader; |
38 | |
import java.io.StringReader; |
39 | |
import java.io.StringWriter; |
40 | |
import java.util.HashMap; |
41 | |
import java.util.Map; |
42 | |
import java.util.Set; |
43 | |
import java.util.StringTokenizer; |
44 | |
import java.util.TreeSet; |
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
|
54 | |
|
55 | 68 | public class AptParser |
56 | |
extends AbstractTextParser |
57 | |
implements AptMarkup |
58 | |
{ |
59 | |
|
60 | |
private static final int TITLE = 0; |
61 | |
|
62 | |
|
63 | |
private static final int SECTION1 = 1; |
64 | |
|
65 | |
|
66 | |
private static final int SECTION2 = 2; |
67 | |
|
68 | |
|
69 | |
private static final int SECTION3 = 3; |
70 | |
|
71 | |
|
72 | |
private static final int SECTION4 = 4; |
73 | |
|
74 | |
|
75 | |
private static final int SECTION5 = 5; |
76 | |
|
77 | |
|
78 | |
private static final int PARAGRAPH = 6; |
79 | |
|
80 | |
|
81 | |
private static final int VERBATIM = 7; |
82 | |
|
83 | |
|
84 | |
private static final int FIGURE = 8; |
85 | |
|
86 | |
|
87 | |
private static final int TABLE = 9; |
88 | |
|
89 | |
|
90 | |
private static final int LIST_ITEM = 10; |
91 | |
|
92 | |
|
93 | |
private static final int NUMBERED_LIST_ITEM = 11; |
94 | |
|
95 | |
|
96 | |
private static final int DEFINITION_LIST_ITEM = 12; |
97 | |
|
98 | |
|
99 | |
private static final int HORIZONTAL_RULE = 13; |
100 | |
|
101 | |
|
102 | |
private static final int PG_BREAK = 14; |
103 | |
|
104 | |
|
105 | |
private static final int LIST_BREAK = 15; |
106 | |
|
107 | |
|
108 | |
private static final int MACRO = 16; |
109 | |
|
110 | |
|
111 | |
private static final int COMMENT_BLOCK = 17; |
112 | |
|
113 | |
|
114 | 2 | private static final String TYPE_NAMES[] = { |
115 | |
"TITLE", |
116 | |
"SECTION1", |
117 | |
"SECTION2", |
118 | |
"SECTION3", |
119 | |
"SECTION4", |
120 | |
"SECTION5", |
121 | |
"PARAGRAPH", |
122 | |
"VERBATIM", |
123 | |
"FIGURE", |
124 | |
"TABLE", |
125 | |
"LIST_ITEM", |
126 | |
"NUMBERED_LIST_ITEM", |
127 | |
"DEFINITION_LIST_ITEM", |
128 | |
"HORIZONTAL_RULE", |
129 | |
"PG_BREAK", |
130 | |
"LIST_BREAK", |
131 | |
"MACRO", |
132 | |
"COMMENT_BLOCK" }; |
133 | |
|
134 | |
|
135 | |
protected static final char[] SPACES; |
136 | |
|
137 | |
|
138 | |
public static final int TAB_WIDTH = 8; |
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
private AptSource source; |
146 | |
|
147 | |
|
148 | |
private Block block; |
149 | |
|
150 | |
|
151 | |
private String blockFileName; |
152 | |
|
153 | |
|
154 | |
private int blockLineNumber; |
155 | |
|
156 | |
|
157 | |
protected String sourceContent; |
158 | |
|
159 | |
|
160 | |
protected Sink sink; |
161 | |
|
162 | |
|
163 | |
protected String line; |
164 | |
|
165 | |
|
166 | |
|
167 | |
protected Map<String, Set<String>> warnMessages; |
168 | |
|
169 | |
private static final int NUMBER_OF_SPACES = 85; |
170 | |
|
171 | |
static |
172 | |
{ |
173 | 2 | SPACES = new char[NUMBER_OF_SPACES]; |
174 | |
|
175 | 172 | for ( int i = 0; i < NUMBER_OF_SPACES; i++ ) |
176 | |
{ |
177 | 170 | SPACES[i] = ' '; |
178 | |
} |
179 | 2 | } |
180 | |
|
181 | |
|
182 | |
|
183 | |
|
184 | |
|
185 | |
|
186 | |
public void parse( Reader source, Sink sink ) |
187 | |
throws ParseException |
188 | |
{ |
189 | 36 | init(); |
190 | |
|
191 | |
try |
192 | |
{ |
193 | 36 | StringWriter contentWriter = new StringWriter(); |
194 | 36 | IOUtil.copy( source, contentWriter ); |
195 | 36 | sourceContent = contentWriter.toString(); |
196 | |
} |
197 | 0 | catch ( IOException e ) |
198 | |
{ |
199 | 0 | throw new AptParseException( "IOException: " + e.getMessage(), e ); |
200 | 36 | } |
201 | |
|
202 | |
try |
203 | |
{ |
204 | 36 | this.source = new AptReaderSource( new StringReader( sourceContent ) ); |
205 | |
|
206 | 36 | this.sink = sink; |
207 | 36 | sink.enableLogging( getLog() ); |
208 | |
|
209 | 36 | blockFileName = null; |
210 | |
|
211 | 36 | blockLineNumber = -1; |
212 | |
|
213 | |
|
214 | 36 | nextLine(); |
215 | |
|
216 | |
|
217 | 36 | nextBlock( true ); |
218 | |
|
219 | |
|
220 | 40 | while ( ( block != null ) && ( block.getType() == COMMENT_BLOCK ) ) |
221 | |
{ |
222 | 4 | block.traverse(); |
223 | 4 | nextBlock( true ); |
224 | |
} |
225 | |
|
226 | 36 | traverseHead(); |
227 | |
|
228 | 36 | traverseBody(); |
229 | |
} |
230 | 0 | catch ( AptParseException ape ) |
231 | |
{ |
232 | |
|
233 | 0 | throw new AptParseException( ape.getMessage(), ape, getSourceName(), getSourceLineNumber(), -1 ); |
234 | |
} |
235 | |
finally |
236 | |
{ |
237 | 36 | logWarnings(); |
238 | |
|
239 | 36 | setSecondParsing( false ); |
240 | 36 | init(); |
241 | 36 | } |
242 | 36 | } |
243 | |
|
244 | |
|
245 | |
|
246 | |
|
247 | |
|
248 | |
|
249 | |
public String getSourceName() |
250 | |
{ |
251 | |
|
252 | 0 | return blockFileName; |
253 | |
} |
254 | |
|
255 | |
|
256 | |
|
257 | |
|
258 | |
|
259 | |
|
260 | |
public int getSourceLineNumber() |
261 | |
{ |
262 | |
|
263 | 0 | return blockLineNumber; |
264 | |
} |
265 | |
|
266 | |
|
267 | |
|
268 | |
|
269 | |
|
270 | |
|
271 | |
|
272 | |
|
273 | |
|
274 | |
|
275 | |
protected void nextLine() |
276 | |
throws AptParseException |
277 | |
{ |
278 | 1404 | line = source.getNextLine(); |
279 | 1404 | } |
280 | |
|
281 | |
|
282 | |
|
283 | |
|
284 | |
|
285 | |
|
286 | |
|
287 | |
|
288 | |
|
289 | |
|
290 | |
protected void doTraverseText( String text, int begin, int end, Sink sink ) |
291 | |
throws AptParseException |
292 | |
{ |
293 | 658 | boolean anchor = false; |
294 | 658 | boolean link = false; |
295 | 658 | boolean italic = false; |
296 | 658 | boolean bold = false; |
297 | 658 | boolean monospaced = false; |
298 | 658 | StringBuffer buffer = new StringBuffer( end - begin ); |
299 | |
|
300 | 13280 | for ( int i = begin; i < end; ++i ) |
301 | |
{ |
302 | 12622 | char c = text.charAt( i ); |
303 | 12622 | switch ( c ) |
304 | |
{ |
305 | |
case BACKSLASH: |
306 | 306 | if ( i + 1 < end ) |
307 | |
{ |
308 | 306 | char escaped = text.charAt( i + 1 ); |
309 | 306 | switch ( escaped ) |
310 | |
{ |
311 | |
case SPACE: |
312 | 16 | ++i; |
313 | 16 | flushTraversed( buffer, sink ); |
314 | 16 | sink.nonBreakingSpace(); |
315 | 16 | break; |
316 | |
case '\r': |
317 | |
case '\n': |
318 | 42 | ++i; |
319 | |
|
320 | 56 | while ( i + 1 < end && Character.isWhitespace( text.charAt( i + 1 ) ) ) |
321 | |
{ |
322 | 14 | ++i; |
323 | |
} |
324 | 42 | flushTraversed( buffer, sink ); |
325 | 42 | sink.lineBreak(); |
326 | 42 | break; |
327 | |
case BACKSLASH: |
328 | |
case PIPE: |
329 | |
case COMMENT: |
330 | |
case EQUAL: |
331 | |
case MINUS: |
332 | |
case PLUS: |
333 | |
case STAR: |
334 | |
case LEFT_SQUARE_BRACKET: |
335 | |
case RIGHT_SQUARE_BRACKET: |
336 | |
case LESS_THAN: |
337 | |
case GREATER_THAN: |
338 | |
case LEFT_CURLY_BRACKET: |
339 | |
case RIGHT_CURLY_BRACKET: |
340 | 220 | ++i; |
341 | 220 | buffer.append( escaped ); |
342 | 220 | break; |
343 | |
case 'x': |
344 | 6 | if ( i + 3 < end && isHexChar( text.charAt( i + 2 ) ) |
345 | |
&& isHexChar( text.charAt( i + 3 ) ) ) |
346 | |
{ |
347 | 6 | int value = '?'; |
348 | |
try |
349 | |
{ |
350 | 6 | value = Integer.parseInt( text.substring( i + 2, i + 4 ), 16 ); |
351 | |
} |
352 | 0 | catch ( NumberFormatException e ) |
353 | |
{ |
354 | 0 | if ( getLog().isDebugEnabled() ) |
355 | |
{ |
356 | 0 | getLog().debug( "Not a number: " + text.substring( i + 2, i + 4 ) ); |
357 | |
} |
358 | 6 | } |
359 | |
|
360 | 6 | i += 3; |
361 | 6 | buffer.append( (char) value ); |
362 | 6 | } |
363 | |
else |
364 | |
{ |
365 | 0 | buffer.append( BACKSLASH ); |
366 | |
} |
367 | 0 | break; |
368 | |
case 'u': |
369 | 16 | if ( i + 5 < end && isHexChar( text.charAt( i + 2 ) ) |
370 | |
&& isHexChar( text.charAt( i + 3 ) ) && isHexChar( text.charAt( i + 4 ) ) |
371 | |
&& isHexChar( text.charAt( i + 5 ) ) ) |
372 | |
{ |
373 | 16 | int value = '?'; |
374 | |
try |
375 | |
{ |
376 | 16 | value = Integer.parseInt( text.substring( i + 2, i + 6 ), 16 ); |
377 | |
} |
378 | 0 | catch ( NumberFormatException e ) |
379 | |
{ |
380 | 0 | if ( getLog().isDebugEnabled() ) |
381 | |
{ |
382 | 0 | getLog().debug( "Not a number: " + text.substring( i + 2, i + 6 ) ); |
383 | |
} |
384 | 16 | } |
385 | |
|
386 | 16 | i += 5; |
387 | 16 | buffer.append( (char) value ); |
388 | 16 | } |
389 | |
else |
390 | |
{ |
391 | 0 | buffer.append( BACKSLASH ); |
392 | |
} |
393 | 0 | break; |
394 | |
default: |
395 | 6 | if ( isOctalChar( escaped ) ) |
396 | |
{ |
397 | 6 | int octalChars = 1; |
398 | 6 | if ( isOctalChar( charAt( text, end, i + 2 ) ) ) |
399 | |
{ |
400 | 6 | ++octalChars; |
401 | 6 | if ( isOctalChar( charAt( text, end, i + 3 ) ) ) |
402 | |
{ |
403 | 6 | ++octalChars; |
404 | |
} |
405 | |
} |
406 | 6 | int value = '?'; |
407 | |
try |
408 | |
{ |
409 | 6 | value = Integer.parseInt( text.substring( i + 1, i + 1 + octalChars ), 8 ); |
410 | |
} |
411 | 0 | catch ( NumberFormatException e ) |
412 | |
{ |
413 | 0 | if ( getLog().isDebugEnabled() ) |
414 | |
{ |
415 | 0 | getLog().debug( |
416 | |
"Not a number: " |
417 | |
+ text.substring( i + 1, i + 1 + octalChars ) ); |
418 | |
} |
419 | 6 | } |
420 | |
|
421 | 6 | i += octalChars; |
422 | 6 | buffer.append( (char) value ); |
423 | 6 | } |
424 | |
else |
425 | |
{ |
426 | 0 | buffer.append( BACKSLASH ); |
427 | |
} |
428 | |
} |
429 | 306 | } |
430 | |
else |
431 | |
{ |
432 | 0 | buffer.append( BACKSLASH ); |
433 | |
} |
434 | 0 | break; |
435 | |
|
436 | |
case LEFT_CURLY_BRACKET: |
437 | 88 | if ( !anchor && !link ) |
438 | |
{ |
439 | 88 | if ( i + 1 < end && text.charAt( i + 1 ) == LEFT_CURLY_BRACKET ) |
440 | |
{ |
441 | 36 | ++i; |
442 | 36 | link = true; |
443 | 36 | flushTraversed( buffer, sink ); |
444 | |
|
445 | 36 | String linkAnchor = null; |
446 | |
|
447 | 36 | if ( i + 1 < end && text.charAt( i + 1 ) == LEFT_CURLY_BRACKET ) |
448 | |
{ |
449 | 22 | ++i; |
450 | 22 | StringBuffer buf = new StringBuffer(); |
451 | 22 | i = skipTraversedLinkAnchor( text, i + 1, end, buf ); |
452 | 22 | linkAnchor = buf.toString(); |
453 | |
} |
454 | |
|
455 | 36 | if ( linkAnchor == null ) |
456 | |
{ |
457 | 14 | linkAnchor = getTraversedLink( text, i + 1, end ); |
458 | |
} |
459 | |
|
460 | 36 | if ( AptUtils.isInternalLink( linkAnchor ) ) |
461 | |
{ |
462 | 18 | linkAnchor = "#" + linkAnchor; |
463 | |
} |
464 | |
|
465 | 36 | int hashIndex = linkAnchor.indexOf( "#" ); |
466 | |
|
467 | 36 | if ( hashIndex != -1 && !AptUtils.isExternalLink( linkAnchor ) ) |
468 | |
{ |
469 | 18 | String hash = linkAnchor.substring( hashIndex + 1 ); |
470 | |
|
471 | 18 | if ( hash.endsWith( ".html" ) && !hash.startsWith( "./" ) ) |
472 | |
{ |
473 | 0 | String msg = "Ambiguous link: '" + hash |
474 | |
+ "'. If this is a local link, prepend \"./\"!"; |
475 | 0 | logMessage( "ambiguousLink", msg ); |
476 | |
} |
477 | |
|
478 | 18 | if ( !DoxiaUtils.isValidId( hash ) ) |
479 | |
{ |
480 | 2 | linkAnchor = |
481 | |
linkAnchor.substring( 0, hashIndex ) + "#" |
482 | |
+ DoxiaUtils.encodeId( hash, true ); |
483 | |
|
484 | 2 | String msg = "Modified invalid link: '" + hash + "' to '" + linkAnchor + "'"; |
485 | 2 | logMessage( "modifiedLink", msg ); |
486 | |
} |
487 | |
} |
488 | |
|
489 | 36 | sink.link( linkAnchor ); |
490 | 36 | } |
491 | |
else |
492 | |
{ |
493 | 52 | anchor = true; |
494 | 52 | flushTraversed( buffer, sink ); |
495 | |
|
496 | 52 | String linkAnchor = getTraversedAnchor( text, i + 1, end ); |
497 | |
|
498 | 52 | linkAnchor = AptUtils.encodeAnchor( linkAnchor ); |
499 | |
|
500 | 52 | sink.anchor( linkAnchor ); |
501 | 52 | } |
502 | |
} |
503 | |
else |
504 | |
{ |
505 | 0 | buffer.append( c ); |
506 | |
} |
507 | 0 | break; |
508 | |
|
509 | |
case RIGHT_CURLY_BRACKET: |
510 | 88 | if ( link && i + 1 < end && text.charAt( i + 1 ) == RIGHT_CURLY_BRACKET ) |
511 | |
{ |
512 | 36 | ++i; |
513 | 36 | link = false; |
514 | 36 | flushTraversed( buffer, sink ); |
515 | 36 | sink.link_(); |
516 | |
} |
517 | 52 | else if ( anchor ) |
518 | |
{ |
519 | 52 | anchor = false; |
520 | 52 | flushTraversed( buffer, sink ); |
521 | 52 | sink.anchor_(); |
522 | |
} |
523 | |
else |
524 | |
{ |
525 | 0 | buffer.append( c ); |
526 | |
} |
527 | 0 | break; |
528 | |
|
529 | |
case LESS_THAN: |
530 | 24 | if ( !italic && !bold && !monospaced ) |
531 | |
{ |
532 | 24 | if ( i + 1 < end && text.charAt( i + 1 ) == LESS_THAN ) |
533 | |
{ |
534 | 16 | if ( i + 2 < end && text.charAt( i + 2 ) == LESS_THAN ) |
535 | |
{ |
536 | 8 | i += 2; |
537 | 8 | monospaced = true; |
538 | 8 | flushTraversed( buffer, sink ); |
539 | 8 | sink.monospaced(); |
540 | |
} |
541 | |
else |
542 | |
{ |
543 | 8 | ++i; |
544 | 8 | bold = true; |
545 | 8 | flushTraversed( buffer, sink ); |
546 | 8 | sink.bold(); |
547 | |
} |
548 | |
} |
549 | |
else |
550 | |
{ |
551 | 8 | italic = true; |
552 | 8 | flushTraversed( buffer, sink ); |
553 | 8 | sink.italic(); |
554 | |
} |
555 | |
} |
556 | |
else |
557 | |
{ |
558 | 0 | buffer.append( c ); |
559 | |
} |
560 | 0 | break; |
561 | |
|
562 | |
case GREATER_THAN: |
563 | 24 | if ( monospaced && i + 2 < end && text.charAt( i + 1 ) == GREATER_THAN |
564 | |
&& text.charAt( i + 2 ) == GREATER_THAN ) |
565 | |
{ |
566 | 8 | i += 2; |
567 | 8 | monospaced = false; |
568 | 8 | flushTraversed( buffer, sink ); |
569 | 8 | sink.monospaced_(); |
570 | |
} |
571 | 16 | else if ( bold && i + 1 < end && text.charAt( i + 1 ) == GREATER_THAN ) |
572 | |
{ |
573 | 8 | ++i; |
574 | 8 | bold = false; |
575 | 8 | flushTraversed( buffer, sink ); |
576 | 8 | sink.bold_(); |
577 | |
} |
578 | 8 | else if ( italic ) |
579 | |
{ |
580 | 8 | italic = false; |
581 | 8 | flushTraversed( buffer, sink ); |
582 | 8 | sink.italic_(); |
583 | |
} |
584 | |
else |
585 | |
{ |
586 | 0 | buffer.append( c ); |
587 | |
} |
588 | 0 | break; |
589 | |
|
590 | |
default: |
591 | 12092 | if ( Character.isWhitespace( c ) ) |
592 | |
{ |
593 | 1302 | buffer.append( SPACE ); |
594 | |
|
595 | |
|
596 | 1412 | while ( i + 1 < end && Character.isWhitespace( text.charAt( i + 1 ) ) ) |
597 | |
{ |
598 | 110 | ++i; |
599 | |
} |
600 | |
} |
601 | |
else |
602 | |
{ |
603 | 10790 | buffer.append( c ); |
604 | |
} |
605 | |
} |
606 | |
} |
607 | |
|
608 | 658 | if ( monospaced ) |
609 | |
{ |
610 | 0 | throw new AptParseException( "missing '" + MONOSPACED_END_MARKUP + "'" ); |
611 | |
} |
612 | 658 | if ( bold ) |
613 | |
{ |
614 | 0 | throw new AptParseException( "missing '" + BOLD_END_MARKUP + "'" ); |
615 | |
} |
616 | 658 | if ( italic ) |
617 | |
{ |
618 | 0 | throw new AptParseException( "missing '" + ITALIC_END_MARKUP + "'" ); |
619 | |
} |
620 | 658 | if ( link ) |
621 | |
{ |
622 | 0 | throw new AptParseException( "missing '" + LINK_END_MARKUP + "'" ); |
623 | |
} |
624 | 658 | if ( anchor ) |
625 | |
{ |
626 | 0 | throw new AptParseException( "missing '" + ANCHOR_END_MARKUP + "'" ); |
627 | |
} |
628 | |
|
629 | 658 | flushTraversed( buffer, sink ); |
630 | 658 | } |
631 | |
|
632 | |
|
633 | |
|
634 | |
|
635 | |
|
636 | |
|
637 | |
|
638 | |
|
639 | |
|
640 | |
|
641 | |
|
642 | |
protected static char charAt( String string, int length, int i ) |
643 | |
{ |
644 | 1262 | return ( i < length ) ? string.charAt( i ) : '\0'; |
645 | |
} |
646 | |
|
647 | |
|
648 | |
|
649 | |
|
650 | |
|
651 | |
|
652 | |
|
653 | |
|
654 | |
|
655 | |
protected static int skipSpace( String string, int length, int i ) |
656 | |
{ |
657 | 6234 | loop: for ( ; i < length; ++i ) |
658 | |
{ |
659 | 3352 | switch ( string.charAt( i ) ) |
660 | |
{ |
661 | |
case SPACE: |
662 | |
case TAB: |
663 | 2466 | break; |
664 | |
default: |
665 | 886 | break loop; |
666 | |
} |
667 | |
} |
668 | 1302 | return i; |
669 | |
} |
670 | |
|
671 | |
|
672 | |
|
673 | |
|
674 | |
|
675 | |
|
676 | |
|
677 | |
|
678 | |
|
679 | |
protected static String replaceAll( String string, String oldSub, String newSub ) |
680 | |
{ |
681 | 3170 | StringBuffer replaced = new StringBuffer(); |
682 | 3170 | int oldSubLength = oldSub.length(); |
683 | |
int begin, end; |
684 | |
|
685 | 3170 | begin = 0; |
686 | 3230 | while ( ( end = string.indexOf( oldSub, begin ) ) >= 0 ) |
687 | |
{ |
688 | 60 | if ( end > begin ) |
689 | |
{ |
690 | 58 | replaced.append( string.substring( begin, end ) ); |
691 | |
} |
692 | 60 | replaced.append( newSub ); |
693 | 60 | begin = end + oldSubLength; |
694 | |
} |
695 | 3170 | if ( begin < string.length() ) |
696 | |
{ |
697 | 3168 | replaced.append( string.substring( begin ) ); |
698 | |
} |
699 | |
|
700 | 3170 | return replaced.toString(); |
701 | |
} |
702 | |
|
703 | |
|
704 | |
protected void init() |
705 | |
{ |
706 | 72 | super.init(); |
707 | |
|
708 | 72 | this.sourceContent = null; |
709 | 72 | this.sink = null; |
710 | 72 | this.source = null; |
711 | 72 | this.block = null; |
712 | 72 | this.blockFileName = null; |
713 | 72 | this.blockLineNumber = 0; |
714 | 72 | this.line = null; |
715 | 72 | this.warnMessages = null; |
716 | 72 | } |
717 | |
|
718 | |
|
719 | |
|
720 | |
|
721 | |
|
722 | |
|
723 | |
|
724 | |
|
725 | |
|
726 | |
|
727 | |
private void traverseHead() |
728 | |
throws AptParseException |
729 | |
{ |
730 | 36 | sink.head(); |
731 | |
|
732 | 36 | if ( block != null && block.getType() == TITLE ) |
733 | |
{ |
734 | 18 | block.traverse(); |
735 | 18 | nextBlock(); |
736 | |
} |
737 | |
|
738 | 36 | sink.head_(); |
739 | 36 | } |
740 | |
|
741 | |
|
742 | |
|
743 | |
|
744 | |
|
745 | |
|
746 | |
private void traverseBody() |
747 | |
throws AptParseException |
748 | |
{ |
749 | 36 | sink.body(); |
750 | |
|
751 | 36 | if ( block != null ) |
752 | |
{ |
753 | 36 | traverseSectionBlocks(); |
754 | |
} |
755 | |
|
756 | 66 | while ( block != null ) |
757 | |
{ |
758 | 30 | traverseSection( 0 ); |
759 | |
} |
760 | |
|
761 | 36 | sink.body_(); |
762 | 36 | } |
763 | |
|
764 | |
|
765 | |
|
766 | |
|
767 | |
|
768 | |
|
769 | |
|
770 | |
private void traverseSection( int level ) |
771 | |
throws AptParseException |
772 | |
{ |
773 | 102 | if ( block == null ) |
774 | |
{ |
775 | 0 | return; |
776 | |
} |
777 | |
|
778 | 102 | int type = SECTION1 + level; |
779 | |
|
780 | 102 | expectedBlock( type ); |
781 | |
|
782 | 102 | switch ( level ) |
783 | |
{ |
784 | |
case 0: |
785 | 30 | sink.section1(); |
786 | 30 | break; |
787 | |
case 1: |
788 | 28 | sink.section2(); |
789 | 28 | break; |
790 | |
case 2: |
791 | 16 | sink.section3(); |
792 | 16 | break; |
793 | |
case 3: |
794 | 16 | sink.section4(); |
795 | 16 | break; |
796 | |
case 4: |
797 | 12 | sink.section5(); |
798 | 12 | break; |
799 | |
default: |
800 | |
break; |
801 | |
} |
802 | |
|
803 | 102 | block.traverse(); |
804 | |
|
805 | 102 | nextBlock(); |
806 | |
|
807 | 102 | traverseSectionBlocks(); |
808 | |
|
809 | 174 | while ( block != null ) |
810 | |
{ |
811 | 118 | if ( block.getType() <= type ) |
812 | |
{ |
813 | 46 | break; |
814 | |
} |
815 | |
|
816 | 72 | traverseSection( level + 1 ); |
817 | |
} |
818 | |
|
819 | 102 | switch ( level ) |
820 | |
{ |
821 | |
case 0: |
822 | 30 | sink.section1_(); |
823 | 30 | break; |
824 | |
case 1: |
825 | 28 | sink.section2_(); |
826 | 28 | break; |
827 | |
case 2: |
828 | 16 | sink.section3_(); |
829 | 16 | break; |
830 | |
case 3: |
831 | 16 | sink.section4_(); |
832 | 16 | break; |
833 | |
case 4: |
834 | 12 | sink.section5_(); |
835 | 12 | break; |
836 | |
default: |
837 | |
break; |
838 | |
} |
839 | 102 | } |
840 | |
|
841 | |
|
842 | |
|
843 | |
|
844 | |
|
845 | |
|
846 | |
private void traverseSectionBlocks() |
847 | |
throws AptParseException |
848 | |
{ |
849 | 392 | loop: while ( block != null ) |
850 | |
{ |
851 | 356 | switch ( block.getType() ) |
852 | |
{ |
853 | |
case PARAGRAPH: |
854 | |
case VERBATIM: |
855 | |
case FIGURE: |
856 | |
case TABLE: |
857 | |
case HORIZONTAL_RULE: |
858 | |
case PG_BREAK: |
859 | |
case MACRO: |
860 | |
case COMMENT_BLOCK: |
861 | 228 | block.traverse(); |
862 | 228 | nextBlock(); |
863 | 228 | break; |
864 | |
|
865 | |
case LIST_ITEM: |
866 | 10 | traverseList(); |
867 | 10 | break; |
868 | |
|
869 | |
case NUMBERED_LIST_ITEM: |
870 | 8 | traverseNumberedList(); |
871 | 8 | break; |
872 | |
|
873 | |
case DEFINITION_LIST_ITEM: |
874 | 8 | traverseDefinitionList(); |
875 | 8 | break; |
876 | |
|
877 | |
case LIST_BREAK: |
878 | |
|
879 | |
|
880 | 0 | nextBlock(); |
881 | 0 | break; |
882 | |
|
883 | |
default: |
884 | |
|
885 | 102 | break loop; |
886 | |
} |
887 | |
} |
888 | 138 | } |
889 | |
|
890 | |
|
891 | |
|
892 | |
|
893 | |
|
894 | |
|
895 | |
private void traverseList() |
896 | |
throws AptParseException |
897 | |
{ |
898 | 18 | if ( block == null ) |
899 | |
{ |
900 | 0 | return; |
901 | |
} |
902 | |
|
903 | 18 | expectedBlock( LIST_ITEM ); |
904 | |
|
905 | 18 | int listIndent = block.getIndent(); |
906 | |
|
907 | 18 | sink.list(); |
908 | |
|
909 | 18 | sink.listItem(); |
910 | |
|
911 | 18 | block.traverse(); |
912 | |
|
913 | 18 | nextBlock(); |
914 | |
|
915 | 68 | loop: while ( block != null ) |
916 | |
{ |
917 | 66 | int blockIndent = block.getIndent(); |
918 | |
|
919 | 66 | switch ( block.getType() ) |
920 | |
{ |
921 | |
case PARAGRAPH: |
922 | 12 | if ( blockIndent < listIndent ) |
923 | |
{ |
924 | 0 | break loop; |
925 | |
} |
926 | |
|
927 | |
case VERBATIM: |
928 | |
case MACRO: |
929 | |
case FIGURE: |
930 | |
case TABLE: |
931 | |
case HORIZONTAL_RULE: |
932 | |
case PG_BREAK: |
933 | 16 | block.traverse(); |
934 | 16 | nextBlock(); |
935 | 16 | break; |
936 | |
|
937 | |
case LIST_ITEM: |
938 | 42 | if ( blockIndent < listIndent ) |
939 | |
{ |
940 | 8 | break loop; |
941 | |
} |
942 | |
|
943 | 34 | if ( blockIndent > listIndent ) |
944 | |
{ |
945 | 8 | traverseList(); |
946 | |
} |
947 | |
else |
948 | |
{ |
949 | 26 | sink.listItem_(); |
950 | 26 | sink.listItem(); |
951 | 26 | block.traverse(); |
952 | 26 | nextBlock(); |
953 | |
} |
954 | 26 | break; |
955 | |
|
956 | |
case NUMBERED_LIST_ITEM: |
957 | 0 | if ( blockIndent < listIndent ) |
958 | |
{ |
959 | 0 | break loop; |
960 | |
} |
961 | |
|
962 | 0 | traverseNumberedList(); |
963 | 0 | break; |
964 | |
|
965 | |
case DEFINITION_LIST_ITEM: |
966 | 0 | if ( blockIndent < listIndent ) |
967 | |
{ |
968 | 0 | break loop; |
969 | |
} |
970 | |
|
971 | 0 | traverseDefinitionList(); |
972 | 0 | break; |
973 | |
|
974 | |
case LIST_BREAK: |
975 | 8 | if ( blockIndent >= listIndent ) |
976 | |
{ |
977 | 8 | nextBlock(); |
978 | |
} |
979 | |
|
980 | |
default: |
981 | |
|
982 | 8 | break loop; |
983 | |
} |
984 | 50 | } |
985 | |
|
986 | 18 | sink.listItem_(); |
987 | 18 | sink.list_(); |
988 | 18 | } |
989 | |
|
990 | |
|
991 | |
|
992 | |
|
993 | |
|
994 | |
|
995 | |
private void traverseNumberedList() |
996 | |
throws AptParseException |
997 | |
{ |
998 | 16 | if ( block == null ) |
999 | |
{ |
1000 | 0 | return; |
1001 | |
} |
1002 | 16 | expectedBlock( NUMBERED_LIST_ITEM ); |
1003 | 16 | int listIndent = block.getIndent(); |
1004 | |
|
1005 | 16 | sink.numberedList( ( (NumberedListItem) block ).getNumbering() ); |
1006 | 16 | sink.numberedListItem(); |
1007 | 16 | block.traverse(); |
1008 | 16 | nextBlock(); |
1009 | |
|
1010 | 40 | loop: while ( block != null ) |
1011 | |
{ |
1012 | 40 | int blockIndent = block.getIndent(); |
1013 | |
|
1014 | 40 | switch ( block.getType() ) |
1015 | |
{ |
1016 | |
case PARAGRAPH: |
1017 | 6 | if ( blockIndent < listIndent ) |
1018 | |
{ |
1019 | 6 | break loop; |
1020 | |
} |
1021 | |
|
1022 | |
case VERBATIM: |
1023 | |
case FIGURE: |
1024 | |
case TABLE: |
1025 | |
case HORIZONTAL_RULE: |
1026 | |
case PG_BREAK: |
1027 | 0 | block.traverse(); |
1028 | 0 | nextBlock(); |
1029 | 0 | break; |
1030 | |
|
1031 | |
case LIST_ITEM: |
1032 | 0 | if ( blockIndent < listIndent ) |
1033 | |
{ |
1034 | 0 | break loop; |
1035 | |
} |
1036 | |
|
1037 | 0 | traverseList(); |
1038 | 0 | break; |
1039 | |
|
1040 | |
case NUMBERED_LIST_ITEM: |
1041 | 32 | if ( blockIndent < listIndent ) |
1042 | |
{ |
1043 | 8 | break loop; |
1044 | |
} |
1045 | |
|
1046 | 24 | if ( blockIndent > listIndent ) |
1047 | |
{ |
1048 | 8 | traverseNumberedList(); |
1049 | |
} |
1050 | |
else |
1051 | |
{ |
1052 | 16 | sink.numberedListItem_(); |
1053 | 16 | sink.numberedListItem(); |
1054 | 16 | block.traverse(); |
1055 | 16 | nextBlock(); |
1056 | |
} |
1057 | 16 | break; |
1058 | |
|
1059 | |
case DEFINITION_LIST_ITEM: |
1060 | 0 | if ( blockIndent < listIndent ) |
1061 | |
{ |
1062 | 0 | break loop; |
1063 | |
} |
1064 | |
|
1065 | 0 | traverseDefinitionList(); |
1066 | 0 | break; |
1067 | |
|
1068 | |
case LIST_BREAK: |
1069 | 2 | if ( blockIndent >= listIndent ) |
1070 | |
{ |
1071 | 2 | nextBlock(); |
1072 | |
} |
1073 | |
|
1074 | |
default: |
1075 | |
|
1076 | 2 | break loop; |
1077 | |
} |
1078 | 24 | } |
1079 | |
|
1080 | 16 | sink.numberedListItem_(); |
1081 | 16 | sink.numberedList_(); |
1082 | 16 | } |
1083 | |
|
1084 | |
|
1085 | |
|
1086 | |
|
1087 | |
|
1088 | |
|
1089 | |
private void traverseDefinitionList() |
1090 | |
throws AptParseException |
1091 | |
{ |
1092 | 8 | if ( block == null ) |
1093 | |
{ |
1094 | 0 | return; |
1095 | |
} |
1096 | 8 | expectedBlock( DEFINITION_LIST_ITEM ); |
1097 | 8 | int listIndent = block.getIndent(); |
1098 | |
|
1099 | 8 | sink.definitionList(); |
1100 | 8 | sink.definitionListItem(); |
1101 | 8 | block.traverse(); |
1102 | 8 | nextBlock(); |
1103 | |
|
1104 | 24 | loop: while ( block != null ) |
1105 | |
{ |
1106 | 24 | int blockIndent = block.getIndent(); |
1107 | |
|
1108 | 24 | switch ( block.getType() ) |
1109 | |
{ |
1110 | |
case PARAGRAPH: |
1111 | 6 | if ( blockIndent < listIndent ) |
1112 | |
{ |
1113 | 6 | break loop; |
1114 | |
} |
1115 | |
|
1116 | |
case VERBATIM: |
1117 | |
case FIGURE: |
1118 | |
case TABLE: |
1119 | |
case HORIZONTAL_RULE: |
1120 | |
case PG_BREAK: |
1121 | 8 | block.traverse(); |
1122 | 8 | nextBlock(); |
1123 | 8 | break; |
1124 | |
|
1125 | |
case LIST_ITEM: |
1126 | 0 | if ( blockIndent < listIndent ) |
1127 | |
{ |
1128 | 0 | break loop; |
1129 | |
} |
1130 | |
|
1131 | 0 | traverseList(); |
1132 | 0 | break; |
1133 | |
|
1134 | |
case NUMBERED_LIST_ITEM: |
1135 | 0 | if ( blockIndent < listIndent ) |
1136 | |
{ |
1137 | 0 | break loop; |
1138 | |
} |
1139 | |
|
1140 | 0 | traverseNumberedList(); |
1141 | 0 | break; |
1142 | |
|
1143 | |
case DEFINITION_LIST_ITEM: |
1144 | 8 | if ( blockIndent < listIndent ) |
1145 | |
{ |
1146 | 0 | break loop; |
1147 | |
} |
1148 | |
|
1149 | 8 | if ( blockIndent > listIndent ) |
1150 | |
{ |
1151 | 0 | traverseDefinitionList(); |
1152 | |
} |
1153 | |
else |
1154 | |
{ |
1155 | 8 | sink.definition_(); |
1156 | 8 | sink.definitionListItem_(); |
1157 | 8 | sink.definitionListItem(); |
1158 | 8 | block.traverse(); |
1159 | 8 | nextBlock(); |
1160 | |
} |
1161 | 8 | break; |
1162 | |
|
1163 | |
case LIST_BREAK: |
1164 | 2 | if ( blockIndent >= listIndent ) |
1165 | |
{ |
1166 | 2 | nextBlock(); |
1167 | |
} |
1168 | |
|
1169 | |
default: |
1170 | |
|
1171 | 2 | break loop; |
1172 | |
} |
1173 | 16 | } |
1174 | |
|
1175 | 8 | sink.definition_(); |
1176 | 8 | sink.definitionListItem_(); |
1177 | 8 | sink.definitionList_(); |
1178 | 8 | } |
1179 | |
|
1180 | |
|
1181 | |
|
1182 | |
|
1183 | |
|
1184 | |
|
1185 | |
private void nextBlock() |
1186 | |
throws AptParseException |
1187 | |
{ |
1188 | 476 | nextBlock( false ); |
1189 | 476 | } |
1190 | |
|
1191 | |
|
1192 | |
|
1193 | |
|
1194 | |
|
1195 | |
|
1196 | |
|
1197 | |
private void nextBlock( boolean firstBlock ) |
1198 | |
throws AptParseException |
1199 | |
{ |
1200 | |
|
1201 | |
int length, indent, i; |
1202 | |
|
1203 | |
skipLoop: for ( ;; ) |
1204 | |
{ |
1205 | 606 | if ( line == null ) |
1206 | |
{ |
1207 | 36 | block = null; |
1208 | 36 | return; |
1209 | |
} |
1210 | |
|
1211 | 570 | length = line.length(); |
1212 | 570 | indent = 0; |
1213 | 1756 | for ( i = 0; i < length; ++i ) |
1214 | |
{ |
1215 | 1666 | switch ( line.charAt( i ) ) |
1216 | |
{ |
1217 | |
case SPACE: |
1218 | 1186 | ++indent; |
1219 | 1186 | break; |
1220 | |
case TAB: |
1221 | 0 | indent += 8; |
1222 | 0 | break; |
1223 | |
default: |
1224 | 480 | break skipLoop; |
1225 | |
} |
1226 | |
} |
1227 | |
|
1228 | 90 | if ( i == length ) |
1229 | |
{ |
1230 | 90 | nextLine(); |
1231 | |
} |
1232 | |
} |
1233 | |
|
1234 | 480 | blockFileName = source.getName(); |
1235 | 480 | blockLineNumber = source.getLineNumber(); |
1236 | 480 | block = null; |
1237 | 480 | switch ( line.charAt( i ) ) |
1238 | |
{ |
1239 | |
case STAR: |
1240 | 148 | if ( indent == 0 ) |
1241 | |
{ |
1242 | 104 | if ( charAt( line, length, i + 1 ) == MINUS && charAt( line, length, i + 2 ) == MINUS ) |
1243 | |
{ |
1244 | 32 | block = new Table( indent, line ); |
1245 | |
} |
1246 | 72 | else if ( charAt( line, length, i + 1 ) == STAR ) |
1247 | |
{ |
1248 | 44 | if ( charAt( line, length, i + 2 ) == STAR ) |
1249 | |
{ |
1250 | 28 | if ( charAt( line, length, i + 3 ) == STAR ) |
1251 | |
{ |
1252 | 12 | block = new Section5( indent, line ); |
1253 | |
} |
1254 | |
else |
1255 | |
{ |
1256 | 16 | block = new Section4( indent, line ); |
1257 | |
} |
1258 | |
} |
1259 | |
else |
1260 | |
{ |
1261 | 16 | block = new Section3( indent, line ); |
1262 | |
} |
1263 | |
} |
1264 | |
else |
1265 | |
{ |
1266 | 28 | block = new Section2( indent, line ); |
1267 | |
} |
1268 | |
} |
1269 | |
else |
1270 | |
{ |
1271 | 44 | block = new ListItem( indent, line ); |
1272 | |
} |
1273 | 44 | break; |
1274 | |
case LEFT_SQUARE_BRACKET: |
1275 | 68 | if ( charAt( line, length, i + 1 ) == RIGHT_SQUARE_BRACKET ) |
1276 | |
{ |
1277 | 12 | block = new ListBreak( indent, line ); |
1278 | |
} |
1279 | |
else |
1280 | |
{ |
1281 | 56 | if ( indent == 0 ) |
1282 | |
{ |
1283 | 8 | block = new Figure( indent, line ); |
1284 | |
} |
1285 | |
else |
1286 | |
{ |
1287 | 48 | if ( charAt( line, length, i + 1 ) == LEFT_SQUARE_BRACKET ) |
1288 | |
{ |
1289 | |
int numbering; |
1290 | |
|
1291 | 32 | switch ( charAt( line, length, i + 2 ) ) |
1292 | |
{ |
1293 | |
case NUMBERING_LOWER_ALPHA_CHAR: |
1294 | 0 | numbering = Sink.NUMBERING_LOWER_ALPHA; |
1295 | 0 | break; |
1296 | |
case NUMBERING_UPPER_ALPHA_CHAR: |
1297 | 10 | numbering = Sink.NUMBERING_UPPER_ALPHA; |
1298 | 10 | break; |
1299 | |
case NUMBERING_LOWER_ROMAN_CHAR: |
1300 | 0 | numbering = Sink.NUMBERING_LOWER_ROMAN; |
1301 | 0 | break; |
1302 | |
case NUMBERING_UPPER_ROMAN_CHAR: |
1303 | 0 | numbering = Sink.NUMBERING_UPPER_ROMAN; |
1304 | 0 | break; |
1305 | |
case NUMBERING: |
1306 | |
default: |
1307 | |
|
1308 | |
|
1309 | 22 | numbering = Sink.NUMBERING_DECIMAL; |
1310 | |
} |
1311 | |
|
1312 | 32 | block = new NumberedListItem( indent, line, numbering ); |
1313 | 32 | } |
1314 | |
else |
1315 | |
{ |
1316 | 16 | block = new DefinitionListItem( indent, line ); |
1317 | |
} |
1318 | |
} |
1319 | |
} |
1320 | 16 | break; |
1321 | |
case MINUS: |
1322 | 26 | if ( charAt( line, length, i + 1 ) == MINUS && charAt( line, length, i + 2 ) == MINUS ) |
1323 | |
{ |
1324 | 26 | if ( indent == 0 ) |
1325 | |
{ |
1326 | 2 | block = new Verbatim( indent, line ); |
1327 | |
} |
1328 | |
else |
1329 | |
{ |
1330 | 24 | if ( firstBlock ) |
1331 | |
{ |
1332 | 18 | block = new Title( indent, line ); |
1333 | |
} |
1334 | |
} |
1335 | |
} |
1336 | |
break; |
1337 | |
case PLUS: |
1338 | 20 | if ( indent == 0 && charAt( line, length, i + 1 ) == MINUS && charAt( line, length, i + 2 ) == MINUS ) |
1339 | |
{ |
1340 | 20 | block = new Verbatim( indent, line ); |
1341 | |
} |
1342 | |
break; |
1343 | |
case EQUAL: |
1344 | 8 | if ( indent == 0 && charAt( line, length, i + 1 ) == EQUAL && charAt( line, length, i + 2 ) == EQUAL ) |
1345 | |
{ |
1346 | 8 | block = new HorizontalRule( indent, line ); |
1347 | |
} |
1348 | |
break; |
1349 | |
case PAGE_BREAK: |
1350 | 8 | if ( indent == 0 ) |
1351 | |
{ |
1352 | 8 | block = new PageBreak( indent, line ); |
1353 | |
} |
1354 | |
break; |
1355 | |
case PERCENT: |
1356 | 10 | if ( indent == 0 && charAt( line, length, i + 1 ) == LEFT_CURLY_BRACKET ) |
1357 | |
{ |
1358 | 10 | block = new MacroBlock( indent, line ); |
1359 | |
} |
1360 | |
break; |
1361 | |
case COMMENT: |
1362 | 12 | if ( charAt( line, length, i + 1 ) == COMMENT ) |
1363 | |
{ |
1364 | 12 | block = new Comment( line.substring( i + 2 ).trim() ); |
1365 | |
} |
1366 | |
break; |
1367 | |
default: |
1368 | |
break; |
1369 | |
} |
1370 | |
|
1371 | 480 | if ( block == null ) |
1372 | |
{ |
1373 | 186 | if ( indent == 0 ) |
1374 | |
{ |
1375 | 30 | block = new Section1( indent, line ); |
1376 | |
} |
1377 | |
else |
1378 | |
{ |
1379 | 156 | block = new Paragraph( indent, line ); |
1380 | |
} |
1381 | |
} |
1382 | 480 | } |
1383 | |
|
1384 | |
|
1385 | |
|
1386 | |
|
1387 | |
|
1388 | |
|
1389 | |
|
1390 | |
private void expectedBlock( int type ) |
1391 | |
throws AptParseException |
1392 | |
{ |
1393 | 144 | int blockType = block.getType(); |
1394 | |
|
1395 | 144 | if ( blockType != type ) |
1396 | |
{ |
1397 | 0 | throw new AptParseException( "expected " + TYPE_NAMES[type] + ", found " + TYPE_NAMES[blockType] ); |
1398 | |
} |
1399 | 144 | } |
1400 | |
|
1401 | |
|
1402 | |
|
1403 | |
|
1404 | |
|
1405 | |
|
1406 | |
|
1407 | |
|
1408 | |
|
1409 | |
private static boolean isOctalChar( char c ) |
1410 | |
{ |
1411 | 18 | return ( c >= '0' && c <= '7' ); |
1412 | |
} |
1413 | |
|
1414 | |
|
1415 | |
|
1416 | |
|
1417 | |
|
1418 | |
|
1419 | |
|
1420 | |
private static boolean isHexChar( char c ) |
1421 | |
{ |
1422 | 76 | return ( ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) ); |
1423 | |
} |
1424 | |
|
1425 | |
|
1426 | |
|
1427 | |
|
1428 | |
|
1429 | |
|
1430 | |
|
1431 | |
private static void flushTraversed( StringBuffer buffer, Sink sink ) |
1432 | |
{ |
1433 | 940 | if ( buffer.length() > 0 ) |
1434 | |
{ |
1435 | 836 | sink.text( buffer.toString() ); |
1436 | 836 | buffer.setLength( 0 ); |
1437 | |
} |
1438 | 940 | } |
1439 | |
|
1440 | |
|
1441 | |
|
1442 | |
|
1443 | |
|
1444 | |
|
1445 | |
|
1446 | |
|
1447 | |
|
1448 | |
|
1449 | |
|
1450 | |
private static int skipTraversedLinkAnchor( String text, int begin, int end, StringBuffer linkAnchor ) |
1451 | |
throws AptParseException |
1452 | |
{ |
1453 | |
int i; |
1454 | 360 | loop: for ( i = begin; i < end; ++i ) |
1455 | |
{ |
1456 | 360 | char c = text.charAt( i ); |
1457 | 360 | switch ( c ) |
1458 | |
{ |
1459 | |
case RIGHT_CURLY_BRACKET: |
1460 | 22 | break loop; |
1461 | |
case BACKSLASH: |
1462 | 0 | if ( i + 1 < end ) |
1463 | |
{ |
1464 | 0 | ++i; |
1465 | 0 | linkAnchor.append( text.charAt( i ) ); |
1466 | |
} |
1467 | |
else |
1468 | |
{ |
1469 | 0 | linkAnchor.append( BACKSLASH ); |
1470 | |
} |
1471 | 0 | break; |
1472 | |
default: |
1473 | 338 | linkAnchor.append( c ); |
1474 | |
} |
1475 | |
} |
1476 | 22 | if ( i == end ) |
1477 | |
{ |
1478 | 0 | throw new AptParseException( "missing '" + RIGHT_CURLY_BRACKET + "'" ); |
1479 | |
} |
1480 | |
|
1481 | 22 | return i; |
1482 | |
} |
1483 | |
|
1484 | |
|
1485 | |
|
1486 | |
|
1487 | |
|
1488 | |
|
1489 | |
|
1490 | |
|
1491 | |
|
1492 | |
|
1493 | |
private String getTraversedLink( String text, int begin, int end ) |
1494 | |
throws AptParseException |
1495 | |
{ |
1496 | 14 | char previous2 = LEFT_CURLY_BRACKET; |
1497 | 14 | char previous = LEFT_CURLY_BRACKET; |
1498 | |
int i; |
1499 | |
|
1500 | 256 | for ( i = begin; i < end; ++i ) |
1501 | |
{ |
1502 | 256 | char c = text.charAt( i ); |
1503 | 256 | if ( c == RIGHT_CURLY_BRACKET && previous == RIGHT_CURLY_BRACKET && previous2 != BACKSLASH ) |
1504 | |
{ |
1505 | 14 | break; |
1506 | |
} |
1507 | |
|
1508 | 242 | previous2 = previous; |
1509 | 242 | previous = c; |
1510 | |
} |
1511 | 14 | if ( i == end ) |
1512 | |
{ |
1513 | 0 | throw new AptParseException( "missing '" + LEFT_CURLY_BRACKET + LEFT_CURLY_BRACKET + "'" ); |
1514 | |
} |
1515 | |
|
1516 | 14 | return doGetTraversedLink( text, begin, i - 1 ); |
1517 | |
} |
1518 | |
|
1519 | |
|
1520 | |
|
1521 | |
|
1522 | |
|
1523 | |
|
1524 | |
|
1525 | |
|
1526 | |
|
1527 | |
|
1528 | |
private String getTraversedAnchor( String text, int begin, int end ) |
1529 | |
throws AptParseException |
1530 | |
{ |
1531 | 52 | char previous = LEFT_CURLY_BRACKET; |
1532 | |
int i; |
1533 | |
|
1534 | 972 | for ( i = begin; i < end; ++i ) |
1535 | |
{ |
1536 | 972 | char c = text.charAt( i ); |
1537 | 972 | if ( c == RIGHT_CURLY_BRACKET && previous != BACKSLASH ) |
1538 | |
{ |
1539 | 52 | break; |
1540 | |
} |
1541 | |
|
1542 | 920 | previous = c; |
1543 | |
} |
1544 | 52 | if ( i == end ) |
1545 | |
{ |
1546 | 0 | throw new AptParseException( "missing '" + RIGHT_CURLY_BRACKET + "'" ); |
1547 | |
} |
1548 | |
|
1549 | 52 | return doGetTraversedLink( text, begin, i ); |
1550 | |
} |
1551 | |
|
1552 | |
|
1553 | |
|
1554 | |
|
1555 | |
|
1556 | |
|
1557 | |
|
1558 | |
|
1559 | |
|
1560 | |
|
1561 | |
private String doGetTraversedLink( String text, int begin, int end ) |
1562 | |
throws AptParseException |
1563 | |
{ |
1564 | 66 | final StringBuffer buffer = new StringBuffer( end - begin ); |
1565 | |
|
1566 | 66 | Sink linkSink = new SinkAdapter() |
1567 | |
{ |
1568 | |
|
1569 | |
public void lineBreak() |
1570 | |
{ |
1571 | 0 | buffer.append( SPACE ); |
1572 | 0 | } |
1573 | |
|
1574 | |
|
1575 | |
public void nonBreakingSpace() |
1576 | |
{ |
1577 | 0 | buffer.append( SPACE ); |
1578 | 0 | } |
1579 | |
|
1580 | |
|
1581 | 66 | public void text( String text ) |
1582 | |
{ |
1583 | 66 | buffer.append( text ); |
1584 | 66 | } |
1585 | |
}; |
1586 | 66 | doTraverseText( text, begin, end, linkSink ); |
1587 | |
|
1588 | 66 | return buffer.toString().trim(); |
1589 | |
} |
1590 | |
|
1591 | |
|
1592 | |
|
1593 | |
|
1594 | |
|
1595 | |
|
1596 | |
|
1597 | |
|
1598 | |
|
1599 | |
private void logMessage( String key, String msg ) |
1600 | |
{ |
1601 | 2 | msg = "[APT Parser] " + msg; |
1602 | 2 | if ( getLog().isDebugEnabled() ) |
1603 | |
{ |
1604 | 0 | getLog().debug( msg ); |
1605 | |
|
1606 | 0 | return; |
1607 | |
} |
1608 | |
|
1609 | 2 | if ( warnMessages == null ) |
1610 | |
{ |
1611 | 2 | warnMessages = new HashMap<String, Set<String>>(); |
1612 | |
} |
1613 | |
|
1614 | 2 | Set<String> set = warnMessages.get( key ); |
1615 | 2 | if ( set == null ) |
1616 | |
{ |
1617 | 2 | set = new TreeSet<String>(); |
1618 | |
} |
1619 | 2 | set.add( msg ); |
1620 | 2 | warnMessages.put( key, set ); |
1621 | 2 | } |
1622 | |
|
1623 | |
|
1624 | |
|
1625 | |
|
1626 | |
private void logWarnings() |
1627 | |
{ |
1628 | 36 | if ( getLog().isWarnEnabled() && this.warnMessages != null && !isSecondParsing() ) |
1629 | |
{ |
1630 | 2 | for ( Map.Entry<String, Set<String>> entry : this.warnMessages.entrySet() ) |
1631 | |
{ |
1632 | 2 | for ( String msg : entry.getValue() ) |
1633 | |
{ |
1634 | 2 | getLog().warn( msg ); |
1635 | |
} |
1636 | |
} |
1637 | |
|
1638 | 2 | this.warnMessages = null; |
1639 | |
} |
1640 | 36 | } |
1641 | |
|
1642 | |
|
1643 | |
|
1644 | |
|
1645 | |
private abstract class Block |
1646 | |
{ |
1647 | |
|
1648 | |
protected int type; |
1649 | |
|
1650 | |
|
1651 | |
protected int indent; |
1652 | |
|
1653 | |
|
1654 | |
protected String text; |
1655 | |
|
1656 | |
|
1657 | |
protected int textLength; |
1658 | |
|
1659 | |
|
1660 | |
|
1661 | |
|
1662 | |
|
1663 | |
|
1664 | |
|
1665 | |
|
1666 | |
public Block( int type, int indent ) |
1667 | |
throws AptParseException |
1668 | |
{ |
1669 | 10 | this( type, indent, null ); |
1670 | 10 | } |
1671 | |
|
1672 | |
|
1673 | |
|
1674 | |
|
1675 | |
|
1676 | |
|
1677 | |
|
1678 | |
|
1679 | |
|
1680 | |
public Block( int type, int indent, String firstLine ) |
1681 | |
throws AptParseException |
1682 | 480 | { |
1683 | 480 | this.type = type; |
1684 | 480 | this.indent = indent; |
1685 | |
|
1686 | |
|
1687 | 480 | AptParser.this.nextLine(); |
1688 | |
|
1689 | 480 | if ( firstLine == null ) |
1690 | |
{ |
1691 | 32 | text = null; |
1692 | 32 | textLength = 0; |
1693 | |
} |
1694 | |
else |
1695 | |
{ |
1696 | |
|
1697 | 448 | StringBuffer buffer = new StringBuffer( firstLine ); |
1698 | |
|
1699 | 778 | while ( AptParser.this.line != null ) |
1700 | |
{ |
1701 | 750 | String l = AptParser.this.line; |
1702 | 750 | int length = l.length(); |
1703 | 750 | int i = 0; |
1704 | |
|
1705 | 750 | i = skipSpace( l, length, i ); |
1706 | 750 | if ( i == length ) |
1707 | |
{ |
1708 | |
|
1709 | 416 | AptParser.this.nextLine(); |
1710 | 416 | break; |
1711 | |
} |
1712 | 334 | else if ( ( AptParser.charAt( l, length, i ) == COMMENT |
1713 | |
&& AptParser.charAt( l, length, i + 1 ) == COMMENT ) |
1714 | |
|| type == COMMENT_BLOCK ) |
1715 | |
{ |
1716 | |
|
1717 | 2 | break; |
1718 | |
} |
1719 | |
|
1720 | 330 | buffer.append( EOL ); |
1721 | 330 | buffer.append( l ); |
1722 | |
|
1723 | 330 | AptParser.this.nextLine(); |
1724 | 330 | } |
1725 | |
|
1726 | 448 | text = buffer.toString(); |
1727 | 448 | textLength = text.length(); |
1728 | |
} |
1729 | 480 | } |
1730 | |
|
1731 | |
|
1732 | |
|
1733 | |
|
1734 | |
|
1735 | |
|
1736 | |
public final int getType() |
1737 | |
{ |
1738 | 824 | return type; |
1739 | |
} |
1740 | |
|
1741 | |
|
1742 | |
|
1743 | |
|
1744 | |
|
1745 | |
|
1746 | |
public final int getIndent() |
1747 | |
{ |
1748 | 172 | return indent; |
1749 | |
} |
1750 | |
|
1751 | |
|
1752 | |
|
1753 | |
|
1754 | |
|
1755 | |
|
1756 | |
public abstract void traverse() |
1757 | |
throws AptParseException; |
1758 | |
|
1759 | |
|
1760 | |
|
1761 | |
|
1762 | |
|
1763 | |
|
1764 | |
|
1765 | |
protected void traverseText( int begin ) |
1766 | |
throws AptParseException |
1767 | |
{ |
1768 | 358 | traverseText( begin, text.length() ); |
1769 | 358 | } |
1770 | |
|
1771 | |
|
1772 | |
|
1773 | |
|
1774 | |
|
1775 | |
|
1776 | |
|
1777 | |
|
1778 | |
protected void traverseText( int begin, int end ) |
1779 | |
throws AptParseException |
1780 | |
{ |
1781 | 374 | AptParser.this.doTraverseText( text, begin, end, AptParser.this.sink ); |
1782 | 374 | } |
1783 | |
|
1784 | |
|
1785 | |
|
1786 | |
|
1787 | |
|
1788 | |
|
1789 | |
protected int skipLeadingBullets() |
1790 | |
{ |
1791 | 146 | int i = skipSpaceFrom( 0 ); |
1792 | 546 | for ( ; i < textLength; ++i ) |
1793 | |
{ |
1794 | 346 | if ( text.charAt( i ) != STAR ) |
1795 | |
{ |
1796 | 146 | break; |
1797 | |
} |
1798 | |
} |
1799 | 146 | return skipSpaceFrom( i ); |
1800 | |
} |
1801 | |
|
1802 | |
|
1803 | |
|
1804 | |
|
1805 | |
|
1806 | |
|
1807 | |
|
1808 | |
|
1809 | |
protected int skipFromLeftToRightBracket( int i ) |
1810 | |
throws AptParseException |
1811 | |
{ |
1812 | 24 | char previous = LEFT_SQUARE_BRACKET; |
1813 | 304 | for ( ++i; i < textLength; ++i ) |
1814 | |
{ |
1815 | 304 | char c = text.charAt( i ); |
1816 | 304 | if ( c == RIGHT_SQUARE_BRACKET && previous != BACKSLASH ) |
1817 | |
{ |
1818 | 24 | break; |
1819 | |
} |
1820 | 280 | previous = c; |
1821 | |
} |
1822 | 24 | if ( i == textLength ) |
1823 | |
{ |
1824 | 0 | throw new AptParseException( "missing '" + RIGHT_SQUARE_BRACKET + "'" ); |
1825 | |
} |
1826 | |
|
1827 | 24 | return i; |
1828 | |
} |
1829 | |
|
1830 | |
|
1831 | |
|
1832 | |
|
1833 | |
|
1834 | |
|
1835 | |
|
1836 | |
protected final int skipSpaceFrom( int i ) |
1837 | |
{ |
1838 | 552 | return AptParser.skipSpace( text, textLength, i ); |
1839 | |
} |
1840 | |
} |
1841 | |
|
1842 | |
|
1843 | |
private class ListBreak |
1844 | |
extends AptParser.Block |
1845 | |
{ |
1846 | |
|
1847 | |
|
1848 | |
|
1849 | |
|
1850 | |
|
1851 | |
|
1852 | |
|
1853 | |
public ListBreak( int indent, String firstLine ) |
1854 | |
throws AptParseException |
1855 | 12 | { |
1856 | 12 | super( AptParser.LIST_BREAK, indent, firstLine ); |
1857 | 12 | } |
1858 | |
|
1859 | |
|
1860 | |
public void traverse() |
1861 | |
throws AptParseException |
1862 | |
{ |
1863 | 0 | throw new AptParseException( "internal error: traversing list break" ); |
1864 | |
} |
1865 | |
} |
1866 | |
|
1867 | |
|
1868 | |
private class Title |
1869 | |
extends Block |
1870 | |
{ |
1871 | |
|
1872 | |
|
1873 | |
|
1874 | |
|
1875 | |
|
1876 | |
|
1877 | |
|
1878 | |
public Title( int indent, String firstLine ) |
1879 | |
throws AptParseException |
1880 | 18 | { |
1881 | 18 | super( TITLE, indent, firstLine ); |
1882 | 18 | } |
1883 | |
|
1884 | |
|
1885 | |
public void traverse() |
1886 | |
throws AptParseException |
1887 | |
{ |
1888 | 18 | StringTokenizer lines = new StringTokenizer( text, EOL ); |
1889 | 18 | int separator = -1; |
1890 | 18 | boolean firstLine = true; |
1891 | 18 | boolean title = false; |
1892 | 18 | boolean author = false; |
1893 | 18 | boolean date = false; |
1894 | |
|
1895 | 120 | loop: while ( lines.hasMoreTokens() ) |
1896 | |
{ |
1897 | 108 | String line = lines.nextToken().trim(); |
1898 | 108 | int lineLength = line.length(); |
1899 | |
|
1900 | 108 | if ( AptParser.charAt( line, lineLength, 0 ) == MINUS |
1901 | |
&& AptParser.charAt( line, lineLength, 1 ) == MINUS |
1902 | |
&& AptParser.charAt( line, lineLength, 2 ) == MINUS ) |
1903 | |
{ |
1904 | 60 | switch ( separator ) |
1905 | |
{ |
1906 | |
case 0: |
1907 | 18 | if ( title ) |
1908 | |
{ |
1909 | 18 | AptParser.this.sink.title_(); |
1910 | |
} |
1911 | |
else |
1912 | |
{ |
1913 | 0 | throw new AptParseException( "missing title" ); |
1914 | |
} |
1915 | |
break; |
1916 | |
case 1: |
1917 | 18 | if ( author ) |
1918 | |
{ |
1919 | 18 | AptParser.this.sink.author_(); |
1920 | |
} |
1921 | |
break; |
1922 | |
case 2: |
1923 | |
|
1924 | |
|
1925 | 6 | break loop; |
1926 | |
default: |
1927 | |
break; |
1928 | |
} |
1929 | |
|
1930 | 54 | ++separator; |
1931 | 54 | firstLine = true; |
1932 | |
} |
1933 | |
else |
1934 | |
{ |
1935 | 48 | if ( firstLine ) |
1936 | |
{ |
1937 | 48 | firstLine = false; |
1938 | 48 | switch ( separator ) |
1939 | |
{ |
1940 | |
case 0: |
1941 | 18 | title = true; |
1942 | 18 | AptParser.this.sink.title(); |
1943 | 18 | break; |
1944 | |
case 1: |
1945 | 18 | author = true; |
1946 | 18 | AptParser.this.sink.author(); |
1947 | 18 | break; |
1948 | |
case 2: |
1949 | 12 | date = true; |
1950 | 12 | AptParser.this.sink.date(); |
1951 | 12 | break; |
1952 | |
default: |
1953 | 0 | break; |
1954 | |
} |
1955 | |
} |
1956 | |
else |
1957 | |
{ |
1958 | |
|
1959 | 0 | AptParser.this.sink.lineBreak(); |
1960 | |
} |
1961 | |
|
1962 | 48 | AptParser.this.doTraverseText( line, 0, lineLength, AptParser.this.sink ); |
1963 | |
} |
1964 | 102 | } |
1965 | |
|
1966 | 18 | switch ( separator ) |
1967 | |
{ |
1968 | |
case 0: |
1969 | 0 | if ( title ) |
1970 | |
{ |
1971 | 0 | AptParser.this.sink.title_(); |
1972 | |
} |
1973 | |
else |
1974 | |
{ |
1975 | 0 | throw new AptParseException( "missing title" ); |
1976 | |
} |
1977 | |
break; |
1978 | |
case 1: |
1979 | 0 | if ( author ) |
1980 | |
{ |
1981 | 0 | AptParser.this.sink.author_(); |
1982 | |
} |
1983 | |
break; |
1984 | |
case 2: |
1985 | 18 | if ( date ) |
1986 | |
{ |
1987 | 12 | AptParser.this.sink.date_(); |
1988 | |
} |
1989 | |
break; |
1990 | |
default: |
1991 | |
break; |
1992 | |
} |
1993 | 18 | } |
1994 | |
} |
1995 | |
|
1996 | |
|
1997 | |
private abstract class Section |
1998 | |
extends Block |
1999 | |
{ |
2000 | |
|
2001 | |
|
2002 | |
|
2003 | |
|
2004 | |
|
2005 | |
|
2006 | |
|
2007 | |
|
2008 | |
public Section( int type, int indent, String firstLine ) |
2009 | |
throws AptParseException |
2010 | 102 | { |
2011 | 102 | super( type, indent, firstLine ); |
2012 | 102 | } |
2013 | |
|
2014 | |
|
2015 | |
public void traverse() |
2016 | |
throws AptParseException |
2017 | |
{ |
2018 | 102 | Title(); |
2019 | 102 | traverseText( skipLeadingBullets() ); |
2020 | 102 | Title_(); |
2021 | 102 | } |
2022 | |
|
2023 | |
|
2024 | |
public abstract void Title(); |
2025 | |
|
2026 | |
|
2027 | |
public abstract void Title_(); |
2028 | |
} |
2029 | |
|
2030 | |
|
2031 | |
private class Section1 |
2032 | |
extends Section |
2033 | |
{ |
2034 | |
|
2035 | |
|
2036 | |
|
2037 | |
|
2038 | |
|
2039 | |
|
2040 | |
|
2041 | |
public Section1( int indent, String firstLine ) |
2042 | |
throws AptParseException |
2043 | 30 | { |
2044 | 30 | super( SECTION1, indent, firstLine ); |
2045 | 30 | } |
2046 | |
|
2047 | |
|
2048 | |
public void Title() |
2049 | |
{ |
2050 | 30 | AptParser.this.sink.sectionTitle1(); |
2051 | 30 | } |
2052 | |
|
2053 | |
|
2054 | |
public void Title_() |
2055 | |
{ |
2056 | 30 | AptParser.this.sink.sectionTitle1_(); |
2057 | 30 | } |
2058 | |
} |
2059 | |
|
2060 | |
|
2061 | |
private class Section2 |
2062 | |
extends Section |
2063 | |
{ |
2064 | |
|
2065 | |
|
2066 | |
|
2067 | |
|
2068 | |
|
2069 | |
|
2070 | |
|
2071 | |
public Section2( int indent, String firstLine ) |
2072 | |
throws AptParseException |
2073 | 28 | { |
2074 | 28 | super( SECTION2, indent, firstLine ); |
2075 | 28 | } |
2076 | |
|
2077 | |
|
2078 | |
public void Title() |
2079 | |
{ |
2080 | 28 | AptParser.this.sink.sectionTitle2(); |
2081 | 28 | } |
2082 | |
|
2083 | |
|
2084 | |
public void Title_() |
2085 | |
{ |
2086 | 28 | AptParser.this.sink.sectionTitle2_(); |
2087 | 28 | } |
2088 | |
} |
2089 | |
|
2090 | |
|
2091 | |
private class Section3 |
2092 | |
extends Section |
2093 | |
{ |
2094 | |
|
2095 | |
|
2096 | |
|
2097 | |
|
2098 | |
|
2099 | |
|
2100 | |
|
2101 | |
public Section3( int indent, String firstLine ) |
2102 | |
throws AptParseException |
2103 | 16 | { |
2104 | 16 | super( SECTION3, indent, firstLine ); |
2105 | 16 | } |
2106 | |
|
2107 | |
|
2108 | |
public void Title() |
2109 | |
{ |
2110 | 16 | AptParser.this.sink.sectionTitle3(); |
2111 | 16 | } |
2112 | |
|
2113 | |
|
2114 | |
public void Title_() |
2115 | |
{ |
2116 | 16 | AptParser.this.sink.sectionTitle3_(); |
2117 | 16 | } |
2118 | |
} |
2119 | |
|
2120 | |
|
2121 | |
private class Section4 |
2122 | |
extends Section |
2123 | |
{ |
2124 | |
|
2125 | |
|
2126 | |
|
2127 | |
|
2128 | |
|
2129 | |
|
2130 | |
|
2131 | |
public Section4( int indent, String firstLine ) |
2132 | |
throws AptParseException |
2133 | 16 | { |
2134 | 16 | super( SECTION4, indent, firstLine ); |
2135 | 16 | } |
2136 | |
|
2137 | |
|
2138 | |
public void Title() |
2139 | |
{ |
2140 | 16 | AptParser.this.sink.sectionTitle4(); |
2141 | 16 | } |
2142 | |
|
2143 | |
|
2144 | |
public void Title_() |
2145 | |
{ |
2146 | 16 | AptParser.this.sink.sectionTitle4_(); |
2147 | 16 | } |
2148 | |
} |
2149 | |
|
2150 | |
|
2151 | |
private class Section5 |
2152 | |
extends Section |
2153 | |
{ |
2154 | |
|
2155 | |
|
2156 | |
|
2157 | |
|
2158 | |
|
2159 | |
|
2160 | |
|
2161 | |
public Section5( int indent, String firstLine ) |
2162 | |
throws AptParseException |
2163 | 12 | { |
2164 | 12 | super( SECTION5, indent, firstLine ); |
2165 | 12 | } |
2166 | |
|
2167 | |
|
2168 | |
public void Title() |
2169 | |
{ |
2170 | 12 | AptParser.this.sink.sectionTitle5(); |
2171 | 12 | } |
2172 | |
|
2173 | |
|
2174 | |
public void Title_() |
2175 | |
{ |
2176 | 12 | AptParser.this.sink.sectionTitle5_(); |
2177 | 12 | } |
2178 | |
} |
2179 | |
|
2180 | |
|
2181 | |
private class Paragraph |
2182 | |
extends Block |
2183 | |
{ |
2184 | |
|
2185 | |
|
2186 | |
|
2187 | |
|
2188 | |
|
2189 | |
|
2190 | |
|
2191 | |
public Paragraph( int indent, String firstLine ) |
2192 | |
throws AptParseException |
2193 | 156 | { |
2194 | 156 | super( PARAGRAPH, indent, firstLine ); |
2195 | 156 | } |
2196 | |
|
2197 | |
|
2198 | |
public void traverse() |
2199 | |
throws AptParseException |
2200 | |
{ |
2201 | 156 | AptParser.this.sink.paragraph(); |
2202 | 156 | traverseText( skipSpaceFrom( 0 ) ); |
2203 | 156 | AptParser.this.sink.paragraph_(); |
2204 | 156 | } |
2205 | |
} |
2206 | |
|
2207 | |
|
2208 | |
private class Comment |
2209 | |
extends Block |
2210 | |
{ |
2211 | |
|
2212 | |
|
2213 | |
|
2214 | |
|
2215 | |
|
2216 | |
|
2217 | |
public Comment( String line ) |
2218 | |
throws AptParseException |
2219 | 12 | { |
2220 | 12 | super( COMMENT_BLOCK, 0, line ); |
2221 | 12 | } |
2222 | |
|
2223 | |
|
2224 | |
public void traverse() |
2225 | |
throws AptParseException |
2226 | |
{ |
2227 | 12 | AptParser.this.sink.comment( text ); |
2228 | 12 | } |
2229 | |
} |
2230 | |
|
2231 | |
|
2232 | |
private class Verbatim |
2233 | |
extends Block |
2234 | |
{ |
2235 | |
|
2236 | |
private boolean boxed; |
2237 | |
|
2238 | |
|
2239 | |
|
2240 | |
|
2241 | |
|
2242 | |
|
2243 | |
|
2244 | |
|
2245 | |
public Verbatim( int indent, String firstLine ) |
2246 | |
throws AptParseException |
2247 | 22 | { |
2248 | 22 | super( VERBATIM, indent, null ); |
2249 | |
|
2250 | |
|
2251 | |
|
2252 | 22 | StringBuffer buffer = new StringBuffer(); |
2253 | 22 | char firstChar = firstLine.charAt( 0 ); |
2254 | 22 | boxed = ( firstChar == PLUS ); |
2255 | |
|
2256 | 52 | while ( AptParser.this.line != null ) |
2257 | |
{ |
2258 | 52 | String l = AptParser.this.line; |
2259 | 52 | int length = l.length(); |
2260 | |
|
2261 | 52 | if ( AptParser.charAt( l, length, 0 ) == firstChar && AptParser.charAt( l, length, 1 ) == MINUS |
2262 | |
&& AptParser.charAt( l, length, 2 ) == MINUS ) |
2263 | |
{ |
2264 | 22 | AptParser.this.nextLine(); |
2265 | |
|
2266 | 22 | break; |
2267 | |
} |
2268 | |
|
2269 | |
|
2270 | |
|
2271 | |
int prevColumn, column; |
2272 | |
|
2273 | 30 | column = 0; |
2274 | |
|
2275 | 878 | for ( int i = 0; i < length; ++i ) |
2276 | |
{ |
2277 | 848 | char c = l.charAt( i ); |
2278 | |
|
2279 | 848 | if ( c == TAB ) |
2280 | |
{ |
2281 | 0 | prevColumn = column; |
2282 | |
|
2283 | 0 | column = ( ( column + 1 + TAB_WIDTH - 1 ) / TAB_WIDTH ) * TAB_WIDTH; |
2284 | |
|
2285 | 0 | buffer.append( SPACES, 0, column - prevColumn ); |
2286 | |
} |
2287 | |
else |
2288 | |
{ |
2289 | 848 | ++column; |
2290 | 848 | buffer.append( c ); |
2291 | |
} |
2292 | |
} |
2293 | 30 | buffer.append( EOL ); |
2294 | |
|
2295 | 30 | AptParser.this.nextLine(); |
2296 | 30 | } |
2297 | |
|
2298 | |
|
2299 | |
|
2300 | 22 | textLength = buffer.length(); |
2301 | |
|
2302 | 22 | if ( textLength > 0 ) |
2303 | |
{ |
2304 | 22 | --textLength; |
2305 | |
|
2306 | 22 | buffer.setLength( textLength ); |
2307 | |
} |
2308 | |
|
2309 | 22 | text = buffer.toString(); |
2310 | 22 | } |
2311 | |
|
2312 | |
|
2313 | |
public void traverse() |
2314 | |
throws AptParseException |
2315 | |
{ |
2316 | 22 | AptParser.this.sink.verbatim( boxed ? SinkEventAttributeSet.BOXED : null ); |
2317 | 22 | AptParser.this.sink.text( text ); |
2318 | 22 | AptParser.this.sink.verbatim_(); |
2319 | 22 | } |
2320 | |
} |
2321 | |
|
2322 | |
|
2323 | |
private class Figure |
2324 | |
extends Block |
2325 | |
{ |
2326 | |
|
2327 | |
|
2328 | |
|
2329 | |
|
2330 | |
|
2331 | |
|
2332 | |
|
2333 | |
public Figure( int indent, String firstLine ) |
2334 | |
throws AptParseException |
2335 | 8 | { |
2336 | 8 | super( FIGURE, indent, firstLine ); |
2337 | 8 | } |
2338 | |
|
2339 | |
|
2340 | |
public void traverse() |
2341 | |
throws AptParseException |
2342 | |
{ |
2343 | 8 | AptParser.this.sink.figure(); |
2344 | |
|
2345 | 8 | int i = skipFromLeftToRightBracket( 0 ); |
2346 | 8 | AptParser.this.sink.figureGraphics( text.substring( 1, i ) ); |
2347 | |
|
2348 | 8 | i = skipSpaceFrom( i + 1 ); |
2349 | 8 | if ( i < textLength ) |
2350 | |
{ |
2351 | 8 | AptParser.this.sink.figureCaption(); |
2352 | 8 | traverseText( i ); |
2353 | 8 | AptParser.this.sink.figureCaption_(); |
2354 | |
} |
2355 | |
|
2356 | 8 | AptParser.this.sink.figure_(); |
2357 | 8 | } |
2358 | |
} |
2359 | |
|
2360 | |
|
2361 | |
private class Table |
2362 | |
extends Block |
2363 | |
{ |
2364 | |
|
2365 | |
|
2366 | |
|
2367 | |
|
2368 | |
|
2369 | |
|
2370 | |
|
2371 | |
public Table( int indent, String firstLine ) |
2372 | |
throws AptParseException |
2373 | 32 | { |
2374 | 32 | super( TABLE, indent, firstLine ); |
2375 | 32 | } |
2376 | |
|
2377 | |
|
2378 | |
public void traverse() |
2379 | |
throws AptParseException |
2380 | |
{ |
2381 | 32 | int captionIndex = -1; |
2382 | 32 | int nextLineIndex = 0; |
2383 | 32 | int init = 2; |
2384 | 32 | int[] justification = null; |
2385 | 32 | int rows = 0; |
2386 | 32 | int columns = 0; |
2387 | 32 | StringBuffer[] cells = null; |
2388 | 32 | boolean[] headers = null; |
2389 | |
boolean grid; |
2390 | |
|
2391 | 32 | AptParser.this.sink.table(); |
2392 | |
|
2393 | 220 | while ( nextLineIndex < textLength ) |
2394 | |
{ |
2395 | 196 | int i = text.indexOf( "*--", nextLineIndex ); |
2396 | 196 | if ( i < 0 ) |
2397 | |
{ |
2398 | 8 | captionIndex = nextLineIndex; |
2399 | 8 | break; |
2400 | |
} |
2401 | |
|
2402 | |
String line; |
2403 | 188 | i = text.indexOf( '\n', nextLineIndex ); |
2404 | 188 | if ( i < 0 ) |
2405 | |
{ |
2406 | 24 | line = text.substring( nextLineIndex ); |
2407 | 24 | nextLineIndex = textLength; |
2408 | |
} |
2409 | |
else |
2410 | |
{ |
2411 | 164 | line = text.substring( nextLineIndex, i ); |
2412 | 164 | nextLineIndex = i + 1; |
2413 | |
} |
2414 | 188 | int lineLength = line.length(); |
2415 | |
|
2416 | 188 | if ( line.indexOf( "*--" ) == 0 ) |
2417 | |
{ |
2418 | 98 | if ( init == 2 ) |
2419 | |
{ |
2420 | 32 | init = 1; |
2421 | 32 | justification = parseJustification( line, lineLength ); |
2422 | 32 | columns = justification.length; |
2423 | 32 | cells = new StringBuffer[columns]; |
2424 | 32 | headers = new boolean[columns]; |
2425 | 110 | for ( i = 0; i < columns; ++i ) |
2426 | |
{ |
2427 | 78 | cells[i] = new StringBuffer(); |
2428 | 78 | headers[i] = false; |
2429 | |
} |
2430 | |
} |
2431 | |
else |
2432 | |
{ |
2433 | 66 | if ( traverseRow( cells, headers, justification ) ) |
2434 | |
{ |
2435 | 66 | ++rows; |
2436 | |
} |
2437 | 66 | justification = parseJustification( line, lineLength ); |
2438 | |
} |
2439 | |
} |
2440 | |
else |
2441 | |
{ |
2442 | 90 | if ( init == 1 ) |
2443 | |
{ |
2444 | 32 | init = 0; |
2445 | 32 | grid = ( AptParser.charAt( line, lineLength, 0 ) == PIPE ); |
2446 | 32 | AptParser.this.sink.tableRows( justification, grid ); |
2447 | |
} |
2448 | |
|
2449 | 90 | line = replaceAll( line, "\\|", "\\u007C" ); |
2450 | |
|
2451 | 90 | StringTokenizer cellLines = new StringTokenizer( line, "|", true ); |
2452 | |
|
2453 | 90 | i = 0; |
2454 | 90 | boolean processedGrid = false; |
2455 | 428 | while ( cellLines.hasMoreTokens() ) |
2456 | |
{ |
2457 | 416 | String cellLine = cellLines.nextToken(); |
2458 | 416 | if ( "|".equals( cellLine ) ) |
2459 | |
{ |
2460 | 196 | if ( processedGrid ) |
2461 | |
{ |
2462 | 16 | headers[i] = true; |
2463 | |
} |
2464 | |
else |
2465 | |
{ |
2466 | 180 | processedGrid = true; |
2467 | 180 | headers[i] = false; |
2468 | |
} |
2469 | 180 | continue; |
2470 | |
} |
2471 | 220 | processedGrid = false; |
2472 | 220 | cellLine = replaceAll( cellLine, "\\", "\\u00A0" ); |
2473 | |
|
2474 | 220 | cellLine = replaceAll( cellLine, "\\u00A0~", "\\~" ); |
2475 | 220 | cellLine = replaceAll( cellLine, "\\u00A0=", "\\=" ); |
2476 | 220 | cellLine = replaceAll( cellLine, "\\u00A0-", "\\-" ); |
2477 | 220 | cellLine = replaceAll( cellLine, "\\u00A0+", "\\+" ); |
2478 | 220 | cellLine = replaceAll( cellLine, "\\u00A0*", "\\*" ); |
2479 | 220 | cellLine = replaceAll( cellLine, "\\u00A0[", "\\[" ); |
2480 | 220 | cellLine = replaceAll( cellLine, "\\u00A0]", "\\]" ); |
2481 | 220 | cellLine = replaceAll( cellLine, "\\u00A0<", "\\<" ); |
2482 | 220 | cellLine = replaceAll( cellLine, "\\u00A0>", "\\>" ); |
2483 | 220 | cellLine = replaceAll( cellLine, "\\u00A0{", "\\{" ); |
2484 | 220 | cellLine = replaceAll( cellLine, "\\u00A0}", "\\}" ); |
2485 | 220 | cellLine = replaceAll( cellLine, "\\u00A0u", "\\u" ); |
2486 | 220 | cellLine = replaceAll( cellLine, "\\u00A0\\u00A0", "\\\\" ); |
2487 | 220 | cellLine = cellLine.trim(); |
2488 | |
|
2489 | 220 | StringBuffer cell = cells[i]; |
2490 | 220 | if ( cellLine.length() > 0 ) |
2491 | |
{ |
2492 | |
|
2493 | 200 | if ( cell.toString().trim().endsWith( "\\u00A0" ) ) |
2494 | |
{ |
2495 | 6 | cell.append( "\\\n" ); |
2496 | |
} |
2497 | |
else |
2498 | |
{ |
2499 | 194 | if ( cell.length() != 0 ) |
2500 | |
{ |
2501 | |
|
2502 | 32 | cell.append( " " ); |
2503 | |
} |
2504 | |
} |
2505 | |
|
2506 | 200 | cell.append( cellLine ); |
2507 | |
} |
2508 | |
|
2509 | 220 | ++i; |
2510 | 220 | if ( i == columns ) |
2511 | |
{ |
2512 | 78 | break; |
2513 | |
} |
2514 | 142 | } |
2515 | |
} |
2516 | 188 | } |
2517 | 32 | if ( rows == 0 ) |
2518 | |
{ |
2519 | 0 | throw new AptParseException( "no table rows" ); |
2520 | |
} |
2521 | 32 | AptParser.this.sink.tableRows_(); |
2522 | |
|
2523 | 32 | if ( captionIndex >= 0 ) |
2524 | |
{ |
2525 | 8 | AptParser.this.sink.tableCaption(); |
2526 | 8 | AptParser.this.doTraverseText( text, captionIndex, textLength, AptParser.this.sink ); |
2527 | 8 | AptParser.this.sink.tableCaption_(); |
2528 | |
} |
2529 | |
|
2530 | 32 | AptParser.this.sink.table_(); |
2531 | 32 | } |
2532 | |
|
2533 | |
|
2534 | |
|
2535 | |
|
2536 | |
|
2537 | |
|
2538 | |
|
2539 | |
|
2540 | |
|
2541 | |
private int[] parseJustification( String jline, int lineLength ) |
2542 | |
throws AptParseException |
2543 | |
{ |
2544 | 98 | int columns = 0; |
2545 | |
|
2546 | 2738 | for ( int i = 2 ; i < lineLength; ++i ) |
2547 | |
{ |
2548 | 2640 | switch ( jline.charAt( i ) ) |
2549 | |
{ |
2550 | |
case STAR: |
2551 | |
case PLUS: |
2552 | |
case COLON: |
2553 | 242 | ++columns; |
2554 | 242 | break; |
2555 | |
default: |
2556 | |
break; |
2557 | |
} |
2558 | |
} |
2559 | |
|
2560 | 98 | if ( columns == 0 ) |
2561 | |
{ |
2562 | 0 | throw new AptParseException( "no columns specified" ); |
2563 | |
} |
2564 | |
|
2565 | 98 | int[] justification = new int[columns]; |
2566 | 98 | columns = 0; |
2567 | 2738 | for ( int i = 2; i < lineLength; ++i ) |
2568 | |
{ |
2569 | 2640 | switch ( jline.charAt( i ) ) |
2570 | |
{ |
2571 | |
case STAR: |
2572 | 146 | justification[columns++] = Sink.JUSTIFY_CENTER; |
2573 | 146 | break; |
2574 | |
case PLUS: |
2575 | 52 | justification[columns++] = Sink.JUSTIFY_LEFT; |
2576 | 52 | break; |
2577 | |
case COLON: |
2578 | 44 | justification[columns++] = Sink.JUSTIFY_RIGHT; |
2579 | 44 | break; |
2580 | |
default: |
2581 | |
break; |
2582 | |
} |
2583 | |
} |
2584 | |
|
2585 | 98 | return justification; |
2586 | |
} |
2587 | |
|
2588 | |
|
2589 | |
|
2590 | |
|
2591 | |
|
2592 | |
|
2593 | |
|
2594 | |
|
2595 | |
|
2596 | |
|
2597 | |
private boolean traverseRow( StringBuffer[] cells, boolean[] headers, int[] justification ) |
2598 | |
throws AptParseException |
2599 | |
{ |
2600 | |
|
2601 | 66 | boolean traversed = false; |
2602 | 66 | for ( int i = 0; i < cells.length; ++i ) |
2603 | |
{ |
2604 | 66 | if ( cells[i].length() > 0 ) |
2605 | |
{ |
2606 | 66 | traversed = true; |
2607 | 66 | break; |
2608 | |
} |
2609 | |
} |
2610 | |
|
2611 | 66 | if ( traversed ) |
2612 | |
{ |
2613 | 66 | AptParser.this.sink.tableRow(); |
2614 | 230 | for ( int i = 0; i < cells.length; ++i ) |
2615 | |
{ |
2616 | 164 | StringBuffer cell = cells[i]; |
2617 | |
|
2618 | |
SinkEventAttributes justif; |
2619 | 164 | switch ( justification[i] ) |
2620 | |
{ |
2621 | |
case Sink.JUSTIFY_CENTER: |
2622 | 100 | justif = SinkEventAttributeSet.CENTER; |
2623 | 100 | break; |
2624 | |
case Sink.JUSTIFY_LEFT: |
2625 | 34 | justif = SinkEventAttributeSet.LEFT; |
2626 | 34 | break; |
2627 | |
case Sink.JUSTIFY_RIGHT: |
2628 | 30 | justif = SinkEventAttributeSet.RIGHT; |
2629 | 30 | break; |
2630 | |
default: |
2631 | 0 | justif = SinkEventAttributeSet.LEFT; |
2632 | |
break; |
2633 | |
} |
2634 | 164 | SinkEventAttributeSet event = new SinkEventAttributeSet(); |
2635 | 164 | event.addAttributes( justif ); |
2636 | |
|
2637 | 164 | if ( headers[i] ) |
2638 | |
{ |
2639 | 16 | AptParser.this.sink.tableHeaderCell( event ); |
2640 | |
} |
2641 | |
else |
2642 | |
{ |
2643 | 148 | AptParser.this.sink.tableCell( event ); |
2644 | |
} |
2645 | 164 | if ( cell.length() > 0 ) |
2646 | |
{ |
2647 | 162 | AptParser.this.doTraverseText( cell.toString(), 0, cell.length(), AptParser.this.sink ); |
2648 | 162 | cell.setLength( 0 ); |
2649 | |
} |
2650 | 164 | if ( headers[i] ) |
2651 | |
{ |
2652 | 16 | AptParser.this.sink.tableHeaderCell_(); |
2653 | |
} |
2654 | |
else |
2655 | |
{ |
2656 | 148 | AptParser.this.sink.tableCell_(); |
2657 | |
} |
2658 | |
} |
2659 | 66 | AptParser.this.sink.tableRow_(); |
2660 | |
} |
2661 | |
|
2662 | 66 | return traversed; |
2663 | |
} |
2664 | |
} |
2665 | |
|
2666 | |
|
2667 | |
private class ListItem |
2668 | |
extends Block |
2669 | |
{ |
2670 | |
|
2671 | |
|
2672 | |
|
2673 | |
|
2674 | |
|
2675 | |
|
2676 | |
|
2677 | |
public ListItem( int indent, String firstLine ) |
2678 | |
throws AptParseException |
2679 | 44 | { |
2680 | 44 | super( LIST_ITEM, indent, firstLine ); |
2681 | 44 | } |
2682 | |
|
2683 | |
|
2684 | |
public void traverse() |
2685 | |
throws AptParseException |
2686 | |
{ |
2687 | 44 | traverseText( skipLeadingBullets() ); |
2688 | 44 | } |
2689 | |
} |
2690 | |
|
2691 | |
|
2692 | |
private class NumberedListItem |
2693 | |
extends Block |
2694 | |
{ |
2695 | |
|
2696 | |
private int numbering; |
2697 | |
|
2698 | |
|
2699 | |
|
2700 | |
|
2701 | |
|
2702 | |
|
2703 | |
|
2704 | |
|
2705 | |
|
2706 | |
public NumberedListItem( int indent, String firstLine, int number ) |
2707 | |
throws AptParseException |
2708 | 32 | { |
2709 | 32 | super( NUMBERED_LIST_ITEM, indent, firstLine ); |
2710 | 32 | this.numbering = number; |
2711 | 32 | } |
2712 | |
|
2713 | |
|
2714 | |
|
2715 | |
|
2716 | |
|
2717 | |
|
2718 | |
public int getNumbering() |
2719 | |
{ |
2720 | 16 | return numbering; |
2721 | |
} |
2722 | |
|
2723 | |
|
2724 | |
public void traverse() |
2725 | |
throws AptParseException |
2726 | |
{ |
2727 | 32 | traverseText( skipItemNumber() ); |
2728 | 32 | } |
2729 | |
|
2730 | |
|
2731 | |
|
2732 | |
|
2733 | |
|
2734 | |
|
2735 | |
|
2736 | |
private int skipItemNumber() |
2737 | |
throws AptParseException |
2738 | |
{ |
2739 | 32 | int i = skipSpaceFrom( 0 ); |
2740 | |
|
2741 | 32 | char prevChar = SPACE; |
2742 | 288 | for ( ; i < textLength; ++i ) |
2743 | |
{ |
2744 | 160 | char c = text.charAt( i ); |
2745 | 160 | if ( c == RIGHT_SQUARE_BRACKET && prevChar == RIGHT_SQUARE_BRACKET ) |
2746 | |
{ |
2747 | 32 | break; |
2748 | |
} |
2749 | 128 | prevChar = c; |
2750 | |
} |
2751 | |
|
2752 | 32 | if ( i == textLength ) |
2753 | |
{ |
2754 | 0 | throw new AptParseException( "missing '" + RIGHT_SQUARE_BRACKET + RIGHT_SQUARE_BRACKET + "'" ); |
2755 | |
} |
2756 | |
|
2757 | 32 | return skipSpaceFrom( i + 1 ); |
2758 | |
} |
2759 | |
} |
2760 | |
|
2761 | |
|
2762 | |
private class DefinitionListItem |
2763 | |
extends Block |
2764 | |
{ |
2765 | |
|
2766 | |
|
2767 | |
|
2768 | |
|
2769 | |
|
2770 | |
|
2771 | |
|
2772 | |
public DefinitionListItem( int indent, String firstLine ) |
2773 | |
throws AptParseException |
2774 | 16 | { |
2775 | 16 | super( DEFINITION_LIST_ITEM, indent, firstLine ); |
2776 | 16 | } |
2777 | |
|
2778 | |
|
2779 | |
public void traverse() |
2780 | |
throws AptParseException |
2781 | |
{ |
2782 | 16 | int i = skipSpaceFrom( 0 ); |
2783 | 16 | int j = skipFromLeftToRightBracket( i ); |
2784 | |
|
2785 | 16 | AptParser.this.sink.definedTerm(); |
2786 | 16 | traverseText( i + 1, j ); |
2787 | 16 | AptParser.this.sink.definedTerm_(); |
2788 | |
|
2789 | 16 | j = skipSpaceFrom( j + 1 ); |
2790 | 16 | if ( j == textLength ) |
2791 | |
{ |
2792 | |
|
2793 | |
|
2794 | |
} |
2795 | |
|
2796 | 16 | AptParser.this.sink.definition(); |
2797 | 16 | traverseText( j ); |
2798 | 16 | } |
2799 | |
} |
2800 | |
|
2801 | |
|
2802 | |
private class HorizontalRule |
2803 | |
extends Block |
2804 | |
{ |
2805 | |
|
2806 | |
|
2807 | |
|
2808 | |
|
2809 | |
|
2810 | |
|
2811 | |
|
2812 | |
public HorizontalRule( int indent, String firstLine ) |
2813 | |
throws AptParseException |
2814 | 8 | { |
2815 | 8 | super( HORIZONTAL_RULE, indent, firstLine ); |
2816 | 8 | } |
2817 | |
|
2818 | |
|
2819 | |
public void traverse() |
2820 | |
throws AptParseException |
2821 | |
{ |
2822 | 8 | AptParser.this.sink.horizontalRule(); |
2823 | 8 | } |
2824 | |
} |
2825 | |
|
2826 | |
|
2827 | |
private class PageBreak |
2828 | |
extends Block |
2829 | |
{ |
2830 | |
|
2831 | |
|
2832 | |
|
2833 | |
|
2834 | |
|
2835 | |
|
2836 | |
|
2837 | |
public PageBreak( int indent, String firstLine ) |
2838 | |
throws AptParseException |
2839 | 8 | { |
2840 | 8 | super( PG_BREAK, indent, firstLine ); |
2841 | 8 | } |
2842 | |
|
2843 | |
|
2844 | |
public void traverse() |
2845 | |
throws AptParseException |
2846 | |
{ |
2847 | 8 | AptParser.this.sink.pageBreak(); |
2848 | 8 | } |
2849 | |
} |
2850 | |
|
2851 | |
|
2852 | 42 | private class MacroBlock |
2853 | |
extends Block |
2854 | |
{ |
2855 | |
|
2856 | |
|
2857 | |
|
2858 | |
|
2859 | |
|
2860 | |
|
2861 | |
|
2862 | |
public MacroBlock( int indent, String firstLine ) |
2863 | |
throws AptParseException |
2864 | 10 | { |
2865 | 10 | super( MACRO, indent ); |
2866 | |
|
2867 | 10 | text = firstLine; |
2868 | 10 | } |
2869 | |
|
2870 | |
|
2871 | |
public void traverse() |
2872 | |
throws AptParseException |
2873 | |
{ |
2874 | 10 | if ( isSecondParsing() ) |
2875 | |
{ |
2876 | 2 | return; |
2877 | |
} |
2878 | |
|
2879 | 8 | final int start = text.indexOf( '{' ); |
2880 | 8 | final int end = text.indexOf( '}' ); |
2881 | |
|
2882 | 8 | String s = text.substring( start + 1, end ); |
2883 | |
|
2884 | 8 | s = escapeForMacro( s ); |
2885 | |
|
2886 | 8 | String[] params = StringUtils.split( s, "|" ); |
2887 | |
|
2888 | 8 | String macroId = params[0]; |
2889 | |
|
2890 | 8 | Map<String, Object> parameters = new HashMap<String, Object>(); |
2891 | |
|
2892 | 26 | for ( int i = 1; i < params.length; i++ ) |
2893 | |
{ |
2894 | 18 | String[] param = StringUtils.split( params[i], "=" ); |
2895 | |
|
2896 | 18 | if ( param.length == 1 ) |
2897 | |
{ |
2898 | 0 | throw new AptParseException( "Missing 'key=value' pair for macro parameter: " + params[i] ); |
2899 | |
} |
2900 | |
|
2901 | 18 | String key = unescapeForMacro( param[0] ); |
2902 | 18 | String value = unescapeForMacro( param[1] ); |
2903 | |
|
2904 | 18 | parameters.put( key, value ); |
2905 | |
} |
2906 | |
|
2907 | 8 | parameters.put( "sourceContent", sourceContent ); |
2908 | |
|
2909 | 8 | AptParser aptParser = new AptParser(); |
2910 | 8 | aptParser.setSecondParsing( true ); |
2911 | 8 | aptParser.enableLogging( getLog() ); |
2912 | 8 | parameters.put( "parser", aptParser ); |
2913 | |
|
2914 | |
|
2915 | |
|
2916 | 8 | MacroRequest request = new MacroRequest( parameters, getBasedir() ); |
2917 | |
try |
2918 | |
{ |
2919 | 8 | AptParser.this.executeMacro( macroId, request, sink ); |
2920 | |
} |
2921 | 0 | catch ( MacroExecutionException e ) |
2922 | |
{ |
2923 | 0 | throw new AptParseException( "Unable to execute macro in the APT document", e ); |
2924 | |
} |
2925 | 0 | catch ( MacroNotFoundException e ) |
2926 | |
{ |
2927 | 0 | throw new AptParseException( "Unable to find macro used in the APT document", e ); |
2928 | 8 | } |
2929 | 8 | } |
2930 | |
|
2931 | |
|
2932 | |
|
2933 | |
|
2934 | |
|
2935 | |
|
2936 | |
|
2937 | |
private String escapeForMacro( String s ) |
2938 | |
{ |
2939 | 8 | if ( s == null || s.length() < 1 ) |
2940 | |
{ |
2941 | 0 | return s; |
2942 | |
} |
2943 | |
|
2944 | 8 | String result = s; |
2945 | |
|
2946 | |
|
2947 | |
|
2948 | 8 | result = StringUtils.replace( result, "\\=", "\u0011" ); |
2949 | 8 | result = StringUtils.replace( result, "\\|", "\u0012" ); |
2950 | |
|
2951 | 8 | return result; |
2952 | |
} |
2953 | |
|
2954 | |
|
2955 | |
|
2956 | |
|
2957 | |
|
2958 | |
|
2959 | |
|
2960 | |
private String unescapeForMacro( String s ) |
2961 | |
{ |
2962 | 36 | if ( s == null || s.length() < 1 ) |
2963 | |
{ |
2964 | 0 | return s; |
2965 | |
} |
2966 | |
|
2967 | 36 | String result = s; |
2968 | |
|
2969 | 36 | result = StringUtils.replace( result, "\u0011", "=" ); |
2970 | 36 | result = StringUtils.replace( result, "\u0012", "|" ); |
2971 | |
|
2972 | 36 | return result; |
2973 | |
} |
2974 | |
} |
2975 | |
} |