mirror of
https://github.com/danog/dart-sass.git
synced 2025-01-10 14:58:38 +01:00
141 lines
4.6 KiB
Dart
141 lines
4.6 KiB
Dart
// Copyright 2016 Google Inc. Use of this source code is governed by an
|
|
// MIT-style license that can be found in the LICENSE file or at
|
|
// https://opensource.org/licenses/MIT.
|
|
|
|
import 'package:charcode/charcode.dart';
|
|
|
|
/// The difference between upper- and lowercase ASCII letters.
|
|
///
|
|
/// `0b100000` can be bitwise-ORed with uppercase ASCII letters to get their
|
|
/// lowercase equivalents.
|
|
const _asciiCaseBit = 0x20;
|
|
|
|
/// Returns whether [character] is an ASCII whitespace character.
|
|
bool isWhitespace(int character) =>
|
|
character == $space || character == $tab || isNewline(character);
|
|
|
|
/// Returns whether [character] is an ASCII newline.
|
|
bool isNewline(int character) =>
|
|
character == $lf || character == $cr || character == $ff;
|
|
|
|
/// Returns whether [character] is a letter or number.
|
|
bool isAlphanumeric(int character) =>
|
|
isAlphabetic(character) || isDigit(character);
|
|
|
|
/// Returns whether [character] is a letter.
|
|
bool isAlphabetic(int character) =>
|
|
(character >= $a && character <= $z) ||
|
|
(character >= $A && character <= $Z);
|
|
|
|
/// Returns whether [character] is a number.
|
|
bool isDigit(int character) =>
|
|
character != null && character >= $0 && character <= $9;
|
|
|
|
/// Returns whether [character] is legal as the start of a Sass identifier.
|
|
bool isNameStart(int character) =>
|
|
character == $_ || isAlphabetic(character) || character >= 0x0080;
|
|
|
|
/// Returns whether [character] is legal in the body of a Sass identifier.
|
|
bool isName(int character) =>
|
|
isNameStart(character) || isDigit(character) || character == $minus;
|
|
|
|
/// Returns whether [character] is a hexadeicmal digit.
|
|
bool isHex(int character) =>
|
|
isDigit(character) ||
|
|
(character >= $a && character <= $f) ||
|
|
(character >= $A && character <= $F);
|
|
|
|
/// Returns whether [character] is the beginning of a UTF-16 surrogate pair.
|
|
bool isHighSurrogate(int character) =>
|
|
character >= 0xD800 && character <= 0xDBFF;
|
|
|
|
// Returns whether [character] can start a simple selector other than a type
|
|
// selector.
|
|
bool isSimpleSelectorStart(int character) =>
|
|
character == $asterisk ||
|
|
character == $lbracket ||
|
|
character == $dot ||
|
|
character == $hash ||
|
|
character == $colon;
|
|
|
|
/// Returns the value of [character] as a hex digit.
|
|
///
|
|
/// Assumes that [character] is a hex digit.
|
|
int asHex(int character) {
|
|
assert(isHex(character));
|
|
if (character <= $9) return character - $0;
|
|
if (character <= $F) return 10 + character - $A;
|
|
return 10 + character - $a;
|
|
}
|
|
|
|
/// Returns the hexadecimal digit for [number].
|
|
///
|
|
/// Assumes that [number] is less than 16.
|
|
int hexCharFor(int number) {
|
|
assert(number < 0x10);
|
|
return number < 0xA ? $0 + number : $a - 0xA + number;
|
|
}
|
|
|
|
/// Returns the value of [character] as a decimal digit.
|
|
///
|
|
/// Assumes that [character] is a decimal digit.
|
|
int asDecimal(int character) {
|
|
assert(character >= $0 && character <= $9);
|
|
return character - $0;
|
|
}
|
|
|
|
/// Returns the decimal digit for [number].
|
|
///
|
|
/// Assumes that [number] is less than 10.
|
|
int decimalCharFor(int number) {
|
|
assert(number < 10);
|
|
return $0 + number;
|
|
}
|
|
|
|
/// Assumes that [character] is a left-hand brace-like character, and returns
|
|
/// the right-hand version.
|
|
int opposite(int character) {
|
|
switch (character) {
|
|
case $lparen:
|
|
return $rparen;
|
|
case $lbrace:
|
|
return $rbrace;
|
|
case $lbracket:
|
|
return $rbracket;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// Returns [character], converted to upper case if it's an ASCII lowercase
|
|
/// letter.
|
|
int toUpperCase(int character) => (character >= $a && character <= $z)
|
|
? character & ~_asciiCaseBit
|
|
: character;
|
|
|
|
/// Returns [character], converted to lower case if it's an ASCII uppercase
|
|
/// letter.
|
|
int toLowerCase(int character) => (character >= $A && character <= $Z)
|
|
? character | _asciiCaseBit
|
|
: character;
|
|
|
|
/// Returns whether [character1] and [character2] are the same, modulo ASCII case.
|
|
bool characterEqualsIgnoreCase(int character1, int character2) {
|
|
if (character1 == character2) return true;
|
|
|
|
// If this check fails, the characters are definitely different. If it
|
|
// succeeds *and* either character is an ASCII letter, they're equivalent.
|
|
if (character1 ^ character2 != _asciiCaseBit) return false;
|
|
|
|
// Now we just need to verify that one of the characters is an ASCII letter.
|
|
var upperCase1 = character1 & ~_asciiCaseBit;
|
|
return upperCase1 >= $A && upperCase1 <= $Z;
|
|
}
|
|
|
|
/// Like [characterEqualsIgnoreCase], but optimized for the fact that [letter]
|
|
/// is known to be a lowercase ASCII letter.
|
|
bool equalsLetterIgnoreCase(int letter, int actual) {
|
|
assert(letter >= $a && letter <= $z);
|
|
return (actual | _asciiCaseBit) == letter;
|
|
}
|