2 * Copyright (c) 2003-2004 Christopher Lenz and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * Christopher Lenz - initial API and implementation
11 * $Id: CssCodeScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
14 package net.sourceforge.phpeclipse.css.ui.internal.text;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.List;
20 import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
21 import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
22 import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences;
23 import net.sourceforge.phpeclipse.css.ui.text.IColorManager;
25 import org.eclipse.jface.preference.IPreferenceStore;
26 import org.eclipse.jface.text.rules.ICharacterScanner;
27 import org.eclipse.jface.text.rules.IRule;
28 import org.eclipse.jface.text.rules.IToken;
29 import org.eclipse.jface.text.rules.IWhitespaceDetector;
30 import org.eclipse.jface.text.rules.Token;
31 import org.eclipse.jface.text.rules.WhitespaceRule;
34 * Rule based scanner responsible for syntax highlighting CSS source.
36 public class CssCodeScanner extends AbstractCssScanner {
38 // Inner Classes -----------------------------------------------------------
41 * Custom rule that detects the SGML/XML comment delimiters
42 * (<code><!--</code> and <code>--></code> which are allowed at the
43 * beginning and the end of CSS content.
45 private class CdoCdcRule implements IRule {
48 * The associated token.
55 * @param token the associated token
57 public CdoCdcRule(IToken token) {
62 * @see IRule#evaluate(ICharacterScanner)
64 public synchronized IToken evaluate(ICharacterScanner scanner) {
65 IToken retVal = Token.UNDEFINED;
67 int c = scanner.read();
82 } else if (c == '-') {
102 * Custom rule that can detect an at-keyword such as <code>@import</code>.
104 private class AtKeywordRule implements IRule {
107 * The associated token.
109 private IToken token;
112 * Collection of known at-keywords.
114 private Collection atKeywords;
119 * @param token the associated token
121 public AtKeywordRule(IToken token) {
123 atKeywords = getProfile().getAtKeywords();
127 * @see IRule#evaluate(ICharacterScanner)
129 public synchronized IToken evaluate(ICharacterScanner scanner) {
130 IToken retVal = Token.UNDEFINED;
132 int c = scanner.read();
135 if (CssTextUtils.isCssIdentifierStart((char) c)) {
138 appendToBuffer((char) c);
141 } while (CssTextUtils.isCssIdentifierPart((char) c));
142 String candidate = getBufferContent().toLowerCase();
143 if (atKeywords.contains(candidate)) {
148 while (count-- > 0) {
157 * Custom rule that can detect a known property.
159 private class PropertyRule implements IRule {
162 * The associated token.
164 private IToken token;
167 * Collection of known properties.
169 private Collection properties;
174 * @param token the associated token
176 public PropertyRule(IToken token) {
178 properties = getProfile().getProperties();
182 * @see IRule#evaluate(ICharacterScanner)
184 public synchronized IToken evaluate(ICharacterScanner scanner) {
185 IToken retVal = Token.UNDEFINED;
187 int c = scanner.read();
188 if (CssTextUtils.isCssIdentifierStart((char) c)) {
191 appendToBuffer((char) c);
194 } while (CssTextUtils.isCssIdentifierPart((char) c));
195 String candidate = getBufferContent().toLowerCase();
196 if (properties.contains(candidate)) {
197 while (CssTextUtils.isCssWhitespace((char) c)) {
207 while (count-- > 0) {
216 * Custom rule that can detect a pseudo-class in a selector.
218 private class PseudoClassRule implements IRule {
221 * The associated token.
223 private IToken token;
226 * Collection of known pseudo-classes.
228 private Collection pseudoClasses;
233 * @param token the associated token
235 public PseudoClassRule(IToken token) {
237 pseudoClasses = getProfile().getPseudoClassNames();
241 * @see IRule#evaluate(ICharacterScanner)
243 public synchronized IToken evaluate(ICharacterScanner scanner) {
244 IToken retVal = Token.UNDEFINED;
246 int c = scanner.read();
249 if (CssTextUtils.isCssIdentifierStart((char) c)) {
252 appendToBuffer((char) c);
255 } while (CssTextUtils.isCssIdentifierPart((char) c));
256 String candidate = getBufferContent().toLowerCase();
257 if (pseudoClasses.contains(candidate)) {
262 while (count-- > 0) {
271 * Detects CSS white space.
273 private static class WhitespaceDetector implements IWhitespaceDetector {
276 * @see IWhitespaceDetector#isWhitespace(char)
278 public boolean isWhitespace(char c) {
279 return CssTextUtils.isCssWhitespace(c);
284 // Instance Variables ------------------------------------------------------
287 * The current CSS profile.
289 private IProfile profile;
292 * Shared buffer used by the word detectors.
294 private StringBuffer buffer = new StringBuffer();
296 // Constructors ------------------------------------------------------------
301 * @param store The preference store
302 * @param manager The color manager
303 * @param profile The CSS profile to use
305 public CssCodeScanner(IPreferenceStore store, IColorManager manager,
307 super(store, manager);
308 this.profile = profile;
310 List rules = new ArrayList();
312 rules.add(new WhitespaceRule(new WhitespaceDetector()));
314 rules.add(new CdoCdcRule(createToken(
315 CssUIPreferences.EDITOR_COMMENT_COLOR,
316 CssUIPreferences.EDITOR_COMMENT_BOLD)));
317 rules.add(new AtKeywordRule(createToken(
318 CssUIPreferences.EDITOR_AT_KEYWORD_COLOR,
319 CssUIPreferences.EDITOR_AT_KEYWORD_BOLD)));
320 rules.add(new PropertyRule(createToken(
321 CssUIPreferences.EDITOR_PROPERTY_COLOR,
322 CssUIPreferences.EDITOR_PROPERTY_BOLD)));
323 rules.add(new PseudoClassRule(createToken(
324 CssUIPreferences.EDITOR_PSEUDO_CLASS_COLOR,
325 CssUIPreferences.EDITOR_PSEUDO_CLASS_BOLD)));
327 setRules((IRule[]) rules.toArray(new IRule[rules.size()]));
329 setDefaultReturnToken(createToken(
330 CssUIPreferences.EDITOR_DEFAULT_COLOR,
331 CssUIPreferences.EDITOR_DEFAULT_BOLD));
334 // Private Methods ---------------------------------------------------------
336 private IProfile getProfile() {
340 private void appendToBuffer(char c) {
344 private String getBufferContent() {
345 return buffer.toString();
348 private void resetBuffer() {