Hi all,
Before I knew about &key I was using &rest to parse keyword parameters.
I could parse a URI in these three forms:
1. (a :href "uri")
2. (a :href "uri" "description")
3. (a "description" :href "uri")
I simply returned all keyword-value pairs in one list and non-keyword
arguments in another for processing.
I've now got many in the second form because I converted the URIs
automatically from the HTML syntax <a href="uri">description</a>.
While duplicating the second form using inbuilt Lisp functionality doesn't
appear possible (an &optional after &key is misplaced), I can't even work
out how to specify the first and third forms without using &rest and
parsing the input myself.
This doesn't work...
(defun a (&optional desc &key href) (write desc) (write href))
...because desc can't be omitted when :href is specified (it leads to the
error "Function called with odd number of keyword arguments.")
I'd like to know how far I can go to provide such variation in input
without having to resort to using &rest and then parsing the resulting
list myself.
Thanks,
Adam
Adam Warner <······@consulting.net.nz> wrote:
+---------------
| Before I knew about &key I was using &rest to parse keyword parameters.
| I could parse a URI in these three forms:
| 1. (a :href "uri")
| 2. (a :href "uri" "description")
| 3. (a "description" :href "uri")
...
| This doesn't work...
| (defun a (&optional desc &key href) (write desc) (write href))
...
| I'd like to know how far I can go to provide such variation in input
| without having to resort to using &rest and then parsing the resulting
| list myself.
+---------------
If you can make one massive search & replace edit over your corpus
and replace all occurences of #2 & #3 with the following alternatives,
life might become a lot simpler for you:
2'. (a :href "uri" :text "description")
3'. (a :text "description" :href "uri")
-Rob
p.s. I replied only because I've been using Tim Bradshaw's HTOUT macro
a lot recently, and he similarly finesses the inverse problem -- what to
do about an HTML attribute that has no value. His solution: Force the Lisp
keyword to be provided an explicit value of NIL in that case, e.g.:
((:ul :compact nil) ; outputs <UL COMPACT>
:li "First item."
:li "Second item.")
p.p.s. In HTOUT, one writes #2 as:
((:a :href "uri") "description")
which is yet another solution that works.
-----
Rob Warnock, PP-ASEL-IA <····@rpw3.org>
627 26th Avenue <URL:http://www.rpw3.org/>
San Mateo, CA 94403 (650)572-2607
* Rob Warnock wrote:
> p.s. I replied only because I've been using Tim Bradshaw's HTOUT macro
> a lot recently, and he similarly finesses the inverse problem -- what to
> do about an HTML attribute that has no value. His solution: Force the Lisp
> keyword to be provided an explicit value of NIL in that case, e.g.:
> ((:ul :compact nil) ; outputs <UL COMPACT>
> :li "First item."
> :li "Second item.")
I'd forgotten that, but it seems like a good approach to me (well, it
would...).
> p.p.s. In HTOUT, one writes #2 as:
> ((:a :href "uri") "description")
> which is yet another solution that works.
I use this notation for the public HTOUT because it makes the common
no-attribute case easy to type, and HTOUT was designed (well, evolved)
in the expectation that people would be typing a fair amount of
lisp-format HTML (indeed, I wrote a whole lisp course in this format -
it's easier to type than real HTML even with all the strings...). In
the case where the sexp representation is being machine-generated, I
now (in a not-yet-public descendent of HTOUT) use a notation like:
(tag attributes &rest body)
where attributes is a keyword attribute list. So:
(a (:href "foo") "bar")
The disadvantage of this for stuff where you want to really type a lot
of lispy HTML is that you have a lot of (:p () ...) type stuff. The
advantage is that it's much more Lispy - the car of the form is the
`function' which does the work (and indeed, there are `macros' which
do transformation on this representation, so:
(tocify (...)
(h1 () ...)
...)
does what you might expect.
--tim