I have a small Lisp program that generates a website's html pages and rss feed, given the original content in latex. However I also wanted to validate the generated html pages, the rss feed as also the site’s CSS.
W3C provides a markup validation service to validate your html, css, and rss.
Edi Weitz has written a web client library called as Drakma. So I thought of using drakma to validate this website’s generated html pages as also the rss feed xml and css.
Drakma library has a http-request method that allows you to send a request to a web server and gives you the return reply. You could then potentially send a web request to whichever markup validation service that you want to consume and scan the returned reply for success or failure.
The html markup validation service api can be found here. From the api, it is clear that we need to send uploaded file and content type parameters when we invoke this service. The code to do this is shown below:
(defvar *w3-html-uri* "http://validator.w3.org/check")
Now in the returned reply, we need to look for the headers which is the 3rd value in the http-request return reply. Hence nth-value 2. The headers tell us if validation was successful, the number of errors and warnings. Here is some sample code to do that:
(defun check (headers)
(check (validate-html "/users/me/some.html"))
The CSS markup service api is available here. It can be seen that there is no option to upload file. The CSS validation service when invoked programatically expects the CSS in the form of a string instead of a file. The sample code to do this is shown below:
(defvar *w3-css-uri* "http://jigsaw.w3.org/css-validator/validator")
The idea is pretty much the same except the parameters change as compared to validating html.
You can reuse the check function to find out if the validation was successful, the number of errors and warnings.
(check (validate-css (generate-string ”/users/me/site.css”)))
Converting your CSS into a string
(defun generate-string (file)
The RSS validation service api is available here. Though the api mentions the uploaded file, it did not seem to work when I tested it out. Further the results are not returned as in the case of html, css. One has to scan the returned body for the word ’Sorry’. If you think that I am mistaken here, please do let me know. As for now, here is the sorry code :-)
(defvar *w3-rss-uri* "http://validator.w3.org/feed/check.cgi")
(check-rss (validate-rss (generate-string ”/users/me/rss.xml”)))
Thus using drakma you can easily validate your html, css and rss. When validations fail, I just open my browser, browse to the required service, upload the errant file, read the verbose output, fix the errors and recheck with the above functions.
This is especially useful when you have some lisp code to generate the html, rss. Then you could easily plugin the above code to validate them as well.
The above code has been tested successfully on SBCL. Let me know in case of any issues. Feel free to use the above code in your programs if you like it.
For anyone who is interested in learning Common Lisp, this could be a possible approach. This is an approach that I figured out in hindsight. Let us get down to business. The first important choice you need to make is of the OS.
Which OS to use?
Through my experience, I would say that for learning Common Lisp (as for any other language), Windows is a bad choice (which it is anyways!).
So choose any *nix. If you are already a *nix user, you are in safe zone. For Windows users, I would recommend using VirtualBox (a virtualization software) to install a Linux. Ubuntu is what I would recommend.
Why a *nix?
The simplest reason is that the entire CL ecosystem (at least open source) is geared towards *nix than Windows.
You may opt for LispWorks, which provides a Windows environment. There is also LispBox setup that you can use. But in the long run, I expect that you may experience pain though I cannot verify that since I have not gone down that path! Even Windows setup just simulates the *nix setup. Hence it is better to go the virtualization way I think.
So choose something like Ubuntu running inside VirtualBox if you are Windows user.
Which implementation do you choose?
I would recommend using SBCL. Clisp, CMUCL are also other good choices.
Thus, choose SBCL as your CL implemenation for your learning process. Do not worry too much initially about various implementations and differences between them. As you work your way through learning CL and get proficient you will also learn to work with different implementations.
It is very simple to install a CL of your choice on a *nix.Just use the package management system of your *nix to install the lisp implemenation of your choice.
Having chosen an OS and a Lisp implementation, the next obvious question is which IDE to use? Honestly, Lisp does not need an IDE.
Which editor to use?
From my experience, I have arrived at this conclusion: ”Lisp REPL itself is the IDE”. So what you need is just a simple, powerful text editor.
Lisp has virtually no syntax, except that you need the editor to help you with the parentheses. I prefer nvi. However here I should point out that I am in a minority.
Most of the Lisp community prefers Emacs and Slimecombination. To be honest, I started out with the same; but later switched to vi.
So if you already an emacs user, you might choose Emacs + Slime. If a vi user, you might go ahead with vi. I find using vi and the lisp REPL a sufficiently powerful and a simple setup at the same time.
With this our setup is ready. It is *nix + SBCL + (EMacs + Slime / Vi).
Where to begin?
I would recommend that you give sufficient time to work through Lisp. So if you come from a weaker language background, it may take some time finding your feet.
To start with, you can begin with either of these 2 books. Practical Common Lisp (PCL) by Peter Siebel or Ansi Common Lisp (ACL) by Paul Graham.
I chose the latter simply because I prefer chapters with exercises to solve which PCL lacks. But that in no way takes away from PCL. I would recommend starting off with any book, using the other as the companion.
The important point here is to work through which ever book you like. By work through it, I mean it is not only importantly to thoroughly understand what is being explained and to solve the exercises, but to also have a few questions. In addition, type out every piece of code and ensure that it works. You will learn a lot through this simple but hard process.
At the end of whichever book you chose to begin with, you must have the big picture in place. Do not expect to attain mastery over advanced topics such as macros or closures. It is important to have a simple mental mode of Lisp here. The simplest model I found is a sketch of the Lisp eval function.
By now you must be comfortable working with Lisp type of code, downloading and installing libraries, using ASDF. You must have a simple clear Lisp model in your head.
Since I came from a Java (OO) background, I completely skipped the CLOS part. Simply because I did not want to give myself a chance to go back to writing Java type OO code in Lisp! Of course, CLOS is way more powerful than the standard OO that you get in other langauges, but I skipped CLOS initially for a valid reason. And that was to grasp the Lisp style of coding.
Now you are ready to tackle the advanced topics in Lisp such as closures and macros. The best book to master these is obviously On Lisp.
This is what I did and it worked well for me. On Lisp is more about utilizing the power of Lisp via macros and closures. But if you read closely it is a book full of problems and solutions. As such read through the problem PG tries to describe and solve it using whatever Lisp knowlege you have. Then compare your solution to that in the book. It will teach you a lot more than simply even working through the book.
Doug Hoyte has rightly pointed out that On Lisp is a zero or one book, that is, either you understand it or you do not. If you cross the On Lisp road, you are well on your way to become a very productive programmer.
About example projects in the PCL, ACL and On Lisp
Initially I just glanced through the example projects in ACL. After working through On Lisp upto chapter 18, I worked through the examples in both ACL (chapters 15,16,17) as well that in On Lisp (chapters 19 through 24). The inference and objects chapters 15 and 17 respectively in ACL merge with chapters 19 and 25 of On Lisp.
After working through the above, you can as well treat say PCL example projects as problems to solve. Or you can pick up a problem to solve of your own and rake up a Lisp solution. The first such thing I did was to write a Lisp program to generate the website that you are now browsing! I was inspired by the chapter 16 in ACL to generate html to write a solution to generate my website.
How much time would it take?
This really depends upon the individual. But as with any learning, consistency is more important. Do not learn anything hard with long breaks in between. Since I also have a day job and other things to take care of, it took me around 10 months to work through these 2 books. But today I can say that it was worth the effort.
Common Lisp Libraries and QuickLisp
When you sit down to write your own real Lisp code, it will extend to more than 1 lisp file. In that case you have to ensure the order in which the files are loaded is correct to manage the dependencies. In addition, you will also try to use existing libraries as much as possible. So you also have to ensure the dependencies of your code on these libraries All of this is taken care of you via Lisp packages, see Erran Gat’s guide for packages and ASDF (a make like tool for Lisp).Common-lisp.net and Cliki are good sources of common lisp libraries.
There is now an excellent way of managing your Lisp Libraries. QuickLisp. Its a GOD send.
I use Ansi Common Lisp Appendix D Language Reference as my reference guide. For detailed reference, Common Lisp The Lanuage, Second Edition is the choice. You can also access the Lisp documentation online.
If you reach this far, you will surely be motivated to use Lisp as much as possible. You can join some open source Lisp project to make contributions.
In addition, you can also spend some time (again regularly) to work through these following Lisp books.
I am a 3D graphics software engineer.