Class: SVGPlot::SVGTag
- Inherits:
-
Object
show all
- Defined in:
- lib/svgplot/plot.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#append_child(child) ⇒ Object
-
#initialize(tag, attributes = {}, &block) ⇒ SVGTag
constructor
A new instance of SVGTag.
-
#linearGradient(id, attributes = {}, if_exists = :skip, &block) ⇒ Object
special case for linearGradient.
-
#matrix(a, b, c, d, e, f) ⇒ Object
-
#merge_defaults ⇒ Object
-
#method_missing(meth, *args, &block) ⇒ Object
-
#path(attributes = {}, &block) ⇒ Object
special case for path block.
-
#pop_defaults ⇒ Object
-
#push_defaults(defaults) ⇒ Object
-
#radialGradient(id, attributes = {}, if_exists = :skip, &block) ⇒ Object
special case for radialGradient.
-
#raw(data) ⇒ Object
special case for raw blocks.
-
#rotate(angle, cx = nil, cy = nil) ⇒ Object
-
#scale(sx, sy = 1) ⇒ Object
-
#skewX(angle) ⇒ Object
-
#skewY(angle) ⇒ Object
-
#spawn_child(tag, *args, &block) ⇒ Object
-
#to_s ⇒ Object
-
#translate(tx, ty = 0) ⇒ Object
Provide methods for SVG transformations.
-
#use(id, attributes = {}) ⇒ Object
special case for use block.
-
#validate_attribute(attribute) ⇒ Object
-
#validate_attributes(attributes) ⇒ Object
-
#validate_child_name(name) ⇒ Object
-
#validate_tag(tag) ⇒ Object
-
#with_style(style = {}, &proc) ⇒ Object
-
#write(output) ⇒ Object
-
#write_points(points, output) ⇒ Object
-
#write_styles(styles, output) ⇒ Object
-
#write_transforms(transforms, output) ⇒ Object
Constructor Details
#initialize(tag, attributes = {}, &block) ⇒ SVGTag
Returns a new instance of SVGTag.
6
7
8
9
10
11
12
13
14
|
# File 'lib/svgplot/plot.rb', line 6
def initialize(tag, attributes={}, &block)
@tag = validate_tag(tag)
@attributes = validate_attributes(attributes)
@children = []
if block
instance_exec &block
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
|
# File 'lib/svgplot/plot.rb', line 231
def method_missing(meth, *args, &block)
check = /^(?<name>.*)(?<op>=|\?)$/.match(meth)
if check
raise "Passing a code block to setter or getter is not permited!" if block
name = validate_attribute(check[:name].to_sym)
if check[:op] == '?'
@attributes[name]
elsif check[:op] == '='
raise "Setting an attribute with multiple values is not permited!" if args.size > 1
@attributes[name] = args[0]
end
elsif child = validate_child_name(meth)
spawn_child(child, *args, &block)
else
super
end
end
|
Instance Attribute Details
#attributes ⇒ Object
Returns the value of attribute attributes.
4
5
6
|
# File 'lib/svgplot/plot.rb', line 4
def attributes
@attributes
end
|
#children ⇒ Object
Returns the value of attribute children.
4
5
6
|
# File 'lib/svgplot/plot.rb', line 4
def children
@children
end
|
#tag ⇒ Object
Returns the value of attribute tag.
4
5
6
|
# File 'lib/svgplot/plot.rb', line 4
def tag
@tag
end
|
Instance Method Details
#append_child(child) ⇒ Object
183
184
185
186
187
|
# File 'lib/svgplot/plot.rb', line 183
def append_child(child)
@children.push(child)
child.push_defaults(merge_defaults()) if @defaults
child
end
|
#linearGradient(id, attributes = {}, if_exists = :skip, &block) ⇒ Object
special case for linearGradient
131
132
133
134
|
# File 'lib/svgplot/plot.rb', line 131
def linearGradient(id, attributes={}, if_exists = :skip, &block)
raise "image reference isn't set, cannot use 'defs' (and thus linearGradient) !" if @img.nil?
@img.add_def(id, SVGPlot::SVGLinearGradient.new(@img, attributes), if_exists, &block)
end
|
#matrix(a, b, c, d, e, f) ⇒ Object
45
46
47
48
|
# File 'lib/svgplot/plot.rb', line 45
def matrix(a, b, c, d, e, f)
add_transform(:matrix, "#{a}, #{b}, #{c}, #{d}, #{e}, #{f}")
self
end
|
#merge_defaults ⇒ Object
190
191
192
193
194
195
|
# File 'lib/svgplot/plot.rb', line 190
def merge_defaults()
result = {}
return result if @defaults.empty?
@defaults.each { |d| result.merge!(d) }
result
end
|
#path(attributes = {}, &block) ⇒ Object
special case for path block
119
120
121
|
# File 'lib/svgplot/plot.rb', line 119
def path(attributes = {}, &block)
append_child SVGPlot::SVGPath.new(@img, attributes, &block)
end
|
#pop_defaults ⇒ Object
204
205
206
|
# File 'lib/svgplot/plot.rb', line 204
def pop_defaults()
@defaults.pop()
end
|
#push_defaults(defaults) ⇒ Object
198
199
200
201
|
# File 'lib/svgplot/plot.rb', line 198
def push_defaults(defaults)
@defaults = [] unless @defaults
@defaults.push(defaults)
end
|
#radialGradient(id, attributes = {}, if_exists = :skip, &block) ⇒ Object
special case for radialGradient
138
139
140
141
|
# File 'lib/svgplot/plot.rb', line 138
def radialGradient(id, attributes={}, if_exists = :skip, &block)
raise "image reference isn't set, cannot use 'defs' (and thus radialGradient) !" if @img.nil?
@img.add_def(id, SVGPlot::SVGRadialGradient.new(@img, attributes), if_exists, &block)
end
|
#raw(data) ⇒ Object
special case for raw blocks.
114
115
116
|
# File 'lib/svgplot/plot.rb', line 114
def raw(data)
append_child SVGPlot::SVGRaw.new(@img, data)
end
|
#rotate(angle, cx = nil, cy = nil) ⇒ Object
30
31
32
33
|
# File 'lib/svgplot/plot.rb', line 30
def rotate(angle, cx = nil, cy = nil)
add_transform(:rotate, "#{angle}#{(cx.nil? or cy.nil?) ? "" : ", #{cx}, #{cy}"}")
self
end
|
#scale(sx, sy = 1) ⇒ Object
25
26
27
28
|
# File 'lib/svgplot/plot.rb', line 25
def scale(sx, sy = 1)
add_transform(:scale, "#{sx}, #{sy}")
self
end
|
#skewX(angle) ⇒ Object
35
36
37
38
|
# File 'lib/svgplot/plot.rb', line 35
def skewX(angle)
add_transform(:skewX, "#{angle}")
self
end
|
#skewY(angle) ⇒ Object
40
41
42
43
|
# File 'lib/svgplot/plot.rb', line 40
def skewY(angle)
add_transform(:skewY, "#{angle}")
self
end
|
#spawn_child(tag, *args, &block) ⇒ Object
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
|
# File 'lib/svgplot/plot.rb', line 146
def spawn_child(tag, *args, &block)
parameters = {} if args.size == 0
unless parameters
parameters = args[0] if args[0].is_a? Hash
end
unless parameters
expansion = SVGPlot::SVG_EXPANSION[tag.to_sym]
raise "Unnamed parameters for #{tag} are not allowed!" unless expansion
if expansion.is_a? Array
raise "Bad unnamed parameter count for #{tag}, expecting #{expansion.size} got #{if args.last.is_a? Hash then args.size-1 else args.size end}" unless (args.size == expansion.size and not args.last.is_a? Hash) or (args.size - 1 == expansion.size and args.last.is_a? Hash)
parameters = Hash[expansion.zip(args)]
if args.last.is_a? Hash
parameters.merge! args.last
end
elsif expansion.is_a? Proc
hash = args.pop if args.last.is_a? Hash
parameters = expansion.call(args)
parameters.merge! hash if hash
else
raise "Unexpected expansion mechanism: #{expansion.class}"
end
end
merge_defaults().each do |key, value|
parameters[key] = value unless parameters[key]
end if @defaults
append_child(SVGPlot::SVGTagWithParent.new(@img, tag, parameters, &block))
end
|
#to_s ⇒ Object
276
277
278
279
280
|
# File 'lib/svgplot/plot.rb', line 276
def to_s
str = ""
write(str)
return str
end
|
#translate(tx, ty = 0) ⇒ Object
Provide methods for SVG transformations
20
21
22
23
|
# File 'lib/svgplot/plot.rb', line 20
def translate(tx, ty = 0)
add_transform(:translate, "#{tx}, #{ty}")
self
end
|
#use(id, attributes = {}) ⇒ Object
special case for use block
124
125
126
127
|
# File 'lib/svgplot/plot.rb', line 124
def use(id, attributes = {})
id = id.attributes[:id] if id.is_a? SVGPlot::SVGTag
append_child SVGPlot::SVGTagWithParent.new(@img, "use", attributes.merge("xlink:href" => "##{id}"))
end
|
#validate_attribute(attribute) ⇒ Object
85
86
87
88
|
# File 'lib/svgplot/plot.rb', line 85
def validate_attribute(attribute)
raise "#{@tag} does not support attribute #{attribute}" unless SVGPlot::SVG_STRUCTURE[@tag.to_sym][:attributes].include?(attribute.to_sym)
attribute.to_sym
end
|
#validate_attributes(attributes) ⇒ Object
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
|
# File 'lib/svgplot/plot.rb', line 55
def validate_attributes(attributes)
clean_attributes = {}
transforms = {}
attributes.delete(:transform) { Hash.new }.each do |key, value|
transforms[key] = value
end
unless transforms.empty?
str = ""
write_transforms(transforms, str)
clean_attributes[validate_attribute(:transform)] = str
end
styles = {}
attributes.delete(:style) { Hash.new }.each { |k, v| styles[k] = v }
unless styles.empty?
clean_attributes[validate_attribute(:style)] = styles
end
attributes.delete(:data) { Hash.new }.each do |key, value|
clean_attributes["data-#{key.to_s}".to_sym] = value
end
attributes.each do |key, value|
clean_attributes[validate_attribute(key)] = value
end
clean_attributes
end
|
#validate_child_name(name) ⇒ Object
218
219
220
221
222
223
224
225
226
227
228
|
# File 'lib/svgplot/plot.rb', line 218
def validate_child_name(name)
name = SVGPlot::SVG_ALIAS[name.to_sym] if SVGPlot::SVG_ALIAS[name.to_sym]
if SVGPlot::SVG_STRUCTURE[@tag.to_sym][:elements].include?(name.to_sym)
name.to_sym
elsif SVGPlot::SVG_ELEMENTS.include?(name.to_sym)
raise "#{@tag} should not contain child #{name}"
end
end
|
#validate_tag(tag) ⇒ Object
50
51
52
53
|
# File 'lib/svgplot/plot.rb', line 50
def validate_tag(tag)
raise "#{tag} is not a valid tag" unless SVGPlot::SVG_ELEMENTS.include?(tag.to_sym)
tag.to_sym
end
|
#with_style(style = {}, &proc) ⇒ Object
209
210
211
212
213
214
215
|
# File 'lib/svgplot/plot.rb', line 209
def with_style(style={}, &proc)
push_defaults(style)
self.instance_exec(&proc)
pop_defaults()
end
|
#write(output) ⇒ Object
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
# File 'lib/svgplot/plot.rb', line 251
def write(output)
raise "Can not write to given output!" unless output.respond_to?(:<<)
output << "<#{@tag.to_s}"
@attributes.each do
|attribute, value|
output << " #{attribute.to_s}=\""
if attribute == :style
write_styles(value, output)
elsif attribute == :points
write_points(value, output)
else
output << "#{value.to_s}"
end
output << "\""
end
if @children.empty?
output << "/>"
else
output << ">"
@children.each { |c| c.write(output) }
output << "</#{@tag.to_s}>"
end
end
|
#write_points(points, output) ⇒ Object
105
106
107
108
109
110
111
|
# File 'lib/svgplot/plot.rb', line 105
def write_points(points, output)
points.each_with_index do |value, index|
output << value.to_s
output << ',' if index.even?
output << ' ' if (index.odd? and (index != points.size-1))
end
end
|
#write_styles(styles, output) ⇒ Object
90
91
92
93
94
95
96
|
# File 'lib/svgplot/plot.rb', line 90
def write_styles(styles, output)
styles.each do |attribute, value|
attribute = attribute.to_s
attribute.gsub!('_','-')
output << "#{attribute}:#{value};"
end
end
|
98
99
100
101
102
103
|
# File 'lib/svgplot/plot.rb', line 98
def write_transforms(transforms, output)
transforms.each do |attribute, value|
value = [value] unless value.is_a?(Array)
output << "#{attribute.to_s}(#{value.join(',')}) "
end
end
|