[QUIZ] Perl 'Hard' Quiz of the Week #2005-04-26 - A Preprocessor for CSS Files

Shlomi Fish <shlomif-ik1l9ssToec+JF/[email protected]> Tue, 26 Apr 2005 22:30:10 +0300
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
IMPORTANT: Please do not post solutions, hints, or other spoilers
        until at least 60 hours after the date of this message.  
        Thanks.

First of all a note: MJD is alive and kicking. He has been quite active in the 
mailing list dedicated to discussions of his newly published book "Higher 
Order Perl". Hopefully he can play a more active role here as well in the 
future. (Hi Mark!)

In any case, for today's quiz, you will write a preprocessor for Cascading 
Style Sheets. Cascading Style Sheets (or CSS) are a W3C standard for 
controlling the look of HTML and other XML standards (like SVG). You can find 
more information on CSS here:

http://www.htmlhelp.com/reference/css/ - an excellent introduction to CSS, 
albeit somewhat dated by now.

http://www.w3.org/Style/CSS/ - the W3C's CSS Home.

http://www.w3.org/TR/REC-CSS2/ - the W3C's CSS 2 Recommendation.

http://www.w3schools.com/css/default.asp - CSS in W3Schools. More up-to-date 
information and resources than htmlhelp.com. (Note just that W3Schools have a 
somewhat bad reputation.)

http://www.csszengarden.com/ - The CSS Zen Garden. Same HTML, different CSS 
Stylesheets, with incredible results.

------------------

Now for the preprocessor itself. It will follow the following conventions:

1. ${ ... } is a preprocessor directive. Note that it does not necessarily 
terminate on the first "}". There could instead be a } embedded within the 
expression so the expression would need to be processed first.

2. ${include-local "other.css"} includes a file starting at the current 
working directory.

3. ${include-abs "/home/shlomi/.latemp/css/myfile.css"} includes a file based 
on an absolute pathname.

4. ${include-search "myfile.css"} includes files by searching in the include 
directories (see below). 

5. ${include-system "header.css"} includes files by searching first in the 
system directories (see below) and then in the include directories.

6. -I /path/to/dir parameters to the program designate an include directory. 
The include directories are searched from right to left.

7. -S /path/to/dir is a system directory.

8. One can assign to a variable by using the set command:

${set myvar ".navbar"}

9. One can retreive the value of a variable by using ${=myvar} or ${print 
myvar}:

<<<<<<<
${set myvar ".navbar"}

${= myvar}
{
	padding-left: 1em;
}

${print myvar} > p
{
	background-color: blue;
}
>>>>

This is equivalent to writing:

.navbar
{
	padding-left: 1em;
}

.navbar > p
{
	background-color: blue;
}

10. Here documents. One can define a here document within an expression:

<<<<<<<<
${set a <<"EOF"}
.navbar
{
    Take it or leave it.
}
EOF
>>>>>>>>>>>

This will cause the value of a to be what between the ".navbar" up to and 
excluding the EOF line.

11. One can set values to variables from the command line using the 
-Dvar=value flag:

	css-pp -Dvar=hello mytemplate.css

Will initilize var to the be the string hello.

12. The --include=mytemplate.css flag will cause the CSS preprocessor to 
include the file mytemplate.css before beginning the processing of the main 
file.

13. A dollar preceded by a \ denotes an actual dollar sign.

15. {$# .... } is a comment.

14. Any other feature you'd like to have there. (!)

For bonus points, also write vim syntax and filetype configurations to 
conveniently edit the preprocessor input.

Regards,

	Shlomi Fish

Caveat Emptor: part of the reason I'm proposing this quiz is because I 
actually need such a preprocessor. The other reason is that I think it would 
be a fun quiz.

---------------------------------------------------------------------
Shlomi Fish      shlomif-ik1l9ssToec+JF/[email protected]
Homepage:        http://www.shlomifish.org/

Hacker sees bug. Hacker fixes bug.