1 packageJavaSyntaxHighterDemo;2
3 importjava.io.BufferedReader;4 importjava.io.File;5 importjava.io.FileInputStream;6 importjava.io.InputStreamReader;7 importjava.util.Arrays;8 importjava.util.HashSet;9 importjava.util.Set;10
11 /**
12 *@authorKevin Tse13 *@version0.114 */
15 public classJavaSyntaxHighlighter {16
17 public static int STATE_TEXT = 1; //普通文本
18 public static int STATE_DOUBLE_QUOTE = 2; //双引号
19 public static int STATE_SINGLE_QUOTE = 3; //单引号
20 public static int STATE_MULTI_LINE_COMMENT = 4; //多行注释
21 public static int STATE_LINE_COMMENT = 5; //单行注释
22
23 private int lineNumber; //行号
24 private boolean enableLineNumber = true; //开启行号标志
25
26 public booleanisEnableLineNumber() {27 returnenableLineNumber;28 }29
30 //line numbers are printed by default.31 //but this behavior can be disabled by invoking this method and setting the32 //flag to false
33 public void setEnableLineNumber(booleanenableLineNumber) {34 this.enableLineNumber =enableLineNumber;35 }36
37 String[] literalArray = { "null", "true", "false" }; //字面常量
38 String[] keywordArray = { "abstract", "break", "case", "catch", "class",39 "const", "continue", "default", "do", "else", "extends", "final",40 "finally", "for", "goto", "if", "implements", "import",41 "instanceof", "interface", "native", "new", "package", "private",42 "protected", "public", "return", "static", "strictfp", "super",43 "switch", "synchronized", "this", "throw", "throws", "transient",44 "try", "volatile", "while" }; //关键词
45 String[] primitiveTypeArray = { "boolean", "char", "byte", "short", "int",46 "long", "float", "double", "void" }; //原始数据类型
47
48 Set literalSet = new HashSet(Arrays.asList(literalArray));49 Set keywordSet = new HashSet(Arrays.asList(keywordArray));50 Set primitiveTypeSet = new HashSet(Arrays51 .asList(primitiveTypeArray));52
53 publicString process(String src) {54 int currentState =STATE_TEXT;55 int identifierLength = 0;56 int currentIndex = -1;57 char currentChar = 0;58 String identifier = "";59 StringBuffer out = newStringBuffer();60
61 while (++currentIndex != src.length() - 1) {62 currentChar =src.charAt(currentIndex);63 if(Character.isJavaIdentifierPart(currentChar)) {64 out.append(currentChar);65 ++identifierLength;66 continue;67 }68 if (identifierLength > 0) {69 identifier = out.substring(out.length() -identifierLength);70 if (currentState ==STATE_TEXT) {71 if (literalSet.contains(identifier)) { //identifier is a72 //literal
73 out.insert(out.length() -identifierLength,74 "
79 out.insert(out.length() -identifierLength,80 "
86 out.insert(out.length() -identifierLength,87 "
94 out.insert(out.length() -identifierLength,95 "
101 out.insert(out.length() -identifierLength,102 "
108 switch(currentChar) {109 //because I handle the "greater than" and "less than" marks110 //somewhere else, I comment them out here111 //case ‘‘:115 //out.append(">");116 //break;
117 case ‘\"‘:118 out.append(‘\"‘);119 if (currentState ==STATE_TEXT) {120 currentState =STATE_DOUBLE_QUOTE;121 out.insert(out.length() - ("\"").length(),122 "
144 out.append(src.charAt(++currentIndex));145 }146 break;147 //if you want to translate tabs into spaces, uncomment the148 //following lines149 //case ‘\t‘:150 // //replace tabs with tabsize number of spaces151 //for (int i = 0; i < tabSize; i++)152 //out.append(" ");153 //break;
154 case ‘*‘:155 out.append(‘*‘);156 if (currentState == STATE_TEXT && currentIndex > 0
157 && src.charAt(currentIndex - 1) == ‘/‘) {158 out.insert(out.length() - ("/*").length(),159 "
166 && src.charAt(currentIndex - 1) == ‘/‘) {167 out.insert(out.length() - ("//").length(),168 "
178 if (currentState ==STATE_LINE_COMMENT) {179 out.insert(out.length() - 1, "
186 out.append(‘\n‘);187
188 if(enableLineNumber)189 out.append("
190 + (++lineNumber) + ".