html-table 1.2.2 → 1.3.0

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.
@@ -5,6 +5,9 @@ module HtmlHandler
5
5
  # Used on HTML attributes. It creates proper HTML text based on the argument
6
6
  # type. A string looks like "attr='text'", a number looks like "attr=1",
7
7
  # while a true value simply looks like "attr" (no equal sign).
8
+ #--
9
+ # This is private method.
10
+ #
8
11
  def modify_html(attribute,arg=nil)
9
12
  if @html_begin.scan(/\b#{attribute}\b/).empty?
10
13
  if arg.kind_of?(Fixnum)
@@ -27,7 +30,12 @@ module HtmlHandler
27
30
 
28
31
  # Returns the HTML text for the current object. Indentation and end tag
29
32
  # options are optional, based on the settings of the classes themselves.
30
- def html
33
+ #
34
+ # If +formatting+ is false, then formatting and whitespace is not applied
35
+ # and you will get a single, very long string. Note that case is still
36
+ # honored.
37
+ #
38
+ def html(formatting = true)
31
39
  if self.class.respond_to?(:html_case)
32
40
  $upper = true if self.class.html_case == "upper"
33
41
  end
@@ -39,16 +47,20 @@ module HtmlHandler
39
47
 
40
48
  ilevel = 0
41
49
 
42
- if self.class.respond_to?(:indent_level)
50
+ if formatting && self.class.respond_to?(:indent_level)
43
51
  ilevel = self.class.indent_level
44
52
  end
45
-
53
+
46
54
  html = ' ' * ilevel + @html_begin[0..-1]
47
55
  len = html.length
48
56
  html[len,len] = '>'
49
57
 
50
58
  if self.kind_of?(Array)
51
- html << self.map{ |e| "\n" + e.html.to_s }.join
59
+ if formatting
60
+ html << self.map{ |e| "\n" + e.html(formatting).to_s }.join
61
+ else
62
+ html << self.map{ |e| e.html(formatting).to_s }.join
63
+ end
52
64
  else
53
65
  html << @html_body
54
66
  end
@@ -64,13 +76,27 @@ module HtmlHandler
64
76
  if self.kind_of?(Array)
65
77
  if Table.global_end_tags?
66
78
  if self.class.respond_to?(:end_tags?)
67
- html << "\n" + ' ' * ilevel + @html_end if self.class.end_tags?
79
+ if formatting
80
+ if self.class.end_tags?
81
+ html << "\n" + (' ' * ilevel) + @html_end
82
+ end
83
+ else
84
+ html << (' ' * ilevel) + @html_end if self.class.end_tags?
85
+ end
68
86
  else
69
- html << "\n" + ' ' * ilevel + @html_end
87
+ if formatting
88
+ html << "\n" + (' ' * ilevel) + @html_end
89
+ else
90
+ html << (' ' * ilevel) + @html_end
91
+ end
70
92
  end
71
93
  else
72
94
  unless self.class.respond_to?(:end_tags?)
73
- html << "\n" + ' ' * ilevel + @html_end
95
+ if formatting
96
+ html << "\n" + (' ' * ilevel) + @html_end
97
+ else
98
+ html << (' ' * ilevel) + @html_end
99
+ end
74
100
  end
75
101
  end
76
102
  else
data/lib/html/row.rb CHANGED
@@ -2,19 +2,42 @@ module HTML
2
2
  class Table::Row < Array
3
3
  include AttributeHandler
4
4
  include HtmlHandler
5
+
5
6
  @indent_level = 3
6
7
  @end_tags = true
7
8
 
8
- # Returns a new Table::Row object. Optionally takes a block. If an
9
- # argument is provided, it is treated as content.
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.
10
13
  #
14
+ # See the # Table::Row#content= method for more information.
15
+ #--
11
16
  # Note that, despite the name, Row is a subclass of Array, not Table.
12
- def initialize(arg=nil)
17
+ #
18
+ def initialize(arg = nil, header = false, &block)
13
19
  @html_begin = '<tr'
14
20
  @html_end = '</tr>'
15
- yield self if block_given?
21
+
22
+ @header = header
23
+
24
+ instance_eval(&block) if block_given?
16
25
  self.content = arg if arg
17
26
  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
40
+ end
18
41
 
19
42
  # Adds content to the Row object.
20
43
  #
@@ -22,33 +45,60 @@ module HTML
22
45
  # arguments to this method must be a Row::Data object, a Row::Header
23
46
  # object, or a String (or an array of any of these). In the latter case,
24
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
+ #
25
66
  def content=(arg)
26
- if arg.kind_of?(String)
27
- td = Table::Row::Data.new(arg)
28
- self.push(td)
29
- elsif arg.kind_of?(Array)
30
- arg.each{ |e|
31
- if e.kind_of?(Table::Row::Data) || e.kind_of?(Table::Row::Header)
32
- self.push(e)
67
+ case arg
68
+ when String
69
+ if @header
70
+ self.push(Table::Row::Header.new(arg))
33
71
  else
34
- td = Table::Row::Data.new(e)
35
- self.push(td)
72
+ self.push(Table::Row::Data.new(arg))
36
73
  end
37
- }
38
- else
39
- self.push(arg)
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)
40
88
  end
41
89
  end
42
90
 
43
91
  # Returns the number of spaces that tags for this class are indented.
44
92
  # For the Row class, the indention level defaults to 3.
93
+ #
45
94
  def self.indent_level
46
95
  @indent_level
47
96
  end
48
97
 
49
98
  # Sets the number of spaces that tags for this class are indented.
99
+ #
50
100
  def self.indent_level=(num)
51
- expect(num,Integer)
101
+ expect(num, Integer)
52
102
  raise ArgumentError if num < 0
53
103
  @indent_level = num
54
104
  end
@@ -56,6 +106,7 @@ module HTML
56
106
  # Returns true or false, depending on whether or not the end tags for
57
107
  # this class, </tr>, are included for each row or not. By default, this
58
108
  # is set to true.
109
+ #
59
110
  def self.end_tags?
60
111
  @end_tags
61
112
  end
@@ -63,6 +114,7 @@ module HTML
63
114
  # Sets the behavior for whether or not the end tags for this class,
64
115
  # </tr>, are included for each row or not. Only true and false are
65
116
  # valid arguments.
117
+ #
66
118
  def self.end_tags=(bool)
67
119
  expect(bool,[TrueClass,FalseClass])
68
120
  @end_tags = bool
@@ -72,11 +124,12 @@ module HTML
72
124
  # accepted as arguments. Specifically, they are Data and Header. An
73
125
  # Array is also valid, but only if it only includes Data or Header
74
126
  # objects.
75
- def []=(index,obj)
127
+ #
128
+ def []=(index, obj)
76
129
  if obj.kind_of?(Array)
77
- obj.each{ |o| expect(o,[Data,Header]) }
130
+ obj.each{ |o| expect(o, [Data, Header]) }
78
131
  else
79
- expect(obj,[Data,Header])
132
+ expect(obj, [Data, Header])
80
133
  end
81
134
  super
82
135
  end
@@ -87,6 +140,7 @@ module HTML
87
140
  #
88
141
  # A plain string or number pushed onto a Row is automatically
89
142
  # converted to a Data object.
143
+ #
90
144
  def push(*args)
91
145
  args.each do |obj|
92
146
  if obj.kind_of?(String) || obj.kind_of?(Fixnum)
@@ -94,7 +148,7 @@ module HTML
94
148
  super(td)
95
149
  next
96
150
  else
97
- expect(obj,[Data,Header])
151
+ expect(obj, [Data, Header])
98
152
  end
99
153
  super(obj)
100
154
  end
@@ -103,12 +157,13 @@ module HTML
103
157
  # This method has been redefined to only allow certain classes to be
104
158
  # accepted as arguments. The rules are the same as they are for
105
159
  # Row#push.
160
+ #
106
161
  def <<(obj)
107
162
  if obj.kind_of?(String) || obj.kind_of?(Fixnum)
108
163
  td = Table::Row::Data.new(obj.to_s)
109
164
  super(td)
110
165
  else
111
- expect(obj,[Data,Header])
166
+ expect(obj, [Data, Header])
112
167
  end
113
168
  super(obj)
114
169
  end
@@ -116,8 +171,9 @@ module HTML
116
171
  # This method has been redefined to only allow certain classes to be
117
172
  # accepted as arguments. The rules are the same as they are for
118
173
  # Row#push.
174
+ #
119
175
  def unshift(obj)
120
- if obj.kind_of?(String) || obj.kind_of?(Fixnum)
176
+ if obj.kind_of?(String) || obj.kind_of?(Fixnum)
121
177
  td = Table::Row::Data.new(obj.to_s)
122
178
  super(td)
123
179
  else
data/lib/html/table.rb CHANGED
@@ -12,18 +12,22 @@ module HTML
12
12
  class Table < Array
13
13
  include AttributeHandler
14
14
  include HtmlHandler
15
- VERSION = "1.2.2"
15
+
16
+ VERSION = '1.3.0'
17
+
16
18
  @indent_level = 0
17
- @html_case = "lower"
19
+ @html_case = 'lower'
20
+
18
21
  @@global_end_tags = true
19
22
 
20
23
  # Returns a new Table object. Optionally takes a block.
21
24
  # If an argument is provided, it is interpreted as content.
22
- def initialize(arg = nil)
25
+ #
26
+ def initialize(arg = nil, &block)
23
27
  @html_begin = '<table'
24
28
  @html_body = ''
25
29
  @html_end = '</table>'
26
- yield self if block_given?
30
+ instance_eval(&block) if block
27
31
  self.content = arg if arg
28
32
  end
29
33
 
@@ -34,20 +38,38 @@ module HTML
34
38
  # an Array of Array's, an Array of Strings, or a single String. In the
35
39
  # last two cases, a single Table::Row with a single Table::Row::Data
36
40
  # object is created, with the string as the content.
41
+ #
37
42
  def content=(arg)
38
43
  if arg.kind_of?(Array)
39
- arg.each{ |e|
40
- tr = Table::Row.new(e)
41
- self.push(tr)
42
- }
44
+ arg.each{ |e| self << Table::Row.new(e) }
45
+ else
46
+ self << Table::Row.new(arg)
47
+ end
48
+ end
49
+
50
+ alias data= content=
51
+
52
+ # A shortcut for creating Table::Row::Header objects in the constructor
53
+ # using the DSL style syntax.
54
+ #
55
+ def header(arg = nil)
56
+ self.header = arg if arg
57
+ end
58
+
59
+ # Adds a Table::Row::Header object (or an Array of them) to the Table
60
+ # object.
61
+ #
62
+ def header=(arg)
63
+ if arg.kind_of?(Array)
64
+ arg.each{ |h| self << Table::Row.new(h, true) }
43
65
  else
44
- tr = Table::Row.new(arg)
45
- self.push(tr)
66
+ self << Table::Row::Header.new(arg)
46
67
  end
47
68
  end
48
69
 
49
70
  # Returns true or false, depending on whether or not end tags have been
50
71
  # turned on or off, respectively.
72
+ #
51
73
  def self.global_end_tags?
52
74
  @@global_end_tags
53
75
  end
@@ -57,19 +79,22 @@ module HTML
57
79
  # sent to this method must be true or false. The default value is true.
58
80
  #
59
81
  # Note that mandatory end tags are unaffected by this setting.
82
+ #
60
83
  def self.global_end_tags=(bool)
61
- expect(bool,[TrueClass,FalseClass])
84
+ expect(bool, [TrueClass, FalseClass])
62
85
  @@global_end_tags = bool
63
86
  end
64
87
 
65
88
  # Returns either "lower" or "upper", indicating the case of all HTML
66
89
  # tags in the final output.
90
+ #
67
91
  def self.html_case
68
92
  @html_case
69
93
  end
70
94
 
71
95
  # Sets the case of all HTML tags to either lower or upper. The only
72
96
  # valid arguments to this method are 'upper' or 'lower'.
97
+ #
73
98
  def self.html_case=(arg)
74
99
  expect(arg,String)
75
100
  arg.downcase!
@@ -85,13 +110,15 @@ module HTML
85
110
  #
86
111
  # Note that each class has its own default indentation level (a multiple
87
112
  # of 3).
113
+ #
88
114
  def self.indent_level
89
115
  @indent_level
90
116
  end
91
117
 
92
118
  # Sets the number of spaces that tags for this class are indented.
119
+ #
93
120
  def self.indent_level=(num)
94
- expect(num,Integer)
121
+ expect(num, Integer)
95
122
  raise ArgumentError,"indent level must be >= 0" if num < 0
96
123
  @indent_level = num
97
124
  end
@@ -104,8 +131,9 @@ module HTML
104
131
  # In addition, a Caption can only be assigned to index 0. A Head can
105
132
  # only be assigned to index 0, or index 1 if a Caption already exists.
106
133
  # A Foot may only be assigned as the last element.
134
+ #
107
135
  def []=(index,obj)
108
- expect(obj,[Caption,ColGroup,Body,Foot,Head,Row])
136
+ expect(obj, [Caption, ColGroup, Body, Foot, Head, Row])
109
137
 
110
138
  # Only allow Caption objects at index 0
111
139
  if index != 0 && obj.kind_of?(HTML::Table::Caption)
@@ -134,40 +162,39 @@ module HTML
134
162
 
135
163
  # This method has been redefined to only allow certain subclasses to
136
164
  # be accepted as arguments. Specifically, only Caption, ColGroup,
137
- # Body, Foot, Head, Row and Row::Data objects may be pushed onto a
138
- # Table.
165
+ # Body, Foot, Head, Row, Row::Data and Row::Header objects may be
166
+ # pushed onto a Table.
139
167
  #
140
168
  # Pushing a Data or Header object onto a Table object creates its own
141
169
  # row for each. If a Caption object is pushed onto the Table, it will
142
170
  # automatically be bumped to the first element. If a Head object is
143
171
  # pushed onto the Table, it is automatically bumped to the first
144
172
  # element, or the second element if a Caption already exists.
173
+ #
145
174
  def push(*args)
146
175
  args.each{ |obj|
147
- expect(obj,[Caption,ColGroup,Body,Foot,Head,Row,Row::Data])
148
-
149
- # Pushing Data or Header objects onto a Table directly gives them
150
- # each their own row.
151
- if obj.kind_of?(HTML::Table::Row::Data)
152
- tr = HTML::Table::Row.new(obj)
153
- self.push(tr)
154
- # Caption objects are always the first row
155
- elsif obj.kind_of?(HTML::Table::Caption)
156
- if self[0].kind_of?(HTML::Table::Caption)
157
- self[0] = obj
176
+ expect(obj, [Caption, ColGroup, Body, Foot, Head,
177
+ Row, Row::Data, Row::Header]
178
+ )
179
+
180
+ case obj
181
+ when Table::Row::Data, Table::Row::Header
182
+ self.push(Table::Row.new(obj))
183
+ when Table::Caption
184
+ if self[0].kind_of?(Table::Caption)
185
+ self[0] = obj
186
+ else
187
+ self.unshift(obj)
188
+ end
189
+ when Table::Head
190
+ if self[0].kind_of?(Table::Caption)
191
+ self.unshift(obj)
192
+ self[0],self[1] = self[1],self[0]
193
+ else
194
+ self.unshift(obj)
195
+ end
158
196
  else
159
- self.unshift(obj)
160
- end
161
- # Head objects are always at row 0 or 1
162
- elsif obj.kind_of?(HTML::Table::Head)
163
- if self[0].kind_of?(HTML::Table::Caption)
164
- self.unshift(obj)
165
- self[0],self[1] = self[1],self[0]
166
- else
167
- self.unshift(obj)
168
- end
169
- else
170
- super(obj)
197
+ super(obj)
171
198
  end
172
199
  }
173
200
  end
@@ -176,45 +203,46 @@ module HTML
176
203
  # be accepted as arguments.
177
204
  #
178
205
  # The restrictions and behavior are identical to the push() method.
206
+ #
179
207
  def <<(obj)
180
- expect(obj,[Caption,ColGroup,Body,Foot,Head,Row,Row::Data])
181
-
182
- # Pushing Data or Header objects onto a Table directly gives them
183
- # each their own row.
184
- if obj.kind_of?(HTML::Table::Row::Data)
185
- tr = HTML::Table::Row.new(obj)
186
- self.push(tr)
187
- # Caption objects are always the first row
188
- elsif obj.kind_of?(HTML::Table::Caption)
189
- if self[0].kind_of?(HTML::Table::Caption)
190
- self[0] = obj
191
- else
192
- self.unshift(obj)
193
- end
194
- # Head objects are always at row 0 or 1
195
- elsif obj.kind_of?(HTML::Table::Head)
196
- if self[0].kind_of?(HTML::Table::Caption)
197
- self.unshift(obj)
198
- self[0],self[1] = self[1],self[0]
208
+ expect(obj, [Caption, ColGroup, Body, Foot,
209
+ Head, Row, Row::Data, Row::Header]
210
+ )
211
+
212
+ case obj
213
+ when Table::Row::Data, Table::Row::Header # Each get their own row
214
+ self << Table::Row.new(obj)
215
+ when Table::Caption # Always the first row
216
+ if self[0].kind_of?(Table::Caption)
217
+ self[0] = obj
218
+ else
219
+ self.unshift(obj)
220
+ end
221
+ when Table::Head # Always at row 0 or 1
222
+ if self[0].kind_of?(Table::Caption)
223
+ self.unshift(obj)
224
+ self[0], self[1] = self[1], self[0]
225
+ else
226
+ self.unshift(obj)
227
+ end
199
228
  else
200
- self.unshift(obj)
201
- end
202
- else
203
- super(obj)
229
+ super(obj)
204
230
  end
205
231
  end
206
232
 
207
233
  # This method has been redefined to only allow certain subclasses to
208
234
  # be unshifted onto a Table object. Specifically, they are Caption,
209
235
  # ColGroup, Body, Foot, Head and Row.
236
+ #
210
237
  def unshift(obj)
211
- expect(obj,[Caption,ColGroup,Body,Foot,Head,Row])
238
+ expect(obj, [Caption, ColGroup, Body, Foot, Head, Row])
212
239
  super
213
240
  end
214
241
 
215
242
  end
216
243
  end
217
244
 
245
+ require "content"
218
246
  require "caption"
219
247
  require "colgroup"
220
248
  require "col"