html-table 1.3.3 → 1.3.4

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,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')