From: Frank Buss
Subject: HTML reader macro
Date: 
Message-ID: <d6psv2$77m$1@newsreader3.netcologne.de>
I want to transform my HTML pages to Lisp, because then I don't have to 
write as much as with raw HTML, the compiler can check missing closing 
tags, I can execute Lisp code for generating parts of the page etc. But I 
don't want to use double-quotes for every text, because text is the 
normal case. I hope this is possible with a reader-macro, perhaps it 
could look like this:

#h ((head
     (title "A Test"))
    (body 
     (p Just a (bold test).(br)
        1 + 2 = (+ 1 2).(br)
        And a link: (a :href "page.html" The Page).)))

If the first word is a known HTML tag, then the next words are 
interpreted as ":key value" pairs for HTML attributes and the rest is 
text. If the first word is not a HTML tag, it is evaluated as a Lisp 
form. The result:
  
<html>
  <head>
    <title>A Test</title>
  </head>
  <body>
    <p>
      Just a <b>test</b>.<br>
      1 + 2 = 3.<br>
      And a link: <a href="page.html">The Page</a>.
    </p>
  </body>
</html>

Do you think this is a good idea? How do I implement it? Normally all 
characters are changed to uppercase with read.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de

From: Eric Lavigne
Subject: Re: HTML reader macro
Date: 
Message-ID: <1116776769.639125.181940@g43g2000cwa.googlegroups.com>
>I want to transform my HTML pages to Lisp, because
>then I don't have to write as much as with raw HTML,
>the compiler can check missing closing tags, I can
>execute Lisp code for generating parts of the page etc.
>But I don't want to use double-quotes for every text,
>because text is the normal case

Have you looked at Allegro Serve? Its syntax is similar to what you
want. It doesn't shy away from double-quotes the way you want to, but
even your example isn't very consistent about that. You used
double-quotes in the title tag, but not in the paragraph tag. The
double quotes are a negligible amount of typing and make things a bit
clearer I think.
From: Jeff Cunningham
Subject: Re: HTML reader macro
Date: 
Message-ID: <pan.2005.05.22.15.51.52.50766@cunningham.net>
On Sun, 22 May 2005 12:12:18 +0000, Frank Buss wrote:

> I want to transform my HTML pages to Lisp, because then I don't have to
> write as much as with raw HTML, the compiler can check missing closing
> tags, I can execute Lisp code for generating parts of the page etc. But
> I don't want to use double-quotes for every text, because text is the
> normal case. I hope this is possible with a reader-macro, perhaps it
> could look like this:

It sounds like a very similar project to one I'm working on. But if I
understand you correctly, you want to be able to write lisp which would
generate correct html for you, wouldn't you call that an html 'writer'?

I am but a "macro newby", as one person put it. But since no one else has
responded yet and I have an interest, I will.

I've been dealing with the issue of text by using a function which
generates quoted text where it's needed. For example, in the case of tags
with attributes you want them to be written in the form:
attribute="value". Here's my function:

(defun write-attributes (alst)
  ;; Writes an alist of (attribute value) pairs as 'attribute="value"' (if
  (null alst)
      nil
      (let ((pair (car alst)))
        (if (cdr alst)
            (progn
              (format t "~A=\"~a\" " (car pair) (second pair))
              (write-attributes (cdr alst)))
            (format t "~A=\"~a\"" (car pair) (second pair))))))

Then I call it like this:

(write-attributes '(("prop1" "some string")("numprop" 23)))

etc. I have been following Paul Graham's chapter on html, so I write
everything to *standard-output* and then redirect this to a file later. I
like this approach alot, because it gets around having to create a
specific stream and push it around everywhere in function/macro calls. It
also makes debugging easier because you can see the output in real time,
rather than having to less a file.

Here is the macro (cleaned up from my other thread) and an example using
the above function:

(defmacro hlink ((dest &optional attributes-form) &body text-forms)
  " Writes text-forms as a hyperlink to dest with optional attributes"
  (let ((spc (not (null attributes-form))))
    `(progn
      ;; format writes dest as a hyperlink target and only ;; puts a space
      after it if there's going to be attributes following (format t "<a
      href=\"~A\"~:[~; ~]" ,dest ,spc) ,attributes-form
      (format t ">~%")
      ,@text-forms
      (format t "~&</a>"))))


(hlink ("index.html" (write-attributes '(("name" "A Name"))))
        (princ "A text hyperlink"))


When I macroexpand the above, it seems to work properly, but again, I'm a
newby.

--jeff cunningham
From: http://public.xdi.org/=pf
Subject: Re: HTML reader macro
Date: 
Message-ID: <m27jhqn1uj.fsf@mycroft.actrix.gen.nz>
On Sun, 22 May 2005 08:51:53 -0700, Jeff Cunningham wrote:

> I've been dealing with the issue of text by using a function which
> generates quoted text where it's needed. For example, in the case of tags
> with attributes you want them to be written in the form:
> attribute="value". Here's my function:

> (defun write-attributes (alst)
>   ;; Writes an alist of (attribute value) pairs as 'attribute="value"' (if
>   (null alst)
>       nil
>       (let ((pair (car alst)))
>         (if (cdr alst)
>             (progn
>               (format t "~A=\"~a\" " (car pair) (second pair))
>               (write-attributes (cdr alst)))
>             (format t "~A=\"~a\"" (car pair) (second pair))))))

I assume it's your news software that screwed up the line break, but
please call the argument ALIST, not ALST.  Never accept style tips
from Paul Graham :-)

  (defun write-attributes (alist)
    (format t "~{~{~(~A~)=\"~A\"~}~^ ~}" alist))

> Then I call it like this:

> (write-attributes '(("prop1" "some string")("numprop" 23)))

Make it a plist and use &rest:

  (defun write-attributes (&rest args &key &allow-other-keys)
    (format t "~{~(~A~)=\"~A\"~^ ~}" args))

(write-attributes :prop1 "some string" :numprop 23)


> (defmacro hlink ((dest &optional attributes-form) &body text-forms)
>   " Writes text-forms as a hyperlink to dest with optional attributes"
>   (let ((spc (not (null attributes-form))))
>     `(progn
>       ;; format writes dest as a hyperlink target and only ;; puts a space
>       after it if there's going to be attributes following (format t "<a
>       href=\"~A\"~:[~; ~]" ,dest ,spc) ,attributes-form
>       (format t ">~%")
>       ,@text-forms
>       (format t "~&</a>"))))

  (defmacro hlink ((dest &rest attrs &key &allow-other-keys) &body body)
    `(format t "<a href=~S~{ ~(~A~)=\"~A\"~}>~A</a>"
             ,dest (list ,@attrs)
             (with-output-to-string (*standard-output*) ,@body)))

> (hlink ("index.html" (write-attributes '(("name" "A Name"))))
>         (princ "A text hyperlink"))

(hlink ("index.html" :name "A Name")
  (princ "A text hyperlink"))


-- 
Must the citizen ever for a moment, or in the least degree, resign his
conscience to the legislator?  Why has every man a conscience, then?
I think that we should be men first, and subjects afterwards.  It is not
desirable to cultivate a respect for the law, so much as for the right.
The only obligation which I have a right to assume is to do at any time
what I think right.
                                                   -- Henry David Thoreau
(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: R. Mattes
Subject: Re: HTML reader macro
Date: 
Message-ID: <pan.2005.05.23.08.15.44.601804@mh-freiburg.de>
On Mon, 23 May 2005 13:54:44 +1200, Paul Foley wrote:

> On Sun, 22 May 2005 08:51:53 -0700, Jeff Cunningham wrote:
> 
>> I've been dealing with the issue of text by using a function which
>> generates quoted text where it's needed. For example, in the case of tags
>> with attributes you want them to be written in the form:
>> attribute="value". Here's my function:
> 
>> (defun write-attributes (alst)
>>   ;; Writes an alist of (attribute value) pairs as 'attribute="value"' (if
>>   (null alst)
>>       nil
>>       (let ((pair (car alst)))
>>         (if (cdr alst)
>>             (progn
>>               (format t "~A=\"~a\" " (car pair) (second pair))
>>               (write-attributes (cdr alst)))
>>             (format t "~A=\"~a\"" (car pair) (second pair))))))
> 
> I assume it's your news software that screwed up the line break, but
> please call the argument ALIST, not ALST.  Never accept style tips
> from Paul Graham :-)
> 
>   (defun write-attributes (alist)
>     (format t "~{~{~(~A~)=\"~A\"~}~^ ~}" alist))

No,no  :-0
Don't use format to do that - even so format has power the above code will
fail:

  (write-attributes 
	'((name  "value") (author "Michael \"the boy\" O'hara")))

  => NAME="value" AUTHOR="Michael "the bat" O'hara"

And that is _not_ valid HTML. 
BTW, i cc'ed to the lispweb mailing list where this might be of interest
as well.


 Cheers Ralf Mattes
From: Pascal Bourguignon
Subject: Re: HTML reader macro
Date: 
Message-ID: <871x7ynfni.fsf@thalassa.informatimago.com>
"R. Mattes" <··@mh-freiburg.de> writes:

> On Mon, 23 May 2005 13:54:44 +1200, Paul Foley wrote:
>
>> On Sun, 22 May 2005 08:51:53 -0700, Jeff Cunningham wrote:
>> 
>>> I've been dealing with the issue of text by using a function which
>>> generates quoted text where it's needed. For example, in the case of tags
>>> with attributes you want them to be written in the form:
>>> attribute="value". Here's my function:
>> 
>>> (defun write-attributes (alst)
>>>   ;; Writes an alist of (attribute value) pairs as 'attribute="value"' (if
>>>   (null alst)
>>>       nil
>>>       (let ((pair (car alst)))
>>>         (if (cdr alst)
>>>             (progn
>>>               (format t "~A=\"~a\" " (car pair) (second pair))
>>>               (write-attributes (cdr alst)))
>>>             (format t "~A=\"~a\"" (car pair) (second pair))))))

You should not mix levels. Use either: cons car cdr cadr caddr ... null
or list first rest second third ... endp

Note that  a-list items are dotted conses: ((a . 1) (b . (value list)))
So you need car and cdr, not first and second.


>> I assume it's your news software that screwed up the line break, but
>> please call the argument ALIST, not ALST.  Never accept style tips
>> from Paul Graham :-)
>> 
>>   (defun write-attributes (alist)
>>     (format t "~{~{~(~A~)=\"~A\"~}~^ ~}" alist))
>
> No,no  :-0
> Don't use format to do that - even so format has power the above code will
> fail:
>
>   (write-attributes 
> 	'((name  "value") (author "Michael \"the boy\" O'hara")))

When this is considered as an alist, the values are: ("value"),
("Michael \"the boy\" O'hara"), not "value" and "Michael \"the boy\" O'hara",
so to format them correctly you'd have to use ~{~S~} insteda of ~S.


>   => NAME="value" AUTHOR="Michael "the bat" O'hara"

The trick is to use ~S instead of ~A.  And while the syntax does not
always match, most of the time, it works (in most of the situations, "
is used to delimit strings, and \ is used to escape an \ or a ").  For
the special cases, you can preprocess the data.

> And that is _not_ valid HTML. 
> BTW, i cc'ed to the lispweb mailing list where this might be of interest
> as well.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
From: R. Mattes
Subject: Re: HTML reader macro
Date: 
Message-ID: <pan.2005.05.23.15.23.54.706491@mh-freiburg.de>
On Mon, 23 May 2005 17:08:49 +0200, Pascal Bourguignon wrote:


> 
> You should not mix levels. Use either: cons car cdr cadr caddr ... null
> or list first rest second third ... endp

I assume you comment on Jeff's code.

> Note that  a-list items are dotted conses: ((a . 1) (b . (value list)))
> So you need car and cdr, not first and second.
> 
> 


>>> 
>>>   (defun write-attributes (alist)
>>>     (format t "~{~{~(~A~)=\"~A\"~}~^ ~}" alist))
>>
>> No,no  :-0
>> Don't use format to do that - even so format has power the above code will
>> fail:
>>
>>   (write-attributes 
>> 	'((name  "value") (author "Michael \"the boy\" O'hara")))
> 
> When this is considered as an alist, the values are: ("value"),
> ("Michael \"the boy\" O'hara"), not "value" and "Michael \"the boy\" O'hara",
> so to format them correctly you'd have to use ~{~S~} insteda of ~S.
> 
> 
>>   => NAME="value" AUTHOR="Michael "the bat" O'hara"
> 
> The trick is to use ~S instead of ~A.  And while the syntax does not
> always match, most of the time, it works (in most of the situations, "
> is used to delimit strings, and \ is used to escape an \ or a ").  For
> the special cases, you can preprocess the data.

That "trick" will most likely not solve the problem i addressed. Using ~S
will print string values readable by a Lisp reader. So we end up with
 
 => NAME="value" AUTHOR="Michael \"the bat\" O'hara"

which still isn't valid SGML/HTML/XML

 
 Cheers Ralf Mattes
From: Jeff Cunningham
Subject: Re: HTML reader macro
Date: 
Message-ID: <pan.2005.05.26.04.11.49.216091@cunningham.net>
On Mon, 23 May 2005 17:23:57 +0200, R. Mattes wrote:


> That "trick" will most likely not solve the problem i addressed. Using ~S
> will print string values readable by a Lisp reader. So we end up with
>  
>  => NAME="value" AUTHOR="Michael \"the bat\" O'hara"
> 
> which still isn't valid SGML/HTML/XML
>

I think I'm following most of this (its a learning experience for me). But
isn't this last bit sort of a non-issue? I mean, so far as I know, no
markup language allows attributes to have double-quote *values*, as they
are delimiters. I don't believe it this is valid html:

<p src="some value" "with a break">

Whereas this is:

<p>"Some text" "with a break"</p>

I don't understand the distinction between using 'first' and 'car'. I
thought they were identical. Am I wrong?

-jeff cunningham
From: http://public.xdi.org/=pf
Subject: Re: HTML reader macro
Date: 
Message-ID: <m2y8a5l5h7.fsf@mycroft.actrix.gen.nz>
On Mon, 23 May 2005 10:15:52 +0200, R Mattes wrote:

>> (defun write-attributes (alist)
>>   (format t "~{~{~(~A~)=\"~A\"~}~^ ~}" alist))

> No,no  :-0
> Don't use format to do that - even so format has power the above code will
> fail:

>   (write-attributes 
> 	'((name  "value") (author "Michael \"the boy\" O'hara")))

>   => NAME="value" AUTHOR="Michael "the bat" O'hara"

Actually, it produces �name="value" author="Michael "the boy" O'hara"�
with lower-case attribute names; I can't imagine why you think it
would change "boy" into "bat" <g>


[OK, so the embedded quotes aren't valid, but what /should/ it produce
in that situation?  Is it even possible to put quotation marks inside
an attribute value in HTML?  You could use ~/DTRT/ instead of ~A if
there is a RT...]

-- 
Must the citizen ever for a moment, or in the least degree, resign his
conscience to the legislator?  Why has every man a conscience, then?
I think that we should be men first, and subjects afterwards.  It is not
desirable to cultivate a respect for the law, so much as for the right.
The only obligation which I have a right to assume is to do at any time
what I think right.
                                                   -- Henry David Thoreau
(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: Wade Humeniuk
Subject: Re: HTML reader macro
Date: 
Message-ID: <e62ke.8829$on1.113@clgrps13>
Frank Buss wrote:
> I want to transform my HTML pages to Lisp, because then I don't have to 
> write as much as with raw HTML, the compiler can check missing closing 
> tags, I can execute Lisp code for generating parts of the page etc. But I 
> don't want to use double-quotes for every text, because text is the 
> normal case. I hope this is possible with a reader-macro, perhaps it 
> could look like this:
> 
> #h ((head
>      (title "A Test"))
>     (body 
>      (p Just a (bold test).(br)
>         1 + 2 = (+ 1 2).(br)
>         And a link: (a :href "page.html" The Page).)))
> 

To do this right you have to use the macro character abilities of
the reader.  Everything after #h and to the end of the expression
should be read and parsed by a user defined reader.  You really cannot
let the stuff in the forms be read by the standard reader.  An immediate
problem in the above example is "link:", this will cause a reader error
Also (bold test).(br) will cause another reader error. (Dot Context
Error in LW).  With the right tools this is not a particularly
difficult job, but it is non-trivial.  If I am not mistaken there are
a few html tags which have the same name as common-lisp functions.

Recommended approach

(set-dispatch-macro-character #\# #\h #'parse-html-expression)

(defun parse-html-expression (stream subchar arg)
    ... return parsed expression)

Probably suck the whole expresson into a string and parse it
from there.

In LW use

(defparser html-expression-parser ....)

Or cl-yacc

(yacc:define-parser html-expression-parser ...)

Wade
From: Wade Humeniuk
Subject: Re: HTML reader macro
Date: 
Message-ID: <ml2ke.8830$on1.4903@clgrps13>
Frank Buss wrote:
> I want to transform my HTML pages to Lisp, because then I don't have to 
> write as much as with raw HTML, the compiler can check missing closing 
> tags, I can execute Lisp code for generating parts of the page etc. But I 
> don't want to use double-quotes for every text, because text is the 
> normal case. I hope this is possible with a reader-macro, perhaps it 
> could look like this:
> 
> #h ((head
>      (title "A Test"))
>     (body 
>      (p Just a (bold test).(br)
>         1 + 2 = (+ 1 2).(br)
>         And a link: (a :href "page.html" The Page).)))
> 

On more thing to think about.  How would you have
iterative constructs that could
calculate the entries of a <ul>?

Wade
From: Rob Warnock
Subject: Re: HTML reader macro
Date: 
Message-ID: <vNSdnVannoeY0AzfRVn-pw@speakeasy.net>
Frank Buss  <··@frank-buss.de> wrote:
+---------------
| I want to transform my HTML pages to Lisp, because then I don't have to 
| write as much as with raw HTML, the compiler can check missing closing 
| tags, I can execute Lisp code for generating parts of the page etc. But I 
| don't want to use double-quotes for every text, because text is the 
| normal case. I hope this is possible with a reader-macro, perhaps it 
| could look like this:
| 
| #h ((head
|      (title "A Test"))
|     (body 
|      (p Just a (bold test).(br)
|         1 + 2 = (+ 1 2).(br)
|         And a link: (a :href "page.html" The Page).)))
+---------------

Search Google Groups for "Bradshaw Naggum TML" for a similar approach to
"quoteless" HTML-exprs. I think your example would be written thusly in TML:

    <html
      <head
	<title|A test>>
      <body
	<p|Just a <bold|test><br>
	   1 + 2 = <eval (+ 1 2)><br>
	   And a link: <a :href "page.html"|The Page>.>>>

[Or maybe "<lisp :eval (+ 1 2)>", I forget...]

[I'm also not sure of the exact rules on when the end-of-attributes
marker "|" can be omitted. I *think* it's whenever the next token
could not be taken as a Lisp symbol, but maybe it's only needed
before keywords. Tim?]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Frank Buss
Subject: Re: HTML reader macro
Date: 
Message-ID: <1c0krlas8vr2j$.bn8orea16t69.dlg@40tude.net>
Rob Warnock wrote:

> Search Google Groups for "Bradshaw Naggum TML" for a similar approach to
> "quoteless" HTML-exprs. I think your example would be written thusly in TML:
> 
>     <html
>       <head
> 	<title|A test>>
>       <body
> 	<p|Just a <bold|test><br>
> 	   1 + 2 = <eval (+ 1 2)><br>
> 	   And a link: <a :href "page.html"|The Page>.>>>

this looks good, if substituting "<" and ">" with "(" and ")", because then
my editor does indention the right way. But I don't know if it is a good
idea to use double quotes for attributes, because for text it is not used.
On the other side it is a bit more natural, because in HTML attributes are
enclosed in double quotes, too. And I don't like the "eval", because I
would like to define my own functions, which should be used like the rest,
like "(footer :email ··@y.z")", which creates a user defined footer for a
page and could be defined as a normal function.

Perhpas it is more clear in the original documentation, but I didn't found
much more information on Google Groups, only that Tim Bradshaw perhaps
wanted to publish it, when it is ready. What I've found is this:

http://jxfire.sourceforge.net/docs/TML.html

but this doesn't look very complete (attributes and inline-Lisp is
missing). Would be a good idea to take a closer look at the rules of the
original system before re-inventing the wheel :-)

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Frank Buss
Subject: Re: HTML reader macro
Date: 
Message-ID: <17q9fwe10kugi$.pik771hvddq6.dlg@40tude.net>
Stefan Ram wrote:

>   Possibly you might get some inspiration from the similar
>   notation "Enamel" by Erik Naggum.
> 
> http://groups.google.es/groups?selm=3207626455633924%40naggum.net&output=gplain

thanks, this looks like the way to go. I think I use Enamel with "("
instead of "<", because unfortunatly I have to generate attributes for HTML
and I'll use ":" instead of "|", because then my editor can format it for
me (otherwise there are problems with the usual "|" meaning in Lisp). So
this is my idea, described by examples:

(br) -> <br> (special handling for HTML tags, because I want HTML 4.01)
(foo : some text) -> <foo>some text</foo>
(input (type text) (name test)) -> <input type="text" name="test">
(a (href page.html) : The page) -> <a href="page.html">The page</a>
(p : This is (b | bold text)) -> <p>This is <b>bold text</b></p>
(ul : (li first) (li second)) -> <ul><li>first</li><li>second</li></ul>
(p : #((+ 1 2))) -> <p>3</p>
(p : 1 \| 2 = #((logior 1 2)) \(or\)) -> <p>1 | 2 = 3 (or)</p>
(p : The base is #(*print-base*)) -> <p>The base is 10</p>

I think there is only "map", which is defined in HTML and CL, but the
normal case are HTML tags, so it is better to make it explicit with "#",
when some Lisp expression is evaluated. To avoid problems with text after
variables, like "#lengthmeter" the syntax is #(lisp), which allow
"#(length)meter" without spaces, but you have to use "#((", if you want to
call a function.

All tags should be expanded to "format t", which could be redirected to
whatever I want with (let ((*standard-output*...))...) :

#H(p | Hello World!) ->
(progn
  (format t "<p>"))
  (format t "Hello World!"))
  (format t "</p>"))

If I want to add my own function, I have to prefix it with #, but I can use
the macro within my function, too:

(defun footer (email)
  #H((hr)
     (p (a (href mailto:#(email)) : (img (src img/email.gif))))
     (adress : #((current-date-of-file)), Frank Bu�)))

If I don't write a space between the HTML tag and the colon, my editor does
the right indention:

#H(html:
   (head: (title: Test page))
   (body:
    (h1: A test)
    (p: Some text.
        Even more text.)
    (footer ··@frank-buss.de)))

-->

<html>
<head><title>Test page</title></head>
<body>
<h1>A Test</h1>
<p>Some text.
Even more text.</p>
<hr>
<p><a ···············@frank-buss.de"><img src="img/email.gif"></a> 
<address>23. May 2005, Frank Bu&szlig;</a></address>
</body>
</html>

But if I use attributes, the indention doesn't look right. It would be nice
to use it with every Common Lisp editor.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Frank Buss
Subject: Re: HTML reader macro
Date: 
Message-ID: <1ot48ahoxr3w3.wul6n8i6wox5$.dlg@40tude.net>
Frank Buss wrote:

> If I don't write a space between the HTML tag and the colon, my editor does
> the right indention:
> 
> #H(html:
>    (head: (title: Test page))
>    (body:
>     (h1: A test)
>     (p: Some text.
>         Even more text.)
>     (footer ··@frank-buss.de)))

I meant "#((footer ··@frank-buss.de))". But thinking again about it, it is
not consistent with "#((+ 1 2))" resulting in '(format t "3")'. Instead of
implicit converting Lisp expressions to strings, embedded Lisp expressions
should be executed, only. So "#((+ 1 2))" becomes "#(princ (+ 1 2))". This
solves the problem Wade wrote, too: Now I can create iterative structures
with Lisp:

#H (table (border 1): (tr: (th: i) (th: 2^i))
          #(loop for i from 1 to 3 do)
          (tr: (td: #(princ i)) (td: #(princ (expt 2 i)))))

which prints this, when executed:

<table border="1"><tr><th>i</th><th>2^i</th></tr>
<tr><td>1</td><td>2</td></tr>
<tr><td>2</td><td>4</td></tr>
<tr><td>3</td><td>8</td></tr>
</table>

Instead of princ, there could be a princ-html function, for escaping "<" to
"&lt;" etc.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Rob Warnock
Subject: Re: HTML reader macro
Date: 
Message-ID: <PuqdnRIiH5ebIg7fRVn-1Q@speakeasy.net>
Frank Buss  <··@frank-buss.de> wrote:
+---------------
| Stefan Ram wrote:
| >   Possibly you might get some inspiration from the similar
| >   notation "Enamel" by Erik Naggum.
| > http://groups.google.es/groups?selm=3207626455633924%40naggum.net&output=gplain
| 
| thanks, this looks like the way to go. I think I use Enamel with "("
| instead of "<", because unfortunatly I have to generate attributes for HTML
| and I'll use ":" instead of "|", because then my editor can format it for
| me (otherwise there are problems with the usual "|" meaning in Lisp).
+---------------

Well, if you're going to do *that*, then why reinvent the wheel?
Why not just use HTOUT or CL-WHO or HTML-GEN or one of the other
macro packages that already exist?!?  [See <http://www.cliki.net/Web>.]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rob Warnock
Subject: Re: HTML reader macro
Date: 
Message-ID: <dI-dnXQ02K_8Ww7fRVn-sA@speakeasy.net>
Frank Buss  <··@frank-buss.de> wrote:
+---------------
| Rob Warnock wrote:
| > Search Google Groups for "Bradshaw Naggum TML" for a similar approach to
| > "quoteless" HTML-exprs. I think your example would be written thusly in TML:
| >     <html
| >       <head
| > 	<title|A test>>
| >       <body
| > 	<p|Just a <bold|test><br>
| > 	   1 + 2 = <eval (+ 1 2)><br>
| > 	   And a link: <a :href "page.html"|The Page>.>>>
| 
| this looks good, if substituting "<" and ">" with "(" and ")",
| because then my editor does indention the right way.
+---------------

No, no, no!  ;-}  ;-} The whole point is to use "<" & ">" so the
parenophobes don't get freaked out by seeing the source of your
documents. You know, "Parens bad; angles good. XML has angles. Yum."

Just teach your editor how to indent angles "the right way"...  ;-}

+---------------
| But I don't know if it is a good idea to use double quotes for
| attributes, because for text it is not used.
+---------------

Ahhhh, in the interest of brevity I neglected to mention a
critical point: Attributes and attribute values are PURE LISP
EXPRESSIONS, intended to be read with Common Lisp's READ and
evaluated by the TML processor. Yes, it's a bit weird to see
the quotes in the case of something as simple as this:

   <a :href "page.html"|The Page>

but more understandable [and the quotes *necessary*!] in more
complex cases:

   <a :href (concatenate 'string base-url "page.html")|The Page>

+---------------
| On the other side it is a bit more natural, because in HTML attributes
| are enclosed in double quotes, too.
+---------------

But as noted above, the actual reason has nothing to do with that.

+---------------
| And I don't like the "eval", because I would like to define
| my own functions, which should be used like the rest, like
| "(footer :email ··@y.z")", which creates a user defined footer
| for a page and could be defined as a normal function.
+---------------

You can certainly do that, given the addition of a a syntax for
defining functions. I think Tim added that [he called them "macros"]
in his DTML extension to TML. But IMHO you still need some sort of
all-purpose eval (by whatever name) that's a generic escape to Lisp.

+---------------
| Perhpas it is more clear in the original documentation, but I didn't found
| much more information on Google Groups, only that Tim Bradshaw perhaps
| wanted to publish it, when it is ready. What I've found is this:
| 
| http://jxfire.sourceforge.net/docs/TML.html
| 
| but this doesn't look very complete (attributes and inline-Lisp is
| missing). Would be a good idea to take a closer look at the rules of the
| original system before re-inventing the wheel :-)
+---------------

That's somebody else's work entirely, completely unrelated to
Tim Bradshaw's use of the acronuym "TML". See the news article
Stephan Ram quoted for Tim's version, which was designed to be
very simply parsable into HTOUT syntax [and then compiled by
the Lisp compiler]. That is, my example above:

    <html
     <head <title|A test>>
     <body
       <p|Just a <bold|test><br>
	  1 + 2 = <eval (+ 1 2)><br>
	  And a link: <a :href "page.html"|The Page>.>>>

translates directly into the following HTOUT s-expr [taking some
minor liberties on the "eval"]:

    (:html
      (:head (:title "A test"))
      (:body
	(:p "Just a " (:bold "test") :br (lfd)
	    "1 + 2 = " (fmt "~d" (+ 1 2)) :br (lfd)
	    "And a link: " ((:a :href "page.html") "The Page") ".")))

and produces the following output:

    <HTML><HEAD><TITLE>A test</TITLE></HEAD>
    <BODY><P>Just a <BOLD>test</BOLD><BR>
    1 + 2 = 3<BR>
    And a link: <A HREF='page.html'>The Page</A>.</P></BODY></HTML>


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Marco Antoniotti
Subject: Re: HTML reader macro
Date: 
Message-ID: <E50le.50$mi7.73559@typhoon.nyu.edu>
Rob Warnock wrote:

> That's somebody else's work entirely, completely unrelated to
> Tim Bradshaw's use of the acronuym "TML". See the news article
> Stephan Ram quoted for Tim's version, which was designed to be
> very simply parsable into HTOUT syntax [and then compiled by
> the Lisp compiler]. That is, my example above:
> 
>     <html
>      <head <title|A test>>
>      <body
>        <p|Just a <bold|test><br>
> 	  1 + 2 = <eval (+ 1 2)><br>
> 	  And a link: <a :href "page.html"|The Page>.>>>
> 
> translates directly into the following HTOUT s-expr [taking some
> minor liberties on the "eval"]:
> 
>     (:html
>       (:head (:title "A test"))
>       (:body
> 	(:p "Just a " (:bold "test") :br (lfd)
> 	    "1 + 2 = " (fmt "~d" (+ 1 2)) :br (lfd)
> 	    "And a link: " ((:a :href "page.html") "The Page") ".")))

Yes, but I bet that you'd get

	(fmt "~A" (+ 1 2))

unless Tim has put in a fancy type inference engine :)

Cheers
--
Marco
From: Frank Buss
Subject: Re: HTML reader macro
Date: 
Message-ID: <13dp7mcyznzvg$.1xogfapxqlvgd.dlg@40tude.net>
Rob Warnock wrote:

> That's somebody else's work entirely, completely unrelated to
> Tim Bradshaw's use of the acronuym "TML". See the news article
> Stephan Ram quoted for Tim's version, which was designed to be
> very simply parsable into HTOUT syntax [and then compiled by
> the Lisp compiler]. That is, my example above:
> 
>     <html
>      <head <title|A test>>
>      <body
>        <p|Just a <bold|test><br>
> 	  1 + 2 = <eval (+ 1 2)><br>
> 	  And a link: <a :href "page.html"|The Page>.>>>

this looks good. I think I'll use "<" and ">", too, because then I can use
"(" and ")" without any escaping in the text, which is helps when quoting
Lisp source :-)

And with your syntax I don't need the pipe char any more, because after all
a tag is only something like a function call, where the HTML-attributes are
the keywords and the text is the rest, so this is easy to understand and
always possible, because HTML-attributes can't contain other elements. If
the text starts with a colon, I have to escape it, but this should not
happen very often. And I don't like "eval", I'll use "#(" for escaping to
Lisp-mode within text. Defining own tags then can be implemented by calling
functions with "#(". This helps to see the difference between atomic tags
and blocks which might be expanded to big HTML fragments.

(defun footer ()
  #H<...>)

#H<html
    <head <title A Test>>
    <body
      <p Just a <bold test><br>
        1 + 2 = #(princ (+ 1 2))<br>
        And a link: <a :href "page.html" The page>.>
      #(footer)>>

Loops looks a bit funny, because I have to escape to Lisp mode for the loop
macro, but the body of the loop is generated by a #H reader macro (which
produces "format t"'s). And within these body I have to escape again to
Lisp mode for printing the loop variables:

#H<table :border 1
    <tr <th i> <th 2^i>>
    #(loop for i from 1 to 3 do
      #H<tr <td #(princ i)> <td #(princ (expt 2 i))>>)>

Could be tricky to implement, but the syntax should be consistent.

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: André Thieme
Subject: Re: HTML reader macro
Date: 
Message-ID: <d6ttcb$trh$1@ulric.tng.de>
Frank Buss schrieb:
> I want to transform my HTML pages to Lisp, because then I don't have to 
> write as much as with raw HTML, the compiler can check missing closing 
> tags, I can execute Lisp code for generating parts of the page etc. But I 
> don't want to use double-quotes for every text, because text is the 
> normal case. I hope this is possible with a reader-macro, perhaps it 
> could look like this:

If you really want that one thing you could do is to program a WYSIWYG
editor. Then you don't have to type any html at all and syntax would
always be correct.
If you press a hotkey then the editor would internally mark the next
things that you write as Lisp code and execute it. The editor could
generate html or lisp as output.


> #h ((head
>      (title "A Test"))
>     (body 
>      (p Just a (bold test).(br)
>         1 + 2 = (+ 1 2).(br)
>         And a link: (a :href "page.html" The Page).)))
> 
> If the first word is a known HTML tag, then the next words are 
> interpreted as ":key value" pairs for HTML attributes and the rest is 
> text. If the first word is not a HTML tag, it is evaluated as a Lisp 
> form. The result:

What is your problem with putting text into a string and gaining all the
benefits of it beeing a string (you could use all functions that operate
on strings with your html-output)?
How would you generate a html page with your system that displays
(+ 1 2)?


#h ((head (title "A Test"))
     (body This is a Lisp-introduction. Type (+ 1 2) in the toplevel.))

Would generate:
This is a Lisp-introduction. Type 2 in the toplevel.



Andr�
-- 
"Reading endangers the stupidity"
From: Frank Buss
Subject: Re: HTML reader macro
Date: 
Message-ID: <2e7halegb19m$.1v01m1pr6f8l8.dlg@40tude.net>
Andr� Thieme wrote:

> Frank Buss schrieb:
>> But I 
>> don't want to use double-quotes for every text, because text is the 
>> normal case. I hope this is possible with a reader-macro, perhaps it 
>> could look like this:
> 
> If you really want that one thing you could do is to program a WYSIWYG
> editor. Then you don't have to type any html at all and syntax would
> always be correct.

I don't like WYSIWYG HTML editors, because I think it is easier for me to
have the source of the web page as a compact Lisp program. With WYSIWYG
editors you are limited to the features of the editor, for example if the
output should be changed from HTML to XHTML, or if a footer has to be added
to all pages automaticly. But if you write a compact source for the pages,
you can do whatever Lisp allows with it and it could be used for other
programs, too, where the HTML output is not the main feature of the
program. With an external editor you have a break between the Lisp program
and the HTML page.

> What is your problem with putting text into a string and gaining all the
> benefits of it beeing a string (you could use all functions that operate
> on strings with your html-output)?

Text is the normal case for my pages, because they are mainly static and I
simply don't want to write lots of double quotes :-)

> How would you generate a html page with your system that displays
> (+ 1 2)?
> 
> 
> #h ((head (title "A Test"))
>      (body This is a Lisp-introduction. Type (+ 1 2) in the toplevel.))
> 
> Would generate:
> This is a Lisp-introduction. Type 2 in the toplevel.

see my other posting in this thread:

http://groups.google.de/group/comp.lang.lisp/msg/7f71364d24216940

It would look like this:

#h ((head: (title: "A Test"))
    (body: This is a Lisp-introduction. Type \(+ 1 2\) in the toplevel.))

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de