clifton_lib 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- clifton_lib (0.0.1)
4
+ clifton_lib (0.0.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -32,6 +32,14 @@ This implementation:
32
32
  2. Inherently supports dynamic XML generation
33
33
  3. Isn't DSL-ish.
34
34
 
35
+ ## Revisions
36
+
37
+ 0.0.5 - Added support to disallow a closing tag for HTML5 compatibility. For example, <img> is valid, <img></img> is seen as a stray ending tag.
38
+ 0.0.4 - Added support to disallow self-closing tags for HTML5 compatibility. For example, <div>...</div> is valid, </div> is not.
39
+ 0.0.3 - Added support for valueless attributes. Example: <nav class="top-bar" data-topbar/>
40
+ 0.0.2 - Additional internal properties for associating the XmlDocument to elements and XmlElement to attributes.
41
+ 0.0.1 - Initial version.
42
+
35
43
  ## A note about the code
36
44
 
37
45
  You'll find that I do certain things, like explicitly return nil when the function isn't intended to return anything. This avoids accidental usage of a return from a function where
@@ -1,3 +1,3 @@
1
1
  module CliftonLib
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -4,11 +4,14 @@ module CliftonXml
4
4
  class XmlAttribute
5
5
  attr_accessor :name
6
6
  attr_accessor :value
7
+ attr_accessor :xml_document
8
+ attr_accessor :xml_element
7
9
 
8
10
  # XmlAttribute.new() {@name = [name]; @value = [value]}
9
11
  def initialize(&block)
10
12
  # this can use the form {@<attr> = <value>}
11
13
  # allow for default constructor.
14
+ @xml_document = nil
12
15
  instance_eval(&block) unless block.nil?
13
16
  # yield self if block_given?
14
17
  # this requires the form {|inst| inst.<attr> = <value>}
@@ -13,29 +13,45 @@ module CliftonXml
13
13
  end
14
14
 
15
15
  # XmlDeclarationNode create_xml_declaration(string version, string encoding)
16
+ # Returns a node that will appear at the beginning of the document as:
17
+ # <?xml version="[ver]" encoding="[enc]" ?>
18
+ # The node must still be added to the parent (root) node with XmlNode#append_child.
16
19
  def create_xml_declaration(version, encoding)
17
20
  declNode = XmlDeclarationNode.new() {
18
21
  @attributes << XmlAttribute.new() {@name='version'; @value=version}
19
22
  @attributes << XmlAttribute.new() {@name='encoding'; @value=encoding}
20
23
  }
21
24
 
22
- declNode
23
- end
25
+ declNode.xml_document = self
24
26
 
25
- # XmlAttribute create_attribute(string name)
26
- def create_attribute(name)
27
- attr = XmlAttribute.new() {@name = name}
28
-
29
- attr
27
+ declNode
30
28
  end
31
29
 
32
30
  # XmlElement create_element(string name)
31
+ # Return an XmlElement. Append to the desired node with XmlNode#append_child.
33
32
  def create_element(name)
34
- elem = XmlElement.new() {@name = name}
33
+ elem = XmlElement.new() {
34
+ @name = name
35
+ }
36
+
37
+ elem.xml_document = self
35
38
 
36
39
  elem
37
40
  end
38
41
 
42
+ # XmlAttribute create_attribute(string name, string val = '')
43
+ # Returns an XmlAttribute. Append to the desired element with XmlElement#append_attribute.
44
+ def create_attribute(name, value = '')
45
+ attr = XmlAttribute.new() {
46
+ @name = name
47
+ @value = value
48
+ }
49
+
50
+ attr.xml_document = self
51
+
52
+ attr
53
+ end
54
+
39
55
  def document_element()
40
56
  # TODO
41
57
  end
@@ -45,6 +61,7 @@ module CliftonXml
45
61
  end
46
62
 
47
63
  # void save(XmlTextWriter writer)
64
+ # Writes the XML tree to the string buffer in XmlTextWriter.
48
65
  def save(writer)
49
66
  write_nodes(writer, @child_nodes)
50
67
 
@@ -87,8 +104,17 @@ module CliftonXml
87
104
  writer.write('</' + node.name + '>')
88
105
  crlf_if_more_nodes(writer, nodes, idx)
89
106
  else
90
- # if no children and no inner text, use the abbreviated closing tag token.
91
- writer.write('/>')
107
+ # if no children and no inner text, use the abbreviated closing tag token unless no closing tag is required and unless self closing tags are not allowed.
108
+ if node.html_closing_tag
109
+ if writer.allow_self_closing_tags
110
+ writer.write('/>')
111
+ else
112
+ writer.write('></' + node.name + '>')
113
+ end
114
+ else
115
+ writer.write('>')
116
+ end
117
+
92
118
  crlf_if_more_nodes(writer, nodes, idx)
93
119
  end
94
120
  end
@@ -106,7 +132,13 @@ module CliftonXml
106
132
  attrs = []
107
133
 
108
134
  node.attributes.each do |attr|
135
+ # special case:
136
+ # example: <nav class="top-bar" data-topbar>
137
+ if attr.value.nil?
138
+ attrs << attr.name
139
+ else
109
140
  attrs << attr.name + '="' + attr.value + '"'
141
+ end
110
142
  end
111
143
 
112
144
  # separate them with a space
@@ -15,6 +15,7 @@ module CliftonXml
15
15
  # void append_attributes(XmlAttribute attr)
16
16
  def append_attribute(attr)
17
17
  @attributes << attr
18
+ attr.xml_element = self
18
19
 
19
20
  nil
20
21
  end
@@ -5,6 +5,8 @@ module CliftonXml
5
5
  attr_accessor :name
6
6
  attr_accessor :inner_text
7
7
  attr_accessor :parent_node # Annoying rubyism -- if in the class itself, property must be read/writeable.
8
+ attr_accessor :xml_document
9
+ attr_accessor :html_closing_tag # Certain HTML closing tags are seen as "stray" if the exist, so we don't emit them if this is set to false.
8
10
  attr_reader :attributes
9
11
  attr_reader :child_nodes
10
12
 
@@ -15,6 +17,8 @@ module CliftonXml
15
17
  @parent_node = nil
16
18
  @name = nil
17
19
  @inner_text = nil
20
+ @xml_document = nil
21
+ @html_closing_tag = true
18
22
 
19
23
  self
20
24
  end
@@ -5,6 +5,7 @@ module CliftonXml
5
5
  # TODO: Implement streams, passing in an output stream to the constructor, like a StringWriter or FileWriter stream.
6
6
  class XmlTextWriter
7
7
  attr_accessor :formatting
8
+ attr_accessor :allow_self_closing_tags
8
9
  attr_reader :output
9
10
 
10
11
  # XmlTextWriter.new()
@@ -12,6 +13,7 @@ module CliftonXml
12
13
  @output = ''
13
14
  @indent = 0
14
15
  @formatting = :none
16
+ @allow_self_closing_tags = true # HTML5 compatibility, set to false.
15
17
  end
16
18
 
17
19
  # void write(string str)
@@ -104,6 +104,71 @@ class XmlDocumentTests < Test::Unit::TestCase
104
104
  xdoc.save(tw)
105
105
  output = tw.output
106
106
  assert_equal %Q|<?xml version="1.0" encoding="UTF-8"?>\r\n<Products>\r\n <Product ID="1" Name="Apples">foobar</Product>\r\n <Product ID="2" Name="Oranges"/>\r\n</Products>|, output
107
- end
108
107
  end
109
108
 
109
+ def test_properties
110
+ xdoc = XmlDocument.new()
111
+ decl_node = xdoc.create_xml_declaration('1.0', 'UTF-8')
112
+
113
+ # decl node is assigned the xml_document.
114
+ assert_equal xdoc, decl_node.xml_document
115
+
116
+ # element is assigned the xml_document.
117
+ elem = xdoc.create_element('Element')
118
+ assert_equal xdoc, elem.xml_document
119
+
120
+ # element is assigned the parent.
121
+ xdoc.append_child(elem)
122
+ assert_equal xdoc, elem.parent_node
123
+
124
+ # attribute is assigned the xml document.
125
+ attr = xdoc.create_attribute('Attribute')
126
+ assert_equal xdoc, attr.xml_document
127
+
128
+ # attribute is assigned the owning element.
129
+ elem.append_attribute(attr)
130
+ assert_equal elem, attr.xml_element
131
+ end
132
+
133
+ def test_attribute_without_value
134
+ # special case:
135
+ # example: <nav class="top-bar" data-topbar>
136
+ xdoc = XmlDocument.new()
137
+ elem = xdoc.create_element('Element')
138
+ xdoc.append_child(elem)
139
+ attr = xdoc.create_attribute('Attribute', nil)
140
+ elem.append_attribute(attr)
141
+ tw = XmlTextWriter.new()
142
+ tw.formatting = :indented
143
+ xdoc.save(tw)
144
+ output = tw.output
145
+ assert_equal %Q|<Element Attribute/>|, output
146
+ end
147
+
148
+ def test_no_self_closing_tags
149
+ xdoc = XmlDocument.new()
150
+ elem = xdoc.create_element('Element')
151
+ xdoc.append_child(elem)
152
+ tw = XmlTextWriter.new()
153
+ tw.allow_self_closing_tags = false
154
+ tw.formatting = :indented
155
+ xdoc.save(tw)
156
+ output = tw.output
157
+ assert_equal %Q|<Element></Element>|, output
158
+
159
+ end
160
+
161
+ def test_no_closing_tag
162
+ xdoc = XmlDocument.new()
163
+ elem = xdoc.create_element('img')
164
+ elem.html_closing_tag = false
165
+ xdoc.append_child(elem)
166
+ tw = XmlTextWriter.new()
167
+ tw.allow_self_closing_tags = false
168
+ tw.formatting = :indented
169
+ xdoc.save(tw)
170
+ output = tw.output
171
+ assert_equal %Q|<img>|, output
172
+
173
+ end
174
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clifton_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-13 00:00:00.000000000 Z
12
+ date: 2014-04-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
- requirement: &26145264 !ruby/object:Gem::Requirement
16
+ requirement: &25447320 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.3'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *26145264
24
+ version_requirements: *25447320
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &26144784 !ruby/object:Gem::Requirement
27
+ requirement: &25447068 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *26144784
35
+ version_requirements: *25447068
36
36
  description: A collection of useful helper classes, initially a set of classes to
37
37
  support creation and serialization of XML.
38
38
  email: