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/CHANGES +7 -0
- data/README +1 -3
- data/Rakefile +145 -142
- data/doc/table_content.rdoc +15 -15
- data/examples/advanced.rb +128 -128
- data/examples/intermediate1.rb +72 -72
- data/examples/intermediate2.rb +62 -62
- data/examples/intermediate3.rb +46 -46
- data/examples/simple1.rb +39 -39
- data/examples/simple2.rb +47 -47
- data/examples/simple3.rb +41 -41
- data/html-table.gemspec +21 -20
- data/lib/html/attribute_handler.rb +403 -403
- data/lib/html/body.rb +38 -38
- data/lib/html/caption.rb +48 -48
- data/lib/html/col.rb +41 -41
- data/lib/html/colgroup.rb +113 -113
- data/lib/html/content.rb +18 -18
- data/lib/html/data.rb +68 -68
- data/lib/html/foot.rb +49 -49
- data/lib/html/head.rb +49 -49
- data/lib/html/header.rb +65 -65
- data/lib/html/html_handler.rb +120 -120
- data/lib/html/row.rb +188 -188
- data/lib/html/table.rb +320 -318
- data/lib/html/tablesection.rb +48 -48
- data/lib/html/tag_handler.rb +121 -121
- data/test/test_attribute_handler.rb +364 -364
- data/test/test_body.rb +90 -90
- data/test/test_caption.rb +83 -83
- data/test/test_col.rb +43 -43
- data/test/test_colgroup.rb +92 -92
- data/test/test_data.rb +80 -80
- data/test/test_foot.rb +114 -114
- data/test/test_head.rb +107 -107
- data/test/test_header.rb +80 -80
- data/test/test_html_handler.rb +40 -40
- data/test/test_row.rb +144 -144
- data/test/test_table.rb +157 -157
- data/test/test_tablesection.rb +45 -45
- data/test/test_tag_handler.rb +93 -93
- metadata +30 -34
data/lib/html/table.rb
CHANGED
@@ -1,318 +1,320 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
#
|
35
|
-
# interpreted
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
@
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
self << Table::Row.new(
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
#
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
self << Table::Row
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
#
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
#
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
#
|
190
|
-
# assigned using direct index notation.
|
191
|
-
#
|
192
|
-
#
|
193
|
-
#
|
194
|
-
#
|
195
|
-
#
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
# pushed onto the Table, it
|
233
|
-
#
|
234
|
-
#
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
when Table::
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
self
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
self
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
#
|
266
|
-
#
|
267
|
-
#
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
when Table::
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
self
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
self
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
#
|
297
|
-
#
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
require
|
311
|
-
require
|
312
|
-
require
|
313
|
-
require
|
314
|
-
require
|
315
|
-
require
|
316
|
-
require
|
317
|
-
require
|
318
|
-
require
|
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')
|