[PATCH] tagz-5.0.0 -- processing instruction support

A

Andrew S. Townley

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
:eek:pen_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"?><test/>
 
A

Andrew S. Townley

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

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:
<list><container><element><child1>hello world</child1></element/><container><element><child1>hello world</child1></element/></list>
^^^^^^^^^^^

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.

<list>
<container>
<element>
<child1>hello world</child1>
</element>
<element2>
<child2>some child</child2>
</element2>
</container>
<container>
<element>
<child1>hello world</child1>
</element>
<element2>
<child2>some child</child2>
</element2>
</container>
</list>

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

[PATCH] tagz-5.0.1 -- processing instruction support 1
[PATCH] tagz-5.0.0 0
[ANN] tagz-5.0.0 43
[ANN] tagz-4.6.0 1
[ANN] tagz-4.2.0 - giraffe slayer 9
[ANN] tagz-1.0.0 0
[BUG/PATCH] cgi/session.rb 11
Writing a parser 17

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top