Modifier and Type | Class and Description |
---|---|
static class |
Source.Snapshot |
Modifier and Type | Field and Description |
---|---|
static char |
NULL_CHAR
the "null" character, this is used to represent the absence of a char value
|
Constructor and Description |
---|
Source(CharSequence source)
Creates a new instance of a
Source , to be used for reading one character at a time from the given source. |
Source(CharSequence source,
int anchorLine,
int anchorColumn)
Creates a new instance of a
Source , to be used for reading one character at a time from the given source. |
Source(CharSequence source,
int anchorLine,
int anchorColumn,
boolean checkInString)
Creates a new instance of a
Source , to be used for reading one character at a time from the given source. |
Source(RawSyntax raw)
|
Source(RawSyntax raw,
boolean checkInString)
|
Modifier and Type | Method and Description |
---|---|
int |
anchorColumn()
Gets the original column of this
Source within the original source. |
int |
anchorLine()
Gets the original line of this
Source within the original source. |
String |
chomp(Token token)
Opposite of
until(Token) , this will advance past the current character and all subsequent characters for as long
as they match the given Token . |
String |
chompEnclosedValue(Token openingToken,
Token closingToken)
Similar to
chomp(Token) , except this expects the value to be enclosed with an opening and closing delimiter Token . |
Source |
collectComments()
Parses all comments and whitespace at the current position in the source.
|
Source |
collectComments(boolean skipWhitespace)
Parses all comments at the current position in the source.
|
int |
column()
Gets the current column position.
|
char |
current()
Gets the character at the current position.
|
boolean |
eof()
Gets whether we are at the end of the source.
|
Source |
expect(Token token)
|
Source |
expect(Token token,
String errorMessage,
Object... args)
|
boolean |
findComments(boolean skipWhitespace)
Parses all comments at the current position in the source.
|
List<String> |
flushComments()
Returns all CSS comments currently in the buffer.
|
void |
forward(int newIndex)
Advance the current position to the given index.
|
String |
fullSource()
Gets the original source.
|
int |
index()
Gets the current index position within the original source.
|
boolean |
inString()
Whether we are currently inside of a string.
|
boolean |
isEscaped()
Gets whether the current character is preceded by the escape character
|
boolean |
isSubSource()
Gets whether this a sub-sequence.
|
int |
length()
Gets the length of the source.
|
int |
line()
Gets the current line number.
|
char |
next()
Advance to the next character.
|
Optional<Character> |
optional(Token token)
|
<T extends Enum<T> & ConstantEnum> |
optionalFromConstantEnum(Class<T> klass)
Similar to
optional(Token) and optionalFromEnum(Class) , except this works with ConstantEnum s,
checking each member of the given enum (in the declared order) for a matching constant. |
<T extends Enum<T> & TokenEnum> |
optionalFromEnum(Class<T> klass)
Similar to
optional(Token) , except this works with TokenEnum s, checking each member of the given enum (in
the declared order) for a matching token. |
boolean |
optionallyPresent(Token token)
Same as
optional(Token) , except it returns the result of Optional.isPresent() . |
int |
originalColumn()
Gets the original column, taking into account both the
anchorColumn() and the current column() . |
int |
originalLine()
Gets the original line, taking into account both the
anchorLine() and the current line() . |
char |
peek()
Gets the next character without advancing the current position.
|
char |
peek(int numCharacters)
Gets the character at the given number of characters forward without advancing the current position.
|
char |
peekPrevious()
Gets the previous character.
|
boolean |
readConstant(String constant)
Reads a constant string at the current position.
|
boolean |
readConstantCaseInsensitive(String constant)
Same as
readConstant(String) , except this version is case-insensitive (and thus less performant). |
Optional<String> |
readIdent()
Reads an ident token.
|
Optional<String> |
readIdentLevel3()
Same as
readIdent() , but this also supports `--` as the first two characters, as specified in the Level 3 spec. |
Optional<String> |
readString()
Reads a value encased in either single or double quotes.
|
String |
remaining()
Gets the remaining text in the source, including the current character.
|
Source |
skip()
|
Source |
skipWhitepace()
If the current character is whitespace then skip it along with all subsequent whitespace characters.
|
Source.Snapshot |
snapshot()
Creates a snapshot of the current index, line, column, and other essential state information.
|
String |
toString() |
String |
toStringContextual()
An alternative to
toString() that limits the returned string to 75 characters before and after the current
position in the source. |
String |
until(Token token)
Advances the current character position until the current character matches the given
Token . |
public static final char NULL_CHAR
public Source(CharSequence source)
Source
, to be used for reading one character at a time from the given source.source
- The source to read.public Source(RawSyntax raw)
Source
, to be used for reading one character at a time from the content in the given
RawSyntax
. This will use the line and column from the given RawSyntax
as the anchor/starting point.raw
- The RawSyntax
containing the source.public Source(RawSyntax raw, boolean checkInString)
Source
, to be used for reading one character at a time from the content in the given
RawSyntax
. This will use the line and column from the given RawSyntax
as the anchor/starting point.raw
- The RawSyntax
containing the source.checkInString
- Whether the source should keep track of whether we are in a string or not. The main reason to specify false here is for
performance reasons, to avoid extra processing that we know wouldn't be relevant.public Source(CharSequence source, int anchorLine, int anchorColumn)
Source
, to be used for reading one character at a time from the given source. This will
use the given starting line and column.source
- The source to read.anchorLine
- The starting line.anchorColumn
- The starting column.public Source(CharSequence source, int anchorLine, int anchorColumn, boolean checkInString)
Source
, to be used for reading one character at a time from the given source. This will
use the given starting line and column.source
- The source to read.anchorLine
- The starting line.anchorColumn
- The starting column.checkInString
- Whether the source should keep track of whether we are in a string or not. The main reason to specify false here is for
performance reasons, to avoid extra processing that we know wouldn't be relevant.public int index()
column()
instead. Note that unlike the line and column number, index is 0-based.public int line()
If you want to get the line number from the original source, regardless of whether this is a sub-source or not then you may
want to use originalLine()
instead.
public int column()
If you want to get the column number from the original source, regardless of whether this is a sub-source or not then you
may want to use originalColumn()
instead.
public int anchorLine()
Source
within the original source. This is mainly useful for sub-sequences
(sequences created from a substring of the original source).public int anchorColumn()
Source
within the original source. This is mainly useful for sub-sequences
(sequences created from a substring of the original source).public int originalLine()
anchorLine()
and the current line()
.
This should be used when you want to get the real line in the original source, even if this Source
is a sub-source
from the original. This is accurate to use even if this source is not a sub-source.
If you want the current line within this exact Source
only then use line()
instead.
public int originalColumn()
anchorColumn()
and the current column()
.
This should be used when you want to get the real column in the original source, even if this Source
is a
sub-source from the original. This is accurate to use even if this source is not a sub-source.
If you want the current column within this exact Source
only then use column()
instead.
public boolean isSubSource()
anchorLine()
or anchorColumn()
is greater than 1.public String fullSource()
public String remaining()
public int length()
public boolean inString()
public boolean isEscaped()
Tokens#ESCAPE
public boolean eof()
public char current()
NULL_CHAR
if at the end.public char next()
The spec encourages normalizing new lines to a single line feed character, however we choose not to do this preprocessing as it isn't necessary for correct parsing. However by not doing this, if the source does not use LF then the line/column number reported by this source (e.g., in error messages) will be incorrect. This seems acceptable as that information is mostly just useful for development purposes anyway. (http://dev.w3 .org/csswg/css-syntax/#preprocessing-the-input-source)
NULL_CHAR
if at the end of the source.public void forward(int newIndex)
newIndex
- Advance to this position.public Source skip()
public char peek()
public char peek(int numCharacters)
numCharacters
- The number of characters ahead to peak.public char peekPrevious()
public Source skipWhitepace()
This doesn't match form feed \f as per the spec because... stupid to use that.
public Optional<Character> optional(Token token)
next()
, this will advance to the next character, but only if the current character matches the
given Token
. If the current character does not match then the current index will remain unchanged. If you don't
need the actual value, consider optionallyPresent(Token)
instead.token
- The token to match.Optional
if not matched.public boolean optionallyPresent(Token token)
optional(Token)
, except it returns the result of Optional.isPresent()
. Basically use this when you
don't care about keeping the actual parsed value (e.g., because it's discarded, you already know what it is, etc...)token
- The token to match.public <T extends Enum<T> & TokenEnum> Optional<T> optionalFromEnum(Class<T> klass)
optional(Token)
, except this works with TokenEnum
s, checking each member of the given enum (in
the declared order) for a matching token.
As with optional(Token)
, if the current character matches the index will be advanced by one.
T
- Type of the enum.klass
- Enum class.Optional
if none match.public <T extends Enum<T> & ConstantEnum> Optional<T> optionalFromConstantEnum(Class<T> klass)
optional(Token)
and optionalFromEnum(Class)
, except this works with ConstantEnum
s,
checking each member of the given enum (in the declared order) for a matching constant.
The main difference between this and optionalFromEnum(Class)
is that this is for enums that have more than one
character to match at a time. Matching a constant as opposed to a single character is less performant, thus if possible
enums should implement TokenEnum
over ConstantEnum
.
T
- Type of the enum.klass
- Enum class.Optional
if none match.public Source expect(Token token)
next()
, except it will enforce that the current character matches the given Token
before
advancing, otherwise an error will be thrown.token
- Ensure that the current token matches this Token
before we advance.public Source expect(Token token, String errorMessage, Object... args)
next()
, except it will enforce that the current character matches the given Token
before
advancing, otherwise an error will be thrown.token
- Ensure that the current token matches this Token
before we advance.errorMessage
- The error message to use if there isn't a match.args
- Optional error message arguments to String#format.public String until(Token token)
Token
. If the given Token
is never matched then this will advance to the end of the source.
This will skip over values inside parenthesis (mainly because ';' can be a valid part of a declaration value, e.g.,
data-uris). This will also skip over values inside of strings, but checkInString
must be turned on.
Important: do not pass in Tokens#OPEN_PAREN
or Tokens#CLOSE_PAREN
. Use chomp(Token)
instead.
token
- The token to match.Token
.public String chomp(Token token)
until(Token)
, this will advance past the current character and all subsequent characters for as long
as they match the given Token
.token
- The token to match.public String chompEnclosedValue(Token openingToken, Token closingToken)
chomp(Token)
, except this expects the value to be enclosed with an opening and closing delimiter Token
.
The opening token must be present at the current position of this source or an error will be thrown. In other words, don't call this until you've checked that the opening token is there, and only if you expect it to be properly closed.
The closing token will be skipped over if it is preceded by Tokens#ESCAPE
(thus no need to worry about handling
escaping).
openingToken
- The opening token.closingToken
- The closing token.public Source collectComments()
Comments can be retrieved with flushComments()
, which will return and remove all comments currently in the
buffer.
This separation into the two methods allows for comments to be collected prematurely without needing to backtrack if the parser later determines it doesn't match. The next parser can still retrieve the comments from the buffer even if another parser triggered the collection of them.
public Source collectComments(boolean skipWhitespace)
Comments can be retrieved with flushComments()
, which will return and remove all comments currently in the
buffer.
This separation into the two methods allows for comments to be collected prematurely without needing to backtrack if the parser later determines it doesn't match. The next parser can still retrieve the comments from the buffer even if another parser triggered the collection of them.
skipWhitespace
- If we should skip past whitespace before, between and after comments.public boolean findComments(boolean skipWhitespace)
Comments can be retrieved with flushComments()
, which will return and remove all comments currently in the
buffer.
This separation into the two methods allows for comments to be collected prematurely without needing to backtrack if the parser later determines it doesn't match. The next parser can still retrieve the comments from the buffer even if another parser triggered the collection of them.
This method will return true if anything was parsed. Pass in a value false to only check for comments and not whitespace, otherwise pass in true.
skipWhitespace
- If we should skip past whitespace before, between and after comments.public List<String> flushComments()
CSS comments are placed into the buffer when collectComments()
is called. After calling this method the buffer
will be emptied.
public Source.Snapshot snapshot()
Creating a snapshot allows you to parse content but then return to a previous state once it becomes clear that the content
doesn't fully match as expected. To revert to the latest snapshot call Source.Snapshot.rollback()
on the snapshot returned
from this method.
public boolean readConstant(String constant)
If a match is found the source is advanced to the end of the constant value. Otherwise the current position will remain unchanged. The constant must be matched exactly -- case does matter.
If possible this method should be avoided as it's less performant than using a Token
based method.
constant
- The exact content to match.public boolean readConstantCaseInsensitive(String constant)
readConstant(String)
, except this version is case-insensitive (and thus less performant).
Important: the constant given MUST be lower-cased.
constant
- The lower-cased version of the constant.public Optional<String> readIdent()
future: the spec allows for non ascii and escaped characters here as well.
Optional
if not matched.public Optional<String> readIdentLevel3()
readIdent()
, but this also supports `--` as the first two characters, as specified in the Level 3 spec.
See Changes from the 20 February 2014 Candidate Recommendation:
Change the definition of ident-like tokens to allow "--" to start an ident. As part of this, rearrange the ordering of the clauses in the "-" step of consume a token so thatAlso see https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier.s are recognized as such instead of becoming a -- <ident-token>.
This implementation can replace readIdent()
once we verify compliance with CSS Level 3 in other
areas of the parser.
Optional
if not matched.public Optional<String> readString()
ParserException
- if the string is not closed properly.public String toStringContextual()
toString()
that limits the returned string to 75 characters before and after the current
position in the source.Copyright (c) 2019, Salesforce.com, Inc. All rights reserved. Licensed under the BSD 3-Clause license. For full license text, see the LICENSE file in the repository.