1 55 56 package freemarker.eclipse.editors; 57 58 import java.util.Vector ; 59 60 import org.eclipse.jface.text.rules.ICharacterScanner; 61 import org.eclipse.jface.text.rules.IRule; 62 import org.eclipse.jface.text.rules.IToken; 63 import org.eclipse.jface.text.rules.MultiLineRule; 64 import org.eclipse.jface.text.rules.RuleBasedScanner; 65 import org.eclipse.jface.text.rules.Token; 66 import org.eclipse.jface.text.rules.WhitespaceRule; 67 68 77 public class XmlScanner extends RuleBasedScanner { 78 79 86 private Vector stack = new Vector (); 87 88 93 public XmlScanner(ITokenManager manager) { 94 Vector rules = new Vector (); 95 IRule[] result; 96 IToken comment; 97 IToken directive; 98 IToken interpolation; 99 IToken string; 100 101 string = manager.getStringToken(); 103 comment = manager.getCommentToken(); 104 directive = manager.getDirectiveToken(); 105 interpolation = manager.getInterpolationToken(); 106 107 rules.add(new MultiLineRule("<#--", "-->", comment)); 109 rules.add(new XmlDirectiveRule(directive)); 110 rules.add(new InterpolationRule(interpolation)); 111 112 rules.add(new XmlAttributeRule(string)); 114 115 rules.add(new WhitespaceRule(new WhitespaceDetector())); 117 118 result = new IRule[rules.size()]; 120 rules.copyInto(result); 121 setRules(result); 122 } 123 124 130 protected String topSequence() { 131 if (stack.isEmpty()) { 132 return null; 133 } else { 134 return (String ) stack.lastElement(); 135 } 136 } 137 138 143 protected void pushSequence(String str) { 144 stack.add(str); 145 } 146 147 150 protected void popSequence() { 151 if (stack.size() > 0) { 152 stack.remove(stack.size() - 1); 153 } 154 } 155 156 165 protected class XmlAttributeRule implements IRule { 166 167 170 private final IToken token; 171 172 177 public XmlAttributeRule(IToken token) { 178 this.token = token; 179 } 180 181 189 private boolean isQuoteChar(char c) { 190 return c == '"' || c == '\''; 191 } 192 193 196 public IToken evaluate(ICharacterScanner scanner) { 197 String start; 198 int c; 199 200 start = topSequence(); 202 if (start == null || !isQuoteChar(start.charAt(0))) { 203 c = scanner.read(); 204 if (c == EOF || !isQuoteChar((char) c)) { 205 scanner.unread(); 206 return Token.UNDEFINED; 207 } 208 pushSequence(String.valueOf((char) c)); 209 start = topSequence(); 210 } 211 212 do { 214 c = scanner.read(); 215 if (c == '$' || c == '#') { 216 c = scanner.read(); 217 scanner.unread(); 218 if (c == '{') { 219 scanner.unread(); 220 return token; 221 } 222 c = '$'; 223 } else if (c == '<') { 224 c = scanner.read(); 225 if (c == '/') { 226 c = scanner.read(); 227 scanner.unread(); 228 } 229 scanner.unread(); 230 if (c == '#' || c == '@') { 231 scanner.unread(); 232 return token; 233 } 234 c = '<'; 235 } 236 } while (c != EOF && c != start.charAt(0)); 237 238 popSequence(); 240 return token; 241 } 242 } 243 244 252 protected class XmlDirectiveRule implements IRule { 253 254 257 private final IToken token; 258 259 264 public XmlDirectiveRule(IToken token) { 265 this.token = token; 266 } 267 268 271 public IToken evaluate(ICharacterScanner scanner) { 272 String start; 273 int parens = 0; 274 int c; 275 276 start = topSequence(); 278 if (start == null || !start.equals("<#")) { 279 if (!FreemarkerTools.readDirectiveStart(scanner)) { 280 return Token.UNDEFINED; 281 } 282 pushSequence("<#"); 283 } 284 285 do { 287 c = scanner.read(); 288 if (c == '<') { 289 scanner.unread(); 290 if (FreemarkerTools.readCommentStart(scanner)) { 291 scanner.unread(); 292 scanner.unread(); 293 scanner.unread(); 294 scanner.unread(); 295 return token; 296 } 297 c = scanner.read(); 298 } else if (c == '"') { 299 FreemarkerTools.readQuoteEnd(scanner); 300 } else if (c == '(') { 301 parens++; 302 } else if (c == ')') { 303 parens--; 304 } 305 } while (c != EOF && (c != '>' || parens > 0)); 306 307 popSequence(); 309 return token; 310 } 311 } 312 } 313 | Popular Tags |