David Steuber wrote:
> I have some questions about macros and their limitations.
>
> First question. Can a macro only expand into code? Or can I define a
> macro that will expand into XML for printing? This expansion may be
> into a string that I pass to format. The mechanism isn't as important
> as the ability to do so. Here are a couple examples in pseudolisp
> with the output after printing as with princ or format:
>
> (xmlify foo :attr1 "string" :attr2 42) =>
> <foo attr1="string" attr2=42/>
>
> (xmlify bar :attr 42 :baz (all your base)) =>
> <bar attr=42>
> <baz>all</baz>
> <baz>your</baz>
> <baz>base</baz>
> </bar>
>
> I'm also making the grand assumption that I can nest macros like this:
>
> (xmlify abar :attr "blue" (xmlify prop1 :attr1 69 attr2 foo)) =>
> <abar attr="blue">
> <prop1 attr1=69 attr2="foo"/>
> </abar>
>
One way is to create a new type like this.
(defstruct xmlified
sym
(plist nil))
(defmacro xmlify (sym &rest plist)
`(make-xmlified :sym ',sym :plist (list ,@plist)))
(defmethod print-object ((obj xmlified) stream)
(write-char #\< stream)
(write (xmlified-sym obj) :stream stream :case :downcase)
(loop for (property value) on (xmlified-plist obj) by #'cddr
do
(write-char #\space stream)
(write-string (string-downcase property) stream)
(write-char #\= stream)
(write value :stream stream))
(write-string "/>" stream))
CL-USER 9 > (xmlify foo :attr1 "string" :attr2 42)
<foo attr1="string" attr2=42/>
CL-USER 10 >
This way the xmlified expression is actually a struct. Then
one can nest the structures and get it printed in your perfered
format. The code above does not do your second example above.
You probably need somemore syntax to make the xmlify macro
better. This is left as an exercise for the reader.
Wade
Wade Humeniuk wrote:
> David Steuber wrote:
>
>> I have some questions about macros and their limitations.
>>
>> First question. Can a macro only expand into code? Or can I define a
>> macro that will expand into XML for printing? This expansion may be
>> into a string that I pass to format. The mechanism isn't as important
>> as the ability to do so. Here are a couple examples in pseudolisp
>> with the output after printing as with princ or format:
>>
>> (xmlify foo :attr1 "string" :attr2 42) =>
>> <foo attr1="string" attr2=42/>
>>
>> (xmlify bar :attr 42 :baz (all your base)) =>
>> <bar attr=42>
>> <baz>all</baz>
>> <baz>your</baz>
>> <baz>base</baz>
>> </bar>
>>
>> I'm also making the grand assumption that I can nest macros like this:
>>
>> (xmlify abar :attr "blue" (xmlify prop1 :attr1 69 attr2 foo)) =>
>> <abar attr="blue">
>> <prop1 attr1=69 attr2="foo"/>
>> </abar>
>>
>
> One way is to create a new type like this.
>
> (defstruct xmlified
> sym
> (plist nil))
>
> (defmacro xmlify (sym &rest plist)
> `(make-xmlified :sym ',sym :plist (list ,@plist)))
>
> (defmethod print-object ((obj xmlified) stream)
> (write-char #\< stream)
> (write (xmlified-sym obj) :stream stream :case :downcase)
> (loop for (property value) on (xmlified-plist obj) by #'cddr
> do
> (write-char #\space stream)
> (write-string (string-downcase property) stream)
> (write-char #\= stream)
> (write value :stream stream))
> (write-string "/>" stream))
>
> CL-USER 9 > (xmlify foo :attr1 "string" :attr2 42)
> <foo attr1="string" attr2=42/>
>
> CL-USER 10 >
>
> This way the xmlified expression is actually a struct. Then
> one can nest the structures and get it printed in your perfered
> format. The code above does not do your second example above.
> You probably need somemore syntax to make the xmlify macro
> better. This is left as an exercise for the reader.
Was that a pun in diguise? ;)
Question: Is there any way in a print-object method to determine the
value of :readably? That way, you could have :readably nil indicate
that you want XML output but :readably t indicate to just print the
structure the normal way.
Ari Johnson wrote:
>> better. This is left as an exercise for the reader.
>
>
> Was that a pun in diguise? ;)
>
> Question: Is there any way in a print-object method to determine the
> value of :readably? That way, you could have :readably nil indicate
> that you want XML output but :readably t indicate to just print the
> structure the normal way.
Yes, just check the value of the special variable *print-readably*.
http://www.lispworks.com/reference/HyperSpec/Body/v_pr_rda.htm#STprint-readablyST
Wade
Wade Humeniuk wrote:
> Ari Johnson wrote:
>
>>> better. This is left as an exercise for the reader.
>>
>>
>>
>> Was that a pun in diguise? ;)
>>
>> Question: Is there any way in a print-object method to determine the
>> value of :readably? That way, you could have :readably nil indicate
>> that you want XML output but :readably t indicate to just print the
>> structure the normal way.
>
>
> Yes, just check the value of the special variable *print-readably*.
>
> http://www.lispworks.com/reference/HyperSpec/Body/v_pr_rda.htm#STprint-readablyST
Is there any particular reason that prin1 doesn't set *print-readably*?
In article <·····················@okepread04>,
Ari Johnson <·····@hotmail.com> wrote:
> Is there any particular reason that prin1 doesn't set *print-readably*?
Because PRINT and PRIN1 have traditionally been allowed to produce
#<...> notations.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
In article <·····················@okepread04>,
Ari Johnson <·····@hotmail.com> wrote:
> Is there any particular reason that prin1 doesn't set *print-readably*?
If you want to differentiate between possibly unreadable "aesthetic" and
"non-aesthetic" forms, you should look at *print-escape* instead.
(Warning: Possible bad style ahead, but it worked for me.)
I was writing a kludgey little time report generator for writing my
timesheets, and had a simple time object. By checking *print-escape*, I
could get this behavior:
(defparameter *t* (make-time 4 27))
(princ *t*) =>
4:27
(prin1 *t*) =>
#<TS-TIME 4:27>
This made using FORMAT to line up output columns relatively easy (just
feed the objects in with, for example, ~12A), but normal output when
writing code had the time objects wrapped in #<...>.
(*print-readably* should always signal an error instead of printing an
object as #<...>. It's very inconvenient to have on unless you need it,
as trying to print CLOS objects with no PRINT-OBJECT methods will signal
errors. If it's set at the REPL, it affects it as well!)
-bcd
--
*** Brian Downing <bdowning at lavos dot net>
Wade Humeniuk <····································@telus.net> writes:
> One way is to create a new type like this.
Thanks, Wade. That was above and beyond what I expected. This is a
good example to work from. I think nesting may be achievable by the
fact that the list would be a tree/nested list. I'll have to play
with it some.
--
I wouldn't mind the rat race so much if it wasn't for all the damn cats.