HTML-generating _ENV

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

HTML-generating _ENV

Tangent 128

Lua 5.2's _ENV functionality naturally expedites some fun syntax tricks;
partly for a side project, and partly for the fun of it, I wrote a
module that creates an _ENV object with a metatable to synthesize
HTML-wrapping functions. Thus,

local _ENV = require"htmlua".new()
return html {
    body {
        div {
            class = "class",
            p "Hello"
        }
    }
}

would yield "<html><body><div
class="class"><p>Hello</p></div></body></html>".


So then, for more fun, I had it generate callable tables instead of raw
functions. As tables, the HTML-wrappers can be further indexed to get
more-specific, class-tagged versions to fit a little more nicely with
today's CSS frameworks:

return html {
    body {
        div.class {
            p "Hello"
        },
        div.two.classes()
    }
}

yields "<html><body><div class=" class"><p>Hello</p></div><div class="
two classes"></div></body></html>"


Implementaion code at
http://fossil.tangent128.name/LuaForum/artifact/adbc426fafc3cb1f37e0a1a2d7f4f50cc4a498c0

~Joseph


Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

steve donovan
On Sat, Nov 17, 2012 at 6:47 AM, Tangent 128 <[hidden email]> wrote:
> local _ENV = require"htmlua".new()
> return html {
>     body {
>         div {
>             class = "class",
>             p "Hello"
>         }
>     }
> }

This is also done in Orbit using a setfenv trick (it's called
'htmlification')  See the tutorial
http://keplerproject.github.com/orbit/example.html and look for
'Generating HTML'

In Penlight, pl.xml allows a similar trick, but the tags must all be
declared first. Otherwise it's too easy to generate bad HTML/XML with
spelling mistakes.

I do like the div.class {p"Hello"} notation you have.

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Ryan Pusztai

Nice job.  I use Orbits htmlification almost every day and like your syntax for multiple classes. I have never tried that in Orbit,  I wonder if it works like that.

I would actually prefer Penlights implementation better because of the misspelling checking,  but cannot figure out how to use it in an Orbit app. Steve,  have you ever tried this before and do you have an example?
--
Regards,
Ryan

Sent from my tablet

On Nov 18, 2012 10:55 AM, "steve donovan" <[hidden email]> wrote:
On Sat, Nov 17, 2012 at 6:47 AM, Tangent 128 <[hidden email]> wrote:
> local _ENV = require"htmlua".new()
> return html {
>     body {
>         div {
>             class = "class",
>             p "Hello"
>         }
>     }
> }

This is also done in Orbit using a setfenv trick (it's called
'htmlification')  See the tutorial
http://keplerproject.github.com/orbit/example.html and look for
'Generating HTML'

In Penlight, pl.xml allows a similar trick, but the tags must all be
declared first. Otherwise it's too easy to generate bad HTML/XML with
spelling mistakes.

I do like the div.class {p"Hello"} notation you have.

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Jay Carlson
In reply to this post by Tangent 128
On Nov 16, 2012, at 11:47 PM, Tangent 128 wrote:

> Lua 5.2's _ENV functionality naturally expedites some fun syntax tricks;
> partly for a side project, and partly for the fun of it, I wrote a
> module that creates an _ENV object with a metatable to synthesize
> HTML-wrapping functions.

> Implementaion code at
> http://fossil.tangent128.name/LuaForum/artifact/adbc426fafc3cb1f37e0a1a2d7f4f50cc4a498c0

One very nice thing is that it produces correct HTML without any extra effort. Strings encountered during processing are considered to be...strings. There is a separate type for "HTML fragment" (a particular metatable) so you have to go out of your way to let people inject cross-side scripting. You mark strings with rawHTML() if you're willing to guarantee that what you're putting in is well-formed, properly quoted HTML.

I know the point was _ENV stuff, but entirely too much Web hackery requires special effort to keep these things straight, and I'm happy to see good examples.

There's still charset correctness to worry about, but standard Lua doesn't help much there (since C doesn't either).

OTOH, your example had a fun braino:

> do _ENV = htmlua
...
> end
> -- use tostring(result)

tostring(result) ->" <tostring>"..result.."</tostring>"
print(result) -> "<print>"..result.."</print>"

:-)
Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Rena

On 2012-11-18 6:03 PM, "Jay Carlson" <[hidden email]> wrote:
>
> On Nov 16, 2012, at 11:47 PM, Tangent 128 wrote:
>
> > Lua 5.2's _ENV functionality naturally expedites some fun syntax tricks;
> > partly for a side project, and partly for the fun of it, I wrote a
> > module that creates an _ENV object with a metatable to synthesize
> > HTML-wrapping functions.
>
> > Implementaion code at
> > http://fossil.tangent128.name/LuaForum/artifact/adbc426fafc3cb1f37e0a1a2d7f4f50cc4a498c0
>
> One very nice thing is that it produces correct HTML without any extra effort. Strings encountered during processing are considered to be...strings. There is a separate type for "HTML fragment" (a particular metatable) so you have to go out of your way to let people inject cross-side scripting. You mark strings with rawHTML() if you're willing to guarantee that what you're putting in is well-formed, properly quoted HTML.
>
> I know the point was _ENV stuff, but entirely too much Web hackery requires special effort to keep these things straight, and I'm happy to see good examples.
>
> There's still charset correctness to worry about, but standard Lua doesn't help much there (since C doesn't either).
>
> OTOH, your example had a fun braino:
>
> > do _ENV = htmlua
> ...
> > end
> > -- use tostring(result)
>
> tostring(result) ->" <tostring>"..result.."</tostring>"
> print(result) -> "<print>"..result.."</print>"
>
> :-)

An issue I've found with this idea though (really any HTML generator) is HTML is pretty silly. There are some tags that have to use short form, and some that can't:
<script src="foo.js" /> -- invalid, and browsers will treat this as an unclosed <script> that will eat the entire page
<br></br> -- invalid AFAIK, at least very silly.

The only solution I know of is to have a table listing what tags can't use short form, but I don't know them all. (I really wonder why there are any...)

p.s. another nice side effect of this type of HTML generation is, if you keep track of recursion depth, it's fairly simple to add the necessary whitespace to generate nicely indented readable code. But again HTML makes things a little more difficult, as adding whitespace can sometimes change the result... It's good for debugging the generated code at least.

Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Peter Cawley
On Mon, Nov 19, 2012 at 12:09 AM, Rena <[hidden email]> wrote:

An issue I've found with this idea though (really any HTML generator) is HTML is pretty silly. There are some tags that have to use short form, and some that can't:

<script src="foo.js" /> -- invalid, and browsers will treat this as an unclosed <script> that will eat the entire page
<br></br> -- invalid AFAIK, at least very silly.

The only solution I know of is to have a table listing what tags can't use short form, but I don't know them all. (I really wonder why there are any...)

A nicer solution is to emit XHTML, and do so along with suitable headers such that browsers don't try to treat it like HTML.
Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Rena
On Sun, Nov 18, 2012 at 7:20 PM, Peter Cawley <[hidden email]> wrote:

> On Mon, Nov 19, 2012 at 12:09 AM, Rena <[hidden email]> wrote:
>>
>> An issue I've found with this idea though (really any HTML generator) is
>> HTML is pretty silly. There are some tags that have to use short form, and
>> some that can't:
>>
>> <script src="foo.js" /> -- invalid, and browsers will treat this as an
>> unclosed <script> that will eat the entire page
>> <br></br> -- invalid AFAIK, at least very silly.
>>
>> The only solution I know of is to have a table listing what tags can't use
>> short form, but I don't know them all. (I really wonder why there are
>> any...)
>
> A nicer solution is to emit XHTML, and do so along with suitable headers
> such that browsers don't try to treat it like HTML.

Hm, I thought even that doesn't allow for short-form script tags.
Perhaps I used the wrong headers?

--
Sent from my Game Boy.

Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Javier Guerra Giraldez
In reply to this post by Rena
On Sun, Nov 18, 2012 at 7:09 PM, Rena <[hidden email]> wrote:
> An issue I've found with this idea though (really any HTML generator) is
> HTML is pretty silly. There are some tags that have to use short form, and
> some that can't:
> <script src="foo.js" /> -- invalid, and browsers will treat this as an
> unclosed <script> that will eat the entire page
> <br></br> -- invalid AFAIK, at least very silly.

oh, yes i hate that!

back when XHTML was 'the way to the future', i couldn't understand how
so many people actually defended that inconsistencies.

when XHTML died, a bit of my faith in humanity died with it.  :'-(

--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Daurnimator
In reply to this post by Rena
On 19 November 2012 11:09, Rena <[hidden email]> wrote:

On 2012-11-18 6:03 PM, "Jay Carlson" <[hidden email]> wrote:
>
> On Nov 16, 2012, at 11:47 PM, Tangent 128 wrote:
>
> > Lua 5.2's _ENV functionality naturally expedites some fun syntax tricks;
> > partly for a side project, and partly for the fun of it, I wrote a
> > module that creates an _ENV object with a metatable to synthesize
> > HTML-wrapping functions.
>
> > Implementaion code at
> > http://fossil.tangent128.name/LuaForum/artifact/adbc426fafc3cb1f37e0a1a2d7f4f50cc4a498c0
>
> One very nice thing is that it produces correct HTML without any extra effort. Strings encountered during processing are considered to be...strings. There is a separate type for "HTML fragment" (a particular metatable) so you have to go out of your way to let people inject cross-side scripting. You mark strings with rawHTML() if you're willing to guarantee that what you're putting in is well-formed, properly quoted HTML.
>
> I know the point was _ENV stuff, but entirely too much Web hackery requires special effort to keep these things straight, and I'm happy to see good examples.
>
> There's still charset correctness to worry about, but standard Lua doesn't help much there (since C doesn't either).
>
> OTOH, your example had a fun braino:
>
> > do _ENV = htmlua
> ...
> > end
> > -- use tostring(result)
>
> tostring(result) ->" <tostring>"..result.."</tostring>"
> print(result) -> "<print>"..result.."</print>"
>
> :-)

An issue I've found with this idea though (really any HTML generator) is HTML is pretty silly. There are some tags that have to use short form, and some that can't:
<script src="foo.js" /> -- invalid, and browsers will treat this as an unclosed <script> that will eat the entire page
<br></br> -- invalid AFAIK, at least very silly.

The only solution I know of is to have a table listing what tags can't use short form, but I don't know them all. (I really wonder why there are any...)

p.s. another nice side effect of this type of HTML generation is, if you keep track of recursion depth, it's fairly simple to add the necessary whitespace to generate nicely indented readable code. But again HTML makes things a little more difficult, as adding whitespace can sometimes change the result... It's good for debugging the generated code at least.

I coded a similar thing up a couple of years ago ( see http://daurnimator.com/post/603878464/html-generation-with-lua )
I've attached what I got up to (I think I called it 'crater'); I added checks in for all the corner cases. Consider it free/MIT.

htmlgen.lua (21K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

steve donovan
In reply to this post by Ryan Pusztai
On Sun, Nov 18, 2012 at 8:28 PM, Ryan Pusztai <[hidden email]> wrote:
> I would actually prefer Penlights implementation better because of the
> misspelling checking,  but cannot figure out how to use it in an Orbit app.
> Steve,  have you ever tried this before and do you have an example?

I haven't done it but it should work fine - the only thing you need to
do is pass the Penlight expression through a tostring, since it
returns a LOM representation rather than a string.  (Can adjust the
auto-indentation of course but it's tuned for XML data not markup)

In _principle_ building up the DOM using an intermediate LOM
representation and then converting to text should be more efficient,
but I haven't tested this.

As for the very cool 'div.class' notation, I think I might steal it ;)

steve d.

Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

William Ahern
In reply to this post by Javier Guerra Giraldez
On Sun, Nov 18, 2012 at 09:00:38PM -0500, Javier Guerra Giraldez wrote:

> On Sun, Nov 18, 2012 at 7:09 PM, Rena <[hidden email]> wrote:
> > An issue I've found with this idea though (really any HTML generator) is
> > HTML is pretty silly. There are some tags that have to use short form, and
> > some that can't:
> > <script src="foo.js" /> -- invalid, and browsers will treat this as an
> > unclosed <script> that will eat the entire page
> > <br></br> -- invalid AFAIK, at least very silly.
>
> oh, yes i hate that!
>
> back when XHTML was 'the way to the future', i couldn't understand how
> so many people actually defended that inconsistencies.
>
> when XHTML died, a bit of my faith in humanity died with it.  :'-(
>

I gave up on web programming years ago, after that debacle--when the XML
haters at WHATWG won the day. But I recently discovered that all the major
browsers now support XSL transformations, including IE, Chrome, Safari, and
Firefox. In fact, with the exception of Chrome, it works identically either
locally or remotely, which really eases development. Skechers.com is the
most prominent example. Plus, there's a half-hearted XHTML5 specification
which works just fine for the most part.

This has restored some of my faith. XSLT support appears to have stagnated,
but I'll be happy as long as it remains as-is.


Reply | Threaded
Open this post in threaded view
|

Re: HTML-generating _ENV

Tangent 128
In reply to this post by Jay Carlson
On 11/18/2012 06:02 PM, Jay Carlson wrote:

> One very nice thing is that it produces correct HTML without any extra
> effort. Strings encountered during processing are considered to
> be...strings. There is a separate type for "HTML fragment" (a
> particular metatable) so you have to go out of your way to let people
> inject cross-side scripting. You mark strings with rawHTML() if you're
> willing to guarantee that what you're putting in is well-formed,
> properly quoted HTML. I know the point was _ENV stuff, but entirely
> too much Web hackery requires special effort to keep these things
> straight, and I'm happy to see good examples. There's still charset
> correctness to worry about, but standard Lua doesn't help much there
> (since C doesn't either).

Yeah, a friend from the Ruby world looked at me pretty strongly until I
implemented that safety approach. :P

As for charsets... with proper webserver configuration, most people are
lucky enough these days to be able to simply insist on UTF-8. (unless
there are security risks beyond mojibake that hermetic handling of
strings won't mitigate? Would be interesting to hear about...)

> OTOH, your example had a fun braino:
>> do _ENV = htmlua
> ...
>> end
>> -- use tostring(result)
> tostring(result) ->" <tostring>"..result.."</tostring>"
> print(result) -> "<print>"..result.."</print>"
>
> :-)
I make a habit of fixing functions I use as locals for faux
optimization, works fine for me. ;)

~Joseph