[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[PATCH] tagz-5.0.0 -- processing instruction support

Andrew S. Townley

3/27/2009 6:06:00 PM

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"?><test/>
--
Andrew S. Townley <ast@atownley.org>
http://at...


1 Answer

Andrew S. Townley

3/29/2009 12:26:00 AM

0

On Sat, 2009-03-28 at 03:05 +0900, Andrew S. Townley wrote:
> 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
--
Andrew S. Townley <ast@atownley.org>
http://at...