Skip to content
Browse files

github import

  • Loading branch information...
0 parents commit 14e335adea7ebdd3e03befa34678c9792468c365 @ahoward committed
363 README
@@ -0,0 +1,363 @@
+NAME
+
+ tagz.rb
+
+SYNOPSIS
+
+ require Tagz
+
+ include Tagz.globally
+
+ a_(:href => "/foo"){ "bar" } #=> <a href="/foo">bar</a>
+
+DESCRIPTION
+
+ tagz.rb is generates html, xml, or any sgml variant like a small ninja
+ running across the backs of a herd of giraffes swatting of heads like a
+ mark-up weedwacker. weighing in at less than 300 lines of code tagz.rb adds
+ an html/xml/sgml syntax to ruby that is both unobtrusive, safe, and available
+ globally to objects without the need for any builder or superfluous objects.
+ tagz.rb is designed for applications that generate html to be able to do so
+ easily in any context without heavyweight syntax or scoping issues, like a
+ ninja sword through butter.
+
+FEATURES
+
+ - use as a library or mixin
+
+ - simple, clean and consistent mark-up that is easy to visually
+ distinguish from other ruby methods
+
+ - auto-compatibility with rails/actionview
+
+ - ability to independently open and close tagz in markup
+
+ - intelligent auto-escaping of both attributes and content for both html
+ and xml
+
+ - validate your html/xml with 'ruby -c' syntax check
+
+ - generally bitchin
+
+ - no lame method_missing approach that prevents tagz like 'type' from being
+ generated
+
+RAILS
+
+ in config/environment.rb
+
+ require 'tagz'
+
+ in a helper
+
+ def list_of_users
+ ul_(:class => 'users'){
+ @users.each{|user| li_{ user }}
+ }
+ end
+
+ in a view
+
+ <%=
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ %>
+
+ in a controller
+
+ def ajax_responder
+ text =
+ tagz{
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ }
+
+ render :text => text
+ end
+
+INSTALL
+
+ gem install tagz
+
+HISTORY
+ 5.0.0
+ - introduce better escaping for attributes using xchar.rb approach
+ - indroduce smart escaping for content
+ - make Tagz.globally kick ass more hard
+ - note that this version is not backward compatibile if you were relying
+ on tagz never escaping any content should be an ok upgrade for most
+ applications
+
+ 4.6.0
+ - fix a bug with self closing tagz that had crept in 1.0.0 -> 4.2.0. thx
+ jeremy hinegardner
+
+ - added tests from 1.0.0 back into svn
+
+ 4.4.0
+ - remove dependancy on cgi lib, tagz is now completely standalone
+
+ 4.3.0
+ - detect rails and auto-include into ActionController::Base and include
+ globally into ActionView::Base
+
+ 4.2.0
+ - general lib cleanup
+ - introduction of dual-mixin technique (Tagz.globally)
+ - few small bug fixes
+ - ninja tales
+
+SAMPLES
+
+ <========< samples/a.rb >========>
+
+ ~ > cat samples/a.rb
+
+ #
+ # in the simplest case tagz generates html using a syntax which safely mixes
+ # in to any object
+ #
+
+ require 'tagz'
+ include Tagz.globally
+
+ class GiraffeModel
+ def link
+ a_(:href => "/giraffe/neck/42"){ "whack!" }
+ end
+ end
+
+ puts GiraffeModel.new.link
+
+ ~ > ruby samples/a.rb
+
+ <a href="/giraffe/neck/42">whack!</a>
+
+
+ <========< samples/b.rb >========>
+
+ ~ > cat samples/b.rb
+
+ #
+ # tagz.rb mixes quite easily with your favourite templating engine, avoiding
+ # the need for '<% rows.each do |row| %> ... <% row.each do |cell| %> '
+ # madness and other types of logic to be coded in the templating language,
+ # leaving templating to template engines and logic and looping to ruby -
+ # unencumbered by extra funky syntax. in rails tagz will automatically be
+ # available in your erb templates.
+ #
+
+ require 'tagz'
+ include Tagz.globally
+
+ require 'erb'
+
+ rows = %w( a b c ), %w( 1 2 3 )
+
+ template = ERB.new <<-ERB
+ <html>
+ <body>
+ <%=
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ %>
+ </body>
+ </html>
+ ERB
+
+ puts template.result(binding)
+
+
+ ~ > ruby samples/b.rb
+
+ <html>
+ <body>
+ <table><tr><td>a</td><td>b</td><td>c</td></tr><tr><td>1</td><td>2</td><td>3</td></tr></table>
+ </body>
+ </html>
+
+
+ <========< samples/c.rb >========>
+
+ ~ > cat samples/c.rb
+
+ #
+ # once you've learned to generate html using tagz you're primed to generate
+ # xml too
+ #
+
+ require 'tagz'
+ include Tagz.globally
+
+ doc =
+ xml_{
+ giraffe_{ 'large' }
+ ninja_{ 'small' }
+ }
+
+ puts doc
+
+ ~ > ruby samples/c.rb
+
+ <xml><giraffe>large</giraffe><ninja>small</ninja></xml>
+
+
+ <========< samples/d.rb >========>
+
+ ~ > cat samples/d.rb
+
+ #
+ # 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 -->"
+ }
+ end
+
+ def footer
+ tagz{
+ ___ "<!-- this is the footer -->"
+
+ body_
+ html_
+ }
+ end
+
+ puts header, footer
+
+ ~ > ruby samples/d.rb
+
+ <html><body class="ninja-like" id="giraffe-slayer">
+ <!-- this is the header -->
+
+ <!-- this is the footer -->
+ <body><html>
+
+
+ <========< samples/e.rb >========>
+
+ ~ > cat samples/e.rb
+
+ #
+ # tagz.rb allows a safer method of mixin which requires any tagz methods to be
+ # insider a tagz block - tagz generating methods outside a tagz block with
+ # raise an error if tagz is included this way. also notice that the error is
+ # reported from where it was raised - not from the bowels of the the tagz.rb
+ # lib.
+ #
+
+ require 'tagz'
+ include Tagz
+
+ puts tagz{
+ html_{ 'works only in here' }
+ }
+
+ begin
+ html_{ 'not out here' }
+ rescue Object => e
+ p :backtrace => e.backtrace
+ end
+
+
+ ~ > ruby samples/e.rb
+
+ <html>works only in here</html>
+ {:backtrace=>["samples/e.rb:17"]}
+
+
+ <========< samples/f.rb >========>
+
+ ~ > cat samples/f.rb
+
+ #
+ # tagz.rb can generate really compact html. this is great to save bandwidth
+ # but can sometimes make reading the generated html a bit rough. of course
+ # using tidy or the dom inspector in firebug obviates the issue; nevertheless
+ # it's sometime nice to break things up a little. you can use 'tagz << "\n"'
+ # or the special shorthand '__' or '___' to accomplish this
+ #
+
+ require 'tagz'
+ include Tagz.globally
+
+ html =
+ div_{
+ span_{ true }
+ __
+ span_{ false } # hey ryan, i fixed this ;-)
+ ___
+
+ ___ 'foo & escaped bar'
+ }
+
+ puts html
+
+ ~ > ruby samples/f.rb
+
+ <div><span>true</span>
+ <span>false</span>
+
+ foo & escaped bar
+ </div>
+
+
+ <========< samples/g.rb >========>
+
+ ~ > cat samples/g.rb
+
+ # tagz gives you low-level control of the output and makes even dashersized
+ # xml tagz easy enough to work with
+ #
+
+ require 'tagz'
+ include Tagz.globally
+
+ xml =
+ root_{
+ tagz__('foo-bar', :key => 'foo&bar'){ 'content' }
+
+ tagz__('bar-foo')
+ tagz.concat 'content'
+ tagz.concat tagz.escape('foo&bar')
+ __tagz('bar-foo')
+ }
+
+ puts xml
+
+
+ ~ > ruby samples/g.rb
+
+ <root><foo-bar key="foo&amp;bar">content</foo-bar><bar-foo>contentfoo&amp;bar</bar-foo></root>
+
126 README.tmpl
@@ -0,0 +1,126 @@
+NAME
+
+ tagz.rb
+
+SYNOPSIS
+
+ require Tagz
+
+ include Tagz.globally
+
+ a_(:href => "/foo"){ "bar" } #=> <a href="/foo">bar</a>
+
+DESCRIPTION
+
+ tagz.rb is generates html, xml, or any sgml variant like a small ninja
+ running across the backs of a herd of giraffes swatting of heads like a
+ mark-up weedwacker. weighing in at less than 300 lines of code tagz.rb adds
+ an html/xml/sgml syntax to ruby that is both unobtrusive, safe, and available
+ globally to objects without the need for any builder or superfluous objects.
+ tagz.rb is designed for applications that generate html to be able to do so
+ easily in any context without heavyweight syntax or scoping issues, like a
+ ninja sword through butter.
+
+FEATURES
+
+ - use as a library or mixin
+
+ - simple, clean and consistent mark-up that is easy to visually
+ distinguish from other ruby methods
+
+ - auto-compatibility with rails/actionview
+
+ - ability to independently open and close tagz in markup
+
+ - intelligent auto-escaping of both attributes and content for both html
+ and xml
+
+ - validate your html/xml with 'ruby -c' syntax check
+
+ - generally bitchin
+
+ - no lame method_missing approach that prevents tagz like 'type' from being
+ generated
+
+RAILS
+
+ in config/environment.rb
+
+ require 'tagz'
+
+ in a helper
+
+ def list_of_users
+ ul_(:class => 'users'){
+ @users.each{|user| li_{ user }}
+ }
+ end
+
+ in a view
+
+ <%=
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ %>
+
+ in a controller
+
+ def ajax_responder
+ text =
+ tagz{
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ }
+
+ render :text => text
+ end
+
+INSTALL
+
+ gem install tagz
+
+HISTORY
+ 5.0.0
+ - introduce better escaping for attributes using xchar.rb approach
+ - indroduce smart escaping for content
+ - make Tagz.globally kick ass more hard
+ - note that this version is not backward compatibile if you were relying
+ on tagz never escaping any content should be an ok upgrade for most
+ applications
+
+ 4.6.0
+ - fix a bug with self closing tagz that had crept in 1.0.0 -> 4.2.0. thx
+ jeremy hinegardner
+
+ - added tests from 1.0.0 back into svn
+
+ 4.4.0
+ - remove dependancy on cgi lib, tagz is now completely standalone
+
+ 4.3.0
+ - detect rails and auto-include into ActionController::Base and include
+ globally into ActionView::Base
+
+ 4.2.0
+ - general lib cleanup
+ - introduction of dual-mixin technique (Tagz.globally)
+ - few small bug fixes
+ - ninja tales
+
+SAMPLES
+
+ @samples
34 gen_readme.rb
@@ -0,0 +1,34 @@
+#! /usr/bin/env ruby
+
+require 'pathname'
+
+$VERBOSE=nil
+
+def indent s, n = 2
+ ws = ' ' * n
+ s.gsub %r/^/, ws
+end
+
+template = IO::read 'README.tmpl'
+
+samples = ''
+prompt = '~ > '
+
+Dir['sample*/*'].sort.each do |sample|
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
+
+ cmd = "cat #{ sample }"
+ samples << indent(prompt + cmd, 2) << "\n\n"
+ samples << indent(`#{ cmd }`, 4) << "\n"
+
+ cmd = "ruby #{ sample }"
+ samples << indent(prompt + cmd, 2) << "\n\n"
+
+ cmd = "ruby -Ilib #{ sample }"
+ samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
+end
+
+#samples.gsub! %r/^/, ' '
+
+readme = template.gsub %r/^\s*@samples\s*$/, samples
+print readme
214 install.rb
@@ -0,0 +1,214 @@
+#!/usr/bin/env ruby
+require 'rbconfig'
+require 'find'
+require 'ftools'
+require 'tempfile'
+include Config
+
+LIBDIR = "lib"
+LIBDIR_MODE = 0644
+
+BINDIR = "bin"
+BINDIR_MODE = 0755
+
+
+$srcdir = CONFIG["srcdir"]
+$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
+$libdir = File.join(CONFIG["libdir"], "ruby", $version)
+$archdir = File.join($libdir, CONFIG["arch"])
+$site_libdir = $:.find {|x| x =~ /site_ruby$/}
+$bindir = CONFIG["bindir"] || CONFIG['BINDIR']
+$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
+$ruby_ext = CONFIG['EXEEXT'] || ''
+$ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
+
+if !$site_libdir
+ $site_libdir = File.join($libdir, "site_ruby")
+elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
+ $site_libdir = File.join($site_libdir, $version)
+end
+
+def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
+#{{{
+ path = []
+ dir = []
+ Find.find(srcdir) do |f|
+ next unless FileTest.file?(f)
+ next if (f = f[srcdir.length+1..-1]) == nil
+ next if (/CVS$/ =~ File.dirname(f))
+ next if (/\.svn/ =~ File.dirname(f))
+ next if f =~ %r/\.lnk/
+ next if f =~ %r/\.svn/
+ next if f =~ %r/\.swp/
+ next if f =~ %r/\.svn/
+ path.push f
+ dir |= [File.dirname(f)]
+ end
+ for f in dir
+ next if f == "."
+ next if f == "CVS"
+ File::makedirs(File.join(destdir, f))
+ end
+ for f in path
+ next if (/\~$/ =~ f)
+ next if (/^\./ =~ File.basename(f))
+ unless bin
+ File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
+ else
+ from = File.join(srcdir, f)
+ to = File.join(destdir, f)
+ shebangify(from) do |sf|
+ $deferr.print from, " -> ", File::catname(from, to), "\n"
+ $deferr.printf "chmod %04o %s\n", mode, to
+ File::install(sf, to, mode, false)
+ end
+ end
+ end
+#}}}
+end
+def shebangify f
+#{{{
+ open(f) do |fd|
+ buf = fd.read 42
+ if buf =~ %r/^\s*#\s*!.*ruby/o
+ ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
+ begin
+ fd.rewind
+ ftmp.puts "#!#{ $ruby }"
+ while((buf = fd.read(8192)))
+ ftmp.write buf
+ end
+ ftmp.close
+ yield ftmp.path
+ ensure
+ ftmp.close!
+ end
+ else
+ yield f
+ end
+ end
+#}}}
+end
+def ARGV.switch
+#{{{
+ return nil if self.empty?
+ arg = self.shift
+ return nil if arg == '--'
+ if arg =~ /^-(.)(.*)/
+ return arg if $1 == '-'
+ raise 'unknown switch "-"' if $2.index('-')
+ self.unshift "-#{$2}" if $2.size > 0
+ "-#{$1}"
+ else
+ self.unshift arg
+ nil
+ end
+#}}}
+end
+def ARGV.req_arg
+#{{{
+ self.shift || raise('missing argument')
+#}}}
+end
+def linkify d, linked = []
+#--{{{
+ if test ?d, d
+ versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
+ versioned.each do |v|
+ src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
+ lnk = nil
+ begin
+ if test ?l, dst
+ lnk = "#{ dst }.lnk"
+ puts "#{ dst } -> #{ lnk }"
+ File::rename dst, lnk
+ end
+ unless test ?e, dst
+ puts "#{ src } -> #{ dst }"
+ File::copy src, dst
+ linked << dst
+ end
+ ensure
+ if lnk
+ at_exit do
+ puts "#{ lnk } -> #{ dst }"
+ File::rename lnk, dst
+ end
+ end
+ end
+ end
+ end
+ linked
+#--}}}
+end
+
+
+#
+# main program
+#
+
+libdir = $site_libdir
+bindir = $bindir
+no_linkify = false
+linked = nil
+help = false
+
+usage = <<-usage
+ #{ File::basename $0 }
+ -d, --destdir <destdir>
+ -l, --libdir <libdir>
+ -b, --bindir <bindir>
+ -r, --ruby <ruby>
+ -n, --no_linkify
+ -s, --sudo
+ -h, --help
+usage
+
+begin
+ while switch = ARGV.switch
+ case switch
+ when '-d', '--destdir'
+ libdir = ARGV.req_arg
+ when '-l', '--libdir'
+ libdir = ARGV.req_arg
+ when '-b', '--bindir'
+ bindir = ARGV.req_arg
+ when '-r', '--ruby'
+ $ruby = ARGV.req_arg
+ when '-n', '--no_linkify'
+ no_linkify = true
+ when '-s', '--sudo'
+ sudo = 'sudo'
+ when '-h', '--help'
+ help = true
+ else
+ raise "unknown switch #{switch.dump}"
+ end
+ end
+rescue
+ STDERR.puts $!.to_s
+ STDERR.puts usage
+ exit 1
+end
+
+if help
+ STDOUT.puts usage
+ exit
+end
+
+system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
+
+unless no_linkify
+ linked = linkify('lib') + linkify('bin')
+end
+
+system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
+
+install_rb(LIBDIR, libdir, LIBDIR_MODE)
+install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
+
+if linked
+ linked.each{|path| File::rm_f path}
+end
+
+system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
40 lib/.svn/entries
@@ -0,0 +1,40 @@
+8
+
+dir
+767
+svn+ssh://ahoward@rubyforge.org/var/svn/codeforpeople/tagz/trunk/lib
+svn+ssh://ahoward@rubyforge.org/var/svn/codeforpeople
+
+
+
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+29922619-e960-4932-8d85-0e0be7f1775a
+
+tagz.rb
+file
+773
+
+
+
+2009-03-24T17:54:28.000000Z
+84261c3492593e1cb37c212543331349
+2009-03-25T07:04:08.834319Z
+773
+ahoward
+
1 lib/.svn/format
@@ -0,0 +1 @@
+8
330 lib/.svn/text-base/tagz.rb.svn-base
@@ -0,0 +1,330 @@
+unless defined? Tagz
+
+ module Tagz
+ unless defined?(Tagz::VERSION)
+ Tagz::VERSION = [
+ Tagz::VERSION_MAJOR = 5,
+ Tagz::VERSION_MINOR = 0,
+ Tagz::VERSION_TEENY = 1
+ ].join('.')
+ def Tagz.version() Tagz::VERSION end
+ end
+
+ private
+
+ # open_tag
+ #
+ def tagz__ name, *argv, &block
+ options = argv.last.is_a?(Hash) ? argv.pop : {}
+ content = argv
+
+ unless options.empty?
+ attributes = ' ' <<
+ options.map do |key, value|
+ key = XChar.escape key.to_s
+ value = XChar.escape value.to_s
+ if value =~ %r/"/
+ raise ArgumentError, value if value =~ %r/'/
+ value = "'#{ value }'"
+ else
+ raise ArgumentError, value if value =~ %r/"/
+ value = "\"#{ value }\""
+ end
+ [key, value].join('=')
+ end.join(' ')
+ else
+ attributes = ''
+ end
+
+ tagz.concat "<#{ name }#{ attributes }>"
+
+ if content.empty?
+ if block
+ size = tagz.size
+ value = block.call(tagz)
+
+ if value.nil?
+ unless(tagz.size > size)
+ tagz[-1] = "/>"
+ else
+ tagz.concat "</#{ name }>"
+ end
+ else
+ tagz << value.to_s unless(tagz.size > size)
+ tagz.concat "</#{ name }>"
+ end
+
+ end
+ else
+ tagz << content.join
+ if block
+ size = tagz.size
+ value = block.call(tagz)
+ tagz << value.to_s unless(tagz.size > size)
+ end
+ tagz.concat "</#{ name }>"
+ end
+
+ tagz
+ end
+
+ # close_tag
+ #
+ def __tagz tag, *a, &b
+ tagz.concat "</#{ tag }>"
+ end
+
+ # access tagz doc and enclose tagz operations
+ #
+ def tagz document = nil, &block
+ @tagz ||= nil ## shut wornings up
+ previous = @tagz
+
+ if block
+ @tagz ||= (Document.for(document) || Document.new)
+ begin
+ size = @tagz.size
+ value = instance_eval(&block)
+ @tagz << value unless(@tagz.size > size)
+ @tagz
+ ensure
+ @tagz = previous
+ end
+ else
+ document ? Document.for(document) : @tagz
+ end
+ end
+
+ # catch special tagz methods
+ #
+ def method_missing m, *a, &b
+ strategy =
+ case m.to_s
+ when %r/^(.*[^_])_(!)?$/o
+ :open_tag
+ when %r/^_([^_].*)$/o
+ :close_tag
+ when 'e'
+ :element
+ when '__', '___'
+ :puts
+ else
+ nil
+ end
+
+ if(strategy.nil? or (tagz.nil? and not Globally===self))
+ begin
+ super
+ ensure
+ $!.set_backtrace caller(skip=1) if $!
+ end
+ end
+
+ case strategy
+ when :open_tag
+ m, bang = $1, $2
+ b ||= lambda{} if bang
+ tagz{ tagz__(m, *a, &b) }
+ when :close_tag
+ m = $1
+ tagz{ __tagz(m, *a, &b) }
+ when :element
+ Element.new(*a, &b)
+ when :puts
+ tagz do
+ tagz.concat("\n")
+ unless a.empty?
+ tagz.concat(a.join)
+ tagz.concat("\n")
+ end
+ end
+ end
+ end
+
+ class Document < ::String
+ def Document.for other
+ Document === other ? other : Document.new(other.to_s)
+ end
+
+ def element
+ Element.new(*a, &b)
+ end
+ alias_method 'e', 'element'
+
+ def << string
+ case string
+ when Document
+ super string.to_s
+ else
+ super XChar.escape(string.to_s)
+ end
+ self
+ end
+
+ def escape(*strings)
+ XChar.escape(strings.join)
+ end
+ alias_method 'h', 'escape'
+
+ def puts string
+ concat "#{ string }\n"
+ end
+ alias_method 'push', 'concat'
+ alias_method 'write', 'concat'
+
+ def document
+ self
+ end
+ alias_method 'doc', 'document'
+
+ def + other
+ self.dup << other
+ end
+
+ def to_s
+ self
+ end
+
+ def to_str
+ self
+ end
+ end
+
+ class Element < ::String
+ def Element.attributes options
+ unless options.empty?
+ ' ' <<
+ options.map do |key, value|
+ key = XChar.escape key.to_s
+ value = XChar.escape value.to_s
+ if value =~ %r/"/
+ raise ArgumentError, value if value =~ %r/'/
+ value = "'#{ value }'"
+ else
+ raise ArgumentError, value if value =~ %r/"/
+ value = "\"#{ value }\""
+ end
+ [key, value].join('=')
+ end.join(' ')
+ else
+ ''
+ end
+ end
+
+ attr 'name'
+
+ def initialize name, *argv, &block
+ options = {}
+ content = []
+
+ argv.each do |arg|
+ case arg
+ when Hash
+ options.update arg
+ else
+ content.push arg
+ end
+ end
+
+ content.push block.call if block
+ content.compact!
+
+ @name = name.to_s
+
+ if content.empty?
+ replace "<#{ @name }#{ Element.attributes options }>"
+ else
+ replace "<#{ @name }#{ Element.attributes options }>#{ content.join }</#{ name }>"
+ end
+ end
+ end
+
+ module XChar
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
+ #
+ CP1252 = {
+ 128 => 8364, # euro sign
+ 130 => 8218, # single low-9 quotation mark
+ 131 => 402, # latin small letter f with hook
+ 132 => 8222, # double low-9 quotation mark
+ 133 => 8230, # horizontal ellipsis
+ 134 => 8224, # dagger
+ 135 => 8225, # double dagger
+ 136 => 710, # modifier letter circumflex accent
+ 137 => 8240, # per mille sign
+ 138 => 352, # latin capital letter s with caron
+ 139 => 8249, # single left-pointing angle quotation mark
+ 140 => 338, # latin capital ligature oe
+ 142 => 381, # latin capital letter z with caron
+ 145 => 8216, # left single quotation mark
+ 146 => 8217, # right single quotation mark
+ 147 => 8220, # left double quotation mark
+ 148 => 8221, # right double quotation mark
+ 149 => 8226, # bullet
+ 150 => 8211, # en dash
+ 151 => 8212, # em dash
+ 152 => 732, # small tilde
+ 153 => 8482, # trade mark sign
+ 154 => 353, # latin small letter s with caron
+ 155 => 8250, # single right-pointing angle quotation mark
+ 156 => 339, # latin small ligature oe
+ 158 => 382, # latin small letter z with caron
+ 159 => 376} # latin capital letter y with diaeresis
+
+ # http://www.w3.org/TR/REC-xml/#dt-chardata
+ #
+ PREDEFINED = {
+ 38 => '&amp;', # ampersand
+ 60 => '&lt;', # left angle bracket
+ 62 => '&gt;'} # right angle bracket
+
+ # http://www.w3.org/TR/REC-xml/#charsets
+ #
+ VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF), (0xE000..0xFFFD), (0x10000..0x10FFFF)]
+
+ def XChar.escape(string)
+ string.unpack('U*').map{|n| xchr(n)}.join # ASCII, UTF-8
+ rescue
+ string.unpack('C*').map{|n| xchr(n)}.join # ISO-8859-1, WIN-1252
+ end
+
+ def XChar.xchr(n)
+ (@xchr ||= {})[n] ||= ((
+ n = XChar::CP1252[n] || n
+ n = 42 unless XChar::VALID.find{|range| range.include? n}
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
+ ))
+ end
+ end
+
+ def Tagz.escapeHTML string
+ XChar.escape(string)
+ end
+
+ module Globally; include Tagz; end
+ def Tagz.globally
+ Globally
+ end
+
+ module Privately; include Tagz; end
+ def Tagz.privately
+ Privately
+ end
+
+ %w( tagz tagz__ __tagz method_missing ).each{|m| module_function(m)}
+ end
+
+ def Tagz *argv, &block
+ if argv.empty? and block.nil?
+ ::Tagz
+ else
+ Tagz.tagz(*argv, &block)
+ end
+ end
+
+ if defined?(Rails)
+ ActionView::Base.send(:include, Tagz.globally)
+ ActionController::Base.send(:include, Tagz)
+ end
+
+end
330 lib/tagz.rb
@@ -0,0 +1,330 @@
+unless defined? Tagz
+
+ module Tagz
+ unless defined?(Tagz::VERSION)
+ Tagz::VERSION = [
+ Tagz::VERSION_MAJOR = 5,
+ Tagz::VERSION_MINOR = 0,
+ Tagz::VERSION_TEENY = 1
+ ].join('.')
+ def Tagz.version() Tagz::VERSION end
+ end
+
+ private
+
+ # open_tag
+ #
+ def tagz__ name, *argv, &block
+ options = argv.last.is_a?(Hash) ? argv.pop : {}
+ content = argv
+
+ unless options.empty?
+ attributes = ' ' <<
+ options.map do |key, value|
+ key = XChar.escape key.to_s
+ value = XChar.escape value.to_s
+ if value =~ %r/"/
+ raise ArgumentError, value if value =~ %r/'/
+ value = "'#{ value }'"
+ else
+ raise ArgumentError, value if value =~ %r/"/
+ value = "\"#{ value }\""
+ end
+ [key, value].join('=')
+ end.join(' ')
+ else
+ attributes = ''
+ end
+
+ tagz.concat "<#{ name }#{ attributes }>"
+
+ if content.empty?
+ if block
+ size = tagz.size
+ value = block.call(tagz)
+
+ if value.nil?
+ unless(tagz.size > size)
+ tagz[-1] = "/>"
+ else
+ tagz.concat "</#{ name }>"
+ end
+ else
+ tagz << value.to_s unless(tagz.size > size)
+ tagz.concat "</#{ name }>"
+ end
+
+ end
+ else
+ tagz << content.join
+ if block
+ size = tagz.size
+ value = block.call(tagz)
+ tagz << value.to_s unless(tagz.size > size)
+ end
+ tagz.concat "</#{ name }>"
+ end
+
+ tagz
+ end
+
+ # close_tag
+ #
+ def __tagz tag, *a, &b
+ tagz.concat "</#{ tag }>"
+ end
+
+ # access tagz doc and enclose tagz operations
+ #
+ def tagz document = nil, &block
+ @tagz ||= nil ## shut wornings up
+ previous = @tagz
+
+ if block
+ @tagz ||= (Document.for(document) || Document.new)
+ begin
+ size = @tagz.size
+ value = instance_eval(&block)
+ @tagz << value unless(@tagz.size > size)
+ @tagz
+ ensure
+ @tagz = previous
+ end
+ else
+ document ? Document.for(document) : @tagz
+ end
+ end
+
+ # catch special tagz methods
+ #
+ def method_missing m, *a, &b
+ strategy =
+ case m.to_s
+ when %r/^(.*[^_])_(!)?$/o
+ :open_tag
+ when %r/^_([^_].*)$/o
+ :close_tag
+ when 'e'
+ :element
+ when '__', '___'
+ :puts
+ else
+ nil
+ end
+
+ if(strategy.nil? or (tagz.nil? and not Globally===self))
+ begin
+ super
+ ensure
+ $!.set_backtrace caller(skip=1) if $!
+ end
+ end
+
+ case strategy
+ when :open_tag
+ m, bang = $1, $2
+ b ||= lambda{} if bang
+ tagz{ tagz__(m, *a, &b) }
+ when :close_tag
+ m = $1
+ tagz{ __tagz(m, *a, &b) }
+ when :element
+ Element.new(*a, &b)
+ when :puts
+ tagz do
+ tagz.concat("\n")
+ unless a.empty?
+ tagz.concat(a.join)
+ tagz.concat("\n")
+ end
+ end
+ end
+ end
+
+ class Document < ::String
+ def Document.for other
+ Document === other ? other : Document.new(other.to_s)
+ end
+
+ def element
+ Element.new(*a, &b)
+ end
+ alias_method 'e', 'element'
+
+ def << string
+ case string
+ when Document
+ super string.to_s
+ else
+ super XChar.escape(string.to_s)
+ end
+ self
+ end
+
+ def escape(*strings)
+ XChar.escape(strings.join)
+ end
+ alias_method 'h', 'escape'
+
+ def puts string
+ concat "#{ string }\n"
+ end
+ alias_method 'push', 'concat'
+ alias_method 'write', 'concat'
+
+ def document
+ self
+ end
+ alias_method 'doc', 'document'
+
+ def + other
+ self.dup << other
+ end
+
+ def to_s
+ self
+ end
+
+ def to_str
+ self
+ end
+ end
+
+ class Element < ::String
+ def Element.attributes options
+ unless options.empty?
+ ' ' <<
+ options.map do |key, value|
+ key = XChar.escape key.to_s
+ value = XChar.escape value.to_s
+ if value =~ %r/"/
+ raise ArgumentError, value if value =~ %r/'/
+ value = "'#{ value }'"
+ else
+ raise ArgumentError, value if value =~ %r/"/
+ value = "\"#{ value }\""
+ end
+ [key, value].join('=')
+ end.join(' ')
+ else
+ ''
+ end
+ end
+
+ attr 'name'
+
+ def initialize name, *argv, &block
+ options = {}
+ content = []
+
+ argv.each do |arg|
+ case arg
+ when Hash
+ options.update arg
+ else
+ content.push arg
+ end
+ end
+
+ content.push block.call if block
+ content.compact!
+
+ @name = name.to_s
+
+ if content.empty?
+ replace "<#{ @name }#{ Element.attributes options }>"
+ else
+ replace "<#{ @name }#{ Element.attributes options }>#{ content.join }</#{ name }>"
+ end
+ end
+ end
+
+ module XChar
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
+ #
+ CP1252 = {
+ 128 => 8364, # euro sign
+ 130 => 8218, # single low-9 quotation mark
+ 131 => 402, # latin small letter f with hook
+ 132 => 8222, # double low-9 quotation mark
+ 133 => 8230, # horizontal ellipsis
+ 134 => 8224, # dagger
+ 135 => 8225, # double dagger
+ 136 => 710, # modifier letter circumflex accent
+ 137 => 8240, # per mille sign
+ 138 => 352, # latin capital letter s with caron
+ 139 => 8249, # single left-pointing angle quotation mark
+ 140 => 338, # latin capital ligature oe
+ 142 => 381, # latin capital letter z with caron
+ 145 => 8216, # left single quotation mark
+ 146 => 8217, # right single quotation mark
+ 147 => 8220, # left double quotation mark
+ 148 => 8221, # right double quotation mark
+ 149 => 8226, # bullet
+ 150 => 8211, # en dash
+ 151 => 8212, # em dash
+ 152 => 732, # small tilde
+ 153 => 8482, # trade mark sign
+ 154 => 353, # latin small letter s with caron
+ 155 => 8250, # single right-pointing angle quotation mark
+ 156 => 339, # latin small ligature oe
+ 158 => 382, # latin small letter z with caron
+ 159 => 376} # latin capital letter y with diaeresis
+
+ # http://www.w3.org/TR/REC-xml/#dt-chardata
+ #
+ PREDEFINED = {
+ 38 => '&amp;', # ampersand
+ 60 => '&lt;', # left angle bracket
+ 62 => '&gt;'} # right angle bracket
+
+ # http://www.w3.org/TR/REC-xml/#charsets
+ #
+ VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF), (0xE000..0xFFFD), (0x10000..0x10FFFF)]
+
+ def XChar.escape(string)
+ string.unpack('U*').map{|n| xchr(n)}.join # ASCII, UTF-8
+ rescue
+ string.unpack('C*').map{|n| xchr(n)}.join # ISO-8859-1, WIN-1252
+ end
+
+ def XChar.xchr(n)
+ (@xchr ||= {})[n] ||= ((
+ n = XChar::CP1252[n] || n
+ n = 42 unless XChar::VALID.find{|range| range.include? n}
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
+ ))
+ end
+ end
+
+ def Tagz.escapeHTML string
+ XChar.escape(string)
+ end
+
+ module Globally; include Tagz; end
+ def Tagz.globally
+ Globally
+ end
+
+ module Privately; include Tagz; end
+ def Tagz.privately
+ Privately
+ end
+
+ %w( tagz tagz__ __tagz method_missing ).each{|m| module_function(m)}
+ end
+
+ def Tagz *argv, &block
+ if argv.empty? and block.nil?
+ ::Tagz
+ else
+ Tagz.tagz(*argv, &block)
+ end
+ end
+
+ if defined?(Rails)
+ ActionView::Base.send(:include, Tagz.globally)
+ ActionController::Base.send(:include, Tagz)
+ end
+
+end
112 samples/.svn/entries
@@ -0,0 +1,112 @@
+8
+
+dir
+767
+svn+ssh://ahoward@rubyforge.org/var/svn/codeforpeople/tagz/trunk/samples
+svn+ssh://ahoward@rubyforge.org/var/svn/codeforpeople
+
+
+
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+29922619-e960-4932-8d85-0e0be7f1775a
+
+a.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+1453cb373773adce3af7c8c4a79a8b0f
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+b.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+a91efe0011a61949635831e584160336
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+c.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+8eff0c239d9bd7713380815ead6fefa4
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+d.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+cf618b240790af1696668b3cbb5023f5
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+e.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+6c849253675cd86642ae1fa782211fb9
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+f.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+5c3b1bf38079878c6524a827c7ce1e83
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+g.rb
+file
+
+
+
+
+2009-03-24T16:41:58.000000Z
+ef640ff0d1f949bbdb79da2cbabeadc4
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
1 samples/.svn/format
@@ -0,0 +1 @@
+8
15 samples/.svn/text-base/a.rb.svn-base
@@ -0,0 +1,15 @@
+#
+# in the simplest case tagz generates html using a syntax which safely mixes
+# in to any object
+#
+
+require 'tagz'
+include Tagz.globally
+
+class GiraffeModel
+ def link
+ a_(:href => "/giraffe/neck/42"){ "whack!" }
+ end
+end
+
+puts GiraffeModel.new.link
36 samples/.svn/text-base/b.rb.svn-base
@@ -0,0 +1,36 @@
+#
+# tagz.rb mixes quite easily with your favourite templating engine, avoiding
+# the need for '<% rows.each do |row| %> ... <% row.each do |cell| %> '
+# madness and other types of logic to be coded in the templating language,
+# leaving templating to template engines and logic and looping to ruby -
+# unencumbered by extra funky syntax. in rails tagz will automatically be
+# available in your erb templates.
+#
+
+require 'tagz'
+include Tagz.globally
+
+require 'erb'
+
+rows = %w( a b c ), %w( 1 2 3 )
+
+template = ERB.new <<-ERB
+ <html>
+ <body>
+ <%=
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ %>
+ </body>
+ </html>
+ERB
+
+puts template.result(binding)
+
15 samples/.svn/text-base/c.rb.svn-base
@@ -0,0 +1,15 @@
+#
+# once you've learned to generate html using tagz you're primed to generate
+# xml too
+#
+
+require 'tagz'
+include Tagz.globally
+
+doc =
+ xml_{
+ giraffe_{ 'large' }
+ ninja_{ 'small' }
+ }
+
+puts doc
28 samples/.svn/text-base/d.rb.svn-base
@@ -0,0 +1,28 @@
+#
+# 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 -->"
+ }
+end
+
+def footer
+ tagz{
+ ___ "<!-- this is the footer -->"
+
+ body_
+ html_
+ }
+end
+
+puts header, footer
21 samples/.svn/text-base/e.rb.svn-base
@@ -0,0 +1,21 @@
+#
+# tagz.rb allows a safer method of mixin which requires any tagz methods to be
+# insider a tagz block - tagz generating methods outside a tagz block with
+# raise an error if tagz is included this way. also notice that the error is
+# reported from where it was raised - not from the bowels of the the tagz.rb
+# lib.
+#
+
+require 'tagz'
+include Tagz
+
+puts tagz{
+ html_{ 'works only in here' }
+}
+
+begin
+ html_{ 'not out here' }
+rescue Object => e
+ p :backtrace => e.backtrace
+end
+
22 samples/.svn/text-base/f.rb.svn-base
@@ -0,0 +1,22 @@
+#
+# tagz.rb can generate really compact html. this is great to save bandwidth
+# but can sometimes make reading the generated html a bit rough. of course
+# using tidy or the dom inspector in firebug obviates the issue; nevertheless
+# it's sometime nice to break things up a little. you can use 'tagz << "\n"'
+# or the special shorthand '__' or '___' to accomplish this
+#
+
+require 'tagz'
+include Tagz.globally
+
+html =
+ div_{
+ span_{ true }
+ __
+ span_{ false } # hey ryan, i fixed this ;-)
+ ___
+
+ ___ 'foo & escaped bar'
+ }
+
+puts html
19 samples/.svn/text-base/g.rb.svn-base
@@ -0,0 +1,19 @@
+# tagz gives you low-level control of the output and makes even dashersized
+# xml tagz easy enough to work with
+#
+
+require 'tagz'
+include Tagz.globally
+
+xml =
+ root_{
+ tagz__('foo-bar', :key => 'foo&bar'){ 'content' }
+
+ tagz__('bar-foo')
+ tagz.concat 'content'
+ tagz.concat tagz.escape('foo&bar')
+ __tagz('bar-foo')
+ }
+
+puts xml
+
15 samples/a.rb
@@ -0,0 +1,15 @@
+#
+# in the simplest case tagz generates html using a syntax which safely mixes
+# in to any object
+#
+
+require 'tagz'
+include Tagz.globally
+
+class GiraffeModel
+ def link
+ a_(:href => "/giraffe/neck/42"){ "whack!" }
+ end
+end
+
+puts GiraffeModel.new.link
36 samples/b.rb
@@ -0,0 +1,36 @@
+#
+# tagz.rb mixes quite easily with your favourite templating engine, avoiding
+# the need for '<% rows.each do |row| %> ... <% row.each do |cell| %> '
+# madness and other types of logic to be coded in the templating language,
+# leaving templating to template engines and logic and looping to ruby -
+# unencumbered by extra funky syntax. in rails tagz will automatically be
+# available in your erb templates.
+#
+
+require 'tagz'
+include Tagz.globally
+
+require 'erb'
+
+rows = %w( a b c ), %w( 1 2 3 )
+
+template = ERB.new <<-ERB
+ <html>
+ <body>
+ <%=
+ table_{
+ rows.each do |row|
+ tr_{
+ row.each do |cell|
+ td_{ cell }
+ end
+ }
+ end
+ }
+ %>
+ </body>
+ </html>
+ERB
+
+puts template.result(binding)
+
15 samples/c.rb
@@ -0,0 +1,15 @@
+#
+# once you've learned to generate html using tagz you're primed to generate
+# xml too
+#
+
+require 'tagz'
+include Tagz.globally
+
+doc =
+ xml_{
+ giraffe_{ 'large' }
+ ninja_{ 'small' }
+ }
+
+puts doc
28 samples/d.rb
@@ -0,0 +1,28 @@
+#
+# 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 -->"
+ }
+end
+
+def footer
+ tagz{
+ ___ "<!-- this is the footer -->"
+
+ body_
+ html_
+ }
+end
+
+puts header, footer
21 samples/e.rb
@@ -0,0 +1,21 @@
+#
+# tagz.rb allows a safer method of mixin which requires any tagz methods to be
+# insider a tagz block - tagz generating methods outside a tagz block with
+# raise an error if tagz is included this way. also notice that the error is
+# reported from where it was raised - not from the bowels of the the tagz.rb
+# lib.
+#
+
+require 'tagz'
+include Tagz
+
+puts tagz{
+ html_{ 'works only in here' }
+}
+
+begin
+ html_{ 'not out here' }
+rescue Object => e
+ p :backtrace => e.backtrace
+end
+
22 samples/f.rb
@@ -0,0 +1,22 @@
+#
+# tagz.rb can generate really compact html. this is great to save bandwidth
+# but can sometimes make reading the generated html a bit rough. of course
+# using tidy or the dom inspector in firebug obviates the issue; nevertheless
+# it's sometime nice to break things up a little. you can use 'tagz << "\n"'
+# or the special shorthand '__' or '___' to accomplish this
+#
+
+require 'tagz'
+include Tagz.globally
+
+html =
+ div_{
+ span_{ true }
+ __
+ span_{ false } # hey ryan, i fixed this ;-)
+ ___
+
+ ___ 'foo & escaped bar'
+ }
+
+puts html
19 samples/g.rb
@@ -0,0 +1,19 @@
+# tagz gives you low-level control of the output and makes even dashersized
+# xml tagz easy enough to work with
+#
+
+require 'tagz'
+include Tagz.globally
+
+xml =
+ root_{
+ tagz__('foo-bar', :key => 'foo&bar'){ 'content' }
+
+ tagz__('bar-foo')
+ tagz.concat 'content'
+ tagz.concat tagz.escape('foo&bar')
+ __tagz('bar-foo')
+ }
+
+puts xml
+
BIN tagz-5.0.1.gem
Binary file not shown.
44 tagz.gemspec
@@ -0,0 +1,44 @@
+#! /usr/bin/env gem build
+
+require 'rubygems'
+
+Gem::Specification::new do |spec|
+ $VERBOSE = nil
+
+ shiteless = lambda do |list|
+ list.delete_if do |file|
+ file =~ %r/\.svn/ or
+ file =~ %r/\.tmp/
+ end
+ end
+
+ spec.name = $lib
+ spec.version = $version
+ spec.platform = Gem::Platform::RUBY
+ spec.summary = $lib
+
+ spec.files = shiteless[Dir::glob("**/**")]
+ spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
+
+ spec.require_path = "lib"
+
+ spec.has_rdoc = true #File::exist? "doc"
+ spec.test_suite_file = "test/#{ $lib }.rb" if File::file?("test/#{ $lib }.rb")
+ #spec.add_dependency 'lib', '>= version'
+ #spec.add_dependency 'fattr'
+
+ spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
+
+ spec.rubyforge_project = 'codeforpeople'
+ spec.author = "Ara T. Howard"
+ spec.email = "ara.t.howard@gmail.com"
+ spec.homepage = "http://codeforpeople.com/lib/ruby/#{ $lib }/"
+end
+
+
+BEGIN{
+ Dir.chdir(File.dirname(__FILE__))
+ $lib = 'tagz'
+ Kernel.load "./lib/#{ $lib }.rb"
+ $version = Tagz.version
+}
41 test/.svn/entries
@@ -0,0 +1,41 @@
+8
+
+dir
+767
+svn+ssh://ahoward@rubyforge.org/var/svn/codeforpeople/tagz/trunk/test
+svn+ssh://ahoward@rubyforge.org/var/svn/codeforpeople
+
+
+
+2009-03-23T22:32:47.865625Z
+767
+ahoward
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+29922619-e960-4932-8d85-0e0be7f1775a
+
+tagz.rb
+file
+773
+
+
+
+2009-03-24T16:59:47.000000Z
+73837f337ed378885f1df0c60e1caaaa
+2009-03-25T07:04:08.834319Z
+773
+ahoward
+has-props
+
1 test/.svn/format
@@ -0,0 +1 @@
+8
5 test/.svn/prop-base/tagz.rb.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
553 test/.svn/text-base/tagz.rb.svn-base
@@ -0,0 +1,553 @@
+#! /usr/bin/env ruby
+
+require 'test/unit'
+
+$VERBOSE = 2
+STDOUT.sync = true
+$:.unshift 'lib'
+$:.unshift '../lib'
+$:.unshift '.'
+
+require 'tagz'
+
+class TagzTest < Test::Unit::TestCase
+ include Tagz
+
+ class ::String
+ Equal = instance_method '=='
+ remove_method '=='
+ def == other
+ Equal.bind(self.delete(' ')).call other.to_s.delete(' ')
+ end
+ end
+
+ def test_000
+ expected = '<foo ></foo>'
+ actual = tagz{
+ foo_
+ _foo
+ }
+ assert_equal expected, actual
+ end
+
+ def test_010
+ expected = '<foo ><bar ></bar></foo>'
+ actual = tagz{
+ foo_
+ bar_
+ _bar
+ _foo
+ }
+ assert_equal expected, actual
+ end
+
+ def test_020
+ expected = '<foo ><bar /></foo>'
+ actual = tagz{
+ foo_
+ bar_{}
+ _foo
+ }
+ assert_equal expected, actual
+ end
+
+ def test_030
+ expected = '<foo ><bar /></foo>'
+ actual = tagz{
+ foo_{
+ bar_{}
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_040
+ expected = '<foo >bar</foo>'
+ actual = tagz{
+ foo_{ 'bar' }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_050
+ expected = '<foo ><bar >foobar</bar></foo>'
+ actual = tagz{
+ foo_{
+ bar_{ 'foobar' }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_060
+ expected = '<foo key="value" ><bar a="b" >foobar</bar></foo>'
+ actual = tagz{
+ foo_('key' => 'value'){
+ bar_(:a => :b){ 'foobar' }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_070
+ expected = '<foo /><bar />'
+ actual = tagz{
+ foo_{} + bar_{}
+ }
+ assert_equal expected, actual
+ end
+
+=begin
+ def test_080
+ assert_raises(Tagz::NotOpen) do
+ foo_{ _bar }
+ end
+ end
+ def test_090
+ assert_raises(Tagz::NotOpen) do
+ _foo
+ end
+ end
+ def test_100
+ assert_nothing_raised do
+ foo_
+ _foo
+ end
+ end
+=end
+
+ def test_110
+ expected = '<foo ><bar >foobar</bar></foo>'
+ actual = tagz{
+ foo_{
+ bar_{ 'foobar' }
+ 'this content is ignored because the block added content'
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_120
+ expected = '<foo ><bar >foobar</bar><baz >barfoo</baz></foo>'
+ actual = tagz{
+ foo_{
+ bar_{ 'foobar' }
+ baz_{ 'barfoo' }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_121
+ expected = '<foo ><bar >foobar</bar><baz >barfoo</baz></foo>'
+ actual = tagz{
+ foo_{
+ bar_{ 'foobar' }
+ baz_{ 'barfoo' }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_130
+ expected = '<foo >a<bar >foobar</bar>b<baz >barfoo</baz></foo>'
+ actual = tagz{
+ foo_{ |t|
+ t << 'a'
+ bar_{ 'foobar' }
+ t << 'b'
+ baz_{ 'barfoo' }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_140
+ expected = '<foo ><bar >baz</bar></foo>'
+ actual = tagz{
+ foo_{
+ bar_ << 'baz'
+ _bar
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_150
+ expected = '<foo ><bar >bar<baz >baz</baz></bar></foo>'
+ actual = tagz{
+ foo_{
+ bar_ << 'bar'
+ tag = baz_
+ tag << 'baz'
+ _baz
+ _bar
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_160
+ expected = '<foo >a<bar >b</bar></foo>'
+ actual = tagz{
+ foo_{ |foo|
+ foo << 'a'
+ bar_{ |bar|
+ bar << 'b'
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_170
+ expected = '<html ><body ><ul ><li >a</li><li >b</li><li >c</li></ul></body></html>'
+ @list = %w( a b c )
+ actual = tagz{
+ html_{
+ body_{
+ ul_{
+ @list.each{|elem| li_{ elem } }
+ }
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_180
+ expected = '<html ><body >42</body></html>'
+ actual = tagz{
+ html_{
+ b = body_
+ b << 42
+ _body
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_190
+ expected = '<html ><body >42</body></html>'
+ actual = tagz{
+ html_{
+ body_
+ tagz << 42 ### tagz is always the current tag!
+ _body
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_200
+ expected = '<html ><body >42</body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ tagz << 42 ### tagz is always the current tag!
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_210
+ expected = '<html ><body >42</body></html>'
+ actual = tagz{
+ html_{
+ body_{ |body|
+ body << 42
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+=begin
+ def test_220
+ expected = '<html ><body >42</body></html>'
+ actual = tagz{
+ 'html'.tag do
+ 'body'.tag do
+ 42
+ end
+ end
+ }
+ assert_equal expected, actual
+ end
+=end
+
+ def test_230
+ expected = '<html ><body ><div k="v" >content</div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_(:k => :v){ "content" }
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_240
+ expected = '<html ><body ><div k="v" >content</div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_ "content", :k => :v
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_241
+ expected = '<html ><body ><div k="v" >content</div></div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_ "content", :k => :v
+ _div
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_250
+ expected = '<html ><body ><div k="v" >content and more content</div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_("content", :k => :v){ ' and more content' }
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_260
+ expected = '<html ><body ><div k="v" >content</div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_ :k => :v
+ tagz << "content"
+ _div
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_270
+ expected = '<html ><body ><div k="v" >content</div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_ :k => :v
+ tagz << "content"
+ _div
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_280
+ expected = 'content'
+ actual = tagz{
+ tagz << "content"
+ }
+ assert_equal expected, actual
+ end
+
+ def test_290
+ expected = 'foobar'
+ actual = tagz{
+ tagz {
+ tagz << 'foo' << 'bar'
+ }
+ }
+ assert_equal expected, actual
+ end
+
+=begin
+ def test_300
+ expected = 'foobar'
+ actual = tagz{
+ tagz{ tagz 'foo', 'bar' }
+ }
+ assert_equal expected, actual
+ end
+=end
+
+ def test_310
+ expected = '<html ><body ><div k="v" >foobar</div></body></html>'
+ actual = tagz{
+ html_{
+ body_{
+ div_! "foo", "bar", :k => :v
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_320
+ expected = '<html ><body ><a href="a" >a</a><span >|</span><a href="b" >b</a><span >|</span><a href="c" >c</a></body></html>'
+ links = %w( a b c )
+ actual = tagz{
+ html_{
+ body_{
+ tagz.write links.map{|link| e(:a, :href => link){ link }}.join(e(:span){ '|' })
+ }
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_330
+ expected = '<a ><b ><c >'
+ actual = tagz{
+ tagz {
+ a_
+ b_
+ c_
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_340
+ expected = '<a ><b ><c ></a>'
+ actual = tagz{
+ a_ {
+ b_
+ c_
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_350
+ expected = '<a ><b ><c >content</c></a>'
+ actual = tagz{
+ a_ {
+ b_
+ c_ "content"
+ }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_360
+ expected = '<a ><b >content</b><c ><d >more content</d></a>'
+ actual = tagz{
+ a_ {
+ b_ "content"
+ c_
+ d_ "more content"
+ }
+ }
+ assert_equal expected, actual
+ end
+
+=begin
+ def test_370
+ expected = 'ab'
+ actual = tagz{
+ re = 'a'
+ re << tagz{'b'}
+ re
+ }
+ assert_equal expected, actual
+ end
+=end
+
+ def test_380
+ expected = 'ab'
+ actual = tagz{
+ tagz{ 'a' } + tagz{ 'b' }
+ }
+ assert_equal expected, actual
+ end
+
+ def test_390
+ expected = '<div class="bar&amp;foo&gt;">foo&amp;bar&gt;</div>'
+ # actual = tagz{ div_(:class => 'bar&foo>'){|t| t.h('foo&bar>') } }
+ actual = tagz{ div_(:class => 'bar&foo>'){ 'foo&bar>' } }
+ assert_equal expected, actual
+
+ expected = %|<div class="bar&amp;foo&gt;">#{ expected }</div>|
+ actual = tagz{ div_(:class => 'bar&foo>'){ actual } }
+ assert_equal expected, actual
+ end
+
+ def test_400
+ expected = '<div><span>foo&amp;bar</span></div>'
+ actual = tagz{ div_{ span_{ 'foo&bar' } } }
+ assert_equal expected, actual
+ end
+
+ def test_410
+ expected = '<div>false</div>'
+ actual = tagz{ div_{ false } }
+ assert_equal expected, actual
+ end
+
+ def test_420
+ expected = "<div>\n<span>foobar</span>\nfoobar\n</div>"
+ actual = tagz{ div_{ __; span_{ :foobar }; ___('foobar'); } }
+ assert_equal expected, actual
+ end
+
+ def test_430
+ c = Class.new{
+ include Tagz.globally
+ def foobar() div_{ 'foobar' } end
+ }.new
+
+ actual=nil
+ assert_nothing_raised{ actual=c.foobar }
+ expected = '<div>foobar</div>'
+ assert_equal expected, actual
+
+=begin
+ e = nil
+ assert_raises(NoMethodError){ begin; c.missing; ensure; e=$!; end }
+ assert e
+ messages = e.backtrace.map{|line| line.split(%r/:/, 3).last}
+ assert messages.all?{|message| message !~ /tagz/}
+=end
+ end
+
+ def test_440
+ c = Class.new{
+ include Tagz
+ def foobar() tagz{ div_{ 'foobar' } } end
+ def barfoo() div_{ 'barfoo' } end
+ }.new
+
+ actual=nil
+ assert_nothing_raised{ actual=c.foobar }
+ expected = '<div>foobar</div>'
+ assert_equal expected, actual
+
+ assert_raises(NoMethodError){ c.barfoo }
+ end
+
+ def test_450
+ c = Class.new{
+ include Tagz.globally
+ def a() tagz{ a_{ b(tagz); nil } } end
+ def b(doc=nil) tagz(doc){ b_{ 'content' } } end
+ }.new
+
+ actual=nil
+ assert_nothing_raised{ actual=c.a }
+ expected = '<a><b>content</b></a>'
+ assert_equal expected, actual
+ assert_nothing_raised{ c.b }
+ end
+end
553 test/tagz.rb
@@ -0,0 +1,553 @@