scalpel
v3.0.0
Published
A CSS selector parser.
Downloads
85
Readme
scalpel
A CSS selector parser.
It parses any valid CSS3 selector into tokens. Try it!
Found a selector that cannot be parsed? Raise an issue.
This parser is implemented using Earley parser algorithm. Read about Writing a CSS selector parser in under 120 LoC.
Note:
This parser could be extended to support the entire CSS grammar. I don't have such a use case. However, should you want to add new grammar, raise an issue.
Usage
import {
createGenerator,
createParser
} from 'scalpel';
const generator = createGenerator();
const parser = createParser();
const tokens: Array<SelectorTokenType | CombinatorTokenType> = parser.parse('.foo.bar');
// [
// {
// type: 'selector',
// body: [
// {
// type: 'classSelector',
// name: 'foo'
// },
// {
// type: 'classSelector',
// name: 'bar'
// }
// ]
// }
// ]
const selector: string = generator.generate(token);
// .foo.bar
Note:
For programmatic type definitions, refer to
./src/types.js
.
Token types
|Type|Description|Example|
|---|---|---|
|adjacentSiblingCombinator
|An adjacent sibling combinator.|.baz0 + .baz1
|
|attributePresenceSelector
|An attribute presence selector.|[qux]
|
|attributeValueSelector
|An attribute value selector.|[qux=val]
, [qux~=val]
|
|childCombinator
|A child combinator.|.baz0 > .baz1
|
|classSelector
|A class selector.|.baz
|
|descendantCombinator
|A descendant combinator.|.baz0 .baz1
|
|generalSiblingCombinator
|A general sibling combinator.|.baz0 ~ .baz1
|
|idSelector
|An ID selector|#bar
|
|pseudoClassSelector
|A pseudo-class selector.|:corge
, :corge()
, :corge(val0, 'val1', "val2")
|
|pseudoElementSelector
|A pseudo-element selector.|::grault
|
|typeSelector
|A type selector.|foo
|
|universalSelector
|A universal selector.|*
|
Fields
Tokens have fields that describe additional information about the token. Fields are token type specific.
adjacentSiblingCombinator
|Name|Description|Example|
|---|---|---|
|type
|Name of the token type.|"adjacentSiblingCombinator"|
attributePresenceSelector
|Name|Description|Example|
|---|---|---|
|name
|Name of the element attribute.|"qux" in [qux]
|
|type
|Name of the token type.|"attributePresenceSelector"|
attributeValueSelector
|Name|Description|Example|
|---|---|---|
|name
|Name of the element attribute.|"qux" in [qux]
|
|operator
|Operator of the expression.|"*=" in [qux*=val]
|
|type
|Name of the token type.|"attributeValueSelector"|
|value
|Value of the expression.|"val" in [qux=val]
|
childCombinator
|Name|Description|Example|
|---|---|---|
|type
|Name of the token type.|"childCombinator"|
classSelector
|Name|Description|Example|
|---|---|---|
|name
|Class name.|"baz" in .baz[qux]
|
|type
|Name of the token type.|"classSelector"|
descendantCombinator
|Name|Description|Example|
|---|---|---|
|type
|Name of the token type.|"descendantCombinator"|
generalSiblingCombinator
|Name|Description|Example|
|---|---|---|
|type
|Name of the token type.|"generalSiblingCombinator"|
idSelector
|Name|Description|Example|
|---|---|---|
|name
|Name of the ID.|"bar" in #bar:corge()
|
|type
|Name of the token type.|"idSelector"|
pseudoClassSelector
|Name|Description|Example|
|---|---|---|
|name
|Name of the pseudo-class.|"corge" in #bar:corge()
|
|parameters
|Array of parameter values.|"var0", "var1" and "var2" in :corge(var0, 'var1', "var2")
|
|type
|Name of the token type.|"pseudoClassSelector"|
pseudoElementSelector
|Name|Description|Example|
|---|---|---|
|name
|Name of the pseudo-element.|"grault" in #bar::grault
|
|type
|Name of the token type.|"pseudoElementSelector"|
typeSelector
|Name|Description|Example|
|---|---|---|
|name
|Name of the node.|"foo" in foo#bar.baz
|
|type
|Name of the token type.|"typeSelector"|
universalSelector
|Name|Description|Example|
|---|---|---|
|type
|Name of the token type.|"universalSelector"|
Development
git pull [email protected]:gajus/scalpel.git
cd ./scalpel
npm install
npm run test
The parser grammar is in the ./src/grammar.ne
file. After making changes to the parser grammar, you need to compile the parser using npm run compile-grammar
command.