[ANN] tagz-5.0.0

*brain asplodes*

···

On Mar 25, 2009, at 08:39 , Tim Pease wrote:

Set the $KCODE and use a unicode character as the separator for namespaces ...

$KCODE = 'u'
foo¦bar_('bar:foo' => 42) #=> "<foo:bar bar:foo=\"42\">"

wow.

clever!

a @ http://codeforpeople.com/

···

On Mar 25, 2009, at 9:39 AM, Tim Pease wrote:

Set the $KCODE and use a unicode character as the separator for namespaces ...

$KCODE = 'u'
foo¦bar_('bar:foo' => 42) #=> "<foo:bar bar:foo=\"42\">"

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

I think in order to do namespaces correctly, you'd still need some kind
of registry, and some way to control emitting the namespace declarations
and prefixes at the right time.

There would still be times when you'd want to suppress it (like the
default case), but at the "top" of the relevant element (like the
document's root node), you'd want to be able to have it emit the
declarations.

Of course, (really dreaming now), but it would be _really_cool_ if it
could manage the nested scopes automatically and ensure that you'd spit
out all of the required namespaces used by all of the nested scopes....

I know I'm not making your day here... :slight_smile:

···

On Thu, 2009-03-26 at 09:16 +0900, ara.t.howard wrote:

On Mar 25, 2009, at 9:21 AM, James Gray wrote:

> It might be neat to add some more dynamic method magic for this, like:
>
> foo_in_bar_ { … }
>
> I realize that's a bad example in case you really have a tag with
> that name, but you get the idea.

i actually did that with xx at one point.

i think that, or some proxy object is the way to go.

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

> Thanks.
>
> If you had to register the namespaces first in some kind of tagz
> registry, maybe you could do something by handling the NameError when
> you did:
>
> foo.bar_('bar:foo' => 42)
>
> If it had registered a namespace prefix of foo, then it'd just "do the
> right thing", otherwise, you'd get the normal name error. This would
> probably be the most logical syntax, but it's way beyond my Ruby
> magical
> abilities to figure out how to actually make it work.
>
> Still, I think it'd be the most readable of the proposed approaches...
> I don't want to have to find unicode characters on my keyboard! :slight_smile:
>
> Cheers,

how about this

I like it, but would change it a bit to allow you to initialize the
namespace URI. Not sure what you'd do with a default namespace
declaration...

cfp:~ > cat a.rb
require 'rubygems'
require 'tagz'

class Namespace
   def initialize(nsuri) &block

       @nsuri = nsuri

     @ns = block.call.to_s
     @context = block
     @self = eval 'self', block
   end

   instance_methods.each{|m| undef_method if m[%r/__/]}

   def method_missing m, *a, &b
     if m.to_s[%r/^_|_$/]
       @self.send("#{ @ns }:#{ m }", *a, &b)
     else
       "#{ @ns }:#{ m }"
     end
   end
end

include Tagz.globally

a = Namespace.new(".."){ :a }
b = Namespace.new(".."){ :b }

xml =
   a.root_(emit_nsuri => true, include_children => true) {
     a.foo_(b.bar => 'bar'){ 'content' }
     b.bar_(a.foo => 'foo'){ 'content' }
   }

puts xml

cfp:~ > ruby a.rb
<a:root xmlns:a="..." xmlns:b="..."><a:foo b:bar="bar">content</a:foo><b:bar a:foo="foo">content</
b:bar></a:root>

What do you think?

···

On Thu, 2009-03-26 at 09:30 +0900, ara.t.howard wrote:

On Mar 25, 2009, at 2:17 PM, Andrew S. Townley wrote:

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

Apologies. Forgot to say thanks for your help. Your suggestion is
probably good enough for what I need to do, and I can try to manage the
namespace declarations manually somehow, or actually implement part of
what I suggested.

Looking forward to getting started with tagz!

Cheers,

ast

···

On Thu, 2009-03-26 at 09:30 +0900, ara.t.howard wrote:

how about this

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

it's fairly fast, but not as fast as erb.

it's faster that builder or rexml for xml though.

i actually find mixing erb and tagz is the best approach. my erb templates are generally < 100 lines and look something like

<title> foobar </title>

<%=

   ul_(:class => 'pretty'{
     @records.each do |record|
       li_{ record.name }
     end
   }

%>

in erb...

when that gets to ugly i factor or helpers that look like this

def the_list
   ul_(:class => 'pretty'{
     @records.each do |record|
       li_{ record.name }
     end
   }
end

and then tagz really starts to shine - you can stay in erb for the designer friendly bits and use straight tagz or factored out tagz for the logic bits.

cheers.

a @ http://codeforpeople.com/

···

On Mar 26, 2009, at 4:47 PM, jonty wrote:

I have been using haml out of necessity recently (sinatra), erb is too much like hard work.
I find that haml is deeply frustrating as getting the whitespace right to nest things properly is, quite frankly, a pain.
Markaby used the right sort of syntax I think and therefore I am mightily intrigued by Tagz.

Is it fast??

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

http://blog.zenspider.com/2009/02/tagz-vs-markabybuilderhamlerub.html

···

On Mar 26, 2009, at 15:47 , jonty wrote:

I have been using haml out of necessity recently (sinatra), erb is too much like hard work.
I find that haml is deeply frustrating as getting the whitespace right to nest things properly is, quite frankly, a pain.
Markaby used the right sort of syntax I think and therefore I am mightily intrigued by Tagz.

Is it fast??

i use that actually - but it really really crawls on large xml docs with syntax hl off. with tagz you just need a { another } and then to bounce on the % key.

a @ http://codeforpeople.com/

···

On Mar 24, 2009, at 11:09 AM, Martin DeMello wrote:

matchit.vim :slight_smile:

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Sorry, I knew about this approach and was avoiding it. I think it was
the term "globally" that had me scared off. This usually means, uh,
globally. But thanks to your hint, I see it is just an include like any
other. So what I really want to do is more like this:

yeah. i means 'globally' in the target scope. aka - a_{} works outside the tagz{} context

b = BindingMaker.new
class << b; include Tagz.globally; end

This way I can use Tagz in that instance of the BindingMaker and nothing
else in my universe is affected. This should be perfect! Thx for the
nudge - m.

clever!

a @ http://codeforpeople.com/

···

On Mar 24, 2009, at 12:46 PM, matt neuburg wrote:
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

FYI, you could do this instead:

  b.extend(Tagz.globally)

Regards,
Sean

···

On Tue, Mar 24, 2009 at 6:46 PM, matt neuburg <matt@tidbits.com> wrote:

b = BindingMaker.new
class << b; include Tagz.globally; end

if that's the case i might roll something like that into tagz.

i'll post any other ideas i have here - really appreciate the feedback!

cheers.

a @ http://codeforpeople.com/

···

On Mar 26, 2009, at 5:43 AM, Andrew S. Townley wrote:

Apologies. Forgot to say thanks for your help. Your suggestion is
probably good enough for what I need to do, and I can try to manage the
namespace declarations manually somehow, or actually implement part of
what I suggested.

Looking forward to getting started with tagz!

Cheers,

ast

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Have tried it out this morning - I am delighted with it - natural ruby style, fast (see
http://blog.zenspider.com/2009/02/tagz-vs-markabybuilderhamlerub.html )

Is there a forum / user group or anything for it? I spotted one or two issues I'd like to discuss somewhere
is this list the best place?

Getting it to work with Sinatra was interesting - I had to setup ruby methods as views, because it is not yet incorporated
as a templating engine by Sinatra, but that works fine. Any plans to fit it into Sinatra like the other templating engines?

But many thanks Ara.

ara.t.howard wrote:

···

On Mar 26, 2009, at 4:47 PM, jonty wrote:

I have been using haml out of necessity recently (sinatra), erb is too much like hard work.
I find that haml is deeply frustrating as getting the whitespace right to nest things properly is, quite frankly, a pain.
Markaby used the right sort of syntax I think and therefore I am mightily intrigued by Tagz.

Is it fast??

it's fairly fast, but not as fast as erb.

it's faster that builder or rexml for xml though.

i actually find mixing erb and tagz is the best approach. my erb templates are generally < 100 lines and look something like

<title> foobar </title>

<%=

  ul_(:class => 'pretty'{
    @records.each do |record|
      li_{ record.name }
    end
  }

%>

in erb...

when that gets to ugly i factor or helpers that look like this

def the_list
  ul_(:class => 'pretty'{
    @records.each do |record|
      li_{ record.name }
    end
  }
end

and then tagz really starts to shine - you can stay in erb for the designer friendly bits and use straight tagz or factored out tagz for the logic bits.

cheers.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

if that's the case i might roll something like that into tagz.

That would be fantastic.

i'll post any other ideas i have here - really appreciate the feedback!

I'm looking at trying to figure out how to do the emit stuff, and I
think that the Namespace class should certainly be part of Tagz.

New would do something similar to your example, but with also adding the
Namespace URI, e.g. (example from
http://www.w3schools.com/Xforms/xforms_namespace.asp\)

include Tagz.globally

xhtml = Tagz::Namespace.new(:xhtml => "http://www.w3.org/1999/xhtml&quot;\)
xf = Tagz::Namespace.new(:xf => "http://www.w3.org/2002/xforms&quot;\)

etc.

I tried to do this based on the example you provided, but I'm getting an
error I don't understand. I'm sure it's due to scoping issues, but I've
no idea how to fix it.

I also discovered that output of empty elements doesn't behave as I'd
expect. If you do

empty_element_

you get "<empty_element>"

rather than "<empty_element/>"

I think this can be fixed easily with a check to see if the value of
tagz is empty on line 62.

Any ideas as to what's going on?

excalibur$ cat /tmp/a.rb
require 'rubygems'
require 'tagz'

class Namespace
  def initialize hash, &block
     @prefix, @uri = hash.inject() { |a, (k, v)| a << k << v }
     @context = block
     @self = eval 'self', block
  end

  instance_methods.each{|m| undef_method if m[%r/__/]}

  def emit_ns
    { "xmlns:#{ @prefix }".to_sym => "#{@uri}" }
  end

  def method_missing m, *a, &b
    if m.to_s[%r/^_|_$/]
      @self.send("#{ @prefix }:#{ m }", *a, &b)
    else
      "#{ @prefix }:#{ m }"
    end
  end
end

include Tagz.globally

xhtml = Namespace.new(:xhtml => "http://www.w3.org/1999/xhtml&quot;\)
xf = Namespace.new(:xf => "http://www.w3.org/2002/xforms&quot;\)

puts xhtml.emit_ns.inspect
puts xf.emit_ns.inspect

# BUG!!
puts empty_element_

doc =
  xhtml.html_(xhmtl.emit_ns, xf.emit_ns) {
    xhtml.head_{
       xhtml.title_ "Important Document"
       xf.model_{
         xf.instance_{
           person_{
             fname_
             lname_
           }
         }
       }
       xf.submission(:id => "form1", :method => "get", :action => "doit.jsp")
    }
    xhtml.body_{
      "..."
    }
  }
excalibur$ ruby /tmp/a.rb
{:"xmlns:xhtml"=>"http://www.w3.org/1999/xhtml&quot;\}
{:"xmlns:xf"=>"http://www.w3.org/2002/xforms&quot;\}
<empty_element>
/tmp/a.rb:38: undefined local variable or method `xhmtl' for #<Object:0x7f1e7ce77358 @tagz=nil> (NameError)

···

On Fri, 2009-03-27 at 02:28 +0900, ara.t.howard wrote:

On Mar 26, 2009, at 5:43 AM, Andrew S. Townley wrote:

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

Apologies for the typo earlier. I think I have it mostly working now,
but it would need a couple of changes in Tagz to do what I want with the
ns declarations and to fix the empty element handling.

Here's the examples:

cat /tmp/a.rb
require 'rubygems'
require 'tagz'

class Namespace
  def initialize hash, &block
    if hash.is_a? Hash
      @prefix, @uri = hash.inject([]) { |a, (k, v)| a << k << v }
    else
      @prefix = nil
      @uri = hash
    end
    @context = block
    @self = eval 'super()', block
  end

  instance_methods.each{|m| undef_method if m[%r/__/]}

  def emit_ns
    if !@prefix.nil?
      return { "xmlns:#{ @prefix }".to_sym => @uri }
    else
      return { :xmlns => @uri }
    end
  end

  def method_missing m, *a, &b
    if m.to_s[%r/^_|_$/] && !@prefix.nil?
      @self.send("#{ @prefix }:#{ m }", *a, &b)
    else
      if @prefix.nil?
        "#{ super }"
      else
        "#{ @prefix }:#{ m }"
      end
    end
  end

end

include Tagz.globally

xhtml = Namespace.new(:xhtml => "http://www.w3.org/1999/xhtml")
xf = Namespace.new(:xf => "http://www.w3.org/2002/xforms")
default = Namespace.new("http://www.w3.org/1999/xhtml")

puts xhtml.emit_ns.inspect
puts xf.emit_ns.inspect
puts default.emit_ns.inspect

xml =
  default.html_(default.emit_ns) {
    a_ "link", :href => "uri"
  }

puts "\nDefault namespace example"
puts xml
puts

# BUG!!
puts empty_element_

xml =
  xhtml.html_{
    xhtml.foo_(xhtml.bar => 'bar') { 'content' }
    xf.bar_(xf.foo => 'foo') { 'content' }
  }

puts
puts xml

nsdecls = xhtml.emit_ns.merge xf.emit_ns
puts nsdecls.inspect

a = Namespace.new(:a => "uri_a")
simple =
doc =
# want to do this:
# xhtml.html_(xhtml.emit_ns, xf.emit_ns) {
  xhtml.html_(nsdecls) {
    xhtml.head_{
       xhtml.title_ "Important Document"
       xf.model_{
         xf.instance_{
           person_{
             fname_
             lname_
           }
         }
       }
       xf.submission(:id => "form1", :method => "get", :action =>
"doit.jsp")
    }
    xhtml.body_{
      "..."
    }
  }

puts "\nXForms example"
puts doc

excalibur$ ruby /tmp/a.rb
{:"xmlns:xhtml"=>"http://www.w3.org/1999/xhtml"}
{:"xmlns:xf"=>"http://www.w3.org/2002/xforms"}
{:xmlns=>"http://www.w3.org/1999/xhtml"}

Default namespace example
<html xmlns="http://www.w3.org/1999/xhtml"><a href="uri">link</a></html>

<empty_element>

<xhtml:html><xhtml:foo xhtml:bar="bar">content</xhtml:foo><xf:bar
xf:foo="foo">content</xf:bar></xhtml:html>
{:"xmlns:xhtml"=>"http://www.w3.org/1999/xhtml", :"xmlns:xf"=>"http://www.w3.org/2002/xforms"}

XForms example
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"><xhtml:head><xhtml:title>Important Document</xhtml:title><xf:model><xf:instance><person><fname><lname></person></xf:instance></xf:model></xhtml:head><xhtml:body>...</xhtml:body></xhtml:html>

···

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

this by design.

it's a false assumption that one never needs to separate opening and ending tags wrt to scopes

(from the samples)

     <========< samples/d.rb >========>

   ~ > cat samples/d.rb

···

On Mar 27, 2009, at 5:16 AM, Andrew S. Townley wrote:

I also discovered that output of empty elements doesn't behave as I'd
expect. If you do

empty_element_

you get "<empty_element>"

rather than "<empty_element/>"

     #
     # tagz.rb doesn't cramp your style, allowing even invalid html to be
     # generated. note the use of the 'tagz' method, which can be used both to
     # capture output and to append content to the top of the stack.
     #

     require 'tagz'
     include Tagz.globally

     def header
       tagz{
         html_
           body_(:class => 'ninja-like', :id => 'giraffe-slayer')

           ___ "<!-- this is the header -->"

             div_(:class => 'content')
       }
     end

     def footer
       tagz{
         ___ "<!-- this is the footer -->"

             _div
           _body
         _html
       }
     end

     puts header, footer

   ~ > ruby samples/d.rb

     <html><body class="ninja-like" id="giraffe-slayer">
     <!-- this is the header -->
     <div class="content">

     <!-- this is the footer -->
     </div></body></html>

however, one can use a bang to indicate a tag should be close even if it has not content

cfp:~/src/ruby/tagz/tagz-5.1.0 > ruby -r tagz -e 'puts Tagz{ element_! }'
<element/>

alternatively you can pass an empty block, which is the style i prefer

cfp:~/src/ruby/tagz/tagz-5.1.0 > ruby -r tagz -e 'puts Tagz{ element_{} }'
<element/>

i'll look into your namespace stuff.

cheers.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

>
> I also discovered that output of empty elements doesn't behave as I'd
> expect. If you do
>
> empty_element_
>
> you get "<empty_element>"
>
> rather than "<empty_element/>"

this by design.

Fair enough.

it's a false assumption that one never needs to separate opening and
ending tags wrt to scopes

It wasn't an assumption I was making. The assumption I *was* making was
that the library was biased to ensuring you had well-formed & correct
mark-up. To me, I'd see the need to separate scopes to be something I'd
want to explicitly request rather than the other way around.

Not a big deal now that I know about the bang operator.

Cheers,

ast

···

On Fri, 2009-03-27 at 23:41 +0900, ara.t.howard wrote:

On Mar 27, 2009, at 5:16 AM, Andrew S. Townley wrote:

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

there is actually one other important usecase br_ etc, and other html4 tags. just fyi.

a @ http://codeforpeople.com/

···

On Mar 27, 2009, at 8:53 AM, Andrew S. Townley wrote:

It wasn't an assumption I was making. The assumption I *was* making was
that the library was biased to ensuring you had well-formed & correct
mark-up. To me, I'd see the need to separate scopes to be something I'd
want to explicitly request rather than the other way around.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

Who uses HTML4 anymore??? :wink:

..maybe an XML vs. HTML mode to switch them?

but I take your point.

···

On Sat, 2009-03-28 at 02:42 +0900, ara.t.howard wrote:

On Mar 27, 2009, at 8:53 AM, Andrew S. Townley wrote:

> It wasn't an assumption I was making. The assumption I *was* making
> was
> that the library was biased to ensuring you had well-formed & correct
> mark-up. To me, I'd see the need to separate scopes to be something
> I'd
> want to explicitly request rather than the other way around.

there is actually one other important usecase br_ etc, and other
html4 tags. just fyi.

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org

Actually, there are enough reasons for sticking with HTML. Especially interesting is the point how most Browsers consume XHTML, to be found in [1], section "HTML-compatible XHTML".

Regards,
Florian

[1]: Understanding HTML, XML and XHTML | WebKit

···

On Mar 27, 2009, at 7:03 PM, Andrew S. Townley wrote:

Who uses HTML4 anymore??? :wink:

--
Florian Gilcher

smtp: flo@andersground.net
jabber: Skade@jabber.ccc.de
gpg: 533148E2

Hi Florian,

I hadn't seen this article, but I'm quite familiar with the differences.
Generating (X)HTML with Tagz will be handy, but it isn't my primary
interest.

I want a really slick tool/syntax for generating complex XML documents
using multiple namespaces and processing instructions. I've been doing
this in various ways for several years, and nearly all of them suck --
equally and in different ways.

One of the things I used to sorta like was Jakarta's Element
Construction Set (ECS), but it was more complicated than it needed to
be because of Java's syntax issues. I've also tried custom templates,
various approaches to fragments, various templating languages, etc.,
etc....

Tagz is the first thing I've seen (accidentally, I might add) that
finally allowed me to write quasi-markup in code vs. the other way
around. It's also quite timely, because I once again need to generate a
bunch of XML, but this time I'm using Ruby and it's looking like I'll be
adopting Tagz across the board for what I'm doing.

I'd already started doing embedded mark-up and was thinking about trying
to fold in one of the template engines. Then I saw Ara's announcement
and thought "Hallelujah! At last, a decent syntax for doing this!"

Hopefully, the namespace PI stuff will make it into an official release
at some stage. I can live with the (from an XML perspective) backwards
view of element closure, because I understand where Ara (and probably
most of you) are coming from and what the main interest in a library
like this is.

As sick as it is, thanks to Tagz, I'm actually sorta excited about
writing code to generate XML instead of feeling the usual sense of
tedium, dread and pending frustration.

If I ever meet Ara, I'm buying him a pint! :slight_smile:

Cheers,

ast

···

On Sat, 2009-03-28 at 03:12 +0900, Florian Gilcher wrote:

On Mar 27, 2009, at 7:03 PM, Andrew S. Townley wrote:
>
> Who uses HTML4 anymore??? :wink:

Actually, there are enough reasons for sticking with HTML. Especially
interesting is the point how most Browsers consume XHTML, to be found
in [1], section "HTML-compatible XHTML".

--
Andrew S. Townley <ast@atownley.org>
http://atownley.org