X-Git-Url: http://secure.phpeclipse.com diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCodeScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCodeScanner.java new file mode 100644 index 0000000..62447eb --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssCodeScanner.java @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2003-2004 Christopher Lenz and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Christopher Lenz - initial API and implementation + * + * $Id: CssCodeScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $ + */ + +package net.sourceforge.phpeclipse.css.ui.internal.text; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils; +import net.sourceforge.phpeclipse.css.core.profiles.IProfile; +import net.sourceforge.phpeclipse.css.ui.internal.CssUIPreferences; +import net.sourceforge.phpeclipse.css.ui.text.IColorManager; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.rules.ICharacterScanner; +import org.eclipse.jface.text.rules.IRule; +import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.IWhitespaceDetector; +import org.eclipse.jface.text.rules.Token; +import org.eclipse.jface.text.rules.WhitespaceRule; + +/** + * Rule based scanner responsible for syntax highlighting CSS source. + */ +public class CssCodeScanner extends AbstractCssScanner { + + // Inner Classes ----------------------------------------------------------- + + /** + * Custom rule that detects the SGML/XML comment delimiters + * (<!-- and --> which are allowed at the + * beginning and the end of CSS content. + */ + private class CdoCdcRule implements IRule { + + /** + * The associated token. + */ + private IToken token; + + /** + * Constructor. + * + * @param token the associated token + */ + public CdoCdcRule(IToken token) { + this.token = token; + } + + /** + * @see IRule#evaluate(ICharacterScanner) + */ + public synchronized IToken evaluate(ICharacterScanner scanner) { + IToken retVal = Token.UNDEFINED; + int count = 1; + int c = scanner.read(); + if (c == '<') { + count++; + c = scanner.read(); + if (c == '!') { + count++; + c = scanner.read(); + if (c == '-') { + count++; + c = scanner.read(); + if (c == '-') { + return token; + } + } + } + } else if (c == '-') { + count++; + c = scanner.read(); + if (c == '-') { + count++; + c = scanner.read(); + if (c == '>') { + return token; + } + } + } + while (count-- > 0) { + scanner.unread(); + } + return retVal; + } + + } + + /** + * Custom rule that can detect an at-keyword such as @import. + */ + private class AtKeywordRule implements IRule { + + /** + * The associated token. + */ + private IToken token; + + /** + * Collection of known at-keywords. + */ + private Collection atKeywords; + + /** + * Constructor. + * + * @param token the associated token + */ + public AtKeywordRule(IToken token) { + this.token = token; + atKeywords = getProfile().getAtKeywords(); + } + + /** + * @see IRule#evaluate(ICharacterScanner) + */ + public synchronized IToken evaluate(ICharacterScanner scanner) { + IToken retVal = Token.UNDEFINED; + int count = 1; + int c = scanner.read(); + if (c == '@') { + c = scanner.read(); + if (CssTextUtils.isCssIdentifierStart((char) c)) { + resetBuffer(); + do { + appendToBuffer((char) c); + c = scanner.read(); + count++; + } while (CssTextUtils.isCssIdentifierPart((char) c)); + String candidate = getBufferContent().toLowerCase(); + if (atKeywords.contains(candidate)) { + return token; + } + } + } + while (count-- > 0) { + scanner.unread(); + } + return retVal; + } + + } + + /** + * Custom rule that can detect a known property. + */ + private class PropertyRule implements IRule { + + /** + * The associated token. + */ + private IToken token; + + /** + * Collection of known properties. + */ + private Collection properties; + + /** + * Constructor. + * + * @param token the associated token + */ + public PropertyRule(IToken token) { + this.token = token; + properties = getProfile().getProperties(); + } + + /** + * @see IRule#evaluate(ICharacterScanner) + */ + public synchronized IToken evaluate(ICharacterScanner scanner) { + IToken retVal = Token.UNDEFINED; + int count = 1; + int c = scanner.read(); + if (CssTextUtils.isCssIdentifierStart((char) c)) { + resetBuffer(); + do { + appendToBuffer((char) c); + c = scanner.read(); + count++; + } while (CssTextUtils.isCssIdentifierPart((char) c)); + String candidate = getBufferContent().toLowerCase(); + if (properties.contains(candidate)) { + while (CssTextUtils.isCssWhitespace((char) c)) { + c = scanner.read(); + count++; + } + if (c == ':') { + scanner.unread(); + return token; + } + } + } + while (count-- > 0) { + scanner.unread(); + } + return retVal; + } + + } + + /** + * Custom rule that can detect a pseudo-class in a selector. + */ + private class PseudoClassRule implements IRule { + + /** + * The associated token. + */ + private IToken token; + + /** + * Collection of known pseudo-classes. + */ + private Collection pseudoClasses; + + /** + * Constructor. + * + * @param token the associated token + */ + public PseudoClassRule(IToken token) { + this.token = token; + pseudoClasses = getProfile().getPseudoClassNames(); + } + + /** + * @see IRule#evaluate(ICharacterScanner) + */ + public synchronized IToken evaluate(ICharacterScanner scanner) { + IToken retVal = Token.UNDEFINED; + int count = 1; + int c = scanner.read(); + if (c == ':') { + c = scanner.read(); + if (CssTextUtils.isCssIdentifierStart((char) c)) { + resetBuffer(); + do { + appendToBuffer((char) c); + c = scanner.read(); + count++; + } while (CssTextUtils.isCssIdentifierPart((char) c)); + String candidate = getBufferContent().toLowerCase(); + if (pseudoClasses.contains(candidate)) { + return token; + } + } + } + while (count-- > 0) { + scanner.unread(); + } + return retVal; + } + + } + + /** + * Detects CSS white space. + */ + private static class WhitespaceDetector implements IWhitespaceDetector { + + /** + * @see IWhitespaceDetector#isWhitespace(char) + */ + public boolean isWhitespace(char c) { + return CssTextUtils.isCssWhitespace(c); + } + + } + + // Instance Variables ------------------------------------------------------ + + /** + * The current CSS profile. + */ + private IProfile profile; + + /** + * Shared buffer used by the word detectors. + */ + private StringBuffer buffer = new StringBuffer(); + + // Constructors ------------------------------------------------------------ + + /** + * Constructor. + * + * @param store The preference store + * @param manager The color manager + * @param profile The CSS profile to use + */ + public CssCodeScanner(IPreferenceStore store, IColorManager manager, + IProfile profile) { + super(store, manager); + this.profile = profile; + + List rules = new ArrayList(); + + rules.add(new WhitespaceRule(new WhitespaceDetector())); + + rules.add(new CdoCdcRule(createToken( + CssUIPreferences.EDITOR_COMMENT_COLOR, + CssUIPreferences.EDITOR_COMMENT_BOLD))); + rules.add(new AtKeywordRule(createToken( + CssUIPreferences.EDITOR_AT_KEYWORD_COLOR, + CssUIPreferences.EDITOR_AT_KEYWORD_BOLD))); + rules.add(new PropertyRule(createToken( + CssUIPreferences.EDITOR_PROPERTY_COLOR, + CssUIPreferences.EDITOR_PROPERTY_BOLD))); + rules.add(new PseudoClassRule(createToken( + CssUIPreferences.EDITOR_PSEUDO_CLASS_COLOR, + CssUIPreferences.EDITOR_PSEUDO_CLASS_BOLD))); + + setRules((IRule[]) rules.toArray(new IRule[rules.size()])); + + setDefaultReturnToken(createToken( + CssUIPreferences.EDITOR_DEFAULT_COLOR, + CssUIPreferences.EDITOR_DEFAULT_BOLD)); + } + + // Private Methods --------------------------------------------------------- + + private IProfile getProfile() { + return profile; + } + + private void appendToBuffer(char c) { + buffer.append(c); + } + + private String getBufferContent() { + return buffer.toString(); + } + + private void resetBuffer() { + buffer.setLength(0); + } + +}