[LRUG] DSLs for newbies: HTML generation (discuss)
Roland Swingler
roland.swingler at gmail.com
Thu Dec 10 06:19:08 PST 2009
or erector
http://erector.rubyforge.org
On Thu, Dec 10, 2009 at 2:17 PM, Glenn Gillen <glenn at rubypond.com> wrote:
> Or Markaby:
>
> http://markaby.rubyforge.org/
>
> On 10 Dec 2009, at 13:56, Alex Graul wrote:
>
>> That's very close to the syntax of Builder, see http://builder.rubyforge.org/
>>
>> Cheers,
>> Alex
>>
>> On 10 Dec 2009, at 13:49, Daniel Barlow wrote:
>>
>>> I'm playing with Ruby for the first time (pretty much) and having seen haml I thought it would be fun to play with alternate syntaxes. This one has much less in the way of funny characters (% and #) and isn't whitespace-sensitive
>>>
>>> It's probably also a really dumb idea. Like I say, first time Ruby programmer. Anyway, here's a motivating example of its use
>>>
>>> h=HTML.new
>>> def h.content
>>> html do
>>> head { title(:id=>123) {"My page title" }}
>>> body do
>>> div do
>>> h1(:class => "fancy_formatted") {"hello world"}
>>> text "some stuff","more stuff"
>>> ul {
>>> %w(red orange yellow green blue indigo violent).map {|name|
>>> li { text name }
>>> }
>>> }
>>> end
>>> end
>>> end
>>> end
>>> h.output
>>>
>>> It's all valid Ruby code. There is a method (implemented with method_missing) for each HTML element: when called it expects HTML arguments as attributes and a block of element content: it outputs the markup for the start-tag/end-tag and calls the block.
>>>
>>> Inside the block you can call more element-making methods, and/or you can call #text (as shown) to output plain text, and/or you can return some (preferably string) value which will also be output as if by #text
>>>
>>> So,
>>> - a neat hack?
>>> - an offence against (your choice of) god?
>>> - dull and unoriginal and every other newbie did exactly the same thing when learning?
>>> - really ugly ruby style?
>>>
>>> All criticism welcome. I'm a Lisp programmer in my day job, so I've almost certainly heard worse.
>>>
>>> Oh, the implementation? The HTML it generates is not entirely valid (attribute quoting and empty elements are two obvious omissions: introducing all that whitespace, I hazily remember from reading SGML specs back in the day, is probably also wrong) and indenting is hacky, but you get the gist. It's more about proof-of-concept and playing with the DSL syntax at this stage than production-quality output
>>>
>>> Is Hash.map supposed to work like that, or is it accidental? It's dashed useful, that I will say
>>>
>>> ---cut here---
>>> class HTML
>>> # this is a partial list for testing, and obviously needs to
>>> # be extending to all tags in whatever version of HTML you want
>>> # to produce
>>> @@allowed_tags=%w(html head title body h1 h2 h3 h4 h5 h6
>>> p div span ul li).map {|n| n.to_sym}
>>>
>>> def texts(stuff)
>>> stuff and
>>> stuff.each {|x| x and @content << ("\n"+(" " * @indent)+x) }
>>> nil
>>> end
>>>
>>> def text(*stuff)
>>> texts stuff
>>> end
>>>
>>> def method_missing(name,*args,&body)
>>> if @@allowed_tags.member?(name)
>>> attributes = args[0] || [];
>>> text "<#{name}"+attributes.map {|k,v| " "+k.to_s+"="+v.to_s }.to_s + ">"
>>> @indent=@indent+4;
>>> texts body.call
>>> @indent=@indent-4;
>>> text "</#{name}>"
>>> else
>>> super # not on our list, let it raise UndefinedMethodError
>>> end
>>> end
>>>
>>> def output
>>> @content=[]
>>> @indent=0
>>> content
>>> print @content
>>> puts
>>> end
>>> end
>>> ---cut here---
>>> _______________________________________________
>>> Chat mailing list
>>> Chat at lists.lrug.org
>>> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>>
>> _______________________________________________
>> Chat mailing list
>> Chat at lists.lrug.org
>> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
More information about the Chat
mailing list