Module: Sevgi::Graphics::Mixtures::Core
- Extended by:
- Forwardable
- Defined in:
- lib/sevgi/graphics/mixtures/core.rb
Overview
Core SVG tree and attribute DSL helpers.
Instance Method Summary collapse
-
#<<(element) ⇒ Sevgi::Graphics::Element
Appends an element as a child.
-
#Adopt(new_parent = nil, index: -1)) ⇒ Sevgi::Graphics::Element
Moves this element under a new parent.
-
#AdoptFirst(new_parent = nil) ⇒ Sevgi::Graphics::Element
Moves this element to the beginning of a parent.
-
#Append(*elements) ⇒ Sevgi::Graphics::Element
Appends distinct existing elements as children in argument order.
-
#Classify(*classes) ⇒ Sevgi::Graphics::Element
Adds CSS classes without duplicating existing values.
-
#Defaults(**attributes) ⇒ Sevgi::Graphics::Element
Assigns default attributes only when they are absent.
-
#Element(tag, *contents, **attributes) { ... } ⇒ Sevgi::Graphics::Element
Builds a child element with an explicit tag name.
-
#Forward(receiver, method, *args, **kwargs) ⇒ Object
Forwards this element as the first argument to another receiver.
-
#Is?(name) ⇒ Boolean
Reports whether this element has the given SVG name.
-
#Orphan ⇒ Sevgi::Graphics::Element?
Removes this element from its parent.
-
#Prepend(*elements) ⇒ Sevgi::Graphics::Element
Prepends distinct existing elements as children in argument order.
-
#Root ⇒ Sevgi::Graphics::Element
Returns the root document element.
-
#Root? ⇒ Boolean
Reports whether this element is the root document element.
-
#Stay(value) ⇒ Sevgi::Graphics::Mixtures::Stop
Wraps a traversal return value as a stop token.
-
#Traverse(depth = 0, leave = nil) {|element, depth| ... } ⇒ Sevgi::Graphics::Element, Object
Traverses the subtree depth-first.
-
#TraverseUp(height = 0) {|element, height| ... } ⇒ Object?
Traverses ancestors from this element to the root.
-
#With(*args, **kwargs) { ... } ⇒ Sevgi::Graphics::Element
Evaluates a block in the parent element context.
-
#Within(*args, **kwargs) { ... } ⇒ Sevgi::Graphics::Element
Evaluates a block in this element context.
Instance Method Details
#<<(element) ⇒ Sevgi::Graphics::Element
Appends an element as a child.
248 249 250 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 248 def <<(element) Append(element) end |
#Adopt(new_parent = nil, index: -1)) ⇒ Sevgi::Graphics::Element
Moves this element under a new parent.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 57 def Adopt(new_parent = nil, index: -1) tap do new_parent ||= parent Adoption.validate(self, new_parent) insertion = Adoption.index_for(self, new_parent, index) self.Orphan() (@parent = new_parent).children.insert(insertion, self) end end |
#AdoptFirst(new_parent = nil) ⇒ Sevgi::Graphics::Element
75 76 77 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 75 def AdoptFirst(*) Adopt(*, index: 0) end |
#Append(*elements) ⇒ Sevgi::Graphics::Element
Appends distinct existing elements as children in argument order. Each element transfers from its current parent. The complete batch is validated before any element moves.
84 85 86 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 84 def Append(*elements) tap { Adoption.batch(elements, self, front: false) } end |
#Classify(*classes) ⇒ Sevgi::Graphics::Element
Adds CSS classes without duplicating existing values.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 91 def Classify(*classes) tap do tokens = proc do |value| case value when nil [] when ::Array value.flat_map { tokens.call(it) } else value.to_s.split end end self[:class] = [*tokens.call(self[:class]), *tokens.call(classes)].uniq end end |
#Defaults(**attributes) ⇒ Sevgi::Graphics::Element
Assigns default attributes only when they are absent.
111 112 113 114 115 116 117 118 119 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 111 def Defaults(**attributes) tap do attributes.each do |key, value| next if has?(key) self[key] = value end end end |
#Element(tag, *contents, **attributes) { ... } ⇒ Sevgi::Graphics::Element
Builds a child element with an explicit tag name.
129 130 131 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 129 def Element(tag, *contents, **attributes, &block) self.class.send(:new, tag, contents: Content.contents(*contents), attributes:, parent: self, &block) end |
#Forward(receiver, method, *args, **kwargs) ⇒ Object
Forwards this element as the first argument to another receiver.
140 141 142 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 140 def Forward(receiver, method, ...) receiver.public_send(method, self, ...) end |
#Is?(name) ⇒ Boolean
Reports whether this element has the given SVG name.
147 148 149 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 147 def Is?(name) self.name() == name.to_sym end |
#Orphan ⇒ Sevgi::Graphics::Element?
Removes this element from its parent.
153 154 155 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 153 def Orphan parent.children&.delete(self) unless Root?() end |
#Prepend(*elements) ⇒ Sevgi::Graphics::Element
Prepends distinct existing elements as children in argument order. Each element transfers from its current parent. The complete batch is validated before any element moves.
162 163 164 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 162 def Prepend(*elements) tap { Adoption.batch(elements, self, front: true) } end |
#Root ⇒ Sevgi::Graphics::Element
Returns the root document element.
168 169 170 171 172 173 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 168 def Root element = self element = element.parent until element.Root?() element end |
#Root? ⇒ Boolean
Reports whether this element is the root document element.
177 178 179 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 177 def Root? self.class.root?(self) end |
#Stay(value) ⇒ Sevgi::Graphics::Mixtures::Stop
185 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 185 def Stay(...) = Stop.new(...) |
#Traverse(depth = 0, leave = nil) {|element, depth| ... } ⇒ Sevgi::Graphics::Element, Object
Traverses the subtree depth-first.
196 197 198 199 200 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 196 def Traverse(depth = 0, leave = nil, &block) ArgumentError.("Block required") unless block Traversal.call(self, depth, leave, &block) end |
#TraverseUp(height = 0) {|element, height| ... } ⇒ Object?
Traverses ancestors from this element to the root.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 210 def TraverseUp(height = 0, &block) ArgumentError.("Block required") unless block element = self loop do yield(element, height).tap { return it.value if it.is_a?(Stop) } break if element.Root?() element = element.parent height += 1 end end |
#With(*args, **kwargs) { ... } ⇒ Sevgi::Graphics::Element
Evaluates a block in the parent element context.
231 232 233 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 231 def With(*args, **kwargs, &block) tap { (args.shift || self).parent.instance_exec(*args, **kwargs, &block) } end |
#Within(*args, **kwargs) { ... } ⇒ Sevgi::Graphics::Element
Evaluates a block in this element context.
241 242 243 |
# File 'lib/sevgi/graphics/mixtures/core.rb', line 241 def Within(*args, **kwargs, &block) tap { (args.shift || self).instance_exec(*args, **kwargs, &block) } end |