An s-expression Domain-Specific Language that compiles nested CSS selectors and declarations into plain CSS text.
- Common Lisp 97.6%
- Just 2.4%
Rename the ASDF system dev.metalisp.css to dev.metalisp.libcss and the package ml-css to ml-libcss, including the test system, suite keyword, documentation, and justfile. |
||
|---|---|---|
| doc | ||
| src | ||
| tests | ||
| .gitignore | ||
| dev.metalisp.libcss.asd | ||
| justfile | ||
| LICENSE | ||
| README.md | ||
dev.metalisp.libcss
An s-expression Domain-Specific Language that compiles nested CSS selectors and declarations into plain CSS text.
Requirements
Fedora Linux and SBCL are the expected baseline. The system depends only on Common Lisp; tests require fiveam, available through Quicklisp.
Quickstart
Load the system with Quicklisp/ASDF:
sbcl --non-interactive --eval '(ql:quickload :dev.metalisp.libcss)' --eval '(uiop:quit 0)'
Run the test suite:
sbcl --non-interactive --eval '(ql:quickload :dev.metalisp.libcss/tests)' \
--eval '(asdf:test-system :dev.metalisp.libcss)' --eval '(uiop:quit 0)'
Example
(ql:quickload :dev.metalisp.libcss)
(ml-libcss:css
(:nav
:background "#333"
(:ul
:list-style :none
(:li
:display :inline)))
(:button
:padding "8px 16px"
("&:hover"
:background "#005")))
renders:
nav {
background: #333;
}
nav ul {
list-style: none;
}
nav ul li {
display: inline;
}
button {
padding: 8px 16px;
}
button:hover {
background: #005;
}
Public API
css— macro that compiles its s-expression body to a CSS string, validating at macroexpansion time.render-stylesheet— function that compiles a stylesheet list to a CSS string.with-css-file— macro that compiles its body atomically to a file.with-css-variables— macro that lexically binds CSS variables, referenced with(:var name).define-css-mixin— macro that defines a named mixin, included with(:mixin name).css-syntax-error— condition signaled on malformed stylesheets or unbound variables/mixins.*minify-css*— special variable; bind to a non-NIL value to emit minified single-line CSS.
Minified output:
(let ((ml-libcss:*minify-css* t))
(ml-libcss:css (:nav :background "#333" (:ul :list-style :none))))
;; => "nav{background:#333;}nav ul{list-style:none;}"
Writing to a file:
(ml-libcss:with-css-file (stream #p"style.css" :minify t)
(:body :margin 0 :color "#333")
(:h1 :color "red"))
Variables and mixins:
(ml-libcss:define-css-mixin :box
:margin 0
:padding 0)
(ml-libcss:with-css-variables ((:brand "#d33"))
(ml-libcss:css
(:div
(:mixin :box)
:color (:var :brand))))
At-rules:
(ml-libcss:css
(:media "screen and (max-width: 600px)"
(:body :margin "8px")))
;; => "@media screen and (max-width: 600px) {\n body {\n margin: 8px;\n }\n}\n"
Full grammar and combinators: see doc/dev.metalisp.libcss.org.