sast
v0.8.1
Published
Parse CSS, Sass, and SCSS into Unist syntax trees
Downloads
43,674
Maintainers
Readme
sast
This is a thing that parses CSS, Sass, and SCSS into a unist-compatible abstract syntax tree (AST), which makes it possible to then search and manipulate with all of the wonderful unist utility modules. Most of the heavy lifting is done by gonzales.
Installation
Install it with npm:
npm install --save sast
Usage
You can import
or require()
the module and access the API as its
methods, like this:
// CommonJS, older versions of Node
const sast = require('sast')
// ES6/ES2016/Babel/etc.
import sast from 'sast'
const tree = sast.parse('a { color: $red; }', {syntax: 'scss'})
console.dir(tree, {depth: null})
or you can import just the API methods you need, like so:
// CommonJS
const {parse} = require('sast')
// ES6
import {parse} from 'sast'
const tree = parse('a { color: $red; }', {syntax: 'scss'})
API
sast.parse(source [, options])
Synchronously parse the CSS, Sass, or SCSS source text (a string) into an
abstract source tree (AST). The default syntax is CSS ({syntax: 'css'}
);
other acceptable values are sass
, scss
, and less
. See the gonzales
docs for more info. To
parse files by path, use parseFile()
.
sast.stringify(node)
Format the resulting AST back into a string, presumably after manipulating it.
sast.jsonify(node)
Coerce the given AST node into JSON data, according to the following rules:
- Numbers are numbers:
1
->1
, not"1"
. - Lists become arrays:
(a, 1)
->["a", 1]
- [Maps][Sass maps] become objects:
(x: 1)
->{x: 1}
- Lists and maps can be nested!
- Everything else is stringified, and should be preserved in
its original form:
- Sass/SCSS variables should preserve their leading
$
. - Hex colors should preserve their leading
#
. rgb()
,rgba()
,hsl()
,hsla()
, and any other functions should preserve their parentheses.- Parentheses that are not parsed as lists or maps should be preserved.
- Sass/SCSS variables should preserve their leading
sast.parseFile(filename [, parseOptions={} [, readOptions='utf8'])
Read a file and parse its contents, returning a Promise. If no
parseOptions.syntax
is provided, or its value is auto
, the filename's
extension will be used as the syntax
option passed to parse()
.
const {parseFile} = require('sast')
parseFile('path/to/some.scss')
.then(tree => console.dir(tree, {depth: null}))
.catch(error => console.error('Parse error:', error))
CLI
The sast
npm package comes with two command line utilities:
sast-parse
Parses a file or stdin as a given syntax, applies one or more simplifying transformations, then outputs the resulting syntax tree in a variety of formats:
- JSON: the raw syntax tree in object form, which can be passed to other CLIs.
- YAML: an easier-to-read alternative to JSON, also suitable for piping to other CLIs.
- Tree: a text representation of the syntax tree provided by unist-util-inspect.
- Text: the stringified syntax tree, which is hopefully valid for the given syntax.
Run sast-parse --help
for available options.
sast-data
Parses one or more SCSS (the only supported syntax at this time) files, and transforms all top-level variable declarations into key-value pairs. The result is a JSON object in which each key is a variable name, and the value is the jsonified variable value.
This is useful for generating [design tokens] from existing SCSS variables if you don't have the ability to go in the other direction.
Run sast-data --help
for available options and more information.
Node types
Most node types are defined by [gonzalez], the underlying parser. After transforming each of the syntax tree nodes into unist nodes, the following nodes are introduced:
Maps
Any parentheses
node whose first operator
child is a :
is interpreted as
a Sass map and recast as a map
node. The children
are preserved as-is,
and key/value pairs separated by :
and delimited by ,
are placed in the
values
property as an array of objects with key
and value
properties,
each of which is a plain old node list. Some examples:
(x: 1)
will be jsonified as{x: 1}
(x: a, y: 2)
will be interpreted as{x: "a", y: 2}
Lists
Any parentheses
node whose first operator
child is a ,
is interpreted as
a list (array) and recast as a list
node. The children
are perserved as-is,
and children that aren't space
nodes are split into subgroups by each ,
operator and converted into value
nodes with one or more children, then
placed in the values
property of the list
node. Some examples:
(1, x)
will be jsonified as[1, "x"]
(a, (b, c))
will be intepreted as["a", ["b", "c"]]