html-table 1.6.3 → 1.7.1

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/{CHANGES.rdoc → CHANGES.md} +76 -68
  4. data/Gemfile +2 -0
  5. data/MANIFEST.md +57 -0
  6. data/{README.rdoc → README.md} +80 -71
  7. data/Rakefile +122 -146
  8. data/doc/attributes.md +160 -0
  9. data/doc/table.md +173 -0
  10. data/doc/table_body.md +9 -0
  11. data/doc/table_caption.md +10 -0
  12. data/doc/table_colgroup.md +8 -0
  13. data/doc/table_colgroup_col.md +7 -0
  14. data/doc/table_content.md +17 -0
  15. data/doc/table_foot.md +8 -0
  16. data/doc/table_head.md +10 -0
  17. data/doc/table_row.md +114 -0
  18. data/doc/table_row_data.md +100 -0
  19. data/doc/table_row_header.md +6 -0
  20. data/examples/simple1.rb +7 -5
  21. data/html-table.gemspec +16 -11
  22. data/lib/html/body.rb +9 -7
  23. data/lib/html/caption.rb +4 -2
  24. data/lib/html/col.rb +37 -34
  25. data/lib/html/colgroup.rb +90 -97
  26. data/lib/html/content.rb +3 -6
  27. data/lib/html/data.rb +3 -1
  28. data/lib/html/foot.rb +53 -45
  29. data/lib/html/head.rb +54 -47
  30. data/lib/html/header.rb +5 -3
  31. data/lib/html/mixin/attribute_handler.rb +59 -55
  32. data/lib/html/mixin/html_handler.rb +33 -35
  33. data/lib/html/mixin/strongtyping.rb +6 -6
  34. data/lib/html/mixin/tag_handler.rb +6 -2
  35. data/lib/html/row.rb +156 -183
  36. data/lib/html/table.rb +45 -45
  37. data/lib/html/tablesection.rb +51 -46
  38. data/spec/attribute_handler_spec.rb +374 -0
  39. data/spec/body_spec.rb +98 -0
  40. data/spec/caption_spec.rb +83 -0
  41. data/spec/colgroup_col_spec.rb +34 -0
  42. data/spec/colgroup_spec.rb +97 -0
  43. data/spec/data_spec.rb +88 -0
  44. data/spec/foot_spec.rb +116 -0
  45. data/spec/head_spec.rb +116 -0
  46. data/spec/header_spec.rb +85 -0
  47. data/spec/html_handler_spec.rb +35 -0
  48. data/spec/row_spec.rb +163 -0
  49. data/spec/table_spec.rb +186 -0
  50. data/spec/tablesection_spec.rb +36 -0
  51. data/spec/tag_handler_spec.rb +85 -0
  52. data.tar.gz.sig +0 -0
  53. metadata +118 -92
  54. metadata.gz.sig +0 -0
  55. data/MANIFEST.rdoc +0 -56
  56. data/doc/attributes.rdoc +0 -143
  57. data/doc/table.rdoc +0 -156
  58. data/doc/table_body.rdoc +0 -9
  59. data/doc/table_caption.rdoc +0 -9
  60. data/doc/table_colgroup.rdoc +0 -8
  61. data/doc/table_colgroup_col.rdoc +0 -9
  62. data/doc/table_content.rdoc +0 -15
  63. data/doc/table_foot.rdoc +0 -8
  64. data/doc/table_head.rdoc +0 -11
  65. data/doc/table_row.rdoc +0 -105
  66. data/doc/table_row_data.rdoc +0 -92
  67. data/doc/table_row_header.rdoc +0 -7
  68. data/test/test_attribute_handler.rb +0 -361
  69. data/test/test_body.rb +0 -87
  70. data/test/test_caption.rb +0 -80
  71. data/test/test_col.rb +0 -40
  72. data/test/test_colgroup.rb +0 -89
  73. data/test/test_data.rb +0 -77
  74. data/test/test_foot.rb +0 -111
  75. data/test/test_head.rb +0 -104
  76. data/test/test_header.rb +0 -77
  77. data/test/test_html_handler.rb +0 -37
  78. data/test/test_row.rb +0 -141
  79. data/test/test_table.rb +0 -159
  80. data/test/test_tablesection.rb +0 -42
  81. data/test/test_tag_handler.rb +0 -90
@@ -1,31 +1,33 @@
1
+ # The HTML module serves as a namespace only.
1
2
  module HTML
3
+ # The Mixin module is a namespace for html-table mixins.
2
4
  module Mixin
5
+ # The HtmlHandler module is the library for generating html output.
3
6
  module HtmlHandler
4
-
5
- $upper = false
6
-
7
7
  # Used on HTML attributes. It creates proper HTML text based on the argument
8
- # type. A string looks like "attr='text'", a number looks like "attr=1",
8
+ # type. A string looks like "attr='text'", a number looks like "attr=1",
9
9
  # while a true value simply looks like "attr" (no equal sign).
10
10
  #--
11
11
  # This is private method.
12
12
  #
13
- def modify_html(attribute,arg=nil)
13
+ def modify_html(attribute, arg = nil)
14
14
  if @html_begin.scan(/\b#{attribute}\b/).empty?
15
- if arg.kind_of?(Integer)
16
- @html_begin << " #{attribute}=#{arg}"
17
- elsif arg.kind_of?(TrueClass)
18
- @html_begin << " #{attribute}"
19
- else
20
- @html_begin << " #{attribute}='#{arg}'"
15
+ case arg
16
+ when Integer
17
+ @html_begin << " #{attribute}=#{arg}"
18
+ when TrueClass
19
+ @html_begin << " #{attribute}"
20
+ else
21
+ @html_begin << " #{attribute}='#{arg}'"
21
22
  end
22
23
  else
23
- if arg.kind_of?(Integer)
24
- @html_begin.gsub!(/#{attribute}=\d+/,"#{attribute}=#{arg}")
25
- elsif arg.kind_of?(FalseClass)
26
- @html_begin.gsub!(/#{attribute}/,'')
27
- else
28
- @html_begin.gsub!(/#{attribute}=['\w\.]+/,"#{attribute}='#{arg}'")
24
+ case arg
25
+ when Integer
26
+ @html_begin.gsub!(/#{attribute}=\d+/, "#{attribute}=#{arg}")
27
+ when FalseClass
28
+ @html_begin.gsub!(/#{attribute}/, '')
29
+ else
30
+ @html_begin.gsub!(/#{attribute}=['\w.]+/, "#{attribute}='#{arg}'")
29
31
  end
30
32
  end
31
33
  end
@@ -38,11 +40,7 @@ module HTML
38
40
  # honored.
39
41
  #
40
42
  def html(formatting = true)
41
- if self.class.respond_to?(:html_case)
42
- $upper = true if self.class.html_case == "upper"
43
- end
44
-
45
- if $upper
43
+ if HTML::Table.html_case == 'upper'
46
44
  @html_begin.upcase!
47
45
  @html_end.upcase!
48
46
  end
@@ -53,15 +51,15 @@ module HTML
53
51
  ilevel = self.class.indent_level
54
52
  end
55
53
 
56
- html = ' ' * ilevel + @html_begin[0..-1]
54
+ html = (' ' * ilevel) + @html_begin[0..]
57
55
  len = html.length
58
- html[len,len] = '>'
56
+ html[len, len] = '>'
59
57
 
60
- if self.kind_of?(Array)
58
+ if is_a?(Array)
61
59
  if formatting
62
- html << self.map{ |e| "\n" + e.html(formatting).to_s }.join
60
+ html << map { |e| "\n#{e.html(formatting)}" }.join
63
61
  else
64
- html << self.map{ |e| e.html(formatting).to_s }.join
62
+ html << map { |e| e.html(formatting).to_s }.join
65
63
  end
66
64
  else
67
65
  html << @html_body
@@ -75,29 +73,29 @@ module HTML
75
73
  # The Table.global_end_tags method overrides the individual class
76
74
  # preferences with regards to end tags.
77
75
  #####################################################################
78
- if self.kind_of?(Array)
76
+ if is_a?(Array)
79
77
  if HTML::Table.global_end_tags?
80
78
  if self.class.respond_to?(:end_tags?)
81
79
  if formatting
82
80
  if self.class.end_tags?
83
- html << "\n" + (' ' * ilevel) + @html_end
81
+ html << ("\n" << (' ' * ilevel) << @html_end)
84
82
  end
85
83
  else
86
- html << (' ' * ilevel) + @html_end if self.class.end_tags?
84
+ html << ((' ' * ilevel) << @html_end) if self.class.end_tags?
87
85
  end
88
86
  else
89
87
  if formatting
90
- html << "\n" + (' ' * ilevel) + @html_end
88
+ html << ("\n" << (' ' * ilevel) << @html_end)
91
89
  else
92
- html << (' ' * ilevel) + @html_end
90
+ html << ((' ' * ilevel) << @html_end)
93
91
  end
94
92
  end
95
93
  else
96
94
  unless self.class.respond_to?(:end_tags?)
97
95
  if formatting
98
- html << "\n" + (' ' * ilevel) + @html_end
96
+ html << ("\n" << (' ' * ilevel) << @html_end)
99
97
  else
100
- html << (' ' * ilevel) + @html_end
98
+ html << ((' ' * ilevel) << @html_end)
101
99
  end
102
100
  end
103
101
  end
@@ -115,7 +113,7 @@ module HTML
115
113
  end
116
114
  end
117
115
 
118
- return html
116
+ html
119
117
  end
120
118
 
121
119
  private :modify_html
@@ -1,16 +1,16 @@
1
- # A pure-ruby replacement for strongtyping gem
2
-
1
+ # The HTML module serves as a namespace only.
3
2
  module HTML
3
+ # The Mixin module serves as a namespace only to prevent collisions.
4
4
  module Mixin
5
+ # The StrongTyping module is a pure Ruby replacement for the strongtyping gem.
5
6
  module StrongTyping
6
- class ArgumentTypeError < ArgumentError; end
7
-
8
7
  def expect(arg, allowed_types)
9
8
  return true if Array(allowed_types).any? do |klass|
10
- arg.kind_of?(klass)
9
+ arg.is_a?(klass)
11
10
  end
12
11
 
13
- raise ArgumentTypeError.new("#{arg} must be of type #{allowed_types}")
12
+ # Defined in table.rb
13
+ raise ArgumentTypeError, "#{arg} must be of type #{allowed_types}"
14
14
  end
15
15
  end
16
16
  end
@@ -5,8 +5,12 @@
5
5
  # Only used for Table::Content objects, which are in turn used by
6
6
  # Table::Row::Data, Table::Row::Header and Table::Caption.
7
7
  ###################################################################
8
+
9
+ # The HTML module serves as a namespace only.
8
10
  module HTML
11
+ # The Mixin module serves as a namespace only.
9
12
  module Mixin
13
+ # The TagHandler module implements handling for standard html physical tags.
10
14
  module TagHandler
11
15
  def bold(bool = nil)
12
16
  @bold ||= nil
@@ -115,9 +119,9 @@ module HTML
115
119
  end_tag = "</#{tag}>"
116
120
 
117
121
  if bool
118
- self.replace(begin_tag << self << end_tag)
122
+ replace(begin_tag << self << end_tag)
119
123
  else
120
- self.replace(self.gsub(/#{begin_tag}|#{end_tag}/,''))
124
+ replace(gsub(/#{begin_tag}|#{end_tag}/, ''))
121
125
  end
122
126
  end
123
127
  end
data/lib/html/row.rb CHANGED
@@ -1,188 +1,161 @@
1
+ # The HTML module is a namespace only.
1
2
  module HTML
2
- class Table::Row < Array
3
- include HTML::Mixin::AttributeHandler
4
- include HTML::Mixin::HtmlHandler
5
-
6
- @indent_level = 3
7
- @end_tags = true
8
-
9
- # Returns a new Table::Row object. Optionally takes a block. If +arg+
10
- # is provided it is treated as content. If +header+ is false, that
11
- # content is transformed into a Row::Data object. Otherwise, it is
12
- # converted into a Row::Header object.
13
- #
14
- # See the # Table::Row#content= method for more information.
15
- #--
16
- # Note that, despite the name, Row is a subclass of Array, not Table.
17
- #
18
- def initialize(arg = nil, header = false, &block)
19
- @html_begin = '<tr'
20
- @html_end = '</tr>'
21
-
22
- @header = header
23
-
24
- instance_eval(&block) if block_given?
25
- self.content = arg if arg
3
+ # The Table::Row class is a subclass of array that encapsulates an
4
+ # html table row, i.e. <tr> element.
5
+ class Table::Row < Array
6
+ include HTML::Mixin::AttributeHandler
7
+ include HTML::Mixin::HtmlHandler
8
+ include HTML::Mixin::StrongTyping
9
+ extend HTML::Mixin::StrongTyping
10
+
11
+ @indent_level = 3
12
+ @end_tags = true
13
+
14
+ # Gets and sets whether or not content is converted into a Row::Header
15
+ # object or a Row::Data object.
16
+ attr_accessor :header
17
+
18
+ # Returns a new Table::Row object. Optionally takes a block. If +arg+
19
+ # is provided it is treated as content. If +header+ is false, that
20
+ # content is transformed into a Row::Data object. Otherwise, it is
21
+ # converted into a Row::Header object.
22
+ #
23
+ # See the # Table::Row#content= method for more information.
24
+ #--
25
+ # Note that, despite the name, Row is a subclass of Array, not Table.
26
+ #
27
+ def initialize(arg = nil, header = false, &block)
28
+ @html_begin = '<tr'
29
+ @html_end = '</tr>'
30
+ @header = header
31
+ instance_eval(&block) if block_given?
32
+ self.content = arg if arg
33
+ end
34
+
35
+ # Returns whether or not content is converted into a Row::Header object
36
+ # (as opposed to a Row::Data object).
37
+ #
38
+ def header?
39
+ @header
40
+ end
41
+
42
+ # Adds content to the Row object.
43
+ #
44
+ # Because a Row object doesn't store any of its own content, the
45
+ # arguments to this method must be a Row::Data object, a Row::Header
46
+ # object, or a String (or an array of any of these). In the latter case,
47
+ # a single Row::Data object is created for each string.
48
+ #
49
+ # Examples (with whitespace and newlines removed):
50
+ #
51
+ # row = Table::Row.new
52
+ #
53
+ # # Same as Table::Row.new('foo')
54
+ # row.content = 'foo'
55
+ # row.html => <tr><td>foo</td></tr>
56
+ #
57
+ # row.content = [['foo,'bar']]
58
+ # row.html => <tr><td>foo</td><td>bar</td></tr>
59
+ #
60
+ # row.content = Table::Row::Data.new('foo')
61
+ # row.html => <tr><td>foo</td></tr>
62
+ #
63
+ # row.content = Table::Row::Header.new('foo')
64
+ # row.html => <tr><th>foo</th></tr>
65
+ #
66
+ def content=(arg)
67
+ Array(arg).each do |e|
68
+ push_content(e)
26
69
  end
27
-
28
- # Returns whether or not content is converted into a Row::Header object
29
- # (as opposed to a Row::Data object).
30
- #
31
- def header?
32
- @header
33
- end
34
-
35
- # Sets whether or not content is converted into a Row::Header object
36
- # or a Row::Data object.
37
- #
38
- def header=(bool)
39
- @header = bool
70
+ end
71
+
72
+ # Returns the number of spaces that tags for this class are indented.
73
+ # For the Row class, the indention level defaults to 3.
74
+ #
75
+ def self.indent_level
76
+ @indent_level
77
+ end
78
+
79
+ # Sets the number of spaces that tags for this class are indented.
80
+ #
81
+ def self.indent_level=(num)
82
+ expect(num, Integer)
83
+ raise ArgumentError, "Indent level must be non-negative" if num < 0
84
+ @indent_level = num
85
+ end
86
+
87
+ # Returns true or false, depending on whether or not the end tags for
88
+ # this class, </tr>, are included for each row or not. By default, this
89
+ # is set to true.
90
+ #
91
+ def self.end_tags?
92
+ @end_tags
93
+ end
94
+
95
+ # Sets the behavior for whether or not the end tags for this class,
96
+ # </tr>, are included for each row or not. Only true and false are
97
+ # valid arguments.
98
+ #
99
+ def self.end_tags=(bool)
100
+ expect(bool, [TrueClass, FalseClass])
101
+ @end_tags = bool
102
+ end
103
+
104
+ # This method has been redefined to only allow certain classes to be
105
+ # accepted as arguments. Specifically, they are Data and Header. An
106
+ # Array is also valid, but only if it only includes Data or Header objects.
107
+ #
108
+ def []=(index, obj)
109
+ objs = obj.is_a?(Array) ? obj : [obj]
110
+ objs.each { |o| expect(o, [Data, Header]) }
111
+ super
112
+ end
113
+
114
+ # This method has been redefined to only allow certain classes to be
115
+ # accepted as arguments. Specifically, they are String, Integer, Data,
116
+ # and Header.
117
+ #
118
+ # A plain string or number pushed onto a Row is automatically
119
+ # converted to a Data object.
120
+ #
121
+ def push(*args)
122
+ args.each { |obj| super(convert_content(obj)) }
123
+ end
124
+
125
+ # This method has been redefined to only allow certain classes to be
126
+ # accepted as arguments. The rules are the same as they are for Row#push.
127
+ #
128
+ def <<(obj)
129
+ super(convert_content(obj))
130
+ end
131
+
132
+ # This method has been redefined to only allow certain classes to be
133
+ # accepted as arguments. The rules are the same as they are for Row#push.
134
+ #
135
+ def unshift(obj)
136
+ super(convert_content(obj))
137
+ end
138
+
139
+ alias to_s html
140
+ alias to_str html
141
+
142
+ private
143
+
144
+ def push_content(e)
145
+ if e.is_a?(Table::Row::Data) || e.is_a?(Table::Row::Header)
146
+ push(e)
147
+ else
148
+ push(@header ? Table::Row::Header.new(e) : Table::Row::Data.new(e))
40
149
  end
41
-
42
- # Adds content to the Row object.
43
- #
44
- # Because a Row object doesn't store any of its own content, the
45
- # arguments to this method must be a Row::Data object, a Row::Header
46
- # object, or a String (or an array of any of these). In the latter case,
47
- # a single Row::Data object is created for each string.
48
- #
49
- # Examples (with whitespace and newlines removed):
50
- #
51
- # row = Table::Row.new
52
- #
53
- # # Same as Table::Row.new('foo')
54
- # row.content = 'foo'
55
- # row.html => <tr><td>foo</td></tr>
56
- #
57
- # row.content = [['foo,'bar']]
58
- # row.html => <tr><td>foo</td><td>bar</td></tr>
59
- #
60
- # row.content = Table::Row::Data.new('foo')
61
- # row.html => <tr><td>foo</td></tr>
62
- #
63
- # row.content = Table::Row::Header.new('foo')
64
- # row.html => <tr><th>foo</th></tr>
65
- #
66
- def content=(arg)
67
- case arg
68
- when String
69
- if @header
70
- self.push(Table::Row::Header.new(arg))
71
- else
72
- self.push(Table::Row::Data.new(arg))
73
- end
74
- when Array
75
- arg.each{ |e|
76
- if e.kind_of?(Table::Row::Data) || e.kind_of?(Table::Row::Header)
77
- self.push(e)
78
- else
79
- if @header
80
- self.push(Table::Row::Header.new(e))
81
- else
82
- self.push(Table::Row::Data.new(e))
83
- end
84
- end
85
- }
86
- else
87
- self.push(arg)
88
- end
89
- end
90
-
91
- # Returns the number of spaces that tags for this class are indented.
92
- # For the Row class, the indention level defaults to 3.
93
- #
94
- def self.indent_level
95
- @indent_level
150
+ end
151
+
152
+ def convert_content(obj)
153
+ if obj.is_a?(String) || obj.is_a?(Integer)
154
+ Table::Row::Data.new(obj.to_s)
155
+ else
156
+ expect(obj, [Data, Header])
157
+ obj
96
158
  end
97
-
98
- # Sets the number of spaces that tags for this class are indented.
99
- #
100
- def self.indent_level=(num)
101
- expect(num, Integer)
102
- raise ArgumentError if num < 0
103
- @indent_level = num
104
- end
105
-
106
- # Returns true or false, depending on whether or not the end tags for
107
- # this class, </tr>, are included for each row or not. By default, this
108
- # is set to true.
109
- #
110
- def self.end_tags?
111
- @end_tags
112
- end
113
-
114
- # Sets the behavior for whether or not the end tags for this class,
115
- # </tr>, are included for each row or not. Only true and false are
116
- # valid arguments.
117
- #
118
- def self.end_tags=(bool)
119
- expect(bool,[TrueClass,FalseClass])
120
- @end_tags = bool
121
- end
122
-
123
- # This method has been redefined to only allow certain classes to be
124
- # accepted as arguments. Specifically, they are Data and Header. An
125
- # Array is also valid, but only if it only includes Data or Header
126
- # objects.
127
- #
128
- def []=(index, obj)
129
- if obj.kind_of?(Array)
130
- obj.each{ |o| expect(o, [Data, Header]) }
131
- else
132
- expect(obj, [Data, Header])
133
- end
134
- super
135
- end
136
-
137
- # This method has been redefined to only allow certain classes to be
138
- # accepted as arguments. Specifically, they are String, Integer,
139
- # Data and Header.
140
- #
141
- # A plain string or number pushed onto a Row is automatically
142
- # converted to a Data object.
143
- #
144
- def push(*args)
145
- args.each do |obj|
146
- if obj.kind_of?(String) || obj.kind_of?(Integer)
147
- td = Table::Row::Data.new(obj.to_s)
148
- super(td)
149
- next
150
- else
151
- expect(obj, [Data, Header])
152
- end
153
- super(obj)
154
- end
155
- end
156
-
157
- # This method has been redefined to only allow certain classes to be
158
- # accepted as arguments. The rules are the same as they are for
159
- # Row#push.
160
- #
161
- def <<(obj)
162
- if obj.kind_of?(String) || obj.kind_of?(Integer)
163
- td = Table::Row::Data.new(obj.to_s)
164
- super(td)
165
- else
166
- expect(obj, [Data, Header])
167
- end
168
- super(obj)
169
- end
170
-
171
- # This method has been redefined to only allow certain classes to be
172
- # accepted as arguments. The rules are the same as they are for
173
- # Row#push.
174
- #
175
- def unshift(obj)
176
- if obj.kind_of?(String) || obj.kind_of?(Integer)
177
- td = Table::Row::Data.new(obj.to_s)
178
- super(td)
179
- else
180
- expect(obj,[Data,Header])
181
- end
182
- super(obj)
183
- end
184
-
185
- alias to_s html
186
- alias to_str html
187
- end
159
+ end
160
+ end
188
161
  end