html-table 1.3.3 → 1.3.4

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