class StringDoc::MetaNode
Lets two or more nodes to be represented as a single node in a doc, then manipulated together.
@api private
Attributes
doc[R]
@api private
internal_nodes[R]
@api private
transforms[R]
@api private
Public Class Methods
new(nodes)
click to toggle source
# File lib/string_doc/meta_node.rb, line 13 def initialize(nodes) # Reparent nodes that belong to the same parent. # nodes.group_by { |node| node.parent }.each_pair do |parent, children| # If the children already belong to a meta node doc, don't reparent them again. # unless children.first.labeled?(:__meta_node) parent.replace_node(children.first, self) end children[1..-1].each do |node| # Remove the node, but don't make it appear to have been removed for transforms. # node.remove(false, false) end end nodes.each do |node| node.set_label(:__meta_node, true) end @doc = StringDoc.from_nodes(nodes) @transforms = { high: [], default: [], low: [] } @internal_nodes = nodes.dup @pipeline = nil end
Public Instance Methods
after(node)
click to toggle source
# File lib/string_doc/meta_node.rb, line 198 def after(node) @doc.append(node) end
append(node)
click to toggle source
# File lib/string_doc/meta_node.rb, line 206 def append(node) internal_nodes.each do |each_node| each_node.append(node) end end
append_html(html)
click to toggle source
# File lib/string_doc/meta_node.rb, line 212 def append_html(html) internal_nodes.each do |each_node| each_node.append_html(html) end end
attributes()
click to toggle source
# File lib/string_doc/meta_node.rb, line 121 def attributes MetaAttributes.new(internal_nodes.map(&:attributes)) end
before(node)
click to toggle source
# File lib/string_doc/meta_node.rb, line 202 def before(node) @doc.prepend(node) end
children()
click to toggle source
# File lib/string_doc/meta_node.rb, line 112 def children internal_nodes.each_with_object(StringDoc.empty) { |node, children| case node.children when StringDoc children.nodes.concat(node.children.nodes) end } end
clear()
click to toggle source
# File lib/string_doc/meta_node.rb, line 194 def clear internal_nodes.each(&:clear) end
delete_label(name)
click to toggle source
# File lib/string_doc/meta_node.rb, line 246 def delete_label(name) internal_nodes.each do |each_node| each_node.delete_label(name) end end
each(descend: false) { |self| ... }
click to toggle source
# File lib/string_doc/meta_node.rb, line 252 def each(descend: false, &block) return enum_for(:each, descend: descend) unless block_given? yield self nodes.each do |node| # Yield each node that isn't an internal node (e.g. added before/after). # unless @internal_nodes.any? { |internal_node| internal_node.equal?(node) } case node when MetaNode node.each do |each_meta_node| yield each_meta_node end else yield node end end end end
each_significant_node(type, descend: false, &block)
click to toggle source
# File lib/string_doc/meta_node.rb, line 273 def each_significant_node(type, descend: false, &block) return enum_for(:each_significant_node, type, descend: descend) unless block_given? internal_nodes.each do |node| node.each_significant_node(type, descend: descend, &block) end end
each_significant_node_with_name(type, name, descend: false, &block)
click to toggle source
# File lib/string_doc/meta_node.rb, line 289 def each_significant_node_with_name(type, name, descend: false, &block) return enum_for(:each_significant_node_with_name, type, name, descend: descend) unless block_given? internal_nodes.each do |node| node.each_significant_node_with_name(type, name, descend: descend, &block) end end
each_significant_node_without_descending_into_type(type, descend: false, &block)
click to toggle source
# File lib/string_doc/meta_node.rb, line 281 def each_significant_node_without_descending_into_type(type, descend: false, &block) return enum_for(:each_significant_node_without_descending_into_type, type, descend: descend) unless block_given? internal_nodes.each do |node| node.each_significant_node_without_descending_into_type(type, descend: descend, &block) end end
finalize_labels(keep: [])
click to toggle source
# File lib/string_doc/meta_node.rb, line 91 def finalize_labels(keep: []) nodes.each do |node| node.finalize_labels(keep: keep) end end
find_first_significant_node(type, descend: false)
click to toggle source
# File lib/string_doc/meta_node.rb, line 297 def find_first_significant_node(type, descend: false) internal_nodes.each do |node| if found = node.find_first_significant_node(type, descend: descend) return found end end nil end
find_significant_nodes(type, descend: false)
click to toggle source
# File lib/string_doc/meta_node.rb, line 307 def find_significant_nodes(type, descend: false) internal_nodes.each_with_object([]) { |node, collected| collected.concat(node.find_significant_nodes(type, descend: descend)) } end
find_significant_nodes_with_name(type, name, descend: false)
click to toggle source
# File lib/string_doc/meta_node.rb, line 313 def find_significant_nodes_with_name(type, name, descend: false) internal_nodes.each_with_object([]) { |node, collected| collected.concat(node.find_significant_nodes_with_name(type, name, descend: descend)) } end
freeze(*)
click to toggle source
Calls superclass method
# File lib/string_doc/meta_node.rb, line 97 def freeze(*) pipeline super end
html()
click to toggle source
# File lib/string_doc/meta_node.rb, line 174 def html internal_nodes[0].html end
html=(html)
click to toggle source
# File lib/string_doc/meta_node.rb, line 178 def html=(html) internal_nodes.each do |node| node.html = html end end
initialize_copy(_)
click to toggle source
@api private
Calls superclass method
# File lib/string_doc/meta_node.rb, line 43 def initialize_copy(_) super nodes, internal_nodes = [], [] @doc.nodes.each do |current_node| duped_node = current_node.dup nodes << duped_node if @internal_nodes.any? { |current_internal_node| current_internal_node.equal?(current_node) } internal_nodes << duped_node end end @doc = StringDoc.from_nodes(nodes) @transforms = @transforms.each_with_object({}) { |(key, value), hash| hash[key] = value.dup } @internal_nodes = internal_nodes @pipeline = nil end
label(name)
click to toggle source
# File lib/string_doc/meta_node.rb, line 224 def label(name) if node = internal_nodes.first node.label(name) else nil end end
labeled?(name)
click to toggle source
# File lib/string_doc/meta_node.rb, line 232 def labeled?(name) if node = internal_nodes.first node.labeled?(name) else false end end
next_transform()
click to toggle source
# File lib/string_doc/meta_node.rb, line 125 def next_transform pipeline.shift end
nodes()
click to toggle source
@api private
# File lib/string_doc/meta_node.rb, line 108 def nodes @doc.nodes end
parent=(parent)
click to toggle source
@api private
# File lib/string_doc/meta_node.rb, line 103 def parent=(parent) @parent = parent end
prepend(node)
click to toggle source
# File lib/string_doc/meta_node.rb, line 218 def prepend(node) internal_nodes.each do |each_node| each_node.prepend(node) end end
remove(label = true, descend = true)
click to toggle source
# File lib/string_doc/meta_node.rb, line 162 def remove(label = true, descend = true) internal_nodes.each do |node| node.remove(label, descend) end @internal_nodes = [] end
removed?()
click to toggle source
# File lib/string_doc/meta_node.rb, line 319 def removed? internal_nodes.all?(&:removed?) end
render(output = String.new, context: nil)
click to toggle source
Converts the node to an xml string.
# File lib/string_doc/meta_node.rb, line 325 def render(output = String.new, context: nil) if transforms_itself? __transform(output, context: context) else nodes.each do |each_node| each_node.render(output, context: context) end end output end
replace(replacement)
click to toggle source
# File lib/string_doc/meta_node.rb, line 154 def replace(replacement) internal_nodes.each do |each_node| each_node.replace(replacement) end @internal_nodes = StringDoc.nodes_from_doc_or_string(replacement) end
replace_children(children)
click to toggle source
# File lib/string_doc/meta_node.rb, line 184 def replace_children(children) internal_nodes.each do |node| node.replace_children(children) end end
set_label(name, value)
click to toggle source
# File lib/string_doc/meta_node.rb, line 240 def set_label(name, value) internal_nodes.each do |each_node| each_node.set_label(name, value) end end
significance?(*types)
click to toggle source
# File lib/string_doc/meta_node.rb, line 148 def significance?(*types) internal_nodes.any? { |node| node.significance?(*types) } end
significant?(type = nil)
click to toggle source
# File lib/string_doc/meta_node.rb, line 142 def significant?(type = nil) internal_nodes.any? { |node| node.significant?(type) } end
soft_copy()
click to toggle source
@api private
# File lib/string_doc/meta_node.rb, line 68 def soft_copy instance = self.class.allocate nodes, internal_nodes = [], [] @doc.nodes.each do |current_node| duped_node = current_node.soft_copy nodes << duped_node if @internal_nodes.any? { |current_internal_node| current_internal_node.equal?(current_node) } internal_nodes << duped_node end end instance.instance_variable_set(:@doc, StringDoc.from_nodes(nodes)) instance.instance_variable_set(:@transforms, @transforms) instance.instance_variable_set(:@internal_nodes, internal_nodes) instance.instance_variable_set(:@pipeline, @pipeline.dup) instance end
tagname()
click to toggle source
# File lib/string_doc/meta_node.rb, line 190 def tagname internal_nodes[0].tagname end
text()
click to toggle source
# File lib/string_doc/meta_node.rb, line 170 def text internal_nodes[0].text end
to_s()
click to toggle source
Returns the node as an xml string, without transforming.
# File lib/string_doc/meta_node.rb, line 341 def to_s nodes.each_with_object(String.new) do |node, string| string << node.to_s end end
transform(priority: :default, &block)
click to toggle source
# File lib/string_doc/meta_node.rb, line 129 def transform(priority: :default, &block) @transforms[priority] << block @pipeline = nil end
transforms?()
click to toggle source
# File lib/string_doc/meta_node.rb, line 134 def transforms? transforms_itself? || children.transforms? end
transforms_itself?()
click to toggle source
# File lib/string_doc/meta_node.rb, line 138 def transforms_itself? pipeline.any? end
Private Instance Methods
__transform(string, context:)
click to toggle source
# File lib/string_doc/meta_node.rb, line 353 def __transform(string, context:) node = if frozen? soft_copy else self end current = node while transform = node.next_transform return_value = transform.call(node, context, string) case return_value when NilClass return when StringDoc return_value.render(string, context: context); return when Node, MetaNode if return_value.removed? return else current = return_value end else string << return_value.to_s; return end end current.render(string, context: context) end
pipeline()
click to toggle source
# File lib/string_doc/meta_node.rb, line 349 def pipeline @pipeline ||= @transforms.values.flatten end