Tagz-5.0.0 -- processing instruction support

Hi Ara,

I’m sure you’re sick of me by now, but I’ve added processing instruction
support to tagz. It may not suit your style, but I’ve tried to keep it
in the spirit of the library.

excalibur$ diff
-u /var/lib/gems/1.8/gems/tagz-5.0.0/lib/tagz.rb /tmp/tagz.rb
— /var/lib/gems/1.8/gems/tagz-5.0.0/lib/tagz.rb 2009-03-24
11:58:05.000000000 +0000
+++ /tmp/tagz.rb 2009-03-27 18:01:11.000000000 +0000
@@ -15,27 +15,7 @@

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
    
  •  attributes, content = process_attributes *argv, &block
     tagz.concat "<#{ name }#{ attributes }>"
    
     if content.empty?
    

@@ -68,6 +48,13 @@
tagz.concat “</#{ tag }>”
end

  • processing instruction

  • def tagz_? name, *argv, &block
  •  attributes, content = process_attributes *argv, &block
    
  •  tagz.concat "<?#{ name }#{ attributes }?>"
    
  • end
  • access tagz doc and enclose tagz operations

    def tagz document = nil, &block
    @@ -94,6 +81,8 @@
    def method_missing m, *a, &b
    strategy =
    case m.to_s
  •      when %r/^(.*[^?])_\?$/o
    
  •        :processing_instruction
         when %r/^(.*[^_])_(!)?$/o
           :open_tag
         when %r/^_([^_].*)$/o
    

@@ -119,6 +108,9 @@
m, bang = $1, $2
b ||= lambda{} if bang
tagz{ tagz__(m, *a, &b) }

  •    when :processing_instruction
    
  •      m = $1
    
  •      tagz{ tagz_?(m, *a, &b) }
       when :close_tag
         m = $1
         tagz{ __tagz(m, *a, &b) }
    

@@ -135,6 +127,33 @@
end
end

  • def process_attributes *argv, &block
  •  options = argv.last.is_a?(Hash) ? argv.pop : {}
    
  •  content = argv
    
  •  attributes = nil
    
  •  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
    
  •  [ attributes, content ]
    
  • end
  • class Document < ::String
    def Document.for other
    Document === other ? other : Document.new(other.to_s)

excalibur$ cat c.rb
require ‘tagz’
include Tagz.globally

doc =
Tagz {
xml_?(:version => “1.0”)
mypi_?(:arg1 => “foo”)
tagz_?(“xml-stylesheet”, :href => “classic.xsl”, :type =>
“text/xml”)
test_!
}

puts doc

excalibur$ ruby c.rb

<?xml version="1.0"?><?mypi arg1="foo"?><?xml-stylesheet type="text/xml"

href=“classic.xsl”?>

On Sat, 2009-03-28 at 03:05 +0900, Andrew S. Townley wrote:

+++ /tmp/tagz.rb 2009-03-27 18:01:11.000000000 +0000
Hi Ara,

I was wondering if you might be able to help me. It seems that by
moving the attribute processing into a separate method, I’ve screwed up
the scope handling. The patch does indeed deliver processing
instructions and works fine in the “happy day” path, but if you use any
kind of conditionals inside an element block, it seems to go haywire.

i.e.:
$ cat a.rb
#require ‘rubygems’
require ‘tagz’

include Tagz.globally

def makeelt
container_{
element_ {
child1_ “hello world”
}
arr = []
if arr.length > 0
element2_ {
child2_ “some child”
}
end
}
end

puts Tagz {
list_{
2.times do
makeelt
end
}
}

With the patch applied, it gives the following bogus markup:
hello
world</element/>hello
world</element/>
^^^^^^^^^^^

With your version, it works as expected, so obviously the patch is
busted.

Clearly, I don’t quite understand what’s going on enough to know why
what I changed would cause this sort of behavior. Would you have any
ideas?

The PI support is a bit of syntax sugar that will be handy for
generating some of the XML that I need to generate, but I can get by
with the vanilla one for now.

Still, I’d like to understand why the behavior occurs. If you or anyone
else has an idea, I’d love to hear it.

If you add an element to the array, it works as expected, so the
conditional is certainly the key somehow…

$ ruby a.rb | tidy -xml -i
No warnings or errors were found.

hello world some child hello world some child

Other than that, I have to say that I’ve found Tagz absolutely fantastic
to work with. I’m in the process of converting some of my code to use
it instead of using string concatenation & hand-coded elements for
building XML, and it just makes sense.

Brilliant stuff!

Cheers,

ast

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs