1 package org.syntax.jedit.tokenmarker;
2
3
4
5
6
7
8
9
10
11
12
13 import javax.swing.text.Segment;
14
15 import org.syntax.jedit.SyntaxUtilities;
16
17 /***
18 * XML Token Marker Rewrite
19 *
20 * @author Tom Bradford
21 * @version $Id$
22 */
23 public class XMLTokenMarker extends TokenMarker {
24 public XMLTokenMarker() {
25 }
26
27 public byte markTokensImpl(byte token, Segment line, int lineIndex) {
28 char[] array = line.array;
29 int offset = line.offset;
30 int lastOffset = offset;
31 int length = line.count + offset;
32
33
34 boolean sk1 = token == Token.KEYWORD1;
35
36 for ( int i = offset; i < length; i++ ) {
37 int ip1 = i+1;
38 char c = array[i];
39 switch ( token ) {
40 case Token.NULL:
41 switch ( c ) {
42 case '<':
43 addToken(i-lastOffset, token);
44 lastOffset = i;
45 if ( SyntaxUtilities.regionMatches(false, line, ip1, "!--") ) {
46 i += 3;
47 token = Token.COMMENT1;
48 }
49 else if ( array[ip1] == '!' ) {
50 i += 1;
51 token = Token.COMMENT2;
52 }
53 else if ( array[ip1] == '?' ) {
54 i += 1;
55 token = Token.KEYWORD3;
56 }
57 else
58 token = Token.KEYWORD1;
59 break;
60
61 case '&':
62 addToken(i - lastOffset, token);
63 lastOffset = i;
64 token = Token.LABEL;
65 break;
66 }
67 break;
68
69 case Token.KEYWORD1:
70 switch ( c ) {
71 case '>':
72 addToken(ip1-lastOffset, token);
73 lastOffset = ip1;
74 token = Token.NULL;
75 sk1 = false;
76 break;
77
78 case ' ':
79 case '\t':
80 addToken(i-lastOffset, token);
81 lastOffset = i;
82 token = Token.KEYWORD2;
83 sk1 = false;
84 break;
85
86 default:
87 if ( sk1 ) {
88 token = Token.KEYWORD2;
89 sk1 = false;
90 }
91 break;
92 }
93 break;
94
95 case Token.KEYWORD2:
96 switch ( c ) {
97 case '>':
98 addToken(ip1-lastOffset, token);
99 lastOffset = ip1;
100 token = Token.NULL;
101 break;
102
103 case '/':
104 addToken(i-lastOffset, token);
105 lastOffset = i;
106 token = Token.KEYWORD1;
107 break;
108
109 case '=':
110 addToken(i-lastOffset, token);
111 lastOffset = i;
112 token = Token.OPERATOR;
113 }
114 break;
115
116 case Token.OPERATOR:
117 switch ( c ) {
118 case '\"':
119 case '\'':
120 addToken(i-lastOffset, token);
121 lastOffset = i;
122 if ( c == '\"' )
123 token = Token.LITERAL1;
124 else
125 token = Token.LITERAL2;
126 break;
127 }
128 break;
129
130 case Token.LITERAL1:
131 case Token.LITERAL2:
132 if ( ( token == Token.LITERAL1 && c == '\"' )
133 || ( token == Token.LITERAL2 && c == '\'' ) ) {
134 addToken(ip1-lastOffset, token);
135 lastOffset = ip1;
136 token = Token.KEYWORD1;
137 }
138 break;
139
140 case Token.LABEL:
141 if ( c == ';' ) {
142 addToken(ip1-lastOffset, token);
143 lastOffset = ip1;
144 token = Token.NULL;
145 break;
146 }
147 break;
148
149 case Token.COMMENT1:
150 if ( SyntaxUtilities.regionMatches(false, line, i, "-->") ) {
151 addToken((i+3)-lastOffset, token);
152 lastOffset = i+3;
153 token = Token.NULL;
154 }
155 break;
156
157 case Token.COMMENT2:
158 if ( SyntaxUtilities.regionMatches(false, line, i, ">") ) {
159 addToken(ip1-lastOffset, token);
160 lastOffset = ip1;
161 token = Token.NULL;
162 }
163 break;
164
165 case Token.KEYWORD3:
166 if ( SyntaxUtilities.regionMatches(false, line, i, "?>") ) {
167 addToken((i+2)-lastOffset, token);
168 lastOffset = i+2;
169 token = Token.NULL;
170 }
171 break;
172
173 default:
174 throw new InternalError("Invalid state: " + token);
175 }
176 }
177
178 switch ( token ) {
179 case Token.LABEL:
180 addToken(length-lastOffset, Token.INVALID);
181 token = Token.NULL;
182 break;
183
184 default:
185 addToken(length-lastOffset, token);
186 break;
187 }
188
189 return token;
190 }
191 }
192
193