# Xx-0.1.0 : xhtml and xml make it twice as dirty

**URL:** <https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089>\
**Category:** Ruby\
**Created:** [January 25, 2006, 12:24am UTC](https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089 "2006-01-25T00:24:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 25, 2006, 12:24am UTC](https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089/1 "2006-01-25T00:24:26Z")

</div>

NAME

xx - twice as dirty

SYNOPSIS

~ \> gem install “double x”

require “xx”

include XX::XHTML

doc = xhtml\_{  
html\_{  
head\_{ title\_{ " go xx! " } }  
body\_{ " one more and it would be illegal " }  
}  
}

URI

[http://rubyforge.org/frs/?group\_id=1024](http://rubyforge.org/frs/?group_id=1024)

DESCRIPTION

xx is a library designed to extend ruby objects with html, xhtml, and  
xml  
generation methods. the syntax provided by xx aims to make the  
generation of  
xml or xhtml as clean looking and natural as ruby it self.

the approach taken, that of extending objects, allows natural  
document  
generation while preserving access to instance data. in essence it  
provides  
ruby objects (including the top level ‘main’ object) an intuitive  
means to  
generate various markup views of their data in a way that is correct  
and  
elegant.

xx is brought to you by the good folks at [http://eparklabs.com](http://eparklabs.com).

SAMPLES

\<========\< sample/a.rb \>========\>

~ \> cat sample/a.rb

```
 require "xx"
 include XX::XHTML
 #
 # xx modules extend the current object to allow natural document 

```

markup  
#  
doc = xhtml\_{  
html\_{  
head\_{ title\_{ " go xx! " } }  
body\_{ " one more and it would be illegal " }  
}  
}  
puts doc.pretty

~ \> ruby sample/a.rb

```
     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

```

“[http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd](http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd)”\>  
  
  
 go xx!   
  
 one more and it would be illegal

\<========\< sample/b.rb \>========\>

~ \> cat sample/b.rb

```
 require "xx"
 #
 # xml is as easy as html. xx extends your object very carefully, 

```

adding an  
# one method that is not prefaced with ‘xx\_’ : ‘method\_missing’.  
the  
# method\_missing defined is conservatively, recognizing only  
methods that end  
# with underscore (‘\_’) as ‘tag’ methods intended to generate  
markup. as with  
# html, attributes may be passed to any tag method as either symbol  
or string.  
#

```
 class Table < ::Array
   include XX::XML
   attr "fields"
   def initialize *a, &b
     @fields = a.shift
     replace a
   end
   def self::[] *a, &b
     new *a, &b
   end
   def to_xml
     xml_{
       table_{
         each do |row|
           row_{
             fields.zip(row) do |field, value|
               field_(:name => field, 'width' => value.size){ value 

```

}  
end  
}  
end  
}  
}  
end  
end

```
 table = Table[
   %w( first_name last_name ssn ),
   %w( jane doe 424-24-2424 ),
   %w( john buck 574-86-4242 ),
 ]

 puts table.to_xml.pretty

```

~ \> ruby sample/b.rb

```
     <?xml version='1.0'?>
     <table>
       <row>
         <field name='first_name' width='4'>jane</field>
         <field name='last_name' width='3'>doe</field>
         <field name='ssn' width='11'>424-24-2424</field>
       </row>
       <row>
         <field name='first_name' width='4'>john</field>
         <field name='last_name' width='4'>buck</field>
         <field name='ssn' width='11'>574-86-4242</field>
       </row>
     </table>

```

\<========\< sample/c.rb \>========\>

~ \> cat sample/c.rb

```
 require "xx"
 #
 # xx makes it impossible to generate invalid (syntactically) 

```

invalid documents  
# - unless to instruct it in insert raw html or xml using the ‘h\_’  
or ‘x\_’  
# methods. text inserted with ‘t\_’ is automatically escaped. like  
all xx  
# methods these can have one or more underscores after them in case  
there is a  
# collision with another method or the tag ‘h’, ‘x’, or ‘t’ needs  
to be  
# generated.  
#  
include XX::XML

```
 doc = xml_{
   root_{
     div_{ t_ "this is escaped < > & text" }
     div_{ h_ "this is raw <html>. & is not escaped" }
     div_{ x_ "<raw> xml </raw>" }
     div_{ x_{ even_{ entire_{ documents_{ "nest" } } } } }
   }
 }
 puts doc.pretty

```

~ \> ruby sample/c.rb

```
     <?xml version='1.0'?>
     <root>
       <div>this is escaped &lt; &gt; &amp; text</div>
       <div>this is raw <html>. & is not escaped</div>
       <div><raw> xml </raw></div>
       <div><even><entire><documents>nest</documents></entire></even></div>
     </root>

```

\<========\< sample/d.rb \>========\>

~ \> cat sample/d.rb

```
 require "xx"
 #
 # xx has only a few methods which end in '_'. these methods, 

```

therefore, cannot  
# be used in conjuction with method\_missing to auto-generate tags.  
for those  
# methods a tag of the same method can be generated using and  
escaped form,  
# namely two or more underscores always mean ‘generate a tag’.  
those methods  
# are:  
#  
# - g\_  
# - text\_  
# - t\_  
# - h\_  
# - x\_  
# - c\_  
# - at\_  
# - att\_  
# - yat\_  
#  
include XX::XML

```
 doc = xml_{
   root_{

     t_{ "this is a text element" }
     t __{ "this is not text, but a__ tag__ called t" }

     x_{ "this un-escaped & < > stuff" }
     x__{ "this is not un-escaped & < > stuff but a tag called x" }
   }
 }
 puts doc.pretty

```

~ \> ruby sample/d.rb

```
     <?xml version='1.0'?>
     <root>this is a text element<t>this is not text, but a __tag__ 

```

called tthis un-escaped & \< \> stuffthis is not un-escaped &  
\< \> stuff but a tag called x

HISTORY

0.1.0:  
- added the “g\_” method, which generates any tag  
^  
g\_(“anytag”, “key” =\> “value”){ b\_{ “bold” } }

```
 - added at_ and att_ methods to parse yaml and k=v strings as 

```

hashes.

```
     at_("src : image.jpg, width : 100%")

       #=> {"src"=>"image.jpg", "width"=> "100%"}

```

0.0.0:  
- initial version

AUTHORS

dan fitzpatrick [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
ara.t.howard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

BUGS

please send bug reports to /dev/null. patches to addresses above.  
😉

LICENSE

ePark Labs Public License version 1 Copyright (c) 2005, ePark Labs,  
Inc. and  
contributors All rights reserved.

Redistribution and use in source and binary forms, with or without  
modification, are permitted provided that the following conditions  
are met:

```
 1. Redistributions of source code must retain the above copyright 

```

notice,  
this list of conditions and the following disclaimer.

```
 2. Redistributions in binary form must reproduce the above 

```

copyright notice,  
this list of conditions and the following disclaimer in the  
documentation  
and/or other materials provided with the distribution.

```
 3. Neither the name of ePark Labs nor the names of its contributors 

```

may be  
used to endorse or promote products derived from this software  
without  
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  
“AS IS”  
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  
THE  
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
PURPOSE ARE  
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE  
LIABLE  
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  
CONSEQUENTIAL  
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE  
GOODS OR  
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  
HOWEVER  
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  
LIABILITY,  
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF  
THE USE  
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

enjoy.

-a

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 25, 2006, 1:12am UTC](https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089/2 "2006-01-25T01:12:51Z")

</div>

Quoting “Ara.T.Howard” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> doc = xhtml\_{  
> html\_{  
> head\_{ title\_{ " go xx! " } }  
> body\_{ " one more and it would be illegal " }  
> }  
> }

Out of curiousity, how does this compare with markaby?

-mental

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 25, 2006, 1:31am UTC](https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089/3 "2006-01-25T01:31:00Z")

</div>

removed\_email\_address@domain.invalid wrote:

> Out of curiousity, how does this compare with markaby?

Or the XML Builder in Nitro, which has a similar syntax?

James

–  
James B.

[http://www.ruby-doc.org](http://www.ruby-doc.org) - Ruby Help & Documentation  
[Ruby Code & Style](http://www.artima.com/rubycs/) - The Journal By & For Rubyists  
[http://www.rubystuff.com](http://www.rubystuff.com) - The Ruby Store for Ruby Stuff  
[http://www.jamesbritt.com](http://www.jamesbritt.com) - Playing with Better Toys  
[http://www.30secondrule.com](http://www.30secondrule.com) - Building Better Tools

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 25, 2006, 4:46am UTC](https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089/4 "2006-01-25T04:46:53Z")

</div>

removed\_email\_address@domain.invalid wrote:

> On Wed, 25 Jan 2006, James B. wrote:
> 
> > removed\_email\_address@domain.invalid wrote:  
> > …

> in the nitro and rails xml builders - they make debugging an absolute  
>   
> Thanks for the details. This looks really quite slick.

James

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 25, 2006, 3:04am UTC](https://www.ruby-forum.com/t/xx-0-1-0-xhtml-and-xml-make-it-twice-as-dirty/53089/5 "2006-01-25T03:04:31Z")

</div>

On Wed, 25 Jan 2006, James B. wrote:

> > Out of curiousity, how does this compare with markaby?
> 
> Or the XML Builder in Nitro, which has a similar syntax?

hmm. i think the implimentation is better 😉

seriously - i have a big problem with blanket method\_missing like those  
used  
in the nitro and rails xml builders - they make debugging an absolute  
nightmare that reminds me of perl. by using a simple rule : tag methods  
end  
in underscore, i can delegate to the default method missing in cases  
where a  
mere typo was made. eg. in nitro

foo

will output

but not in xx. you have to be explicit that you need to generate a tag  
using

foo\_{ 42 }

which will generate

42

also, the return value of blocks do not appear to be used very well in  
nitro  
(i could be wrong here). my reading of the docs seems to suggest that

foo{ 42 }

would output simply

in xx this outputs

42

as you would expect.

again, alot of this revolves around handling method\_missing in a  
catch-all  
fashion. because the handling is so generic in nitro’s xml builder it  
is  
un-suitable to mixin to your own classes, let alone built-in ones. with  
‘xx’  
this is not so - the library is quite carefully designed to pollute the  
includee (is that a word?) namespace minimally and certainly will not  
hide  
errors or, worse, simply output xml/xhtml when a typo is made. this is  
all  
possible due to the requirement that tag methods end in underscore.

xx handles both xml, xhtml, and xhtml. for all of them you will be hard  
pressed to generate invalid documents - generating end tags is not  
supported  
because it is always done for you in a sensible way.

lastly - ‘xx’ generates xhtml in a way that should be friendly to IE -  
something which is harder than it ought to be. i can thank sean (rexml)  
for  
that!

cheers.

-a
