Created
January 9, 2020 18:30
-
-
Save jonathantneal/8a91bee7df1a40e94d0354b9c51285ca to your computer and use it in GitHub Desktop.
CSS Parser Super Core (the barest bits)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function parse(cssText) { | |
// this regex matches all non-contextual nodes; which are comments, whitespaces, strings, numbers, named identifiers, and delimiters. | |
var cssRegExp = /\/\*((?:[^*]|\*[^\/])*)\*\/|([ \t\n\f\r]+)|"((?:[^"\\\n\f\r]|\\\r\n|\\[\W\w])*)"|'((?:[^'\\\n\f\r]|\\\r\n|\\[\W\w])*)'|#((?:[-\w]|[^\x00-\x7F]|\\[^\n\f\r])+)|([+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[Ee]-?\d+)?)|(-?(?:[-A-Z_a-z]|[^\x00-\x7F]|\\[^\n\f\r])(?:[-\w]|[^\x00-\x7F]|\\[^\n\f\r])*)|([\uD800-\uDBFF][\uDC00-\uDFFF]|[\W\w])/g; | |
// the contextual nodes generated from these matches are: | |
// - numbers with a unit (number + named identifier), | |
// - at identifiers (`@` + named identifier), | |
// - blocks (everything between equally nested `(` and `)` or `[` and `]` or `{` and `}`), and | |
// - functions (named identifier + block). | |
// you will likely create a root/parent scope for organizing your blocks and functions | |
// var cssRoot = { value: [] }, cssParent = cssRoot; | |
var cssMatches; | |
while ((cssMatches = cssRegExp.exec(cssText)) !== null) { | |
// the regex includes a `lastIndex` property, critical for building source maps | |
// the matches spread nicely into a function | |
parser.apply(cssRegExp, cssMatches); | |
} | |
// return cssRoot | |
function parser(value, comment, whitespace, stringDoubleQuoted, stringSingleQuoted, hashIdentifier, number, namedIdentifier, delimiter) { | |
// any of these nodes are assigned the current parent scope (initially the root). | |
// a `comment` is the content within `/*` and `*/`. | |
// a `whitespace` is the consecutive spaces, tabs, and newlines. | |
// a `stringDoubleQuoted` or `stringSingleQuoted` is the content within its respective quotes. | |
// a `hashIdentifier` is the content after its hash mark, like `00f` or `main`. | |
// a `number` is the numeric content, including decimals and stuff with `e`, with an empty unit. | |
// a `namedIdentifier` is the alphanumeric content, including keywords and property names. | |
// - any namedIdentifier following a number are merged into a number with a unit. | |
// - any namedIdentifier following a `@` delimiter are merged into an `atIdentifier`. | |
// a `delimiter` is a boundary-like character, like `,` or `;` or `>`. | |
// - any `(` or `[` or `{` creates a block assigned its respective delimiter, which is the new parent scope. | |
// - any `(` block following a namedIdentifier becomes a function. | |
// - any `)` or `]` or `}` matching the parent block delimiter closes out the parent scope. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment