Java代码高亮

嗲吗高亮显示

package com.linda.web.hilight;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class JavaHilighter implements Hilighter {

	@Override
	public String parse(String code) {
		int currentState = STATE_TEXT;
		int identifierLength = 0;
		int currentIndex = -1;
		char currentChar = 0;
		String identifier = "";
		StringBuffer out = new StringBuffer();
		while (++currentIndex != code.length() - 1) {
			currentChar = code.charAt(currentIndex);
			if (Character.isJavaIdentifierPart(currentChar)) {
				out.append(currentChar);
				++identifierLength;
				continue;
			}
			if (identifierLength > 0) {
				identifier = out.substring(out.length() - identifierLength);
				if (currentState == STATE_TEXT) {
					if (literalSet.contains(identifier)) { // identifier is a literal
						out.insert(out.length() - identifierLength,
						"<div class=\"literalStyle\">");
						out.append("</div>");
					} else if (keywordSet.contains(identifier)) { // identifier  is a keyword
						out.insert(out.length() - identifierLength,
						"<div class=\"keywordStyle\">");
						out.append("</div>");
					} else if (primitiveTypeSet.contains(identifier)) { // identifier is a primitive type
						out.insert(out.length() - identifierLength,"<div class=\"primitiveTypeStyle\">");
						out.append("</div>");
					} else if (identifier.equals(identifier.toUpperCase())&& !Character.isDigit(identifier.charAt(0))) { // identifier is a constant
						out.insert(out.length() - identifierLength,
						"<div class=\"constantStyle\">");
						out.append("</div>");
					} else if (Character.isUpperCase(identifier.charAt(0))) { // identifier is non-primitive type
						out.insert(out.length() - identifierLength,"<div class=\"nonPrimitiveTypeStyle\">");
						out.append("</div>");
					}
				}
			}
			switch (currentChar) {
			// because I handle the "greater than" and "less than" marks
			// somewhere else, I comment them out here
			// case '<':
			// out.append("<");
			// break;
			// case '>':
			// out.append(">");
			// break;
			case '\"':
				out.append('\"');
				if (currentState == STATE_TEXT) {
					currentState = STATE_DOUBLE_QUOTE;
					out.insert(out.length() - ("\"").length(),
					"<div class=\"doubleQuoteStyle\">");
				} else if (currentState == STATE_DOUBLE_QUOTE) {
					currentState = STATE_TEXT;
					out.append("</div>");
				}
				break;
			case '\'':
				out.append("\'");
				if (currentState == STATE_TEXT) {
					currentState = STATE_SINGLE_QUOTE;
					out.insert(out.length() - ("\'").length(),
					"<div class=\"singleQuoteStyle\">");
				} else if (currentState == STATE_SINGLE_QUOTE) {
					currentState = STATE_TEXT;
					out.append("</div>");
				}
				break;
			case '\\':
				out.append("\\");
				if (currentState == STATE_DOUBLE_QUOTE|| currentState == STATE_SINGLE_QUOTE) {
					// treat as a character escape sequence
					out.append(code.charAt(++currentIndex));
				}
				break;
			// if you want to translate tabs into spaces, uncomment the
			// following lines
			// case '\t':
			// // replace tabs with tabsize number of spaces
			// for (int i = 0; i < tabSize; i++)
			// out.append("    ");
			// break;
			case '*':
				out.append('*');
				if (currentState == STATE_TEXT && currentIndex > 0&& code.charAt(currentIndex - 1) == '/') {
					out.insert(out.length() - ("/*").length(),"<div class=\"multiLineCommentStyle\">");
					currentState = STATE_MULTI_LINE_COMMENT;
				}
				break;
			case '/':
				out.append("/");
				if (currentState == STATE_TEXT && currentIndex > 0&& code.charAt(currentIndex - 1) == '/') {
					out.insert(out.length() - ("//").length(),
					"<div class=\"singleLineCommentStyle\">");
					currentState = STATE_LINE_COMMENT;
				} else if (currentState == STATE_MULTI_LINE_COMMENT) {
					out.append("</div>");
					currentState = STATE_TEXT;
				}
				break;
			case '\r':
			case '\n':
				// end single line comments
				if (currentState == STATE_LINE_COMMENT) {
					out.insert(out.length() - 1, "</div>");
					currentState = STATE_TEXT;
				}
				if (currentChar == '\r' && currentIndex < code.length() - 1) {
					out.append("\r\n");
					++currentIndex;
				} else
					out.append('\n');
				if (enableLineNumber)
					out.append("<div class=\"lineNumberStyle\">"+ (++lineNumber) + ".</div>");
				break;
			case 0:
				if (currentState == STATE_LINE_COMMENT&& currentIndex == (code.length() - 1))out.append("</div>");
				break;
			default: // everything else
				out.append(currentChar);
			}
			identifierLength = 0;
		}
		return out.toString();
	}

	public static int STATE_TEXT = 1; // 普通文本
	public static int STATE_DOUBLE_QUOTE = 2; // 双引号
	public static int STATE_SINGLE_QUOTE = 3; // 单引号
	public static int STATE_MULTI_LINE_COMMENT = 4; // 多行注释
	public static int STATE_LINE_COMMENT = 5; // 单行注释
	private int lineNumber; // 行号
	private boolean enableLineNumber = true; // 开启行号标志

	public boolean isEnableLineNumber() {
		return enableLineNumber;
	}

	// line numbers are printed by default.
	// but this behavior can be disabled by invoking this method and setting the
	// flag to false
	public void setEnableLineNumber(boolean enableLineNumber) {
		this.enableLineNumber = enableLineNumber;
	}

	String[] literalArray = { "null", "true", "false" }; // 字面常量
	String[] keywordArray = { "abstract", "break", "case", "catch", "class","const", "continue", 
	"default", "do", "else", "extends", "final","finally", "for", "goto", "if", "implements", "import",
	"instanceof", "interface", "native", "new", "package", "private","protected", "public", "return",
	"static", "strictfp", "super","switch", "synchronized", "this", "throw", "throws", "transient",
	"try", "volatile", "while" }; // 关键词
	String[] primitiveTypeArray = { "boolean", "char", "byte", "short", "int","long", "float", "double", "void" }; // 原始数据类型
	Set<String> literalSet = new HashSet<String>(Arrays.asList(literalArray));
	Set<String> keywordSet = new HashSet<String>(Arrays.asList(keywordArray));
	Set<String> primitiveTypeSet = new HashSet<String>(Arrays.asList(primitiveTypeArray));

	public static void main(String args[]) throws Exception {
		File file = new File("D:\\work\\web-project\\webmusic\\src\\main\\java\\com\\linda\\web\\hilight\\JavaHilighter.java");
		BufferedReader br = new BufferedReader(new InputStreamReader(
		new FileInputStream(file), "UTF-8"));
		StringBuffer sb = new StringBuffer();
		String temp = null;
		while ((temp = br.readLine()) != null) {
			sb.append(temp).append('\n');
		}
		String src = sb.toString();
		JavaHilighter jsh = new JavaHilighter();
		System.out.println(jsh.parse(src));
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值