1 /* gnu.classpath.tools.java2xhtml.Java2xhtml
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 /** Java2xhtml.java Version 0.9
22 * Produces an XHTML file from Java source code with syntax highlighting,
23 * includes additional options (line numbering, tab spacing, etc.)
25 * NOTE: Common java naming structure is assumed
26 * Capitalize the first letter that appears in a class or interface name
27 * Use lowercase for the first letter in a method or variable name
28 * Use only uppercase letters when naming constants
30 * @version 0.9, March 2003
31 * @author Shayne Steele
33 package gnu.classpath.tools.java2xhtml;
38 public class Java2xhtml
40 //--- define CSS classes for individual output elements
42 private static final String sourceCodeStyle = "source";
43 private static final String lineNumberStyle = "line-number even";
44 private static final String modulusLineNumberStyle = "line-number odd";
46 private static final String keywordStyle = "keyword";
47 private static final String methodStyle = "method member";
48 private static final String variableStyle = "variable member";
49 private static final String singleLineCommentStyle = "line comment";
50 private static final String traditionalCommentStyle = "c comment";
51 private static final String javadocCommentStyle = "javadoc comment";
52 private static final String javadocTagStyle = "javadoc tag";
53 private static final String importNameStyle = "import header type";
54 private static final String packageNameStyle = "package header type";
55 private static final String primitiveTypeStyle = "primitive type";
56 private static final String nonPrimitiveTypeStyle = "non-primitive type";
57 private static final String constructorStyle = "constructor member";
58 private static final String constantStyle = "constant member";
59 private static final String doubleQuoteStyle = "double quote";
60 private static final String singleQuoteStyle = "single quote";
61 private static final String numericLiteralStyle = "numeric literal";
62 private static final String primitiveLiteralStyle = "primitive literal";
64 private static final String iconStyle = "icon";
68 // parse the command line arguments
69 // give a decent responce for bad input
70 // call the HTMLifier on good input
71 public static void main(String args[])
73 // parse the invokation arguments
74 if (args.length < 1 || args.length > 3) // invoked program incorrectly
76 System.out.println("Java2xhtml Version 0.9 (C) 2005 Free Software Foundation");
77 System.out.println(" Produces an XHTML file of Java source" +
78 " code with syntax highlighting,");
79 System.out.println(" includes additional options " +
80 "(line numbering, tab spacing, etc.)");
81 System.out.println(" This tool is part of GNU Classpath.");
82 System.out.println(" GNU Classpath is free software; you can redistribute it and/or modify");
83 System.out.println(" it under the terms of the GNU General Public License as published by");
84 System.out.println(" the Free Software Foundation; either version 2, or (at your option)");
85 System.out.println(" any later version.");
86 System.out.println(" NOTE: Common java naming structure is " +
88 System.out.println("");
89 System.out.println("USAGE:");
90 System.out.println("java [java options] Java2xhtml " +
91 "source.java [options file] " +
93 System.out.println("");
94 System.out.println(" - java is the name of the Java interpreter");
95 System.out.println(" - [java options] are the optional options " +
96 "of the Java interpreter");
97 System.out.println(" - Java2xhtml is the name of this " +
99 System.out.println(" - source is a file or the directory to the " +
100 "Java source file(s)");
101 System.out.println(" - [options file] is the optional " +
102 "path of a file with");
103 System.out.println(" a structure like this:");
104 System.out.println(" externalStyleSheetName=file_name" +
105 " (default style.css)");
106 System.out.println(" tabSize=integer (default value is 4)");
107 System.out.println(" extraIndentation=integer " +
108 "(default value is 0)");
109 System.out.println(" lineModulus=integer (default value 5)");
110 System.out.println(" isCodeSnippet=boolean" +
112 System.out.println(" isXHTML_1_1=boolean" +
114 System.out.println(" hasInternalStyleSheet=boolean" +
116 System.out.println(" hasExternalStyleSheet=boolean" +
118 System.out.println(" hasTitle=boolean" +
120 System.out.println(" hasLegend=boolean" +
122 System.out.println(" hasAllBoldSourceCode=boolean" +
124 System.out.println(" hasLineNumbers=boolean" +
126 System.out.println(" hasLineModulusDrawnLines=boolean" +
128 System.out.println(" hasLineModulusCodeBlocks=boolean" +
130 System.out.println(" hasFooter=boolean" +
132 System.out.println(" hasFooterIcons=boolean" +
134 System.out.println(" hasFooterDate=boolean" +
136 System.out.println(" NOTE: filename must end with '.prop'");
137 System.out.println(" Default [options file] is " +
139 System.out.println(" - [output file] is name of the XHTML file " +
141 System.out.println(" Default [output file] is source_java.html");
142 System.out.println("");
143 System.out.println("Output: source.java --> [output file]");
144 System.out.println(" Default Output is ");
145 System.out.println(" source.java --> source_java.html");
146 System.out.println("");
147 System.out.println("Examples of calling the program:");
148 System.out.println(" process one file (say Java2xhtml.java):");
149 System.out.println(" java Java2xhtml Java2xhtml.java");
150 System.out.println(" process one directory (say C:\\HOME):");
151 System.out.println(" java Java2xhtml C:\\HOME");
152 System.out.println(" process one directory (say C:\\HOME with a " +
153 "given options file (options.prop)):");
154 System.out.println(" java Java2xhtml C:\\HOME options.prop");
158 // invoked program correctly, now get command line arguments
159 // get the source file name
161 sourceName = args[0];
162 // make sure that the source file exist and if so HTMLify it
163 File sourceFilePath = new File(sourceName);
164 if (sourceFilePath.exists())
166 // good pathname so HTMLify it
167 // get the default html options file name
168 String propertiesFileName = "options.prop";
169 // create a unique default html file name,
170 // bubba.java -> bubba_java.html
171 String htmlFileName = sourceName.replace('.', '_') + ".html";
172 if (args.length == 2 || args.length == 3)
174 if (args[1].endsWith(".prop"))
176 // get the user supplied html options file name
177 propertiesFileName = args[1];
181 // get the user supplied html outputfile name
182 htmlFileName = args[1];
185 if (args.length == 3)
187 if (args[2].endsWith(".prop"))
189 // get the user supplied html options file name
190 propertiesFileName = args[2];
194 // get the user supplied html outputfile name
195 htmlFileName = args[2];
198 new Java2xhtml(propertiesFileName, sourceFilePath,
201 else // source file does not exist, print message and exit normally
203 System.out.println("The source parameter must be an existent" +
204 " file or directory");
205 System.out.println("Run Java2xHtml without parameters for " +
211 // collect various sets of keywords
212 static Collection keywordCollection;
213 static Collection primitiveTypeCollection;
214 static Collection primitiveLiteralCollection;
215 static Collection javadocTagCollection;
217 // all these variables are changeable by a options file
218 int extraIndentation = 0;
221 boolean hasLegend = false;
222 boolean hasLineNumbers = false;
223 boolean hasLineModulusDrawnLines = false;
224 boolean hasLineModulusCodeBlocks = false;
225 boolean hasFooter = false;
226 boolean hasFooterIcons = false;
227 boolean hasFooterDate = true;
228 boolean isCodeSnippet = false;
229 boolean isXHTML_1_1 = true;
230 boolean hasTitle = false;
231 boolean hasAllBoldSourceCode = false;
232 boolean hasInternalStyleSheet = true;
233 boolean hasExternalStyleSheet = true;
234 String externalStyleSheetName = "style.css";
238 // collection type is Hashset for unique elements and fast retieval
239 String keywordArray[] =
241 "abstract", "default", "if", "private",
242 "do", "implements", "protected", "throws",
243 "break", "import", "public", "transient",
244 "else", "instanceof", "return", "try",
245 "case", "extends", "throw", "static",
246 "catch", "final", "interface", "while",
247 "volatile", "finally", "super", "synchronized",
248 "class", "native", "switch", "package",
249 "const", "for", "new", "goto",
250 "continue", "this", "assert", "strictfp"
252 keywordCollection = new HashSet(Arrays.asList(keywordArray));
253 String primitiveTypeArray[] =
255 "boolean", "char", "byte", "short", "int",
256 "long", "float", "double", "void"
258 primitiveTypeCollection =
259 new HashSet(Arrays.asList(primitiveTypeArray));
260 String primitiveLiteralArray[]=
262 "false", "null", "true"
264 primitiveLiteralCollection =
265 new HashSet(Arrays.asList(primitiveLiteralArray));
266 String javadocTagArray[]=
268 "see", "author", "version", "param", "return", "exception",
269 "deprecated", "throws", "link", "since", "serial",
270 "serialField","serialData", "beaninfo"
272 javadocTagCollection = new HashSet(Arrays.asList(javadocTagArray));
279 // create the various keyword collections
280 // parse the html options file
281 Java2xhtml(String propertiesFileName, File sourceFilePath,
284 // get html properties (use defaults if necessary)
285 File propertiesFilePath = new File (propertiesFileName);
286 if (propertiesFilePath.exists())
288 // html properies file exist try parsing it
291 InputStream propertiesFile =
292 new FileInputStream(propertiesFileName);
293 Properties htmlProperties = new Properties();
294 htmlProperties.load(propertiesFile);
295 propertiesFile.close();
296 setProperties(htmlProperties);
298 catch (IOException exception)
300 System.out.println(exception);
303 if (sourceFilePath.isFile())
306 processFile(sourceFilePath, htmlFileName);
308 else if (sourceFilePath.isDirectory())
310 // process a directory
311 File [] sourceFilePathArray = sourceFilePath.listFiles();
312 for (int i = 0; i < sourceFilePathArray.length; i++)
314 if (((sourceFilePathArray[i]).getName()).endsWith(".java"))
316 // process each file that ends in .java
317 // create a unique default html file name,
318 // bubba.java -> bubba_java.html
319 htmlFileName = ((sourceFilePathArray[i]).getName()).replace(
321 processFile(sourceFilePathArray[i], htmlFileName);
327 public void setProperties(Properties htmlProperties)
330 = Boolean.valueOf(htmlProperties.getProperty("hasLegend",
331 "false")).booleanValue();
333 = Integer.parseInt(htmlProperties.getProperty("extraIndentation", "0"));
335 = Integer.parseInt(htmlProperties.getProperty("tabSize", "4"));
337 = Boolean.valueOf(htmlProperties.getProperty("hasLineNumbers",
338 "false")).booleanValue();
340 = Integer.parseInt(htmlProperties.getProperty("lineModulus", "5"));
341 hasLineModulusDrawnLines
342 = Boolean.valueOf(htmlProperties.getProperty("hasLineModulusDrawnLines",
343 "false")).booleanValue();
344 hasLineModulusCodeBlocks
345 = Boolean.valueOf(htmlProperties.getProperty("hasLineModulusCodeBlocks",
346 "false")).booleanValue();
348 = Boolean.valueOf(htmlProperties.getProperty("hasFooter",
349 "false")).booleanValue();
351 = Boolean.valueOf(htmlProperties.getProperty("hasFooterIcons",
352 "false")).booleanValue();
354 = Boolean.valueOf(htmlProperties.getProperty("hasFooterDate",
355 "true")).booleanValue();
357 = Boolean.valueOf(htmlProperties.getProperty("isXHTML_1_1",
358 "true")).booleanValue();
360 = Boolean.valueOf(htmlProperties.getProperty("isCodeSnippet",
361 "false")).booleanValue();
363 = Boolean.valueOf(htmlProperties.getProperty("hasTitle",
364 "false")).booleanValue();
366 = Boolean.valueOf(htmlProperties.getProperty("hasAllBoldSourceCode",
367 "false")).booleanValue();
368 hasInternalStyleSheet
369 = Boolean.valueOf(htmlProperties.getProperty("hasInternalStyleSheet",
370 "true")).booleanValue();
371 hasExternalStyleSheet
372 = Boolean.valueOf(htmlProperties.getProperty("hasExternalStyleSheet",
373 "true")).booleanValue();
374 externalStyleSheetName
375 = htmlProperties.getProperty("externalStyleSheetName", "style.css");
379 // read the file and put it into a stringbuffer
380 void processFile(File sourceFilePath, String htmlFileName)
382 // open the file, copy it to a Stringbuffer , process into an
383 // HTMLified String and convert result into an HTML file
386 BufferedReader sourceReader =
387 new BufferedReader(new FileReader(sourceFilePath));
388 StringBuffer bufferIn = new StringBuffer();
390 char presentChar = 0;
391 // copy file into a Stringbuffer
392 while (readInInt != -1) // -1 value means end of stream/file
394 // put the file into a Stringbuffer
395 readInInt= sourceReader.read();
396 presentChar = ((readInInt >= 0) ? (char) readInInt : 0);
397 bufferIn.append(presentChar);
399 sourceReader.close();
400 BufferedWriter tempBufferedWriter =
401 new BufferedWriter(new FileWriter(htmlFileName));
402 tempBufferedWriter.write(makeHTML(bufferIn,
403 sourceFilePath.getName()));
404 tempBufferedWriter.close();
405 System.out.println(sourceFilePath.getName() + " --> " +
408 catch (IOException exception)
410 System.out.println(exception);
414 // constant 'States' java source code can be in
415 public final static class State
417 public final static State TEXT = new State();
418 public final static State IMPORT_NAME = new State();
419 public final static State PARAM_VARIABLE = new State();
420 public final static State JAVADOC = new State();
421 public final static State PACKAGE_NAME = new State();
422 public final static State DOUBLE_QUOTE = new State();
423 public final static State SINGLE_QUOTE = new State();
424 public final static State TRADITIONAL_COMMENT = new State();
425 public final static State LINE_COMMENT = new State();
434 // Convert java source code StringBufffer into colorized (and tab spaced)
436 // Assumes that Java naming convention is used
437 // Uses a very basic state machine design.
438 public String makeHTML(StringBuffer bufferIn, String sourceFileName)
440 int codeLineNumber = 0;
441 boolean isNewLine = true;
442 boolean isNewBlock = true;
443 int identifierLength = 0;
444 int qualifiedIdentifierLength = 0;
445 int presentIndex = -1;
448 char presentChar = 0;
449 State presentState = State.TEXT;
450 StringBuffer bufferOut = new StringBuffer(8192);
453 bufferOut.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
456 bufferOut.append("<!DOCTYPE html PUBLIC " +
457 "\"-//W3C//DTD XHTML 1.1//EN\"\r\n");
458 bufferOut.append(" \"http://www.w3.org/TR/xhtml11/DTD/" +
459 "xhtml11.dtd\">\r\n");
460 bufferOut.append("<html xmlns=\"http://www.w3.org/1999/xhtml\""+
461 " xml:lang=\"en\">\r\n");
465 bufferOut.append("<!DOCTYPE html PUBLIC " +
466 "\"-//W3C//DTD XHTML 1.0 Strict//EN\"\r\n");
467 bufferOut.append(" \"http://www.w3.org/TR/xhtml1/DTD/" +
468 "xhtml1-strict.dtd\">\r\n");
469 bufferOut.append("<html xmlns=\"http://www.w3.org/1999/xhtml\""+
470 " xml:lang=\"en\" lang=\"en\">\r\n");
472 bufferOut.append(" <head>\r\n");
473 bufferOut.append(" <title>\r\n");
474 bufferOut.append(" " + sourceFileName + "\r\n");
475 bufferOut.append(" </title>\r\n");
476 bufferOut.append(" <meta name=\"generator\"\r\n");
477 bufferOut.append(" content=\"Java2xhtml 0.9\" />\r\n");
478 if (hasInternalStyleSheet)
480 bufferOut.append(" <style type=\"text/css\">\r\n");
481 bufferOut.append(" <!-- /* <![CDATA[ */\r\n");
482 bufferOut.append(" ." + sourceCodeStyle + "\r\n");
483 bufferOut.append(" {\r\n");
484 bufferOut.append(" color: #000000;\r\n");
485 bufferOut.append(" background-color: #FFFFFF;\r\n");
486 if (hasAllBoldSourceCode)
488 bufferOut.append(" font-weight: bold;\r\n");
490 bufferOut.append(" }\r\n");
491 bufferOut.append(" ." + lineNumberStyle + "\r\n");
492 bufferOut.append(" {\r\n");
493 bufferOut.append(" font-weight: normal;\r\n");
494 bufferOut.append(" color: #000000;\r\n");
495 bufferOut.append(" background-color: transparent;\r\n");
496 bufferOut.append(" }\r\n");
499 bufferOut.append(" ." + modulusLineNumberStyle + "\r\n");
500 bufferOut.append(" {\r\n");
501 bufferOut.append(" font-weight: bold;\r\n");
502 bufferOut.append(" color: #000000;\r\n");
503 bufferOut.append(" background-color: ");
504 bufferOut.append("transparent;\r\n");
505 bufferOut.append(" }\r\n");
506 if (hasLineModulusDrawnLines)
508 bufferOut.append(" .modulusLineStyle\r\n");
509 bufferOut.append(" {\r\n");
510 bufferOut.append(" text-decoration: ");
511 bufferOut.append("line-through;\r\n");
512 bufferOut.append(" color: #000000;\r\n");
513 bufferOut.append(" background-color: ");
514 bufferOut.append("transparent;\r\n");
515 bufferOut.append(" }\r\n");
517 if (hasLineModulusCodeBlocks)
519 bufferOut.append(" .modulusBlockPREStyle\r\n");
520 bufferOut.append(" {\r\n");
521 bufferOut.append(" margin: 0em\r\n");
522 bufferOut.append(" }\r\n");
523 bufferOut.append(" .modulusBlockStyle\r\n");
524 bufferOut.append(" {\r\n");
525 bufferOut.append(" color: #000000;\r\n");
526 bufferOut.append(" background-color: ");
527 bufferOut.append("#CCCCCC;\r\n");
528 bufferOut.append(" }\r\n");
531 bufferOut.append(" ." + keywordStyle + "\r\n");
532 bufferOut.append(" {\r\n");
533 bufferOut.append(" color: #9900FF;\r\n");
534 bufferOut.append(" background-color: transparent;\r\n");
535 bufferOut.append(" }\r\n");
536 bufferOut.append(" ." + methodStyle + "\r\n");
537 bufferOut.append(" {\r\n");
538 bufferOut.append(" color: #0000FF;\r\n");
539 bufferOut.append(" background-color: transparent;\r\n");
540 bufferOut.append(" }\r\n");
541 bufferOut.append(" ." + variableStyle + "\r\n");
542 bufferOut.append(" {\r\n");
543 bufferOut.append(" color: #CC9933;\r\n");
544 bufferOut.append(" background-color: transparent;\r\n");
545 bufferOut.append(" }\r\n");
546 bufferOut.append(" ." + singleLineCommentStyle + "\r\n");
547 bufferOut.append(" {\r\n");
548 bufferOut.append(" color: #CC3333;\r\n");
549 bufferOut.append(" background-color: transparent;\r\n");
550 bufferOut.append(" }\r\n");
551 bufferOut.append(" ." + traditionalCommentStyle + "\r\n");
552 bufferOut.append(" {\r\n");
553 bufferOut.append(" color: #FF0000;\r\n");
554 bufferOut.append(" background-color: transparent;\r\n");
555 bufferOut.append(" }\r\n");
556 bufferOut.append(" ." + javadocCommentStyle + "\r\n");
557 bufferOut.append(" {\r\n");
558 bufferOut.append(" color: #CC0033;\r\n");
559 bufferOut.append(" background-color: transparent;\r\n");
560 bufferOut.append(" }\r\n");
561 bufferOut.append(" ." + javadocTagStyle + "\r\n");
562 bufferOut.append(" {\r\n");
563 bufferOut.append(" color: #0099CC;\r\n");
564 bufferOut.append(" background-color: transparent;\r\n");
565 bufferOut.append(" }\r\n");
566 bufferOut.append(" ." + importNameStyle + "\r\n");
567 bufferOut.append(" {\r\n");
568 bufferOut.append(" color: #33CCCC;\r\n");
569 bufferOut.append(" background-color: transparent;\r\n");
570 bufferOut.append(" }\r\n");
571 bufferOut.append(" ." + packageNameStyle + "\r\n");
572 bufferOut.append(" {\r\n");
573 bufferOut.append(" color: #339999;\r\n");
574 bufferOut.append(" background-color: transparent;\r\n");
575 bufferOut.append(" }\r\n");
576 bufferOut.append(" ." + primitiveTypeStyle + "\r\n");
577 bufferOut.append(" {\r\n");
578 bufferOut.append(" color: #009900;\r\n");
579 bufferOut.append(" background-color: transparent;\r\n");
580 bufferOut.append(" }\r\n");
581 bufferOut.append(" ." + nonPrimitiveTypeStyle + "\r\n");
582 bufferOut.append(" {\r\n");
583 bufferOut.append(" color: #009966;\r\n");
584 bufferOut.append(" background-color: transparent;\r\n");
585 bufferOut.append(" }\r\n");
586 bufferOut.append(" ." + constructorStyle + "\r\n");
587 bufferOut.append(" {\r\n");
588 bufferOut.append(" color: #3300CC;\r\n");
589 bufferOut.append(" background-color: transparent;\r\n");
590 bufferOut.append(" }\r\n");
591 bufferOut.append(" ." + constantStyle + "\r\n");
592 bufferOut.append(" {\r\n");
593 bufferOut.append(" color: #666666;\r\n");
594 bufferOut.append(" background-color: transparent;\r\n");
595 bufferOut.append(" }\r\n");
596 bufferOut.append(" ." + doubleQuoteStyle + "\r\n");
597 bufferOut.append(" {\r\n");
598 bufferOut.append(" color: #996633;\r\n");
599 bufferOut.append(" background-color: transparent;\r\n");
600 bufferOut.append(" font-style: italic;\r\n");
601 bufferOut.append(" }\r\n");
602 bufferOut.append(" ." + singleQuoteStyle + "\r\n");
603 bufferOut.append(" {\r\n");
604 bufferOut.append(" color: #663333;\r\n");
605 bufferOut.append(" background-color: transparent;\r\n");
606 bufferOut.append(" font-style: oblique;\r\n");
607 bufferOut.append(" }\r\n");
608 bufferOut.append(" ." + numericLiteralStyle + "\r\n");
609 bufferOut.append(" {\r\n");
610 bufferOut.append(" color: #333300;\r\n");
611 bufferOut.append(" background-color: transparent;\r\n");
612 bufferOut.append(" }\r\n");
613 bufferOut.append(" ." + primitiveLiteralStyle + "\r\n");
614 bufferOut.append(" {\r\n");
615 bufferOut.append(" color: #006600;\r\n");
616 bufferOut.append(" background-color: transparent;\r\n");
617 bufferOut.append(" }\r\n");
620 bufferOut.append(" ." + iconStyle + "\r\n");
621 bufferOut.append(" {\r\n");
622 bufferOut.append(" border-style: none;\r\n");
623 bufferOut.append(" }\r\n");
627 bufferOut.append(" #title\r\n");
628 bufferOut.append(" {\r\n");
629 bufferOut.append(" text-align: center;\r\n");
630 bufferOut.append(" font-size: xx-large;\r\n");
631 bufferOut.append(" }\r\n");
635 bufferOut.append(" #legendTitle\r\n");
636 bufferOut.append(" {\r\n");
637 bufferOut.append(" text-align: center;\r\n");
638 bufferOut.append(" font-size: x-large;\r\n");
639 bufferOut.append(" }\r\n");
640 bufferOut.append(" #legend\r\n");
641 bufferOut.append(" {\r\n");
642 bufferOut.append(" font-family: monospace;\r\n");
643 bufferOut.append(" font-size: large;\r\n");
644 bufferOut.append(" }\r\n");
648 bufferOut.append(" #footer\r\n");
649 bufferOut.append(" {\r\n");
650 bufferOut.append(" font-size: xx-small;\r\n");
651 bufferOut.append(" }\r\n");
653 bufferOut.append(" /* ]]> */ -->\r\n");
654 bufferOut.append(" </style>\r\n");
657 if (hasExternalStyleSheet)
659 bufferOut.append(" <link rel=\"stylesheet\" " +
660 "type=\"text/css\" href=\"" +
661 externalStyleSheetName + "\" />\r\n");
663 bufferOut.append(" </head>\r\n");
664 bufferOut.append(" <body>\r\n");
668 bufferOut.append(" <div id=\"title\">\r\n");
669 bufferOut.append(" " + sourceFileName + "\r\n");
670 bufferOut.append(" </div>\r\n");
671 bufferOut.append(" <hr />\r\n");
675 bufferOut.append(" <div id=\"legendTitle\">\r\n");
676 bufferOut.append(" Legend\r\n");
677 bufferOut.append(" </div>\r\n");
678 bufferOut.append(" <div class=\"" + sourceCodeStyle + "\">\r\n");
679 bufferOut.append(" <div id=\"legend\">\r\n");
680 bufferOut.append(" <span class=\"" + keywordStyle + "\">");
681 bufferOut.append("keyword</span>\r\n");
682 bufferOut.append(" <span class=\"" + methodStyle + "\">");
683 bufferOut.append("method</span>\r\n");
684 bufferOut.append(" <span class=\"" + variableStyle + "\">variable" +
686 bufferOut.append(" <span class=\"" + singleLineCommentStyle + "\">" +
687 "singleLineComment</span>\r\n");
688 bufferOut.append(" <span class=\"" + traditionalCommentStyle + "\">" +
689 "traditionalComment</span>\r\n");
690 bufferOut.append(" <span class=\"" + javadocCommentStyle + "\">" +
691 "javadocComment</span>\r\n");
692 bufferOut.append(" <span class=\"" + javadocTagStyle + "\">javadocTag" +
694 bufferOut.append(" <span class=\"" + importNameStyle + "\">" +
695 "importName</span>\r\n");
696 bufferOut.append(" <span class=\"" + packageNameStyle + "\">" +
697 "packageName</span>\r\n");
698 bufferOut.append(" <span class=\"" + primitiveTypeStyle + "\">" +
699 "primitiveType</span>\r\n");
700 bufferOut.append(" <span class=\"" + nonPrimitiveTypeStyle + "\">" +
701 "nonPrimitiveType</span>\r\n");
702 bufferOut.append(" <span class=\"" + constructorStyle + "\">" +
703 "constructor</span>\r\n");
704 bufferOut.append(" <span class=\"" + constantStyle + "\">" +
705 "constant</span>\r\n");
706 bufferOut.append(" <span class=\"" + doubleQuoteStyle + "\">" +
707 "doubleQuote</span>\r\n");
708 bufferOut.append(" <span class=\"" + singleQuoteStyle + "\">" +
709 "singleQuote</span>\r\n");
710 bufferOut.append(" <span class=\"" + numericLiteralStyle + "\">" +
711 "numericLiteral</span>\r\n");
712 bufferOut.append(" <span class=\"" + primitiveLiteralStyle + "\">" +
713 "primitiveLiteral</span>\r\n");
714 bufferOut.append(" </div>\r\n");
715 bufferOut.append(" </div>\r\n");
716 bufferOut.append(" <hr />\r\n");
718 bufferOut.append(" <div class=\"" + sourceCodeStyle + "\">\r\n");
719 if (hasLineModulusCodeBlocks)
721 bufferOut.append("<pre class=\"modulusBlockPREStyle\">\r\n");
725 bufferOut.append("<pre>\r\n");
727 // process the input Java code Stringbuffer
728 // subtract 2 from the bufferIn.length() to get EOF marker
729 while (presentIndex++ < (bufferIn.length() - 2))
731 for (int i = 0; i < extraIndentation; i++)
733 bufferOut.append(" ");
735 if ((hasLineNumbers || hasLineModulusCodeBlocks) && isNewLine)
737 // add line numbers if desired
738 // line numbers are 1 - 9999 then rotate line numbers
739 codeLineNumber = (++codeLineNumber)%10000;
740 if ((lineModulus > 0) && hasLineModulusCodeBlocks &&
741 (codeLineNumber%lineModulus == 1))
745 if ((State.TRADITIONAL_COMMENT == presentState) ||
746 (State.JAVADOC == presentState))
748 bufferOut.insert((bufferOut.length() -
752 bufferOut.append("</pre>\r\n");
753 bufferOut.append(" <div class=");
754 bufferOut.append("\"modulusBlockStyle\">");
755 bufferOut.append("\r\n<pre class=\"");
756 bufferOut.append("modulusBlockPREStyle\">\r\n");
757 if (State.TRADITIONAL_COMMENT == presentState)
759 bufferOut.append("<span class=" +
760 "\"" + traditionalCommentStyle + "\">");
762 if (State.JAVADOC == presentState)
764 bufferOut.append("<span class=" +
765 "\"" + javadocCommentStyle + "\">");
768 isNewBlock = !isNewBlock;
770 // make straight columns of line numbers
771 if (codeLineNumber < 1000)
773 bufferOut.append(" ");
775 if (codeLineNumber < 100)
777 bufferOut.append(" ");
779 if (codeLineNumber < 10)
781 bufferOut.append(" ");
783 bufferOut.append("<a name=\"line.");
784 bufferOut.append(codeLineNumber);
785 bufferOut.append("\">");
789 if ((lineModulus > 0) && (codeLineNumber%lineModulus == 0))
791 bufferOut.append("<span class=" +
792 "\"" + modulusLineNumberStyle + "\">");
793 bufferOut.append(codeLineNumber);
794 bufferOut.append(": </span>");
795 if (hasLineModulusDrawnLines)
797 // compute spaceLength so a line can be drawn
798 while ((presentIndex != (bufferIn.length() - 1)) &&
799 ((Character.isSpaceChar(
800 bufferIn.charAt(presentIndex))) ||
801 (bufferIn.charAt(presentIndex) == '\t')))
803 // for each tab, insert tabSize spaces
804 if (bufferIn.charAt(presentIndex) == '\t')
806 for (int i = 0; i < tabSize; i++)
808 bufferIn.insert(presentIndex + 1, " ");
813 if (' ' == bufferIn.charAt(presentIndex))
815 // read a space so place a space
816 bufferOut.append(" ");
817 spaceLength += (" ").length();
821 // a white space character was read
822 bufferOut.append(bufferIn.charAt(
828 // check if line is empty
829 // (no printable characters on line)
830 if ((presentIndex == (bufferIn.length() - 1)) ||
831 (Character.isWhitespace(bufferIn.charAt(
839 bufferOut.insert((bufferOut.length() -
840 spaceLength), "<span class=" +
841 "\"modulusLineStyle\">");
842 bufferOut.insert((bufferOut.length() -
843 (" ").length()), "</span>");
850 // line numbers are in lineNumberColor
851 bufferOut.append("<span class=\"" + lineNumberStyle + "\">");
852 bufferOut.append(codeLineNumber);
853 bufferOut.append(":</span> ");
858 bufferOut.append("</a>");
861 presentChar = bufferIn.charAt(presentIndex);
862 if ((Character.isJavaIdentifierPart(presentChar)) ||
863 ((State.IMPORT_NAME == presentState) && (presentChar == '*')))
865 // this is an identifier
866 bufferOut.append(presentChar);
868 continue; // keep adding characters until identifier is done
870 if (identifierLength > 0)
873 qualifiedIdentifierLength =
874 qualifiedIdentifierLength + identifierLength;
875 if (bufferIn.charAt(presentIndex) == '.')
877 // qualified identifier
878 bufferOut.append(presentChar);
879 qualifiedIdentifierLength++;
880 identifierLength = 0;
881 continue; // keep adding characters to qualified identifier
884 bufferOut.substring(bufferOut.length() -
886 if ((State.PARAM_VARIABLE == presentState))
888 // any identifier after a param in a javadoc is assumed to
890 bufferOut.insert(bufferOut.length() -
891 qualifiedIdentifierLength,
892 "<span class=\"" + variableStyle + "\">");
893 bufferOut.append("</span>");
894 presentState = State.JAVADOC;
896 else if (State.JAVADOC == presentState)
899 if ((javadocTagCollection.contains(identifier)) &&
900 (bufferIn.charAt(presentIndex -
901 (identifierLength + 1)) == '@'))
903 // identifier is a javadocTag
904 bufferOut.insert(bufferOut.length() - identifierLength,
905 "<span class=\"" + javadocTagStyle + "\">");
906 bufferOut.append("</span>");
907 if (("param").equals(identifier))
909 // any identifier after a param is assumed to
910 // be a variable, get into a state to do this
911 presentState = State.PARAM_VARIABLE;
915 else if (State.IMPORT_NAME == presentState)
918 bufferOut.insert(bufferOut.length() -
919 qualifiedIdentifierLength,
920 "<span class=\"" + importNameStyle + "\">");
921 bufferOut.append("</span>");
922 presentState = State.TEXT;
924 else if (State.PACKAGE_NAME == presentState)
926 // package identifier
927 bufferOut.insert(bufferOut.length() -
928 qualifiedIdentifierLength,
929 "<span class=\"" + packageNameStyle + "\">");
930 bufferOut.append("</span>");
931 presentState = State.TEXT;
933 else if (State.TEXT == presentState)
935 if (keywordCollection.contains(identifier))
937 // identifier is a keyword
938 bufferOut.insert(bufferOut.length() -
939 qualifiedIdentifierLength,
940 "<span class=\"" + keywordStyle + "\">");
941 bufferOut.append("</span>");
942 if (("import").equals(identifier))
944 // anything after an import in text mode must be
945 // an import name, so enter state to process this
946 presentState = State.IMPORT_NAME;
948 else if (("package").equals(identifier))
950 // anything after an package in text mode must be
951 // an package name, so enter state to process this
952 presentState = State.PACKAGE_NAME;
955 else if (primitiveTypeCollection.contains(identifier))
957 // identifier is a primitive type
958 bufferOut.insert(bufferOut.length() -
959 qualifiedIdentifierLength,
960 "<span class=\"" + primitiveTypeStyle + "\">");
961 bufferOut.append("</span>");
963 else if ((identifier.equals(identifier.toUpperCase())) &&
964 (!(Character.isDigit(identifier.charAt(0)))))
966 // identifier is a constant
967 bufferOut.insert(bufferOut.length() -
968 qualifiedIdentifierLength,
969 "<span class=\"" + constantStyle + "\">");
970 bufferOut.append("</span>");
972 else if (Character.isUpperCase(identifier.charAt(0)))
974 // identifier is a constructor or non-primitive type
976 saveIndex = presentIndex;
977 while (Character.isWhitespace(
978 bufferIn.charAt(saveIndex++)))
982 if (bufferIn.charAt(--saveIndex) == '(')
983 { // identifier is a constructor
984 bufferOut.insert(bufferOut.length() -
985 qualifiedIdentifierLength,
987 "\"" + constructorStyle + "\">");
988 bufferOut.append("</span>");
992 // identifier is a non-primitive type
993 bufferOut.insert(bufferOut.length() -
994 qualifiedIdentifierLength,
996 "\"" + nonPrimitiveTypeStyle + "\">");
997 bufferOut.append("</span>");
1000 else if (!(Character.isDigit(identifier.charAt(0)) ||
1001 primitiveLiteralCollection.contains(identifier)))
1003 // identifier is a method or a variable
1005 saveIndex = presentIndex;
1006 while (Character.isWhitespace(
1007 bufferIn.charAt(saveIndex++)))
1012 // identifier is a method
1013 if (bufferIn.charAt(saveIndex) == '(')
1015 bufferOut.insert(bufferOut.length() -
1016 qualifiedIdentifierLength,
1017 "<span class=\"" + methodStyle + "\">");
1018 bufferOut.append("</span>");
1020 else if (bufferIn.charAt(saveIndex) == ',')
1022 // comma seperated variables
1023 bufferOut.insert(bufferOut.length() -
1024 qualifiedIdentifierLength,
1025 "<span class=\"" + variableStyle + "\">");
1026 bufferOut.append("</span>");
1031 // take care of cases such as array[index].variable
1032 if (bufferIn.charAt(presentIndex -
1033 (qualifiedIdentifierLength
1036 qualifiedIdentifierLength++;
1038 bufferOut.insert(bufferOut.length() -
1039 qualifiedIdentifierLength,
1040 "<span class=\"" + variableStyle + "\">");
1041 bufferOut.append("</span>");
1046 if (primitiveLiteralCollection.contains(identifier))
1048 // primitiveLiteral (boolean or null)
1049 bufferOut.insert(bufferOut.length() -
1050 identifierLength, "<span class=" +
1051 "\"" + primitiveLiteralStyle + "\">");
1052 bufferOut.append("</span>");
1054 // a numeric literal
1057 if (((presentIndex -
1058 (qualifiedIdentifierLength + 1)) > 0) &&
1059 (bufferIn.charAt(presentIndex -
1060 (qualifiedIdentifierLength + 1)) == '.'))
1062 qualifiedIdentifierLength++;
1064 bufferOut.insert(bufferOut.length() -
1065 qualifiedIdentifierLength,
1067 "\"" + numericLiteralStyle + "\">");
1068 bufferOut.append("</span>");
1072 qualifiedIdentifierLength = 0;
1073 identifierLength = 0;
1075 // process characters NOT in identifiers
1076 switch (presentChar)
1078 case '&': //ampersand
1079 bufferOut.append("&"); // HTMLify character
1081 case '<': // less than sign
1082 bufferOut.append("<"); // HTMLify character
1084 case '>': // greater than sign
1085 bufferOut.append(">"); // HTMLify character
1087 case '\"': // double quote
1088 bufferOut.append("""); // HTMLify character
1089 if (State.TEXT == presentState)
1091 presentState = State.DOUBLE_QUOTE;
1092 bufferOut.insert(bufferOut.length()-(""").length(),
1093 "<span class=\"" + doubleQuoteStyle + "\">");
1095 else if (State.DOUBLE_QUOTE == presentState)
1097 presentState = State.TEXT;
1098 bufferOut.append("</span>");
1101 case '\'': // single quote
1102 bufferOut.append("\'");
1103 if (State.TEXT == presentState)
1105 presentState = State.SINGLE_QUOTE;
1106 bufferOut.insert(bufferOut.length() - ("\'").length(),
1107 "<span class=\"" + singleQuoteStyle + "\">");
1109 else if (State.SINGLE_QUOTE == presentState)
1111 presentState = State.TEXT;
1112 bufferOut.append("</span>");
1115 case '\\': // backslash
1116 bufferOut.append("\\");
1117 if ((State.DOUBLE_QUOTE == presentState) ||
1118 (State.SINGLE_QUOTE == presentState))
1120 // treat as a character escape sequence
1121 bufferOut.append(bufferIn.charAt(++presentIndex));
1125 // replace tabs with tabsize number of spaces
1126 for (int i = 0; i < tabSize; i++)
1128 bufferOut.append(' ');
1132 bufferOut.append("*");
1133 if ((State.TEXT == presentState) &&
1134 (bufferIn.charAt(presentIndex - 1) == '/'))
1136 if (((bufferIn.length() - 1) > presentIndex) &&
1137 (bufferIn.charAt(presentIndex + 1) == '*'))
1139 presentState = State.JAVADOC;
1140 bufferOut.insert(bufferOut.length() -
1141 ("/*").length(), "<span class=" +
1142 "\"" + javadocCommentStyle + "\">");
1146 presentState = State.TRADITIONAL_COMMENT;
1147 bufferOut.insert(bufferOut.length() -
1148 ("/*").length(), "<span class=" +
1149 "\"" + traditionalCommentStyle + "\">");
1153 case '/': // foward slash
1154 bufferOut.append("/");
1155 if (((State.TRADITIONAL_COMMENT == presentState) ||
1156 (State.JAVADOC == presentState)) &&
1157 (bufferIn.charAt(presentIndex - 1) == '*'))
1159 bufferOut.append("</span>");
1160 presentState = State.TEXT;
1162 if ((State.TEXT == presentState) &&
1163 (presentIndex > 0) &&
1164 (bufferIn.charAt(presentIndex - 1) == '/'))
1166 bufferOut.insert(bufferOut.length() - ("//").length(),
1168 "\"" + singleLineCommentStyle + "\">");
1169 presentState = State.LINE_COMMENT;
1172 case '\r': // carriage return
1174 case '\n': // line feed
1175 // all HTML lines end in \r\n
1176 if ((bufferIn.charAt(presentIndex) == '\r') &&
1177 ((bufferIn.length() - 1) > presentIndex) &&
1178 (bufferIn.charAt(presentIndex + 1) == '\n'))
1182 // end single line comments
1183 if (State.LINE_COMMENT == presentState)
1185 bufferOut.append("</span>");
1186 presentState = State.TEXT;
1189 if ((lineModulus > 0) && hasLineModulusCodeBlocks &&
1190 ((codeLineNumber%lineModulus == 0) && !isNewBlock))
1192 // end multi-line spanning states
1193 if ((State.TRADITIONAL_COMMENT == presentState) ||
1194 (State.JAVADOC == presentState))
1196 bufferOut.append("</span>");
1198 bufferOut.append("\r\n");
1199 bufferOut.append("</pre>\r\n");
1200 bufferOut.append(" </div>\r\n");
1201 bufferOut.append("<pre class=\"");
1202 bufferOut.append("modulusBlockPREStyle\">\r\n");
1203 // restart multi-line spanning states
1204 if (State.TRADITIONAL_COMMENT == presentState)
1206 bufferOut.append("<span class=" +
1207 "\"" + traditionalCommentStyle + "\">");
1209 if (State.JAVADOC == presentState)
1211 bufferOut.append("<span class=" +
1212 "\"" + javadocCommentStyle + "\">");
1217 // div automatically starts new line
1218 bufferOut.append("\r\n");
1222 case 0: // nul character
1223 if ((State.LINE_COMMENT == presentState) &&
1224 (presentIndex == (bufferIn.length() - 1)))
1226 bufferOut.append("</span>");
1229 default: // everything else
1230 bufferOut.append(presentChar);
1232 qualifiedIdentifierLength = 0;
1234 if (presentState == State.LINE_COMMENT) {
1235 bufferOut.append("</span>\r\n");
1238 bufferOut.append("</pre>\r\n");
1239 // end block early if no more source code
1240 if ((lineModulus > 0) && hasLineModulusCodeBlocks && !isNewBlock &&
1241 (codeLineNumber%lineModulus != 0))
1243 bufferOut.append(" </div>\r\n");
1245 bufferOut.append(" </div>\r\n"); // end div of sourceCodeStyle
1246 // if code snippet then don't add ending tags of xhtml page
1249 // if footer mode then add a footer
1252 bufferOut.append(" <hr />\r\n");
1253 bufferOut.append(" <div id=\"footer\">\r\n");
1258 bufferOut.append(" <script type=\"text/javaScript\"");
1259 bufferOut.append(">\r\n");
1260 bufferOut.append(" <!-- // <![CDATA[\r\n");
1261 bufferOut.append(" document.write(\"Document last");
1262 bufferOut.append(" modified on \"");
1263 bufferOut.append(" + document.lastModified + ");
1264 bufferOut.append("\"<br />\");\r\n");
1265 bufferOut.append(" // ]]> -->\r\n");
1266 bufferOut.append(" </script>\r\n");
1268 bufferOut.append(" <a href=\"");
1269 bufferOut.append("http://validator.w3.org/check/referer");
1270 bufferOut.append("\">\r\n");
1271 bufferOut.append(" <img class=\"" + iconStyle + "\" src=\"");
1272 bufferOut.append("http://www.w3.org/Icons/");
1275 bufferOut.append("valid-xhtml11\"\r\n");
1276 bufferOut.append(" alt=\"Valid XHTML 1.1!\"");
1280 bufferOut.append("valid-xhtml10\"\r\n");
1281 bufferOut.append(" alt=\"Valid XHTML 1.0!\"");
1283 bufferOut.append(" height=\"31\" ");
1284 bufferOut.append("width=\"88\" />\r\n");
1285 bufferOut.append(" </a>\r\n");
1286 bufferOut.append("  \r\n");
1287 bufferOut.append(" <a href=\"");
1288 bufferOut.append("http://jigsaw.w3.org");
1289 bufferOut.append("/css-validator/check/referer");
1290 bufferOut.append("\">\r\n");
1291 bufferOut.append(" <img class=\"" + iconStyle + "\" src=\"");
1292 bufferOut.append("http://jigsaw.w3.org/");
1293 bufferOut.append("css-validator/images/vcss");
1294 bufferOut.append("\"\r\n");
1295 bufferOut.append(" alt=\"Valid CSS!\"");
1296 bufferOut.append(" height=\"31\" width=\"88\" />\r\n");
1297 bufferOut.append(" </a>\r\n");
1301 bufferOut.append(" This is a valid\r\n");
1302 bufferOut.append(" <a href=\"http://");
1303 bufferOut.append("validator.w3.org/check/referer");
1306 bufferOut.append("\">XHTML 1.1</a>\r\n");
1310 bufferOut.append("\">XHTML 1.0</a>\r\n");
1312 bufferOut.append(" with\r\n");
1313 bufferOut.append(" <a href=\"http://");
1314 bufferOut.append("jigsaw.w3.org");
1315 bufferOut.append("/css-validator/check/referer");
1316 bufferOut.append("\">CSS</a>\r\n");
1317 bufferOut.append(" document \r\n");
1320 bufferOut.append(" <script type=\"text/javaScript\"");
1321 bufferOut.append(">\r\n");
1322 bufferOut.append(" <!-- // <![CDATA[\r\n");
1323 bufferOut.append(" document.write(\"last modified");
1324 bufferOut.append(" on \" + document.lastModified);");
1325 bufferOut.append("\r\n");
1326 bufferOut.append(" // ]]> -->\r\n");
1327 bufferOut.append(" </script>\r\n");
1330 bufferOut.append(" </div>\r\n");
1332 bufferOut.append(" </body>\r\n");
1333 bufferOut.append("</html>\r\n");
1335 return bufferOut.toString();