This Prolog library provides a DCG, css//1
for generating CSS in the style of html//
.
You can install it by running pack_install(css_write).
or view it in the SWI-Prolog package directory.
You can use this to write CSS rules as nested functors with arity one or two; see below for examples.
One-arity functors are interpreted as selector(styles)
, so for example p(margin('3em'))
will generate the CSS rule p { margin: 3em; }
.
The styles
can also be a list, to provide multiple styles (e.g. p([margin('3em'), 'font-size'(small)])
generates p { margin: 3em; font-size: small; }
).
For two-arity functors, the first argument is the styles, as above, and the second argument will be nested child selectors.
For example, p(margin('3em'), [img(width('300px'), strong('font-size'(large)))])
generates:
p { margin: 3em; }
p img { width: 300px; }
p strong { font-size: large; }
This can of course themselves be nested, so you could write:
p([],
strong([color(blue)],
emph([color(red)]))).
to generate
p strong { color: blue; }
p strong emph { color: red; }
One special extension to the CSS syntax is added: if a selector begins with &
, the ampersand will be replaced with the parent rule.
For example,
p(color(red),
'&:hover'(color(blue))).
Generates
p { color: red; }
p:hover { color: blue; }
To include a CSS DCG inside another one, you write \(module:other_dcg)
.
For example:
:- module(foo, []).
some_css -->
css([code('font-family'('"PragmataPro Mono"))]).
main_css -->
css([body(margin('3em')),
\(foo:some_css)]).
Generates
body { margin: 3em; }
code { font-family: "PragmataPro Mono"; }
See the example in tests/
for some more complicated usage.
Using with html_write
:- use_module(library(css_write), [css//1, write_css/2]).
:- use_module(library(http/html_write), [reply_html_page/2,
html//1,
html_post//2,
html_receive//1]).
main_css -->
css([body(margin('3em')),
p([color(red), 'font-size'(small)],
['.thing'([margin('0 auto'),
'font-family'(monospace)])])])
home_page(_Request) :-
reply_html_page([title('CSS Demo'),
\html_receive(css)],
\home_page_body).
include_css(CssDcg) -->
{ write_css(CssDcg, CssTxt) },
html_post(css, style([], CssTxt)).
home_page_body -->
html([\include_css(main_css),
div(id(main),
[p([],
["Hello world",
strong(class(thing), "Some stuff")])])]).