html-table 1.3.1 → 1.3.2

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/lib/html/table.rb CHANGED
@@ -1,255 +1,311 @@
1
- require "rbconfig"
2
- include Config
3
-
4
- $LOAD_PATH.unshift(File.dirname(__FILE__))
5
-
6
- require "attribute_handler"
7
- require "html_handler"
8
- require "strongtyping"
9
- include StrongTyping
10
-
11
- module HTML
12
- class Table < Array
13
- include AttributeHandler
14
- include HtmlHandler
15
-
16
- VERSION = '1.3.1'
17
-
18
- @indent_level = 0
19
- @html_case = 'lower'
20
-
21
- @@global_end_tags = true
22
-
23
- # Returns a new Table object. Optionally takes a block.
24
- # If an argument is provided, it is interpreted as content.
25
- #
26
- def initialize(arg = nil, &block)
27
- @html_begin = '<table'
28
- @html_body = ''
29
- @html_end = '</table>'
30
- instance_eval(&block) if block
31
- self.content = arg if arg
32
- end
33
-
34
- # Adds content to the table. How this method behaves depends on the
35
- # type of argument being passed.
36
- #
37
- # The +arg+ may be a Table::Row object, an Array of Table::Row objects,
38
- # an Array of Array's, an Array of Strings, or a single String. In the
39
- # last two cases, a single Table::Row with a single Table::Row::Data
40
- # object is created, with the string as the content.
41
- #
42
- def content=(arg)
43
- if arg.kind_of?(Array)
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) }
65
- else
66
- self << Table::Row::Header.new(arg)
67
- end
68
- end
69
-
70
- # Returns true or false, depending on whether or not end tags have been
71
- # turned on or off, respectively.
72
- #
73
- def self.global_end_tags?
74
- @@global_end_tags
75
- end
76
-
77
- # Sets the end tag class variable. This is used to set whether or not
78
- # to include optional end tags in the final HTML output. The argument
79
- # sent to this method must be true or false. The default value is true.
80
- #
81
- # Note that mandatory end tags are unaffected by this setting.
82
- #
83
- def self.global_end_tags=(bool)
84
- expect(bool, [TrueClass, FalseClass])
85
- @@global_end_tags = bool
86
- end
87
-
88
- # Returns either "lower" or "upper", indicating the case of all HTML
89
- # tags in the final output.
90
- #
91
- def self.html_case
92
- @html_case
93
- end
94
-
95
- # Sets the case of all HTML tags to either lower or upper. The only
96
- # valid arguments to this method are 'upper' or 'lower'.
97
- #
98
- def self.html_case=(arg)
99
- expect(arg,String)
100
- arg.downcase!
101
- unless arg == "upper" || arg == "lower"
102
- msg = "Argument to html_case() must be 'upper' or 'lower'"
103
- raise ArgumentError, msg
104
- end
105
- @html_case = arg
106
- end
107
-
108
- # Returns the number of spaces that tags for this class are indented.
109
- # For the Table class, the indention level defaults to 0.
110
- #
111
- # Note that each class has its own default indentation level (a multiple
112
- # of 3).
113
- #
114
- def self.indent_level
115
- @indent_level
116
- end
117
-
118
- # Sets the number of spaces that tags for this class are indented.
119
- #
120
- def self.indent_level=(num)
121
- expect(num, Integer)
122
- raise ArgumentError,"indent level must be >= 0" if num < 0
123
- @indent_level = num
124
- end
125
-
126
- # This method has been redefined to only allow certain subclasses to
127
- # be assigned using a direct index notation. Specifically, only
128
- # Caption, ColGroup, Body, Foot, Head and Row objects may be use
129
- # assigned using direct index notation.
130
- #
131
- # In addition, a Caption can only be assigned to index 0. A Head can
132
- # only be assigned to index 0, or index 1 if a Caption already exists.
133
- # A Foot may only be assigned as the last element.
134
- #
135
- def []=(index,obj)
136
- expect(obj, [Caption, ColGroup, Body, Foot, Head, Row])
137
-
138
- # Only allow Caption objects at index 0
139
- if index != 0 && obj.kind_of?(HTML::Table::Caption)
140
- msg = "CAPTION can only be added at index 0"
141
- raise ArgumentError, msg
142
- end
143
-
144
- # Only allow Head objects at index 0 or 1
145
- if obj.kind_of?(HTML::Table::Head)
146
- if self[0].kind_of?(HTML::Table::Caption) && index != 1
147
- msg = "THEAD must be at index 1 when Caption is included"
148
- raise ArgumentError, msg
149
- end
150
- if !self[0].kind_of?(HTML::Table::Caption) && index != 0
151
- msg = "THEAD must be at index 0 when no Caption is included"
152
- raise ArgumentError, msg
153
- end
154
- end
155
-
156
- if obj.kind_of?(HTML::Table::Foot) && index != -1
157
- msg = "FOOT must be last element"
158
- raise ArgumentError, msg
159
- end
160
- super
161
- end
162
-
163
- # This method has been redefined to only allow certain subclasses to
164
- # be accepted as arguments. Specifically, only Caption, ColGroup,
165
- # Body, Foot, Head, Row, Row::Data and Row::Header objects may be
166
- # pushed onto a Table.
167
- #
168
- # Pushing a Data or Header object onto a Table object creates its own
169
- # row for each. If a Caption object is pushed onto the Table, it will
170
- # automatically be bumped to the first element. If a Head object is
171
- # pushed onto the Table, it is automatically bumped to the first
172
- # element, or the second element if a Caption already exists.
173
- #
174
- def push(*args)
175
- args.each{ |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
196
- else
197
- super(obj)
198
- end
199
- }
200
- end
201
-
202
- # This method has been redefined to only allow certain subclasses to
203
- # be accepted as arguments.
204
- #
205
- # The restrictions and behavior are identical to the push() method.
206
- #
207
- def <<(obj)
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
228
- else
229
- super(obj)
230
- end
231
- end
232
-
233
- # This method has been redefined to only allow certain subclasses to
234
- # be unshifted onto a Table object. Specifically, they are Caption,
235
- # ColGroup, Body, Foot, Head and Row.
236
- #
237
- def unshift(obj)
238
- expect(obj, [Caption, ColGroup, Body, Foot, Head, Row])
239
- super
240
- end
241
-
242
- end
243
- end
244
-
245
- require "content"
246
- require "caption"
247
- require "colgroup"
248
- require "col"
249
- require "row"
250
- require "header"
251
- require "data"
252
- require "tablesection"
253
- require "head"
254
- require "foot"
255
- require "body"
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'attribute_handler'
4
+ require 'html_handler'
5
+ require 'strongtyping'
6
+ include StrongTyping
7
+
8
+ module HTML
9
+ class Table < Array
10
+ include AttributeHandler
11
+ include HtmlHandler
12
+
13
+ # The version of this library
14
+ VERSION = '1.3.2'
15
+
16
+ # The indentation level for the <table> and </table> tags
17
+ @indent_level = 0
18
+
19
+ # The default character case used for printing output
20
+ @html_case = 'lower'
21
+
22
+ # Determines whether or not end tags will be included in printed output
23
+ @@global_end_tags = true
24
+
25
+ # Returns a new Table object. Optionally takes a block which is
26
+ # eval'd if provided. If an argument is provided it is interpreted as
27
+ # content. See the Table#content= method for how that data will be
28
+ # interpreted.
29
+ #
30
+ # Examples:
31
+ #
32
+ # # A single data item
33
+ # HTML::Table.new(1).html
34
+ #
35
+ # # Output
36
+ # <table>
37
+ # <tr>
38
+ # <td>1</td>
39
+ # </tr>
40
+ # </table>
41
+ #
42
+ # # One row per data item
43
+ # HTML::Table.new(['Matz', 'Larry', 'Guido']).html
44
+ #
45
+ # # Output
46
+ # <table>
47
+ # <tr>
48
+ # <td>Matz</td>
49
+ # </tr>
50
+ # <tr>
51
+ # <td>Larry</td>
52
+ # </tr>
53
+ # <tr>
54
+ # <td>Guido</td>
55
+ # </tr>
56
+ # </tr>
57
+ # </table>
58
+ #
59
+ # # Multiple data items per row
60
+ # Table.new{ |t|
61
+ # t.content = [['a','b'], [1,2], ['x','y']]
62
+ # }.html
63
+ #
64
+ # # Output
65
+ # <table>
66
+ # <tr>
67
+ # <td>a</td>
68
+ # <td>b</td>
69
+ # </tr>
70
+ # <tr>
71
+ # <td>1</td>
72
+ # <td>2</td>
73
+ # </tr>
74
+ # <tr>
75
+ # <td>x</td>
76
+ # <td>y</td>
77
+ # </tr>
78
+ # </table>
79
+ #
80
+ def initialize(arg = nil, &block)
81
+ @html_begin = '<table'
82
+ @html_body = ''
83
+ @html_end = '</table>'
84
+ instance_eval(&block) if block
85
+ self.content = arg if arg
86
+ end
87
+
88
+ # Adds content to the table. How this method behaves depends on the
89
+ # type of argument being passed.
90
+ #
91
+ # The +arg+ may be a Table::Row object, an Array of Table::Row objects,
92
+ # an Array of Array's, an Array of Strings, or a single String. In the
93
+ # last two cases, a single Table::Row with a single Table::Row::Data
94
+ # object is created, with the string as the content.
95
+ #
96
+ def content=(arg)
97
+ if arg.kind_of?(Array)
98
+ arg.each{ |e| self << Table::Row.new(e) }
99
+ else
100
+ self << Table::Row.new(arg)
101
+ end
102
+ end
103
+
104
+ alias data= content=
105
+
106
+ # A shortcut for creating Table::Row::Header objects in the constructor
107
+ # using the DSL style syntax.
108
+ #
109
+ def header(arg = nil)
110
+ self.header = arg if arg
111
+ end
112
+
113
+ # Adds a Table::Row::Header object (or an Array of them) to the Table
114
+ # object.
115
+ #
116
+ def header=(arg)
117
+ if arg.kind_of?(Array)
118
+ arg.each{ |h| self << Table::Row.new(h, true) }
119
+ else
120
+ self << Table::Row::Header.new(arg)
121
+ end
122
+ end
123
+
124
+ # Returns true or false, depending on whether or not end tags have been
125
+ # turned on or off, respectively.
126
+ #
127
+ def self.global_end_tags?
128
+ @@global_end_tags
129
+ end
130
+
131
+ # Sets the end tag class variable. This is used to set whether or not
132
+ # to include optional end tags in the final HTML output. The argument
133
+ # sent to this method must be true or false. The default value is true.
134
+ #
135
+ # Note that mandatory end tags are unaffected by this setting.
136
+ #
137
+ def self.global_end_tags=(bool)
138
+ expect(bool, [TrueClass, FalseClass])
139
+ @@global_end_tags = bool
140
+ end
141
+
142
+ # Returns either "lower" or "upper", indicating the case of all HTML
143
+ # tags in the final output.
144
+ #
145
+ def self.html_case
146
+ @html_case
147
+ end
148
+
149
+ # Sets the case of all HTML tags to either lower or upper. The only
150
+ # valid arguments to this method are 'upper' or 'lower'.
151
+ #
152
+ def self.html_case=(arg)
153
+ expect(arg,String)
154
+ arg.downcase!
155
+ unless arg == "upper" || arg == "lower"
156
+ msg = "Argument to html_case() must be 'upper' or 'lower'"
157
+ raise ArgumentError, msg
158
+ end
159
+ @html_case = arg
160
+ end
161
+
162
+ # Returns the number of spaces that tags for this class are indented.
163
+ # For the Table class, the indention level defaults to 0.
164
+ #
165
+ # Note that each class has its own default indentation level (a multiple
166
+ # of 3).
167
+ #
168
+ def self.indent_level
169
+ @indent_level
170
+ end
171
+
172
+ # Sets the number of spaces that tags for this class are indented.
173
+ #
174
+ def self.indent_level=(num)
175
+ expect(num, Integer)
176
+ raise ArgumentError,"indent level must be >= 0" if num < 0
177
+ @indent_level = num
178
+ end
179
+
180
+ # This method has been redefined to only allow certain subclasses to
181
+ # be assigned using a direct index notation. Specifically, only
182
+ # Caption, ColGroup, Body, Foot, Head and Row objects may be use
183
+ # assigned using direct index notation.
184
+ #
185
+ # In addition, a Caption can only be assigned to index 0. A Head can
186
+ # only be assigned to index 0, or index 1 if a Caption already exists.
187
+ # A Foot may only be assigned as the last element.
188
+ #
189
+ def []=(index,obj)
190
+ expect(obj, [Caption, ColGroup, Body, Foot, Head, Row])
191
+
192
+ # Only allow Caption objects at index 0
193
+ if index != 0 && obj.kind_of?(HTML::Table::Caption)
194
+ msg = "CAPTION can only be added at index 0"
195
+ raise ArgumentError, msg
196
+ end
197
+
198
+ # Only allow Head objects at index 0 or 1
199
+ if obj.kind_of?(HTML::Table::Head)
200
+ if self[0].kind_of?(HTML::Table::Caption) && index != 1
201
+ msg = "THEAD must be at index 1 when Caption is included"
202
+ raise ArgumentError, msg
203
+ end
204
+ if !self[0].kind_of?(HTML::Table::Caption) && index != 0
205
+ msg = "THEAD must be at index 0 when no Caption is included"
206
+ raise ArgumentError, msg
207
+ end
208
+ end
209
+
210
+ if obj.kind_of?(HTML::Table::Foot) && index != -1
211
+ msg = "FOOT must be last element"
212
+ raise ArgumentError, msg
213
+ end
214
+ super
215
+ end
216
+
217
+ # This method has been redefined to only allow certain subclasses to
218
+ # be accepted as arguments. Specifically, only Caption, ColGroup,
219
+ # Body, Foot, Head, Row, Row::Data and Row::Header objects may be
220
+ # pushed onto a Table.
221
+ #
222
+ # Pushing a Data or Header object onto a Table object creates its own
223
+ # row for each. If a Caption object is pushed onto the Table, it will
224
+ # automatically be bumped to the first element. If a Head object is
225
+ # pushed onto the Table, it is automatically bumped to the first
226
+ # element, or the second element if a Caption already exists.
227
+ #
228
+ def push(*args)
229
+ args.each{ |obj|
230
+ expect(obj, [Caption, ColGroup, Body, Foot, Head,
231
+ Row, Row::Data, Row::Header]
232
+ )
233
+
234
+ case obj
235
+ when Table::Row::Data, Table::Row::Header
236
+ self.push(Table::Row.new(obj))
237
+ when Table::Caption
238
+ if self[0].kind_of?(Table::Caption)
239
+ self[0] = obj
240
+ else
241
+ self.unshift(obj)
242
+ end
243
+ when Table::Head
244
+ if self[0].kind_of?(Table::Caption)
245
+ self.unshift(obj)
246
+ self[0],self[1] = self[1],self[0]
247
+ else
248
+ self.unshift(obj)
249
+ end
250
+ else
251
+ super(obj)
252
+ end
253
+ }
254
+ end
255
+
256
+ # This method has been redefined to only allow certain subclasses to
257
+ # be accepted as arguments.
258
+ #
259
+ # The restrictions and behavior are identical to the push() method.
260
+ #
261
+ def <<(obj)
262
+ expect(obj, [Caption, ColGroup, Body, Foot,
263
+ Head, Row, Row::Data, Row::Header]
264
+ )
265
+
266
+ case obj
267
+ when Table::Row::Data, Table::Row::Header # Each get their own row
268
+ self << Table::Row.new(obj)
269
+ when Table::Caption # Always the first row
270
+ if self[0].kind_of?(Table::Caption)
271
+ self[0] = obj
272
+ else
273
+ self.unshift(obj)
274
+ end
275
+ when Table::Head # Always at row 0 or 1
276
+ if self[0].kind_of?(Table::Caption)
277
+ self.unshift(obj)
278
+ self[0], self[1] = self[1], self[0]
279
+ else
280
+ self.unshift(obj)
281
+ end
282
+ else
283
+ super(obj)
284
+ end
285
+ end
286
+
287
+ # This method has been redefined to only allow certain subclasses to
288
+ # be unshifted onto a Table object. Specifically, they are Caption,
289
+ # ColGroup, Body, Foot, Head and Row.
290
+ #
291
+ def unshift(obj)
292
+ expect(obj, [Caption, ColGroup, Body, Foot, Head, Row])
293
+ super
294
+ end
295
+
296
+ alias to_s html
297
+ alias to_str html
298
+ end
299
+ end
300
+
301
+ require "content"
302
+ require "caption"
303
+ require "colgroup"
304
+ require "col"
305
+ require "row"
306
+ require "header"
307
+ require "data"
308
+ require "tablesection"
309
+ require "head"
310
+ require "foot"
311
+ require "body"