001: package net.xoetrope.builder.editor.syntaxhighlight;
002:
003: /*
004: * XMLTokenMarker.java - XML token marker
005: * Copyright (C) 1998, 1999 Slava Pestov
006: * Copyright (C) 2001 Tom Bradford
007: *
008: * You may use and modify this package for any purpose. Redistribution is
009: * permitted, in both source and binary form, provided that this notice
010: * remains intact in all source distributions of this package.
011: */
012:
013: import javax.swing.text.Segment;
014:
015: /**
016: * XML Token Marker Rewrite
017: *
018: * @author Tom Bradford
019: * @version $Id: XMLTokenMarker.java,v 1.23 2005/01/05 17:20:50 luano Exp $
020: */
021: public class XMLTokenMarker extends TokenMarker {
022: public XMLTokenMarker() {
023: }
024:
025: public byte markTokensImpl(byte token, Segment line, int lineIndex) {
026: char[] array = line.array;
027: int offset = line.offset;
028: int lastOffset = offset;
029: int length = line.count + offset;
030:
031: // Ugly hack to handle multi-line tags
032: boolean sk1 = token == Token.KEYWORD1;
033:
034: for (int i = offset; i < length; i++) {
035: int ip1 = i + 1;
036: char c = array[i];
037: switch (token) {
038: case Token.NULL: // text
039: switch (c) {
040: case '<':
041: addToken(i - lastOffset, token);
042: lastOffset = i;
043: if (SyntaxUtilities.regionMatches(false, line, ip1,
044: "!--")) {
045: i += 3;
046: token = Token.COMMENT1;
047: } else if (array[ip1] == '!') {
048: i += 1;
049: token = Token.COMMENT2;
050: } else if (array[ip1] == '?') {
051: i += 1;
052: token = Token.KEYWORD3;
053: } else
054: token = Token.KEYWORD1;
055: break;
056:
057: case '&':
058: addToken(i - lastOffset, token);
059: lastOffset = i;
060: token = Token.LABEL;
061: break;
062: }
063: break;
064:
065: case Token.KEYWORD1: // tag
066: switch (c) {
067: case '>':
068: addToken(ip1 - lastOffset, token);
069: lastOffset = ip1;
070: token = Token.NULL;
071: sk1 = false;
072: break;
073:
074: case ' ':
075: case '\t':
076: addToken(i - lastOffset, token);
077: lastOffset = i;
078: token = Token.KEYWORD2;
079: sk1 = false;
080: break;
081:
082: default:
083: if (sk1) {
084: token = Token.KEYWORD2;
085: sk1 = false;
086: }
087: break;
088: }
089: break;
090:
091: case Token.KEYWORD2: // attribute
092: switch (c) {
093: case '>':
094: addToken(ip1 - lastOffset, token);
095: lastOffset = ip1;
096: token = Token.NULL;
097: break;
098:
099: case '/':
100: addToken(i - lastOffset, token);
101: lastOffset = i;
102: token = Token.KEYWORD1;
103: break;
104:
105: case '=':
106: addToken(i - lastOffset, token);
107: lastOffset = i;
108: token = Token.OPERATOR;
109: }
110: break;
111:
112: case Token.OPERATOR: // equal for attribute
113: switch (c) {
114: case '\"':
115: case '\'':
116: addToken(i - lastOffset, token);
117: lastOffset = i;
118: if (c == '\"')
119: token = Token.LITERAL1;
120: else
121: token = Token.LITERAL2;
122: break;
123: }
124: break;
125:
126: case Token.LITERAL1:
127: case Token.LITERAL2: // strings
128: if ((token == Token.LITERAL1 && c == '\"')
129: || (token == Token.LITERAL2 && c == '\'')) {
130: addToken(ip1 - lastOffset, token);
131: lastOffset = ip1;
132: token = Token.KEYWORD1;
133: }
134: break;
135:
136: case Token.LABEL: // entity
137: if (c == ';') {
138: addToken(ip1 - lastOffset, token);
139: lastOffset = ip1;
140: token = Token.NULL;
141: break;
142: }
143: break;
144:
145: case Token.COMMENT1: // Inside a comment
146: if (SyntaxUtilities
147: .regionMatches(false, line, i, "-->")) {
148: addToken((i + 3) - lastOffset, token);
149: lastOffset = i + 3;
150: token = Token.NULL;
151: }
152: break;
153:
154: case Token.COMMENT2: // Inside a declaration
155: if (SyntaxUtilities.regionMatches(false, line, i, ">")) {
156: addToken(ip1 - lastOffset, token);
157: lastOffset = ip1;
158: token = Token.NULL;
159: }
160: break;
161:
162: case Token.KEYWORD3: // Inside a processor instruction
163: if (SyntaxUtilities.regionMatches(false, line, i, "?>")) {
164: addToken((i + 2) - lastOffset, token);
165: lastOffset = i + 2;
166: token = Token.NULL;
167: }
168: break;
169:
170: default:
171: throw new InternalError("Invalid state: " + token);
172: }
173: }
174:
175: switch (token) {
176: case Token.LABEL:
177: addToken(length - lastOffset, Token.INVALID);
178: token = Token.NULL;
179: break;
180:
181: default:
182: addToken(length - lastOffset, token);
183: break;
184: }
185:
186: return token;
187: }
188: }
|