From: Wade Humeniuk
Subject: Re: macro-biology
Date: 
Message-ID: <d%Npc.10770$RM.5177@edtnps89>
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

From: Ari Johnson
Subject: Re: macro-biology
Date: 
Message-ID: <faOpc.65297$Fl5.26751@okepread04>
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.
From: Wade Humeniuk
Subject: Re: macro-biology
Date: 
Message-ID: <DgOpc.10774$RM.3847@edtnps89>
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
From: Ari Johnson
Subject: Re: macro-biology
Date: 
Message-ID: <M0Ppc.65806$Fl5.37823@okepread04>
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*?
From: Barry Margolin
Subject: Re: macro-biology
Date: 
Message-ID: <barmar-9DEFFA.17471716052004@comcast.dca.giganews.com>
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 ***
From: Brian Downing
Subject: Re: macro-biology
Date: 
Message-ID: <Aq5qc.68233$z06.9034334@attbi_s01>
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> 
From: David Steuber
Subject: Re: macro-biology
Date: 
Message-ID: <87wu3bvpx2.fsf@david-steuber.com>
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.