16 releases (stable)
3.5.0 | Nov 1, 2023 |
---|---|
2.5.0 |
|
2.4.0 | Oct 17, 2023 |
2.3.0 | Jan 17, 2023 |
0.2.1 | Apr 29, 2019 |
#703 in Parser implementations
Used in 2 crates
100KB
3.5K
SLoC
Syncat Stylesheets
This documentation consists only of the usage of the syncat_stylesheet
crate.
For documentation on the syntax and semantics of these stylesheets, see the
syncat-themes repository.
Stylesheets
Stylesheets are loaded from files. All imports will be resolved relative to the file during the loading process.
// colours.syncat
$variable: red;
$value: bryellow;
// syncat.syncat
import "./colours.syncat";
declaration variable { color: $variable; }
declaration value { color: $value; }
let stylesheet = Stylesheet::from_file("syncat.syncat");
Queries
Queries take the form of trees, as these stylesheets are typically used to apply properties (i.e. styles) to trees (as in parse trees).
Each node of a Query
has a kind
and a token
, which must be provided. These
nodes may also contain child nodes, which are also just Query
, which can have
more subqueries.
When matching against rules, the nodes of the rule are checked with the right-most branch of the tree.
For example, with the following source code:
$hello: world;
You could construct this Query
:
let mut query = Query::new("declaration", "$hello: world;");
query.add_child(Query::new("variable", "$hello"));
query.add_child(Query::new("value", "$world"));
Which corresponds to a tree like this:
(declaration (variable "$hello")
(value "world"))
Which can then be matched against a Stylesheet
by using the Stylesheet::style
method.
This will return Some(style)
if there were matches, or None
if there were
none. Often this distinction does not matter, so you can unwrap to the default
Style
.
let style = stylesheet.style(&query).unwrap_or_default();
// successfully:
declaration value {} // because the value is on the right-most branch, and has the declaration as a parent
variable + value {} // because the value is on the right-most branch, and a direct sibling of the variable
declaration {} // because the declaration is a parent of the rightmost branch
value & "world" {} // because the value on the right-most branch has token "world"
// unsuccessfully
declaration > variable {} // because the variable is not on the right-most branch
value & "wor" {} // because the token "wor" does not match the token "world"
declaration variable value {} // because the value is not nested within the variable
declaration > {} // because the declaration is not the node directly at the end of the right-most branch
Applications
Once you have a Style
value, its properties can be extracted using the Style::get
or Style::try_get
methods. Style::get
will retrieve the raw value, while Style::try_get
will attempt to convert that value to a contextual type.
With the ansi_term
feature enabled (it is not by default), conversions to
ansi_term::Style
are provided. Alternatively, you can simply extract whatever
properties you expect from the Style
and interpret them however you choose.
let content: String = style.try_get("content")?.unwrap_or_else(|| String::from("hello world"));
let ansi_style: ansi_term::Style = style.try_into()?;
println!("{}", ansi_style.paint(content));
Dependencies
~3–5MB
~93K SLoC