# Xx-2.1.0

**URL:** <https://www.ruby-forum.com/t/xx-2-1-0/86728>\
**Category:** Ruby\
**Created:** [February 25, 2007, 3:13am UTC](https://www.ruby-forum.com/t/xx-2-1-0/86728 "2007-02-25T03:13:52Z")\
**Posts on this page:** 3\
**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:** [February 25, 2007, 3:13am UTC](https://www.ruby-forum.com/t/xx-2-1-0/86728/1 "2007-02-25T03:13:52Z")

</div>

NAME

xx

SYNOPSIS

xhtml and xml generation =\> twice as dirty!

USAGE

require “xx”

include XX::XHTML

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

puts doc

INSTALL

harp:~ \> gem install “double x”

URIS

[http://rubyforge.org/projects/codeforpeople/](http://rubyforge.org/projects/codeforpeople/)  
hhtp://codeforpeople.com/xx/

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 itself, while  
still  
being entirely robust and safe.

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) mixin ability 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).

HISTORY

2.1.0:  
- introduction of XX::Template (see samples h,i,j)  
- fixed and indentation bug (too much)

SAMPLES

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

~ \> cat samples/a.rb

```
 require "xx"
 include XX::XHTML
 #
 # xx modules extend any object with natural document markup 

```

methods. the  
# special ‘tag\_name\_(attributes){ block }’ is a bit odd first but,  
as you will  
# see, has many important properties  
#

```
 puts xhtml_{
   html_{
     head_{ title_{ " go xx! " } }
     body_{ " one more 'x' and it would be illegal " }
   }
 }

```

~ \> ruby samples/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 'x' and it would be illegal

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

~ \> cat samples/b.rb

```
 require "xx"
 #
 # xx doesn't name clash
 #
 class C
   include XX::XHTML

   attr 'body'

   def initialize
     @body = 'body'
   end

   def to_html
     xhtml_{ html_{ body_{ body } } }
   end
 end

 puts C.new.to_html

```

~ \> ruby samples/b.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)”\>  
  
body

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

~ \> cat samples/c.rb

```
 require "xx"
 #
 # no reserved words prohibiting tags - oh, and xml too. also note 

```

the  
# blockless form of tag generation which is also supported  
#  
class C  
include XX::XML

```
   attr 'table'

   def initialize
     @table = %w( a b c ), %w( 1 2 3 )
   end

   def to_xml
     xml_{
       class_{ self.class }
       object_id_{ 42 }
       send_ 'send'
       exit_ 'exit'

       table_{
         table.each do |row|
           tr_{
             row.each do |cell|
               td_ cell
             end
           }
         end
       }
     }
   end
 end

 puts C.new.to_xml.pretty # auto indentation with 'pretty'

```

~ \> ruby samples/c.rb

```
 <?xml version='1.0'?>
 <class>C<object_id>42</object_id>
   <send>send</send>
   <exit>exit</exit>
   <table>
     <tr>
       <td>a</td>
       <td>b</td>
       <td>c</td>
     </tr>
     <tr>
       <td>1</td>
       <td>2</td>
       <td>3</td>
     </tr>
   </table>
 </class>

```

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

~ \> cat samples/d.rb

```
 require "xx"
 #
 # the brackets make it dang easy to bounce on the '%' key (or 

```

whatever key  
# matches braces in your editor) to balance tags. and the phrase  
‘\_{’ is very  
# useful for searching huge doccuments for tag generation methods  
#  
class C  
include XX::XML

```
   def to_xml
     xml_{ a_{ b_{ c_{ d_{ e_{ f_{ ' but am i balanced? ' }}}}}}} 

```

# vim will tell you!

```
   end
 end

 puts C.new.to_xml

```

~ \> ruby samples/d.rb

```
 <?xml version='1.0'?><a><b><c><d><e><f> but am i balanced? 

```

\<========\< samples/e.rb \>========\>

~ \> cat samples/e.rb

```
 require "xx"
 #
 # the handy '_' method can bail you out when your tags aren't valid 

```

ruby  
# syntax  
#

```
 include XX::XML

 puts xml_{ _('mething missing is cool'){ 'but not always the best 

```

fit’ } }

~ \> ruby samples/e.rb

```
 <?xml version='1.0'?><mething missing is cool>but not always the 

```

best fit\</mething missing is cool\>

\<========\< samples/f.rb \>========\>

~ \> cat samples/f.rb

```
 require "xx"
 #
 # '_' really bails you out for namespaces
 #
 module Furniture
   class Table
     include XX::XML

     attr 'legs'

     def initialize
       @legs = %w[1 2 3 4]
     end

     def to_xml
       xml_{
         _('furniture:table', 'xmlns:f' => 

```

‘[http://www.w3schools.com/furniture](http://www.w3schools.com/furniture)’){  
legs.each{|leg|  
\_(‘furniture:leg’){ “leg #{ leg }” }  
}  
}  
}  
end  
end  
end

```
 #
 # xml types don't get formatted by default - use pretty for that
 #
 puts Furniture::Table.new.to_xml.pretty

```

~ \> ruby samples/f.rb

```
 <?xml version='1.0'?>
 <furniture:table xmlns:f='http://www.w3schools.com/furniture'>
   <furniture:leg>leg 1</furniture:leg>
   <furniture:leg>leg 2</furniture:leg>
   <furniture:leg>leg 3</furniture:leg>
   <furniture:leg>leg 4</furniture:leg>
 </furniture:table>

```

\<========\< samples/g.rb \>========\>

~ \> cat samples/g.rb

```
 require "xx"
 #
 # there are bunch of shorthand methods - each is 'escaped' via a 

```

double  
# underscore  
#  
include XX::XHTML  
include XX::XML

```
 puts xml_{ t__{ 'this is text data' } }
 puts xml_{ x__{ '<xml> in raw form, nothing is auto-escaped </xml>' 

```

} }  
puts xml\_{ h\_\_{ ‘ entities like & are ignored ’ } }  
puts xml\_{ c\_\_{ ‘cdata’ } }  
puts xml\_{ tag\_(a\_\_(‘k=v, x=y’)){ ‘a\_\_ is a handy attribute parser’  
} }  
puts xml\_{ tag\_(y\_\_(‘k: v, a: b’)){ ‘y\_\_ is too - yaml style’ } }

~ \> ruby samples/g.rb

```
 <?xml version='1.0'?>this is text data
 <?xml version='1.0'?><xml> in raw form, nothing is auto-escaped 

```

 \<?xml version='1.0'?\> entities like & are ignored \<?xml version='1.0'?\> \<?xml version='1.0'?\>a\_\_ is a handy attribute parser \<?xml version='1.0'?\>y\_\_ is too - yaml style

\<========\< samples/h.rb \>========\>

~ \> cat samples/h.rb

```
 require "xx"
 #
 # xx supports templates with grace and applomb
 #
 template = XX::Template::Inline.new <<-xhtml
   xhtml_{
     html_{
       body_{
         table_{ @table.each{|row| tr_{ row.each{|cell| td_ cell} }} 

```

}

```
         b_ local_variable
       }
     }
   }
 xhtml

 @table = [
   %w( a b c ),
   %w( x y z ),
 ]

 local_variable = 'local_variable'

 template.expand binding

```

~ \> ruby samples/h.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)”\>

  
  
  
  
  
  
  
  
  
  
  

| a | b | c |
| x | y | z |

  
**local\_variable**  
  

\<========\< samples/i.rb \>========\>

~ \> cat samples/i.rb

```
 require "xx"
 #
 # file based templates are also supported
 #
 xhtml = <<-xhtml
   xhtml_{
     html_{
       body_{
         table_{ @table.each{|row| tr_{ row.each{|cell| td_ cell} }} 

```

}

```
         b_ local_variable
       }
     }
   }
 xhtml

 # generate template on the fly
 require "tempfile"
 t = Tempfile.new Process.pid.to_s
 t << xhtml
 t.close

 template = XX::Template::File.new t.path

 @table = [
   %w( a b c ),
   %w( x y z ),
 ]

 local_variable = 'local_variable'

 template.expand binding

```

~ \> ruby samples/i.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)”\>

  
  
  
  
  
  
  
  
  
  
  

| a | b | c |
| x | y | z |

  
**local\_variable**  
  

\<========\< samples/j.rb \>========\>

~ \> cat samples/j.rb

```
 require "xx"
 #
 # the return type of all tag_ methods are suitable for injection 

```

into a  
# doccument, so you can break apart html generation into methods.  
note that  
# these methods are not returning strings, but REXML elements which  
can be  
# injected into other doccuments  
#  
class Table \< Array  
include XX::XHTML  
def to\_html  
xhtml\_{ html\_{ body\_{ table\_{ each{|row| row\_html row} } } } }  
end  
def row\_html row  
tr\_{ row.each{|cell| cell\_html cell} }  
end  
def cell\_html cell  
td\_{ cell }  
end  
end

```
 t = Table[%w( 0 1 2 ), %w( 3 4 5 )]

 puts t.to_html

```

~ \> ruby samples/j.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)”\>

  
  
  
  
  
  
  
  
  
  
  

| 0 | 1 | 2 |
| 3 | 4 | 5 |

  
  

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.

-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:** [February 25, 2007, 5:31am UTC](https://www.ruby-forum.com/t/xx-2-1-0/86728/2 "2007-02-25T05:31:00Z")

</div>

Having a great Sat night eh Ara?

On Sun, Feb 25, 2007 at 11:13:38AM +0900, Ara.T.Howard wrote:

> INSTALL
> 
> harp:~ \> gem install “double x”

Hmm… not quite sure this works, feature in gems I don’t know  
about ?

```
aramis:~ $ ruby -v
ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-darwin8.8.1]

aramis:~ $ gem -v
0.9.1

aramis:~ $ sudo gem install "double x"
ERROR: While executing gem ... (Gem::GemNotFoundException)
    Could not find double x (> 0) in any repository

```

But the expected way works:

```
aramis:~ $ sudo gem install xx
Successfully installed xx-2.1.0

```

And did you want to ship xx.rb.bak ?

```
aramis:~ $ gem specification xx
[...]
files:
- lib/xx.rb.bak
- lib/xx-2.1.0.rb
- lib/binding_of_caller.rb
- lib/xx.rb
- test/xx.rb
[...]

```

Hopefully I’m making false assumptions here 🙂

enjoy,

-jeremy

---

<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:** [February 25, 2007, 5:50am UTC](https://www.ruby-forum.com/t/xx-2-1-0/86728/3 "2007-02-25T05:50:01Z")

</div>

On Sun, 25 Feb 2007, Jeremy H. wrote:

> Having a great Sat night eh Ara?

heh. got a sick kid…

> ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-darwin8.8.1]  
> aramis:~ $ sudo gem install xx  
> Successfully installed xx-2.1.0

ok. that must have changed. for a while [rubyforge.org](http://rubyforge.org) choked on the  
two  
letter name. i confess i’m not sure what has changed or if i’ve made a  
mistake. neverthless it looks like

gem install xx

is the way to go

> […]  
> oh yeah - it’s the really good one.

😉

> Hopefully I’m making false assumptions here 🙂

thanks. i’ll check it out.

-a
