com.squarespace.less.core.CharClass Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of less-compiler Show documentation
Show all versions of less-compiler Show documentation
LESS compiler in Java based on less.js
/**
* Copyright (c) 2014 SQUARESPACE, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squarespace.less.core;
/**
* Custom character classifications for CSS/LESS. Builds an internal table which
* contains flags for each character from 0x00 through 0x80. Used in place of
* a switch() or if/else block for each character class.
*/
public class CharClass {
// Character class bits that can be set/cleared in a bit mask
public static final int DIGIT = 0x01;
public static final int LOWERCASE = 0x02;
public static final int UPPERCASE = 0x04;
public static final int KEYWORD_START = 0x08;
public static final int DIMENSION_START = 0x10;
public static final int NONASCII = 0x20;
public static final int NONPRINTABLE = 0x40;
public static final int CALL_START = 0x80;
public static final int COMBINATOR = 0x100;
public static final int SELECTOR_END = 0x200;
public static final int PROPERTY_START = 0x400;
public static final int VARIABLE_START = 0x800;
public static final int ENCODE_URI = 0x1000;
public static final int ENCODE_URI_COMPONENT = 0x2000;
public static final int ESCAPE = 0x4000;
/**
* The characters we care about all live below this limit.
*/
private static final int LIMIT = 0x80;
/**
* Table of character codes, where the value is a bit mask indicating which
* classes that character belongs to.
*/
private static final int[] CHARACTER_CLASSES = new int[LIMIT];
static {
for (int i = 0; i < LIMIT; i++) {
CHARACTER_CLASSES[i] = classify((char)i);
}
}
public static boolean callStart(char ch) {
return isMember(ch, CALL_START);
}
public static boolean combinator(char ch) {
return isMember(ch, COMBINATOR);
}
public static boolean digit(char ch) {
return isMember(ch, DIGIT);
}
public static boolean dimensionStart(char ch) {
return isMember(ch, DIMENSION_START);
}
public static boolean keywordStart(char ch) {
return isMember(ch, KEYWORD_START);
}
public static boolean nonprintable(char ch) {
return isMember(ch, NONPRINTABLE);
}
public static boolean propertyStart(char ch) {
return isMember(ch, PROPERTY_START);
}
public static boolean ruleStart(char ch) {
return isMember(ch, PROPERTY_START | VARIABLE_START);
}
public static boolean selectorEnd(char ch) {
return isMember(ch, SELECTOR_END);
}
public static boolean skippable(char ch) {
return ch == ';' || whitespace(ch);
}
public static boolean uppercase(char ch) {
return isMember(ch, UPPERCASE);
}
public static boolean whitespace(char ch) {
return (ch >= '\t' && ch <= '\r')
|| (ch == ' ')
// v8 JavaScript engine's whitespace ranges follow
|| (ch == '\u00a0')
|| (ch == '\u1680')
|| (ch == '\u180e')
|| (ch >= '\u2000' && ch <= '\u200a')
|| (ch >= '\u2028' && ch <= '\u2029')
|| (ch == '\u202f')
|| (ch == '\u205f')
|| (ch == '\u3000')
|| (ch == '\ufeff');
}
public static boolean isMember(char ch, int cls) {
return (ch >= LIMIT) ? false : (CHARACTER_CLASSES[ch] & cls) > 0;
}
/**
* Table used to generate static char classification table. This is only called
* for each character < LIMIT once to build the lookup table.
*/
private static int classify(char ch) {
switch (ch) {
case '\u0000':
case '\u0001':
case '\u0002':
case '\u0003':
case '\u0004':
case '\u0005':
case '\u0006':
case '\u0007':
case '\u0008':
return NONPRINTABLE;
case '\u000E':
case '\u000F':
case '\u0010':
case '\u0011':
case '\u0012':
case '\u0013':
case '\u0014':
case '\u0015':
case '\u0016':
case '\u0017':
case '\u0018':
case '\u0019':
case '\u001A':
case '\u001B':
case '\u001C':
case '\u001D':
case '\u001E':
case '\u001F':
return NONPRINTABLE;
case '!':
return ENCODE_URI | ENCODE_URI_COMPONENT;
case '#':
return ENCODE_URI | ESCAPE;
case '$':
return ENCODE_URI;
case '%':
return CALL_START;
case '&':
return ENCODE_URI;
case '\'':
return ENCODE_URI | ENCODE_URI_COMPONENT;
case '(':
return ENCODE_URI | ENCODE_URI_COMPONENT | ESCAPE;
case ')':
return SELECTOR_END | ENCODE_URI | ENCODE_URI_COMPONENT | ESCAPE;
case '*':
return PROPERTY_START | ENCODE_URI | ENCODE_URI_COMPONENT;
case '+':
return DIMENSION_START | COMBINATOR | ENCODE_URI;
case ',':
return SELECTOR_END | ENCODE_URI;
case '-':
return CALL_START | DIMENSION_START | KEYWORD_START | PROPERTY_START | ENCODE_URI | ENCODE_URI_COMPONENT;
case '.':
return DIMENSION_START | ENCODE_URI | ENCODE_URI_COMPONENT;
case '/':
return ENCODE_URI;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return DIGIT | DIMENSION_START | PROPERTY_START;
case ':':
return ENCODE_URI | ESCAPE;
case ';':
return SELECTOR_END | ENCODE_URI | ESCAPE;
case '=':
return ENCODE_URI | ESCAPE;
case '>':
return COMBINATOR;
case '?':
return ENCODE_URI;
case '@':
return VARIABLE_START | ENCODE_URI;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
return UPPERCASE | CALL_START | KEYWORD_START;
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
return UPPERCASE | CALL_START | KEYWORD_START;
case '_':
return CALL_START | KEYWORD_START | PROPERTY_START | ENCODE_URI | ENCODE_URI_COMPONENT;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
return LOWERCASE | CALL_START | KEYWORD_START | PROPERTY_START;
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
return LOWERCASE | CALL_START | KEYWORD_START | PROPERTY_START;
case '{':
return SELECTOR_END;
case '|':
return COMBINATOR;
case '}':
return SELECTOR_END;
case '~':
return COMBINATOR | ENCODE_URI | ENCODE_URI_COMPONENT;
default:
break;
}
return (ch >= Chars.NO_BREAK_SPACE) ? NONASCII : 0;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy