From: David J Cooper Jr
Subject: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <m3pt7vry9z.fsf@graham.genworks.com>
Hi,

 Has anyone looked into making pretty-printed HTML output using
 HTMLgen or similar, using the CL pretty-printer? I know Steven
 Haflich has mentioned using the pretty-printer with his HTML/XML
 generator.

 As has been mentioned here several times, pretty-printed HTML is
 useful for development and debugging even though it is probably a
 waste of time and bandwidth for production apps.


Thanks,

 -dave

From: Edi Weitz
Subject: Re: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <87u0x79n7m.fsf@bird.agharta.de>
On 19 Jun 2004 18:14:16 -0400, David J Cooper Jr <·······@genworks.com> wrote:

>  Has anyone looked into making pretty-printed HTML output using
>  HTMLgen or similar, using the CL pretty-printer? I know Steven
>  Haflich has mentioned using the pretty-printer with his HTML/XML
>  generator.
>
>  As has been mentioned here several times, pretty-printed HTML is
>  useful for development and debugging even though it is probably a
>  waste of time and bandwidth for production apps.

I don't know if this is what you're looking for but you might want to
look at CL-WHO, specifically at its :INDENT keyword argument:

  <http://weitz.de/cl-who/#with-html-output>

Edi.


  * (with-html-output (*standard-output* nil :indent t)
      (:html (:body :bgcolor "white"
                    (:table :border 0
                            (:tr (:td "First col")
                                 (:td "Second col"))
                            (:tr (:td :colspan 2
                                      (:b "Single row, bold"))))))
      (values))

  <html>
    <body bgcolor='white'>
      <table border='0'>
        <tr>
          <td>
            First col
          </td>
          <td>
            Second col
          </td>
        </tr>
        <tr>
          <td colspan='2'>
            <b>
              Single row, bold
            </b>
          </td>
        </tr>
      </table>
    </body>
  </html>
From: Steven M. Haflich
Subject: Re: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <40DD9CDB.2000707@alum.mit.edu>
See xml-generator.lisp here:

http://dynamiclearningcenter.com/samples/ray-tracing/description.html

This covers html, as the preferred syntax for html is (or should be) xhtml.
The printer does use the pretty printer, meaning it get the usual pprinter
adaptive behavior with regard to stream output width.

   !(time @"The current UT is " !((ut @tz *time-zone*) @(get-universal-time))))
   <time>The current UT is <ut tz="8">3297253569</ut></time>

I won't describe the api here (it's described in the source file) except
to explain the need for a syntax marker (a macro or reader macro) in order
to mark an xml element in code.  The set of elements in xml is not predefined,
as it is for html, so element names cannot simply be predefined keywords.
I also find it important aethetically that the xml generation operators work
orthogonally with the rest of Lisp syntax.  One thing I don't like about
AllegroServe htmlgen is the need to reimplement :if and other control syntax.
The following fragment should illustrate:

	 !(tr (loop for i from 1 to 10 do !(th @(* 100 i))))
	 !(tr (loop for i from 1 to 10
		  do !(td !((input @type "radio" @name "res" @value i
				   (when (eql i res)
				     @checked "checked"))))))

This is an old version of this software, which someday needs to include
namespace support, support for subtrees that should not be pretty printed
(e.g. html <pre>), and better optimization when pretty printing is not
desired.

I find development of x/html emitting code to be insane without the
debuggability of pretty printing, but of course, after the code is developed,
pretty printing is a complete waste of both processor time and transmission
bandwidth.  It is nice to be able to turn on `debugging' simply by binding
*print-pretty* true, but in the current implementation there is still some
overhead from the pretty printer when *print-pretty* is false.
From: Rob Warnock
Subject: Re: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <J8ydnTNzeq2KcELdRVn-vg@speakeasy.net>
Steven M. Haflich <·················@alum.mit.edu> wrote:
+---------------
| I also find it important aethetically that the xml generation operators
| work orthogonally with the rest of Lisp syntax.  One thing I don't
| like about AllegroServe htmlgen is the need to reimplement :if and
| other control syntax. The following fragment should illustrate:
| 
| 	 !(tr (loop for i from 1 to 10 do !(th @(* 100 i))))
| 	 !(tr (loop for i from 1 to 10
| 		  do !(td !((input @type "radio" @name "res" @value i
| 				   (when (eql i res)
| 				     @checked "checked"))))))
+---------------

Tim Bradshaw's HTOUT and Edi Wietz's CL-WHO provide exactly this mutual
nestability, if you substitute their macrolet "HTM" for your "!" [though
the method of handling optional attributes is a bit different]:

  (htm (:tr (loop for i from 1 to 10
              do (htm (:th (fmt "~d" (* 100 i)))))))
  (htm (:tr (loop for i from 1 to 10
              do (htm (:td (if (eql i res)
                             (htm ((:input :type "radio" :name "res"
                                           :value i :checked)))
                             (htm ((:input :type "radio" :name "res"
                                           :value i)))))))))


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Steven M. Haflich
Subject: Re: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <dw4Gc.6668$dH3.3586@newssvr25.news.prodigy.com>
Rob Warnock wrote:

> Steven M. Haflich <·················@alum.mit.edu> wrote:
> Tim Bradshaw's HTOUT and Edi Wietz's CL-WHO provide exactly this mutual
> nestability, if you substitute their macrolet "HTM" for your "!" [though
> the method of handling optional attributes is a bit different]:
> 
>   (htm (:tr (loop for i from 1 to 10
>               do (htm (:th (fmt "~d" (* 100 i)))))))
>   (htm (:tr (loop for i from 1 to 10
>               do (htm (:td (if (eql i res)
>                              (htm ((:input :type "radio" :name "res"
>                                            :value i :checked)))
>                              (htm ((:input :type "radio" :name "res"
>                                            :value i)))))))))

I think that abbreviating the analogous htmlgen macro name to three
characters is helpful, but I still prefer using the reader macro.
There are a couple reasons, and some bear repeating since their importance
might not be self evident.

   There is an elegance to having the Lisp code parallel the structure of the
html it generates, but when generating a complex page the number of nested
levels can be large.  If there are many transitions between html and lisp,
the reader macro doesn't consume indentation and parentheses levels.
Imagine what sphere-control-form would look like in
http://dynamiclearningcenter.com/samples/ray-tracing/webpage.lisp
replacing all the ! with a parenthesized (html ...)

   Defining macros in the keyword package works _only_ for the known set of
html element names.  It don't scale for xml, where the set of element
names is unrestricted.  Furthermore, if Tim defines a set of html macros,
and you define a set of macros for html generation, and jkf defines yet
another set, and I load some system using jkf's code and some system using
your code and some system using Tim's code, into the same web server, I'll
soon find out why violating the wise suggestion in ANS 11.1.2.3.2 even
though it specifically applies only to property list indicators and has
only oblique implications on the operator namespace.
From: Tim Bradshaw
Subject: Re: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <fbc0f5d1.0407050613.68c7d5d2@posting.google.com>
"Steven M. Haflich" <·················@alum.mit.edu> wrote in message news:<···················@newssvr25.news.prodigy.com>...

>    Defining macros in the keyword package works _only_ for the known set of
> html element names.  It don't scale for xml, where the set of element
> names is unrestricted.  

Actually, it works fine, because they're not macros, they're just
forms that the macro expander processes.  In fact, HTOUT has a
predicate which decides if something is markup or Lisp, which you can
change - you could say that only symbols in a certain package or set
of packaqes were markup, or that strings were, or that strings whose
names are the names of the days of the week in Czech were.

The predicate can't be given as the argument to the macro, it's the
value of a special variable (at least not in the released version, I
think I may have changed it since then, if not I will one day, but
it's substantially after `find a way of earning a living which has
nothing at all to do with computers' on my to-do list), and the tag
*output* protocol (EMIT-TAG) is a real botch, but there is no problem
with markup recognition.

You may be confusing HTOUT with one of these terribly rudimantary
systems which defines macros for all the HTML tags, or something. 
That would be a mistake, just as those systems are.

> Furthermore, if Tim defines a set of html macros,
> and you define a set of macros for html generation, and jkf defines yet
> another set, and I load some system using jkf's code and some system using
> your code and some system using Tim's code, into the same web server, I'll
> soon find out why violating the wise suggestion in ANS 11.1.2.3.2 even
> though it specifically applies only to property list indicators and has
> only oblique implications on the operator namespace.

That can't be a problem for HTOUT, unless your system's macros are
confusable with HTML tags in some awful way.  For instance, if your
system's wrapping macro is WITH-XML-OUTPUT, and it uses keywords like
HTOUT does, then this will work just fine:

(with-html-output (s)
  ;; these things are rewritten by htout
  (:html
   (:head
    ...
   (with-xml-output (s)
     ;; and these by the other macro
     (:top
      (:grunge ...)))))

--tim
From: Edi Weitz
Subject: Re: Pretty-printing HTML with HTMLgen?
Date: 
Message-ID: <877jtiq193.fsf@bird.agharta.de>
On Mon, 05 Jul 2004 04:09:45 GMT, "Steven M. Haflich" <·················@alum.mit.edu> wrote:

>    There is an elegance to having the Lisp code parallel the
> structure of the html it generates, but when generating a complex
> page the number of nested levels can be large.

Agreed. That's a general problem that's hard to avoid although most of
the HTML-generating packages will of course allow you to insert
shortcuts (also known as functions ...:). For example with CL-WHO I
might do something like this

  (defun fancy-submit-button (name value-list)
    (with-html-output (*html-stream*)
      (:tr
       (:td :style "background-color: green"
            (:select :style "margin:-2; text-align:right; font-size: 8pt"
                     :name name
                     (dolist (value value-list)
                       (htm (:option :style "text-align:right; font-size: 8pt;"
                                     :value value
                                     (str value)))))))))

and then

  (with-html-output (*html-stream*)
    (:table :cellpadding "4"
            :cellspacing "0"
            :border "1"
            :style "border-style:solid; border-collapse:collapse"
            (loop for (name . value-list) in name-value-list-alist
                  do (fancy-submit-button name value-list))))

>    Defining macros in the keyword package works _only_ for the known
> set of html element names.  It don't scale for xml, where the set of
> element names is unrestricted.

At least in CL-WHO (and I think also in Tim's package) there aren't
any macros defined in the keyword package. CL-WHO doesn't care whether
you write :INPUT or :INXPUT because it doesn't have any knowledge
about HTML, XHTML, or XML.

Cheers,
Edi.

-- 

"Lisp doesn't look any deader than usual to me."
(David Thornley, reply to a question older than most languages)

Real email: (replace (subseq ·········@agharta.de" 5) "edi")