glimmer 0.1.0.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.rvmrc +1 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.markdown +54 -0
  5. data/Rakefile +54 -0
  6. data/VERSION +1 -0
  7. data/bin/glimmer +132 -0
  8. data/glimmer.gemspec +145 -0
  9. data/images/Bitter-sweet.jpg +0 -0
  10. data/{src → lib}/command_handler.rb +7 -10
  11. data/{src → lib}/command_handler_chain_factory.rb +29 -22
  12. data/{src → lib}/command_handler_chain_link.rb +19 -22
  13. data/{src → lib}/command_handlers.rb +29 -26
  14. data/{src → lib}/command_handlers/bind_command_handler.rb +25 -28
  15. data/lib/command_handlers/combo_selection_data_binding_command_handler.rb +39 -0
  16. data/{src → lib}/command_handlers/data_binding_command_handler.rb +61 -64
  17. data/lib/command_handlers/list_selection_data_binding_command_handler.rb +42 -0
  18. data/lib/command_handlers/models/list_observer.rb +31 -0
  19. data/{src → lib}/command_handlers/models/model_observer.rb +28 -25
  20. data/{src → lib}/command_handlers/models/observable_array.rb +53 -46
  21. data/lib/command_handlers/models/observable_model.rb +61 -0
  22. data/{src → lib}/command_handlers/models/r_runnable.rb +11 -14
  23. data/{src → lib}/command_handlers/models/r_shell.rb +23 -26
  24. data/lib/command_handlers/models/r_tab_item_composite.rb +25 -0
  25. data/{src → lib}/command_handlers/models/r_widget.rb +16 -14
  26. data/lib/command_handlers/models/r_widget_listener.rb +9 -0
  27. data/{src → lib}/command_handlers/models/r_widget_packages.rb +5 -8
  28. data/{src → lib}/command_handlers/models/table_items_updater.rb +38 -39
  29. data/{src → lib}/command_handlers/models/widget_observer.rb +4 -6
  30. data/{src → lib}/command_handlers/shell_command_handler.rb +14 -17
  31. data/{src → lib}/command_handlers/swt_constant_command_handler.rb +18 -21
  32. data/lib/command_handlers/tab_item_command_handler.rb +22 -0
  33. data/{src → lib}/command_handlers/table_column_properties_data_binding_command_handler.rb +20 -23
  34. data/{src → lib}/command_handlers/table_items_data_binding_command_handler.rb +26 -29
  35. data/{src → lib}/command_handlers/widget_command_handler.rb +22 -25
  36. data/{src → lib}/command_handlers/widget_listener_command_handler.rb +36 -34
  37. data/{src → lib}/command_handlers/widget_method_command_handler.rb +18 -21
  38. data/{src → lib}/glimmer.rb +52 -45
  39. data/lib/parent.rb +5 -0
  40. data/{src → lib}/shine.rb +21 -24
  41. data/{src → lib}/xml_command_handlers.rb +15 -18
  42. data/{src → lib}/xml_command_handlers/html_command_handler.rb +45 -49
  43. data/{src → lib}/xml_command_handlers/models/depth_first_search_iterator.rb +17 -20
  44. data/{src → lib}/xml_command_handlers/models/name_space_visitor.rb +17 -20
  45. data/{src → lib}/xml_command_handlers/models/node.rb +80 -83
  46. data/{src → lib}/xml_command_handlers/models/node_visitor.rb +8 -11
  47. data/{src → lib}/xml_command_handlers/models/xml_visitor.rb +58 -61
  48. data/{src → lib}/xml_command_handlers/xml_command_handler.rb +18 -22
  49. data/{src → lib}/xml_command_handlers/xml_name_space_command_handler.rb +31 -34
  50. data/{src → lib}/xml_command_handlers/xml_tag_command_handler.rb +23 -26
  51. data/{src → lib}/xml_command_handlers/xml_text_command_handler.rb +19 -22
  52. data/samples/contactmanager/contact.rb +0 -3
  53. data/samples/contactmanager/contact_manager.rb +1 -4
  54. data/samples/contactmanager/contact_manager_presenter.rb +0 -3
  55. data/samples/contactmanager/contact_repository.rb +0 -3
  56. data/samples/hello_combo.rb +32 -0
  57. data/samples/hello_world.rb +1 -4
  58. data/samples/login.rb +1 -4
  59. data/samples/tictactoe/tic_tac_toe.rb +2 -5
  60. data/samples/tictactoe/tic_tac_toe_board.rb +0 -3
  61. data/test/glimmer_combo_data_binding_test.rb +131 -0
  62. data/test/glimmer_constant_test.rb +6 -11
  63. data/test/glimmer_data_binding_test.rb +16 -16
  64. data/test/glimmer_list_data_binding_test.rb +223 -0
  65. data/test/glimmer_listeners_test.rb +6 -6
  66. data/test/glimmer_shine_data_binding_test.rb +7 -6
  67. data/test/glimmer_tab_item_test.rb +61 -0
  68. data/test/glimmer_table_data_binding_test.rb +7 -20
  69. data/test/glimmer_test.rb +18 -13
  70. data/test/helper.rb +21 -0
  71. data/test/observable_model_test.rb +2 -4
  72. data/test/r_widget_test.rb +5 -5
  73. data/test/samples/contactmanager/contact_manager_presenter_test.rb +1 -4
  74. data/test/samples/tictactoe/tic_tac_toe_test.rb +1 -4
  75. data/test/xml/glimmer_xml_test.rb +43 -43
  76. metadata +210 -105
  77. data/COPYING.LGPL +0 -504
  78. data/README +0 -27
  79. data/src/command_handlers/models/observable_model.rb +0 -35
  80. data/src/command_handlers/models/r_widget_listener.rb +0 -12
  81. data/src/parent.rb +0 -8
  82. data/src/swt.rb +0 -10
  83. data/src/xml.rb +0 -10
@@ -0,0 +1,5 @@
1
+ module Parent
2
+ def process_block(block)
3
+ raise "must be implemented by a class"
4
+ end
5
+ end
@@ -1,24 +1,21 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/glimmer"
5
-
6
- class Array
7
- include Glimmer
8
-
9
- alias original_compare <=>
10
-
11
- def <=>(other)
12
- if (self[0].class.name == "RWidget")
13
- add_contents(self[0]) {
14
- if (other.size == 2)
15
- eval("#{self[1]} bind (other[0], other[1])")
16
- elsif (other.size == 3)
17
- eval("#{self[1]} bind (other[0], other[1], other[2])")
18
- end
19
- }
20
- else
21
- original_compare(other)
22
- end
23
- end
24
- end
1
+ require File.dirname(__FILE__) + "/glimmer"
2
+
3
+ class Array
4
+ include Glimmer
5
+
6
+ alias original_compare <=>
7
+
8
+ def <=>(other)
9
+ if (self[0].class.name == "RWidget")
10
+ add_contents(self[0]) {
11
+ if (other.size == 2)
12
+ eval("#{self[1]} bind (other[0], other[1])")
13
+ elsif (other.size == 3)
14
+ eval("#{self[1]} bind (other[0], other[1], other[2])")
15
+ end
16
+ }
17
+ else
18
+ original_compare(other)
19
+ end
20
+ end
21
+ end
@@ -1,18 +1,15 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/command_handler_chain_factory"
5
- require File.dirname(__FILE__) + "/xml_command_handlers/xml_name_space_command_handler"
6
- require File.dirname(__FILE__) + "/xml_command_handlers/xml_text_command_handler"
7
- require File.dirname(__FILE__) + "/xml_command_handlers/xml_tag_command_handler"
8
- require File.dirname(__FILE__) + "/xml_command_handlers/html_command_handler"
9
- require File.dirname(__FILE__) + "/xml_command_handlers/xml_command_handler"
10
-
11
- # edit to add more command handlers and extend Glimmer
12
- CommandHandlerChainFactory.set_command_handlers(
13
- XmlNameSpaceCommandHandler.new,
14
- XmlTextCommandHandler.new,
15
- XmlTagCommandHandler.new,
16
- HtmlCommandHandler.new,
17
- XmlCommandHandler.new
18
- )
1
+ require File.dirname(__FILE__) + "/command_handler_chain_factory"
2
+ require File.dirname(__FILE__) + "/xml_command_handlers/xml_name_space_command_handler"
3
+ require File.dirname(__FILE__) + "/xml_command_handlers/xml_text_command_handler"
4
+ require File.dirname(__FILE__) + "/xml_command_handlers/xml_tag_command_handler"
5
+ require File.dirname(__FILE__) + "/xml_command_handlers/html_command_handler"
6
+ require File.dirname(__FILE__) + "/xml_command_handlers/xml_command_handler"
7
+
8
+ # edit to add more command handlers and extend Glimmer
9
+ CommandHandlerChainFactory.def_dsl(:xml,
10
+ XmlNameSpaceCommandHandler.new,
11
+ XmlTextCommandHandler.new,
12
+ XmlTagCommandHandler.new,
13
+ HtmlCommandHandler.new,
14
+ XmlCommandHandler.new
15
+ )
@@ -1,49 +1,45 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require "facets/dictionary"
5
- require File.dirname(__FILE__) + "/../command_handler"
6
- require File.dirname(__FILE__) + "/models/node"
7
-
8
- class HtmlCommandHandler
9
- include CommandHandler
10
-
11
- def can_handle?(parent, command_symbol, *args, &block)
12
- (parent == nil or parent.is_a?(Node)) and
13
- (args.size == 0 or ((args.size == 1) and ((args[0].is_a?(Hash)) or (args[0].is_a?(Hash)))))
14
- end
15
-
16
- def do_handle(parent, command_symbol, *args, &block)
17
- attributes = Dictionary.new
18
- attributes = args[0] if (args.size == 1)
19
- append_id_and_class_attributes(command_symbol.to_s, attributes)
20
- tag_name = parse_tag_name(command_symbol.to_s)
21
- Node.new(parent, tag_name, attributes, &block)
22
- end
23
-
24
- def parse_tag_name(command)
25
- match_data = command.match("_")
26
- if (match_data.to_a.size > 0)
27
- command.match("_").pre_match
28
- else
29
- command
30
- end
31
- end
32
-
33
- def append_id_and_class_attributes(command, attributes)
34
- class_only_match = command.match("__.+").to_s
35
- if class_only_match.length > 0
36
- class_value = class_only_match[2, class_only_match.length]
37
- else
38
- match_data = command.match("_[^_]+")
39
- return unless match_data
40
- match = match_data.to_s
41
- id_value = match[1, match.length] if match.length > 0
42
- attributes[:id] = id_value if id_value
43
- match2 = match_data.post_match.match("_[^_]+").to_s if match_data.post_match
44
- class_value = match2[1, match2.length] if match2.length > 0
45
- end
46
- attributes[:class] = class_value if class_value
47
- end
48
-
49
- end
1
+ require File.dirname(__FILE__) + "/../command_handler"
2
+ require File.dirname(__FILE__) + "/models/node"
3
+
4
+ class HtmlCommandHandler
5
+ include CommandHandler
6
+
7
+ def can_handle?(parent, command_symbol, *args, &block)
8
+ (parent == nil or parent.is_a?(Node)) and
9
+ (args.size == 0 or ((args.size == 1) and ((args[0].is_a?(Hash)) or (args[0].is_a?(Hash)))))
10
+ end
11
+
12
+ def do_handle(parent, command_symbol, *args, &block)
13
+ attributes = Hash.new
14
+ attributes = args[0] if (args.size == 1)
15
+ append_id_and_class_attributes(command_symbol.to_s, attributes)
16
+ tag_name = parse_tag_name(command_symbol.to_s)
17
+ Node.new(parent, tag_name, attributes, &block)
18
+ end
19
+
20
+ def parse_tag_name(command)
21
+ match_data = command.match("_")
22
+ if (match_data.to_a.size > 0)
23
+ command.match("_").pre_match
24
+ else
25
+ command
26
+ end
27
+ end
28
+
29
+ def append_id_and_class_attributes(command, attributes)
30
+ class_only_match = command.match("__.+").to_s
31
+ if class_only_match.length > 0
32
+ class_value = class_only_match[2, class_only_match.length]
33
+ else
34
+ match_data = command.match("_[^_]+")
35
+ return unless match_data
36
+ match = match_data.to_s
37
+ id_value = match[1, match.length] if match.length > 0
38
+ attributes[:id] = id_value if id_value
39
+ match2 = match_data.post_match.match("_[^_]+").to_s if match_data.post_match
40
+ class_value = match2[1, match2.length] if match2.length > 0
41
+ end
42
+ attributes[:class] = class_value if class_value
43
+ end
44
+
45
+ end
@@ -1,20 +1,17 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- class DepthFirstSearchIterator
5
- def initialize(node, node_visitor)
6
- @node = node
7
- @node_visitor = node_visitor
8
- end
9
-
10
- def iterate
11
- process(@node)
12
- end
13
-
14
- def process(node)
15
- @node_visitor.process_before_children(node)
16
- node.children.each { |child| process(child) } unless node.is_a?(String)
17
- @node_visitor.process_after_children(node)
18
- end
19
-
20
- end
1
+ class DepthFirstSearchIterator
2
+ def initialize(node, node_visitor)
3
+ @node = node
4
+ @node_visitor = node_visitor
5
+ end
6
+
7
+ def iterate
8
+ process(@node)
9
+ end
10
+
11
+ def process(node)
12
+ @node_visitor.process_before_children(node)
13
+ node.children.each { |child| process(child) } unless node.is_a?(String)
14
+ @node_visitor.process_after_children(node)
15
+ end
16
+
17
+ end
@@ -1,21 +1,18 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/node_visitor"
5
-
6
- class NameSpaceVisitor < NodeVisitor
7
-
8
- def initialize(name_space_name)
9
- @name_space_name = name_space_name
10
- end
11
-
12
- def process_before_children(node)
13
- return if node.is_a?(String)
14
- node.name_space = Node.new(nil, @name_space_name, nil) if node and !node.name_space
15
- end
16
-
17
- def process_after_children(node)
18
- #NOOP
19
- end
20
-
1
+ require File.dirname(__FILE__) + "/node_visitor"
2
+
3
+ class NameSpaceVisitor < NodeVisitor
4
+
5
+ def initialize(name_space_name)
6
+ @name_space_name = name_space_name
7
+ end
8
+
9
+ def process_before_children(node)
10
+ return if node.is_a?(String)
11
+ node.name_space = Node.new(nil, @name_space_name, nil) if node and !node.name_space
12
+ end
13
+
14
+ def process_after_children(node)
15
+ #NOOP
16
+ end
17
+
21
18
  end
@@ -1,83 +1,80 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/depth_first_search_iterator"
5
- require File.dirname(__FILE__) + "/xml_visitor"
6
-
7
- class Node
8
- include Parent, Glimmer
9
-
10
- attr_accessor :children, :name, :contents, :attributes, :is_name_space, :is_attribute, :name_space, :parent
11
-
12
- def initialize(parent, name, attributes, &contents)
13
- @is_name_space = false
14
- @children = []
15
- @parent = parent
16
- if (parent and parent.is_name_space)
17
- @name_space = parent
18
- @parent = @name_space.parent
19
- end
20
- @parent.children << self if @parent
21
- @name = name
22
- @contents = contents
23
- @attributes = attributes
24
- if @attributes
25
- @attributes.each_key do |attribute|
26
- if attribute.is_a?(Node)
27
- attribute.is_attribute = true
28
- attribute.parent.children.delete(attribute) if attribute.parent
29
- attribute.parent = nil #attributes do not usually have parents
30
- end
31
- end
32
- p attributes
33
- end
34
- end
35
-
36
- def method_missing(symbol, *args, &block)
37
- @is_name_space = true
38
- parent.children.delete(self) if parent
39
- Glimmer.add_contents(self) {@tag = super}
40
- @tag
41
- end
42
-
43
- def to_xml
44
- xml_visitor = XmlVisitor.new
45
- DepthFirstSearchIterator.new(self, xml_visitor).iterate
46
- xml_visitor.document
47
- end
48
-
49
- def process_block(block)
50
- return_value = block.call(@widget)
51
- if return_value.is_a?(String) and !@children.include?(return_value)
52
- text = return_value
53
- first_match = text.match(/[#][^{]+[{][^}]+[}]/)
54
- match = first_match
55
- while (match)
56
- Glimmer.module_eval(text_command(match.pre_match))
57
- tag_text = match.to_s
58
- Glimmer.module_eval(rubyize(tag_text))
59
- text = tag_text
60
- post_match = match.post_match
61
- match = text.match(/[#]\w+[{]\w+[}]/)
62
- end
63
- Glimmer.module_eval(text_command(post_match)) if post_match
64
- @children << return_value unless first_match
65
- end
66
- end
67
-
68
- def text_command(text)
69
- "text \"#{text}\""
70
- end
71
-
72
- def rubyize(text)
73
- text = text.gsub(/[}]/, '"}')
74
- text = text.gsub(/[{]/, '{"')
75
- text = text.gsub(/[#]/, '')
76
- end
77
-
78
- #override Object default id method and route it to Glimmer engine
79
- def id
80
- method_missing(:id)
81
- end
82
-
83
- end
1
+ require File.dirname(__FILE__) + "/depth_first_search_iterator"
2
+ require File.dirname(__FILE__) + "/xml_visitor"
3
+
4
+ class Node
5
+ include Parent, Glimmer
6
+
7
+ attr_accessor :children, :name, :contents, :attributes, :is_name_space, :is_attribute, :name_space, :parent
8
+
9
+ def initialize(parent, name, attributes, &contents)
10
+ @is_name_space = false
11
+ @children = []
12
+ @parent = parent
13
+ if (parent and parent.is_name_space)
14
+ @name_space = parent
15
+ @parent = @name_space.parent
16
+ end
17
+ @parent.children << self if @parent
18
+ @name = name
19
+ @contents = contents
20
+ @attributes = attributes
21
+ if @attributes
22
+ @attributes.each_key do |attribute|
23
+ if attribute.is_a?(Node)
24
+ attribute.is_attribute = true
25
+ attribute.parent.children.delete(attribute) if attribute.parent
26
+ attribute.parent = nil #attributes do not usually have parents
27
+ end
28
+ end
29
+ p attributes
30
+ end
31
+ end
32
+
33
+ def method_missing(symbol, *args, &block)
34
+ @is_name_space = true
35
+ parent.children.delete(self) if parent
36
+ Glimmer.add_contents(self) {@tag = super}
37
+ @tag
38
+ end
39
+
40
+ def to_xml
41
+ xml_visitor = XmlVisitor.new
42
+ DepthFirstSearchIterator.new(self, xml_visitor).iterate
43
+ xml_visitor.document
44
+ end
45
+
46
+ def process_block(block)
47
+ return_value = block.call(@widget)
48
+ if return_value.is_a?(String) and !@children.include?(return_value)
49
+ text = return_value
50
+ first_match = text.match(/[#][^{]+[{][^}]+[}]/)
51
+ match = first_match
52
+ while (match)
53
+ Glimmer.module_eval(text_command(match.pre_match))
54
+ tag_text = match.to_s
55
+ Glimmer.module_eval(rubyize(tag_text))
56
+ text = tag_text
57
+ post_match = match.post_match
58
+ match = text.match(/[#]\w+[{]\w+[}]/)
59
+ end
60
+ Glimmer.module_eval(text_command(post_match)) if post_match
61
+ @children << return_value unless first_match
62
+ end
63
+ end
64
+
65
+ def text_command(text)
66
+ "text \"#{text}\""
67
+ end
68
+
69
+ def rubyize(text)
70
+ text = text.gsub(/[}]/, '"}')
71
+ text = text.gsub(/[{]/, '{"')
72
+ text = text.gsub(/[#]/, '')
73
+ end
74
+
75
+ #override Object default id method and route it to Glimmer engine
76
+ def id
77
+ method_missing(:id)
78
+ end
79
+
80
+ end
@@ -1,12 +1,9 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- class NodeVisitor
5
- def process_before_children
6
- raise "must be implemented by a class"
7
- end
8
-
9
- def process_after_children
10
- raise "must be implemented by a class"
11
- end
1
+ class NodeVisitor
2
+ def process_before_children
3
+ raise "must be implemented by a class"
4
+ end
5
+
6
+ def process_after_children
7
+ raise "must be implemented by a class"
8
+ end
12
9
  end
@@ -1,62 +1,59 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/node_visitor"
5
-
6
- class XmlVisitor < NodeVisitor
7
-
8
- attr_reader :document
9
-
10
- def initialize
11
- @document = ""
12
- end
13
-
14
- def process_before_children(node)
15
- if (node.is_a?(String))
16
- @document << node
17
- return
18
- end
19
- begin_open_tag(node)
20
- append_attributes(node) if node.attributes
21
- end_open_tag(node)
22
- end
23
-
24
- def process_after_children(node)
25
- return if (node.is_a?(String))
26
- append_close_tag(node)
27
- end
28
-
29
- def begin_open_tag(node)
30
- @document << "<"
31
- @document << "#{node.name_space.name}:" if node.name_space
32
- @document << node.name
33
- end
34
-
35
- def end_open_tag(node)
36
- if (node.contents)
37
- @document << ">"
38
- else
39
- @document << " " if node.attributes.keys.size > 0
40
- @document << "/>"
41
- end
42
- end
43
-
44
- def append_close_tag(node)
45
- if (node.contents)
46
- @document << "</"
47
- @document << "#{node.name_space.name}:" if node.name_space
48
- @document << "#{node.name}>"
49
- end
50
- end
51
-
52
- def append_attributes(node)
53
- puts "Take 3"
54
- p node.attributes
55
- node.attributes.each_key do |attribute|
56
- attribute_name = attribute
57
- attribute_name = "#{attribute.name_space.name}:#{attribute.name}" if attribute.is_a?(Node)
58
- @document << " #{attribute_name}=\"#{node.attributes[attribute]}\""
59
- end
60
- end
61
-
1
+ require File.dirname(__FILE__) + "/node_visitor"
2
+
3
+ class XmlVisitor < NodeVisitor
4
+
5
+ attr_reader :document
6
+
7
+ def initialize
8
+ @document = ""
9
+ end
10
+
11
+ def process_before_children(node)
12
+ if (node.is_a?(String))
13
+ @document << node
14
+ return
15
+ end
16
+ begin_open_tag(node)
17
+ append_attributes(node) if node.attributes
18
+ end_open_tag(node)
19
+ end
20
+
21
+ def process_after_children(node)
22
+ return if (node.is_a?(String))
23
+ append_close_tag(node)
24
+ end
25
+
26
+ def begin_open_tag(node)
27
+ @document << "<"
28
+ @document << "#{node.name_space.name}:" if node.name_space
29
+ @document << node.name
30
+ end
31
+
32
+ def end_open_tag(node)
33
+ if (node.contents)
34
+ @document << ">"
35
+ else
36
+ @document << " " if node.attributes.keys.size > 0
37
+ @document << "/>"
38
+ end
39
+ end
40
+
41
+ def append_close_tag(node)
42
+ if (node.contents)
43
+ @document << "</"
44
+ @document << "#{node.name_space.name}:" if node.name_space
45
+ @document << "#{node.name}>"
46
+ end
47
+ end
48
+
49
+ def append_attributes(node)
50
+ puts "Take 3"
51
+ p node.attributes
52
+ node.attributes.each_key do |attribute|
53
+ attribute_name = attribute
54
+ attribute_name = "#{attribute.name_space.name}:#{attribute.name}" if attribute.is_a?(Node)
55
+ @document << " #{attribute_name}=\"#{node.attributes[attribute]}\""
56
+ end
57
+ end
58
+
62
59
  end