html-table 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
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"