html-table 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,129 @@
1
+ module HTML
2
+ class Table::Row < Array
3
+ include AttributeHandler
4
+ include HtmlHandler
5
+ @indent_level = 3
6
+ @end_tags = true
7
+
8
+ # Returns a new Table::Row object. Optionally takes a block. If an
9
+ # argument is provided, it is treated as content.
10
+ #
11
+ # Note that, despite the name, Row is a subclass of Array, not Table.
12
+ def initialize(arg=nil)
13
+ @html_begin = '<tr'
14
+ @html_end = '</tr>'
15
+ yield self if block_given?
16
+ self.content = arg if arg
17
+ end
18
+
19
+ # Adds content to the Row object.
20
+ #
21
+ # Because a Row object doesn't store any of its own content, the
22
+ # arguments to this method must be a Row::Data object, a Row::Header
23
+ # object, or a String (or an array of any of these). In the latter case,
24
+ # a single Row::Data object is created for each string.
25
+ def content=(arg)
26
+ if arg.kind_of?(String)
27
+ td = Table::Row::Data.new(arg)
28
+ self.push(td)
29
+ elsif arg.kind_of?(Array)
30
+ arg.each{ |e|
31
+ if e.kind_of?(Table::Row::Data) || e.kind_of?(Table::Row::Header)
32
+ self.push(e)
33
+ else
34
+ td = Table::Row::Data.new(e)
35
+ self.push(td)
36
+ end
37
+ }
38
+ else
39
+ self.push(arg)
40
+ end
41
+ end
42
+
43
+ # Returns the number of spaces that tags for this class are indented.
44
+ # For the Row class, the indention level defaults to 3.
45
+ def self.indent_level
46
+ @indent_level
47
+ end
48
+
49
+ # Sets the number of spaces that tags for this class are indented.
50
+ def self.indent_level=(num)
51
+ expect(num,Integer)
52
+ raise ArgumentError if num < 0
53
+ @indent_level = num
54
+ end
55
+
56
+ # Returns true or false, depending on whether or not the end tags for
57
+ # this class, </tr>, are included for each row or not. By default, this
58
+ # is set to true.
59
+ def self.end_tags?
60
+ @end_tags
61
+ end
62
+
63
+ # Sets the behavior for whether or not the end tags for this class,
64
+ # </tr>, are included for each row or not. Only true and false are
65
+ # valid arguments.
66
+ def self.end_tags=(bool)
67
+ expect(bool,[TrueClass,FalseClass])
68
+ @end_tags = bool
69
+ end
70
+
71
+ # This method has been redefined to only allow certain classes to be
72
+ # accepted as arguments. Specifically, they are Data and Header. An
73
+ # Array is also valid, but only if it only includes Data or Header
74
+ # objects.
75
+ def []=(index,obj)
76
+ if obj.kind_of?(Array)
77
+ obj.each{ |o| expect(o,[Data,Header]) }
78
+ else
79
+ expect(obj,[Data,Header])
80
+ end
81
+ super
82
+ end
83
+
84
+ # This method has been redefined to only allow certain classes to be
85
+ # accepted as arguments. Specifically, they are String, Fixnum,
86
+ # Data and Header.
87
+ #
88
+ # A plain string or number pushed onto a Row is automatically
89
+ # converted to a Data object.
90
+ def push(*args)
91
+ args.each do |obj|
92
+ if obj.kind_of?(String) || obj.kind_of?(Fixnum)
93
+ td = Table::Row::Data.new(obj.to_s)
94
+ super(td)
95
+ next
96
+ else
97
+ expect(obj,[Data,Header])
98
+ end
99
+ super(obj)
100
+ end
101
+ end
102
+
103
+ # This method has been redefined to only allow certain classes to be
104
+ # accepted as arguments. The rules are the same as they are for
105
+ # Row#push.
106
+ def <<(obj)
107
+ if obj.kind_of?(String) || obj.kind_of?(Fixnum)
108
+ td = Table::Row::Data.new(obj.to_s)
109
+ super(td)
110
+ else
111
+ expect(obj,[Data,Header])
112
+ end
113
+ super(obj)
114
+ end
115
+
116
+ # This method has been redefined to only allow certain classes to be
117
+ # accepted as arguments. The rules are the same as they are for
118
+ # Row#push.
119
+ def unshift(obj)
120
+ if obj.kind_of?(String) || obj.kind_of?(Fixnum)
121
+ td = Table::Row::Data.new(obj.to_s)
122
+ super(td)
123
+ else
124
+ expect(obj,[Data,Header])
125
+ end
126
+ super(obj)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,227 @@
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
+ VERSION = "1.2.2"
16
+ @indent_level = 0
17
+ @html_case = "lower"
18
+ @@global_end_tags = true
19
+
20
+ # Returns a new Table object. Optionally takes a block.
21
+ # If an argument is provided, it is interpreted as content.
22
+ def initialize(arg = nil)
23
+ @html_begin = '<table'
24
+ @html_body = ''
25
+ @html_end = '</table>'
26
+ yield self if block_given?
27
+ self.content = arg if arg
28
+ end
29
+
30
+ # Adds content to the table. How this method behaves depends on the
31
+ # type of argument being passed.
32
+ #
33
+ # The +arg+ may be a Table::Row object, an Array of Table::Row objects,
34
+ # an Array of Array's, an Array of Strings, or a single String. In the
35
+ # last two cases, a single Table::Row with a single Table::Row::Data
36
+ # object is created, with the string as the content.
37
+ def content=(arg)
38
+ if arg.kind_of?(Array)
39
+ arg.each{ |e|
40
+ tr = Table::Row.new(e)
41
+ self.push(tr)
42
+ }
43
+ else
44
+ tr = Table::Row.new(arg)
45
+ self.push(tr)
46
+ end
47
+ end
48
+
49
+ # Returns true or false, depending on whether or not end tags have been
50
+ # turned on or off, respectively.
51
+ def self.global_end_tags?
52
+ @@global_end_tags
53
+ end
54
+
55
+ # Sets the end tag class variable. This is used to set whether or not
56
+ # to include optional end tags in the final HTML output. The argument
57
+ # sent to this method must be true or false. The default value is true.
58
+ #
59
+ # Note that mandatory end tags are unaffected by this setting.
60
+ def self.global_end_tags=(bool)
61
+ expect(bool,[TrueClass,FalseClass])
62
+ @@global_end_tags = bool
63
+ end
64
+
65
+ # Returns either "lower" or "upper", indicating the case of all HTML
66
+ # tags in the final output.
67
+ def self.html_case
68
+ @html_case
69
+ end
70
+
71
+ # Sets the case of all HTML tags to either lower or upper. The only
72
+ # valid arguments to this method are 'upper' or 'lower'.
73
+ def self.html_case=(arg)
74
+ expect(arg,String)
75
+ arg.downcase!
76
+ unless arg == "upper" || arg == "lower"
77
+ msg = "Argument to html_case() must be 'upper' or 'lower'"
78
+ raise ArgumentError, msg
79
+ end
80
+ @html_case = arg
81
+ end
82
+
83
+ # Returns the number of spaces that tags for this class are indented.
84
+ # For the Table class, the indention level defaults to 0.
85
+ #
86
+ # Note that each class has its own default indentation level (a multiple
87
+ # of 3).
88
+ def self.indent_level
89
+ @indent_level
90
+ end
91
+
92
+ # Sets the number of spaces that tags for this class are indented.
93
+ def self.indent_level=(num)
94
+ expect(num,Integer)
95
+ raise ArgumentError,"indent level must be >= 0" if num < 0
96
+ @indent_level = num
97
+ end
98
+
99
+ # This method has been redefined to only allow certain subclasses to
100
+ # be assigned using a direct index notation. Specifically, only
101
+ # Caption, ColGroup, Body, Foot, Head and Row objects may be use
102
+ # assigned using direct index notation.
103
+ #
104
+ # In addition, a Caption can only be assigned to index 0. A Head can
105
+ # only be assigned to index 0, or index 1 if a Caption already exists.
106
+ # A Foot may only be assigned as the last element.
107
+ def []=(index,obj)
108
+ expect(obj,[Caption,ColGroup,Body,Foot,Head,Row])
109
+
110
+ # Only allow Caption objects at index 0
111
+ if index != 0 && obj.kind_of?(HTML::Table::Caption)
112
+ msg = "CAPTION can only be added at index 0"
113
+ raise ArgumentError, msg
114
+ end
115
+
116
+ # Only allow Head objects at index 0 or 1
117
+ if obj.kind_of?(HTML::Table::Head)
118
+ if self[0].kind_of?(HTML::Table::Caption) && index != 1
119
+ msg = "THEAD must be at index 1 when Caption is included"
120
+ raise ArgumentError, msg
121
+ end
122
+ if !self[0].kind_of?(HTML::Table::Caption) && index != 0
123
+ msg = "THEAD must be at index 0 when no Caption is included"
124
+ raise ArgumentError, msg
125
+ end
126
+ end
127
+
128
+ if obj.kind_of?(HTML::Table::Foot) && index != -1
129
+ msg = "FOOT must be last element"
130
+ raise ArgumentError, msg
131
+ end
132
+ super
133
+ end
134
+
135
+ # This method has been redefined to only allow certain subclasses to
136
+ # be accepted as arguments. Specifically, only Caption, ColGroup,
137
+ # Body, Foot, Head, Row and Row::Data objects may be pushed onto a
138
+ # Table.
139
+ #
140
+ # Pushing a Data or Header object onto a Table object creates its own
141
+ # row for each. If a Caption object is pushed onto the Table, it will
142
+ # automatically be bumped to the first element. If a Head object is
143
+ # pushed onto the Table, it is automatically bumped to the first
144
+ # element, or the second element if a Caption already exists.
145
+ def push(*args)
146
+ args.each{ |obj|
147
+ expect(obj,[Caption,ColGroup,Body,Foot,Head,Row,Row::Data])
148
+
149
+ # Pushing Data or Header objects onto a Table directly gives them
150
+ # each their own row.
151
+ if obj.kind_of?(HTML::Table::Row::Data)
152
+ tr = HTML::Table::Row.new(obj)
153
+ self.push(tr)
154
+ # Caption objects are always the first row
155
+ elsif obj.kind_of?(HTML::Table::Caption)
156
+ if self[0].kind_of?(HTML::Table::Caption)
157
+ self[0] = obj
158
+ else
159
+ self.unshift(obj)
160
+ end
161
+ # Head objects are always at row 0 or 1
162
+ elsif obj.kind_of?(HTML::Table::Head)
163
+ if self[0].kind_of?(HTML::Table::Caption)
164
+ self.unshift(obj)
165
+ self[0],self[1] = self[1],self[0]
166
+ else
167
+ self.unshift(obj)
168
+ end
169
+ else
170
+ super(obj)
171
+ end
172
+ }
173
+ end
174
+
175
+ # This method has been redefined to only allow certain subclasses to
176
+ # be accepted as arguments.
177
+ #
178
+ # The restrictions and behavior are identical to the push() method.
179
+ def <<(obj)
180
+ expect(obj,[Caption,ColGroup,Body,Foot,Head,Row,Row::Data])
181
+
182
+ # Pushing Data or Header objects onto a Table directly gives them
183
+ # each their own row.
184
+ if obj.kind_of?(HTML::Table::Row::Data)
185
+ tr = HTML::Table::Row.new(obj)
186
+ self.push(tr)
187
+ # Caption objects are always the first row
188
+ elsif obj.kind_of?(HTML::Table::Caption)
189
+ if self[0].kind_of?(HTML::Table::Caption)
190
+ self[0] = obj
191
+ else
192
+ self.unshift(obj)
193
+ end
194
+ # Head objects are always at row 0 or 1
195
+ elsif obj.kind_of?(HTML::Table::Head)
196
+ if self[0].kind_of?(HTML::Table::Caption)
197
+ self.unshift(obj)
198
+ self[0],self[1] = self[1],self[0]
199
+ else
200
+ self.unshift(obj)
201
+ end
202
+ else
203
+ super(obj)
204
+ end
205
+ end
206
+
207
+ # This method has been redefined to only allow certain subclasses to
208
+ # be unshifted onto a Table object. Specifically, they are Caption,
209
+ # ColGroup, Body, Foot, Head and Row.
210
+ def unshift(obj)
211
+ expect(obj,[Caption,ColGroup,Body,Foot,Head,Row])
212
+ super
213
+ end
214
+
215
+ end
216
+ end
217
+
218
+ require "caption"
219
+ require "colgroup"
220
+ require "col"
221
+ require "row"
222
+ require "header"
223
+ require "data"
224
+ require "tablesection"
225
+ require "head"
226
+ require "foot"
227
+ require "body"
@@ -0,0 +1,42 @@
1
+ module HTML
2
+ # Superclass for THEAD, TBODY, TFOOT
3
+ class Table::TableSection < Array
4
+ include AttributeHandler
5
+ include HtmlHandler
6
+ def initialize
7
+ yield self if block_given?
8
+ end
9
+
10
+ # Adds a Table::Row object as content. The +arg+ is passed as the value
11
+ # to the Table::Row constructor.
12
+ def content=(arg)
13
+ tr = Table::Row.new(arg)
14
+ self.push(tr)
15
+ end
16
+
17
+ def self.indent_level
18
+ @indent_level
19
+ end
20
+
21
+ def self.indent_level=(num)
22
+ expect(num,Integer)
23
+ raise ArgumentError,"indent_level must be >= 0" if num < 0
24
+ @indent_level = num
25
+ end
26
+
27
+ def []=(index,obj)
28
+ expect(obj,Table::Row)
29
+ super
30
+ end
31
+
32
+ def push(*args)
33
+ args.each{ |obj| expect(obj,Table::Row) }
34
+ super
35
+ end
36
+
37
+ def unshift(obj)
38
+ expect(obj,Table::Row)
39
+ super
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,64 @@
1
+ ###################################################################
2
+ # tag_handler.rb
3
+ #
4
+ # Module for handling standard html physical tags (<b>, <i>, etc).
5
+ # Only used for Table objects that contain text content. That
6
+ # means Table::Row::Data, Table::Row::Header and Table::Caption.
7
+ ###################################################################
8
+ module Tag_Handler
9
+
10
+ def bold=(bool)
11
+ handle_physical_tag('b',bool)
12
+ end
13
+
14
+ def big=(bool)
15
+ handle_physical_tag('big',bool)
16
+ end
17
+
18
+ def blink=(bool)
19
+ if $VERBOSE
20
+ STDERR.puts("The 'blink' tag is very annoying. Please reconsider.")
21
+ end
22
+ handle_physical_tag('blink',bool)
23
+ end
24
+
25
+ def italic=(bool)
26
+ handle_physical_tag('i',bool)
27
+ end
28
+
29
+ def strike=(bool)
30
+ handle_physical_tag('strike',bool)
31
+ end
32
+
33
+ def sub=(bool)
34
+ handle_physical_tag('sub',bool)
35
+ end
36
+
37
+ def sup=(bool)
38
+ handle_physical_tag('sup',bool)
39
+ end
40
+
41
+ def tt=(bool)
42
+ handle_physical_tag('tt',bool)
43
+ end
44
+
45
+ def underline=(bool)
46
+ handle_physical_tag('u',bool)
47
+ end
48
+
49
+ def handle_physical_tag(tag,bool)
50
+ begin_tag = "<#{tag}>"
51
+ end_tag = "</#{tag}>"
52
+ unless bool == true || bool == false
53
+ msg = "Invalid tag value: #{bool}"
54
+ raise ArgumentError, msg
55
+ end
56
+ if bool == true
57
+ @html_body = begin_tag + @html_body + end_tag
58
+ else
59
+ @html_body.gsub!(/#{begin_tag}|#{end_tag}/,'')
60
+ end
61
+ @html_body
62
+ end
63
+
64
+ end