a css grammar for lisp
Common Lisp
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
COPYING added my name to the copying file, glad to see that Vladimir's name … Feb 7, 2010
README initial state of css-lite repository, as it came from vladimir Feb 6, 2010
README.org
css-lite.asd
css-lite.lisp Fix cascading with compound rules Mar 11, 2012
example-usage.lisp Exported the css function `comment' Jul 12, 2011
lite-utility.lisp seperated out into files baed on function Feb 7, 2010
package.lisp Bugfix: loading css-lite before loading parenscript no longer crashes Aug 4, 2011
paren-css-lite.lisp
utility.lisp now with fully powerful lisp functions ROCK Feb 7, 2010

README.org

css-lite is a library for generating CSS from an s-exp based syntax. When compiled with Parenscript loaded in the Lisp image, it also provides the same CSS generation facilities in Parenscript-generated JavaScript code.

Instalation

First, install Quicklisp.

After that, type in your Lisp prompt the following:

(ql:quickload 'css-lite)

It should download and load css-lite. This download is only done once, after that Quicklisp will always load your local copy of css-lite.

Note: In previous versions of css-lite there was a bug where you sometimes couldn’t call (ql:quickload 'css-lite) without having previously called (ql:quickload 'parenscript). This bug has hopefully now been fixed.

Examples

After loading the css-lite library, you are now ready to try these examples.

First Example

Set the width of the “body” tag to be 70%

(css-lite:css
  (("body") (:width "70%")))

Output:

"
body {
width:70%;
}
"

By default, css-lite doesn’t indent the properties. If you wish to indent them, see the documentation for the variable css-lite:*indent-css*, or the section “Change the indentation” of this README. For example, if you change the value of the variable css-lite:*indent-css* to 4, this would be the output:

"
body {
    width:70%;
}
"

Second Example

Set the height of the ID “foo” to 50px and the width to 10em

(css-lite:css
  (("#foo")
    (:height "50px"
     :width "10em")))

Output:

"
#foo {
height:50px;
width:10em;
}
"

To do the same thing, but to a class “foo”, simply replace “#foo” with “.foo”.

(css-lite:css
  ((".foo")
    (:height "50px"
     :width "10em")))

Output:

"
.foo {
height:50px;
width:10em;
}
"

Third Example

Define the properties of rules “#foo” and “#foo li”

(css-lite:css
  (("#foo")
    (:length "50px"
     :margin "50 px 30 px"
     :border "1px solid red")
   (("li")
    (:width "50px"
     :float "left"
     :margin "50 px 30 px"
     :border "1px solid red"))))

Output:

"
#foo {
length:50px;
margin:50 px 30 px;
border:1px solid red;
}

#foo li {
width:50px;
float:left;
margin:50 px 30 px;
border:1px solid red;
}
"

Fourth Example

In the third example, the rules “margin:50 px 30 px;” and “border:1px solid red;” are repeated twice. css-lite has something called CSS variables that allow to abstract this.

You create a CSS variable by using the macro css-lite:make-css-var.

(css-lite:make-css-var my-favorite-border-var '(:border "1px solid red"))
(css-lite:make-css-var my-margin-var '(:margin "50px 30px"))

Then you could write the third example as this:

(css-lite:css
   (("#foo")
     (:length "50px"
      my-margin-var
      my-favorite-border-var)
    (("li")
     (:width "50px"
      :float "left"
      my-margin-var
      my-favorite-border-var))))

Output:

"
#foo {
length:50px;
margin:50px 30px;
border:1px solid red;
}

#foo li {
width:50px;
float:left;
margin:50px 30px;
border:1px solid red;
}
"

Fifth Example

In addition to the CSS variables, css-lite also provides the ability to define CSS functions. This allows you to perform arbitrary modifications on the rules.

This function is declared using the macro css-lite:make-css-func and can receive any number of arguments. However, it should return a list with 2 values, the first being the name of the property and the second its value.

For example, to create a function that receives the name of a property and its value in inches and converts that value into centimeters use this:

(css-lite:make-css-func convert-in-to-cm (property-name value)
  ;; Assumes that `value' is a string with the following
  ;; format: XXin, where XX represents a number greater than 0
  (let* ((inches (parse-integer
                   (string-right-trim "in " value)))
          (centimeters (round (* inches 2.54))))
    (list property-name
      (concatenate 'string
        (write-to-string centimeters)
        "cm"))))

So this call:

(convert-in-to-cm :width "10in")

Returns this list:

(:WIDTH "4cm")

So to use this function to convert the height of the identifier “#foo” from inches to centimeters, you would write this code:

(css-lite:css
  (("#foo")
    (:length "50px"
     my-margin-var
     (convert-in-to-cm :width "10in")
     my-favorite-border-var)))

Output:

"
#foo {
length:50px;
margin:50px 30px;
width:4cm;
border:1px solid red;
}
"

Sixth Example

To add a CSS comment use the function css-lite:comment

(css-lite:css
  (("body")
    ((css-lite:comment "These are the rules for the body tag")
     :width "80%"
     :float "left")))

Output:

"
body {
/*These are the rules for the body tag*/
width:80%;
float:left;
}
"

To see more examples, see the file example-usage.lisp

Change the indentation

As you can see be the above examples, by default, css-lite doesn’t indent the rules.

However you can customize this behaviour by changing the value of the variable css-lite:*indent-css*.

There are three possible values:

  • nil - The default value, indicates that no indentation should be performed
  • the symbol ‘tab - Indicates that the rules should be indented using a #\Tab character
  • a number greater than 0 - Indicates that the rules should be indented with that many #\Space characters.

For example, to indent the rules with 4 spaces, you would type:

(setf css-lite:*indent-css* 4)

The next time you call the css-lite:css function, the code will be indented with 4 spaces.

For example, calling the function css-lite:css with this value:

(css-lite:css
    (("body")
      ((css-lite:comment "These are the rules for the body tag")
       :width "80%"
       :float "left")))

Output:

"
body {
    /*These are the rules for the body tag*/
    width:80%;
    float:left;
}
"