cz.vutbr.web.csskit.antlr4.CSSToken Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jstyleparser Show documentation
Show all versions of jstyleparser Show documentation
jStyleParser is a CSS parser written in Java. It has its own application interface that is designed to allow an efficient CSS processing in Java and mapping the values to the Java data types. It parses CSS 2.1 style sheets into structures that can be efficiently assigned to DOM elements. It is intended be the primary CSS parser for the CSSBox library. While handling errors, it is user agent conforming according to the CSS specification.
The newest version!
package cz.vutbr.web.csskit.antlr4;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.Pair;
import java.net.URL;
import java.util.Map;
import java.util.TreeMap;
/**
* Token with encapsulation of LexerState during parse.
* Models view at token text by removing syntactic sugar
* from tokens with contains it,
* e.g. STRING, URI, FUNCTION
* @author kapy
*
*/
public class CSSToken extends CommonToken {
/**
* Extended with EOF_TOKEN
*/
private static final long serialVersionUID = 3L;
/**
* Current lexer state
*/
protected CSSLexerState ls;
/** Base URL for URIs */
protected URL base;
protected boolean valid = true;
// token types
public static final int FUNCTION = 1;
public static final int URI = 2;
public static final int STRING = 3;
public static final int CLASSKEYWORD = 4;
public static final int HASH = 5;
public static final int UNCLOSED_STRING = 6;
public static final int UNCLOSED_URI = 7;
private final TypeMapper typeMapper;
/**
* Creates CSSToken, this is base {@code emit()} constructor
* @param input Input stream
* @param type Type of token
* @param channel Channel of token
* @param start Start position in stream
* @param stop End position in stream
*/
public CSSToken(Pair input, int type, int channel, int start, int stop, TypeMapper typeMapper) {
super(input, type, channel, start, stop);
this.typeMapper = typeMapper;
}
/**
* Creates CSSToken of given type with cloning lexer state
* automatically
* @param type Type of token
* @param state State of lexer, which will be copied
*/
public CSSToken(int type, CSSLexerState state, TypeMapper typeMapper) {
this(type, state, 0, 0, typeMapper);
}
/**
* Creates CSSToken of given type with cloning lexer state
* automatically, allows to set text boundaries in input stream
* @param type Type of token
* @param state State of lexer, which will be copied
* @param start Start position in stream
* @param stop End position in stream
*/
public CSSToken(int type, CSSLexerState state, int start, int stop, TypeMapper typeMapper) {
this(new Pair(null,null), type, Token.DEFAULT_CHANNEL, start, stop, typeMapper);
this.ls = new CSSLexerState(state);
}
/**
* Sets lexer state for current token
* @param state Current lexer state
* @return Modified CSSToken
*/
public CSSToken setLexerState(CSSLexerState state) {
this.ls = state;
return this;
}
/**
* Gets lexer state at creation of token
* @return the lexer state
*/
public CSSLexerState getLexerState() {
return ls;
}
/**
* Obtains the base URL used for the relative URIs
* @return the URL or null if not set
*/
public URL getBase()
{
return base;
}
/**
* Sets the base URL used for the relative URIs
* @param base the base URL to set
*/
public void setBase(URL base)
{
this.base = base;
}
public boolean isValid() {
return valid;
}
public void setValid(boolean valid) {
this.valid = valid;
}
/**
* Considers text as content of STRING token,
* and models view at this text as an common string,
* that is one character removed from the both beginning
* and the end.
* @param string Content of STRING token
* @return String with trimmed quotation marks
*/
public static String extractSTRING(String string) {
return string.substring(1, string.length()-1);
}
public static String extractUNCLOSEDSTRING(String string) {
return string.substring(1, string.length());
}
/**
* Considers text as content of URI token,
* and models view at this text as an common string,
* that is removed {@code 'url('} from the beginning
* and {@code ')'} from the and. If result of this operation
* is STRING, remove even quotation marks
* @param uri Content of URI token
* @return String with trimmed URI syntax sugar and
* optionally quotation marks
*/
public static String extractURI(String uri) {
String ret = uri.substring(4, uri.length()-1).trim();
// trim string
if(ret.length() > 0 && (ret.charAt(0)=='\'' || ret.charAt(0)=='"'))
ret = ret.substring(1, ret.length()-1);
return ret;
}
public static String extractUNCLOSEDURI(String uri) {
String ret = uri.substring(4).trim();
// trim quotes (if any)
if(ret.length() > 0) {
final char fc = ret.charAt(0);
if (fc == '\'' || fc == '"') {
final char lc = (ret.length() > 1) ? ret.charAt(ret.length() - 1) : ' ';
if (fc == lc)
ret = ret.substring(1, ret.length() - 1); //both quotes (finished string)
else
ret = ret.substring(1, ret.length()); //left quote only (unfinished string)
}
}
return ret;
}
/**
* Considers text as content of FUNCTION token,
* and models view at this text as an common string,
* that is removed {@code '('} from the end of string
* @param function Content of FUNCTION token
* @return String with trimmed FUNCTION open parenthesis
*/
public static String extractFUNCTION(String function) {
return function.substring(0, function.length()-1);
}
/**
* Considers text as content of HASH token,
* and models view at this text as an common string,
* that is removed {@code '#'} from the beginning of string
* @param hash Content of HASH token
* @return String with trimmed HASH # character
*/
public static String extractHASH(String hash) {
return hash.substring(1,hash.length());
}
/**
* Considers text as content of CLASSKEYWORD token,
* and models view at this text as an common string,
* that is removed {@code '.'} from the beginning of string
* @param className Content of CLASSKEYWORD token
* @return String with trimmed CLASSKEYWORD dot
*/
public static String extractCLASSKEYWORD(String className) {
return className.substring(1,className.length());
}
/**
* Returns common text stored in token. Content is not modified.
* @return Model view of text in token
*/
@Override
public String getText() {
// sets text from input if not text directly available
text = super.getText();
int t;
try {
t = typeMapper.inverse().get(type);
} catch (NullPointerException e) {
return text;
}
switch (t) {
case FUNCTION:
return text.substring(0, text.length()-1);
case URI:
return extractURI(text);
case UNCLOSED_URI:
return extractUNCLOSEDURI(text);
case STRING:
return extractSTRING(text);
case UNCLOSED_STRING:
return extractUNCLOSEDSTRING(text);
case CLASSKEYWORD:
return extractCLASSKEYWORD(text);
case HASH:
return extractHASH(text);
default:
return text;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("/").append(ls).append("/")
.append(super.toString());
return sb.toString();
}
/**
* Convert between type values defined in two classes.
*/
public static class TypeMapper {
private final Map map;
private final TypeMapper inverse;
private TypeMapper(Map map, TypeMapper inverse) {
this.map = map;
this.inverse = inverse;
}
public TypeMapper(Class> classA, Class> classB, String... fieldNames) {
map = new TreeMap();
Map inverseMap = new TreeMap();
for (String f : fieldNames) {
try {
int a = classA.getField(f).getInt(null);
int b = classB.getField(f).getInt(null);
map.put(a, b);
inverseMap.put(b, a);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
inverse = new TypeMapper(inverseMap, this);
}
public int get(int type) throws NullPointerException {
return map.get(type);
}
public TypeMapper inverse() {
return inverse;
}
}
public static TypeMapper createDefaultTypeMapper(Class extends Lexer> lexerClass) {
return new TypeMapper(CSSToken.class, lexerClass, "FUNCTION", "URI", "STRING", "CLASSKEYWORD", "HASH", "UNCLOSED_STRING", "UNCLOSED_URI");
}
/**
* extract charset value from CHARSET token
*/
public static String extractCHARSET(String charset){
final String arg = charset.replace("@charset","").replace(";","").trim();
if (arg.length() > 2)
return extractSTRING(arg);
else
return "";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy