clifton_lib 0.0.1 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: