www.css - CSS parsing and construction ¶This module provides tools to convert between S-expression and CSS.
The S-expression CSS (SxCSS) is a convenient way to manipulate CSS in Scheme.
For example, the following CSS and SxCSS are equivalent, and can be converted back and forth:
CSS:
body { padding-left: 11em;
font-family: Georgia, "Times New Roman", Times, serif;
color: purple;
background-color: #d8da3d }
ul.navbar li { background: white;
margin: 0.5em 0;
padding: 0.3em;
border-right: 1em solid black }
ul#spec > a { text-decoration: none }
a:visited { color: purple !important }
SxCSS:
((style-rule body (padding-left (11 em)) (font-family (:or Georgia "Times New Roman" Times serif)) (color purple) (background-color (color "d8da3d"))) (style-rule ((ul (class navbar)) li) (background white) (margin #((0.5 em) 0)) (padding (0.3 em)) (border-right #((1 em) solid black))) (style-rule ((ul (id spec)) > a) (text-decoration none)) (style-rule (a (: visited)) (color purple !important)))
See the “CSS in S-expression” section below for the complete specification.
{www.css}
Take SxCSS and writes out CSS to the given port, defaulted to
the current output port.
{www.css}
Read CSS from the given port, defaulted to the current input port,
and returns SxCSS.
When it encounters unparsable CSS (either a malformed CSS, or unsupported syntax), it emits a warning message, ignore the unparsable part and tries to continue reading the rest.
NB: Currently we don’t handle @charset directive; we assume
the text is already in the port’s encoding. We may support
it in future versions.
{www.css}
Read the CSS text from the given file and parse it using
parse-css. Again, we don’t handle @charset directive
yet, and you have to pass encoding argument if
the CSS text isn’t in the Gauche’s native character encoding.
{www.css}
This parses the selector part of the CSS.
(parse-css-selector-string "ul li.item span#foo") ⇒ (ul (li (class item)) (span (id foo))) (parse-css-selector-string "h1,h2") ⇒ (:or h1 h2)
The following is the complete rules of SxCSS syntax.
<sxcss> : ({<style-rule> | <at-rule>} ...)
<style-rule> : (style-rule <pattern> <declaration> ...)
| (style-decls <declaration> ...)
<pattern> : <selector> | (:or <selector> ...)
<selector> : <simple-selector>
| <chained-selector>
<chained-selector> : (<simple-selector> . (<op>? . <chained-selector>))
<op> : > | + | ~
<simple-selector> : <element-name>
| (<element-name> <option> ...)
<option> : (id <name>) ; E#id
| (class <ident>) ; E.class
| (has <ident>) ; E[attrib]
| (= <ident> <attrib-value>) ; E[attrib=val]
| (~= <ident> <attrib-value>) ; E[attrib~=val]
| (:= <ident> <attrib-value>) ; E[attrib|=val]
| (*= <ident> <attrib-value>) ; E[attrib*=val]
| (^= <ident> <attrib-value>) ; E[attrib^=val]
| ($= <ident> <attrib-value>) ; E[attrib$=val]
| (:not <negation-arg>) ; E:not(s)
| (: <ident>) ; E:pseudo-class
| (: (<fn> <ident> ...)) ; E:pseudo-class(arg)
| (:: <ident>) ; E::pseudo-element
<element-name> : <ident> | *
<attrib-value> : <ident> | <string>
<negation-arg> | <element-name> | * | <option> ; except <negation-arg>
<declaration> : (<ident> <expr> <expr2> ... <important>?)
<important> : !important
<expr> : <term>
| (/ <term> <term> ...)
| (:or <term> <term> ...)
| #(<term> <term> ...) ; juxtaposition
<term> : <quantity> | (- <quantity>) | (+ <quantity>)
| <string> | <ident> | <url> | <hexcolor> | <function>
<quantity> : <number>
| (<number> %)
| (<number> <ident>)
<url> | (url <string>)
<hexcolor> | (color <string>) ; <string> must be hexdigits
<function> | (<fn> <arg> ...)
<arg> | <term> | #(<term> ...) | (/ <term> <term> ...)
<at-rule> : <at-media-rule> | <at-import-rule>
; NB: Other at-rules are not supported yet
<at-media-rule> : (@media (<symbol> ...) <style-rule> ...)
<at-import-rule> : (@import <string> (<symbol> ...))
NB: Negation op is :not instead of not,
since (not <negation-arg>)
would be ambiguous from the simple node named "not" with one option.
NB: style-decls selector rule is currently won’t appear in
the parse-css output; it can be used in SxCSS to make
construct-css render declarations only, which can be
used in the style attribute of the document, for example.
(with-output-to-string
(cut construct-css
'((style-decls (width (50 %))
(padding #(0 (10 pt) 0 (10 pt)))))))
⇒ "width:50%;padding:0 10pt 0 10pt"