Class: CSL::Node
- Extended by:
- Extensions::Nesting, Forwardable
- Includes:
- PrettyPrinter, Treelike, Comparable, Enumerable
- Defined in:
- lib/csl/node.rb
Direct Known Subclasses
Info, Info::Author, Info::Category, Info::Contributor, Info::Link, Info::Translator, Locale, Locale::Date, Locale::DatePart, Locale::StyleOptions, Locale::Term, Locale::Terms, Style, Style::Bibliography, Style::Choose, Style::Choose::Block, Style::Citation, Style::Date, Style::DatePart, Style::EtAl, Style::Group, Style::Label, Style::Layout, Style::Macro, Style::Name, Style::NamePart, Style::Names, Style::Number, Style::Sort, Style::Sort::Key, Style::Substitute, Style::Text, TextNode
Instance Attribute Summary collapse
-
#attributes ⇒ Object
readonly
Returns the value of attribute attributes.
Attributes included from Treelike
Class Method Summary collapse
- .constantize(name) ⇒ Object
-
.create(name, attributes = {}, &block) ⇒ Object
Returns a new node with the passed in name and attributes.
- .create_attributes(attributes) ⇒ Object
- .default_attributes ⇒ Object
- .hide_default_attributes! ⇒ Object
- .hide_default_attributes? ⇒ Boolean
-
.match?(name_pattern) ⇒ Boolean
Whether or not the node’s name matches the passed-in name pattern.
-
.matches? ⇒ Boolean
Whether or not the node’s name matches the passed-in name pattern.
- .parse(data) ⇒ Object
- .parse!(data) ⇒ Object
- .show_default_attributes! ⇒ Object
- .types ⇒ Object
Instance Method Summary collapse
- #<=>(other) ⇒ Object
-
#attribute?(name) ⇒ Boolean
Returns true if the node contains an attribute with the passed-in name; false otherwise.
-
#attributes?(*names) ⇒ Boolean
True if the node contains attributes for all passed-in names; false otherwise.
-
#attributes_for(*filter) ⇒ Hash
The node’s attributes matching the filter.
-
#custom_attributes ⇒ Hash
The attributes currently not set to their default values.
- #deep_copy ⇒ Object
-
#default_attribute?(name) ⇒ Boolean
Whether or not key is set to the default value.
-
#default_attributes ⇒ Hash
The attributes currently set to their default values.
-
#each(&block) ⇒ Object
(also: #each_pair)
Iterates through the Node’s attributes.
-
#exact_match?(name = nodename, conditions = {}) ⇒ Boolean
(also: #matches_exactly?)
Tests whether or not the Name matches the passed-in node name and attribute conditions exactly; if a Hash is passed as a single argument, it is taken as the conditions parameter (the name parameter is automatically matches in this case).
-
#format_page_ranges? ⇒ Boolean
Whether or not page ranges should be formatted when rendering this node.
-
#formatting_options ⇒ Hash
The node’s formatting options.
-
#has_attributes? ⇒ Boolean
Returns true if the node contains any attributes (ignores nil values); false otherwise.
-
#has_default_attributes? ⇒ Boolean
(also: #has_defaults?)
Whether or not the node has default attributes.
- #has_language? ⇒ Boolean
-
#initialize(attributes = {}) {|_self| ... } ⇒ Node
constructor
A new instance of Node.
- #initialize_copy(other) ⇒ Object
- #inspect ⇒ Object
-
#match?(name = nodename, conditions = {}) ⇒ Boolean
(also: #matches?)
Tests whether or not the Name matches the passed-in node name and attribute conditions; if a Hash is passed as a single argument, it is taken as the conditions parameter (the name parameter automatically matches in this case).
- #merge!(options) ⇒ Object
- #page_range_format ⇒ Object
- #quotes? ⇒ Boolean
- #reverse_merge!(options) ⇒ Object
- #save_to(path, options = {}) ⇒ Object
- #strip_periods? ⇒ Boolean
-
#tags ⇒ Object
Returns the node’ XML tags (including attribute assignments) as an array of strings.
- #textnode? ⇒ Boolean (also: #has_text?)
Methods included from Extensions::Nesting
Methods included from PrettyPrinter
Methods included from Treelike
#<<, #add_child, #add_children, #ancestors, #closest, #delete_child, #delete_children, #depth, #descendants, #each_ancestor, #each_child, #each_descendant, #each_sibling, #empty?, #find_child, #find_children, #has_children?, #root, #root?, #siblings, #unlink
Constructor Details
#initialize(attributes = {}) {|_self| ... } ⇒ Node
Returns a new instance of Node.
229 230 231 232 233 234 |
# File 'lib/csl/node.rb', line 229 def initialize(attributes = {}) @attributes = self.class.create_attributes(attributes) @children = self.class.create_children yield self if block_given? end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
Returns the value of attribute attributes.
225 226 227 |
# File 'lib/csl/node.rb', line 225 def attributes @attributes end |
Class Method Details
.constantize(name) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/csl/node.rb', line 44 def constantize(name) pattern = /:#{name.to_s.tr('-', '')}$/i klass = types.detect { |t| t.matches?(pattern) } case when !klass.nil? klass when nesting[-2].respond_to?(:constantize) nesting[-2].constantize(name) else nil end end |
.create(name, attributes = {}, &block) ⇒ Object
Returns a new node with the passed in name and attributes.
66 67 68 69 70 71 72 |
# File 'lib/csl/node.rb', line 66 def create(name, attributes = {}, &block) klass = constantize(name) node = (klass || Node).new(attributes, &block) node.nodename = name node end |
.create_attributes(attributes) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/csl/node.rb', line 74 def create_attributes(attributes) if const?(:Attributes) const_get(:Attributes).new(default_attributes.merge(attributes)) else default_attributes.merge(attributes) end end |
.default_attributes ⇒ Object
28 29 30 |
# File 'lib/csl/node.rb', line 28 def default_attributes @default_attributes ||= {} end |
.hide_default_attributes! ⇒ Object
36 37 38 |
# File 'lib/csl/node.rb', line 36 def hide_default_attributes! @show_default_attributes = false end |
.hide_default_attributes? ⇒ Boolean
32 33 34 |
# File 'lib/csl/node.rb', line 32 def hide_default_attributes? !@show_default_attributes end |
.match?(name_pattern) ⇒ Boolean
Returns whether or not the node’s name matches the passed-in name pattern.
60 61 62 |
# File 'lib/csl/node.rb', line 60 def match?(name_pattern) name_pattern === name end |
.matches? ⇒ Boolean
Returns whether or not the node’s name matches the passed-in name pattern.
63 64 65 |
# File 'lib/csl/node.rb', line 63 def match?(name_pattern) name_pattern === name end |
.parse(data) ⇒ Object
82 83 84 85 86 |
# File 'lib/csl/node.rb', line 82 def parse(data) parse!(data) rescue nil end |
.parse!(data) ⇒ Object
88 89 90 91 92 93 94 95 |
# File 'lib/csl/node.rb', line 88 def parse!(data) node = CSL.parse!(data, self) raise ParseError, "root node not #{self.name}: #{node.inspect}" unless node.class == self || Node.equal?(self) node end |
.show_default_attributes! ⇒ Object
40 41 42 |
# File 'lib/csl/node.rb', line 40 def show_default_attributes! @show_default_attributes = true end |
.types ⇒ Object
24 25 26 |
# File 'lib/csl/node.rb', line 24 def types @types ||= Set.new end |
Instance Method Details
#<=>(other) ⇒ Object
478 479 480 481 482 483 |
# File 'lib/csl/node.rb', line 478 def <=>(other) return nil unless other.is_a?(Node) comparables <=> other.comparables rescue nil end |
#attribute?(name) ⇒ Boolean
Returns true if the node contains an attribute with the passed-in name; false otherwise.
307 308 309 |
# File 'lib/csl/node.rb', line 307 def attribute?(name) attributes.fetch(name, false) end |
#attributes?(*names) ⇒ Boolean
Returns true if the node contains attributes for all passed-in names; false otherwise.
314 315 316 317 318 |
# File 'lib/csl/node.rb', line 314 def attributes?(*names) names.flatten(1).all? do |name| attribute?(name) end end |
#attributes_for(*filter) ⇒ Hash
Returns the node’s attributes matching the filter.
427 428 429 430 431 432 433 |
# File 'lib/csl/node.rb', line 427 def attributes_for(*filter) filter.flatten! Hash[map { |name, value| !value.nil? && filter.include?(name) ? [name, value.to_s] : nil }.compact] end |
#custom_attributes ⇒ Hash
Returns the attributes currently not set to their default values.
299 300 301 302 303 |
# File 'lib/csl/node.rb', line 299 def custom_attributes attributes.to_hash.reject do |name, _| default_attribute?(name) end end |
#deep_copy ⇒ Object
241 242 243 244 245 246 247 248 249 |
# File 'lib/csl/node.rb', line 241 def deep_copy copy = dup each_child do |child| copy.add_child child.deep_copy end copy end |
#default_attribute?(name) ⇒ Boolean
Returns whether or not key is set to the default value.
283 284 285 286 287 288 289 |
# File 'lib/csl/node.rb', line 283 def default_attribute?(name) defaults = self.class.default_attributes name, value = name.to_sym, attributes.fetch(name) return false unless !value.nil? || defaults.key?(name) defaults[name] == value end |
#default_attributes ⇒ Hash
Returns the attributes currently set to their default values.
292 293 294 295 296 |
# File 'lib/csl/node.rb', line 292 def default_attributes attributes.to_hash.select do |name, _| default_attribute?(name) end end |
#each(&block) ⇒ Object Also known as: each_pair
Iterates through the Node’s attributes
271 272 273 274 275 276 277 278 |
# File 'lib/csl/node.rb', line 271 def each(&block) if block_given? attributes.each_pair(&block) self else to_enum end end |
#exact_match?(name = nodename, conditions = {}) ⇒ Boolean Also known as: matches_exactly?
Tests whether or not the Name matches the passed-in node name and attribute conditions exactly; if a Hash is passed as a single argument, it is taken as the conditions parameter (the name parameter is automatically matches in this case).
Whether or not the arguments match the node is determined as follows:
-
The name must match Treelike#nodename
-
All attribute name/value pairs of the node must match the corresponding pairs in the passed-in Hash
Note that all node attributes are used by this method – if you want to match only a subset of attributes #match? should be used instead.
412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/csl/node.rb', line 412 def exact_match?(name = nodename, conditions = {}) name, conditions = match_conditions_for(name, conditions) return false unless name === nodename return true if conditions.empty? conditions.values_at(*attributes.keys).zip( attributes.values_at(*attributes.keys)).all? do |condition, value| condition === value end end |
#format_page_ranges? ⇒ Boolean
Whether or not page ranges should be formatted when rendering this node.
Page ranges must be formatted if the node is part of a Style with a page-range-format value.
460 461 462 |
# File 'lib/csl/node.rb', line 460 def format_page_ranges? root.respond_to?(:has_page_range_format?) && root.has_page_range_format? end |
#formatting_options ⇒ Hash
The node’s formatting options. If the node’s parent responds to ‘inheritable_formatting_options`, these will be included in the result. This makes it easy for nodes to push formatting options to their child nodes.
442 443 444 445 446 447 448 449 450 |
# File 'lib/csl/node.rb', line 442 def = attributes_for Schema.attr(:formatting) if !root? && parent.respond_to?(:inheritable_formatting_options) parent..merge() else end end |
#has_attributes? ⇒ Boolean
Returns true if the node contains any attributes (ignores nil values); false otherwise.
322 323 324 |
# File 'lib/csl/node.rb', line 322 def has_attributes? !attributes.empty? end |
#has_default_attributes? ⇒ Boolean Also known as: has_defaults?
Returns whether or not the node has default attributes.
265 266 267 |
# File 'lib/csl/node.rb', line 265 def has_default_attributes? !default_attributes.empty? end |
#has_language? ⇒ Boolean
326 327 328 |
# File 'lib/csl/node.rb', line 326 def has_language? false end |
#initialize_copy(other) ⇒ Object
236 237 238 239 |
# File 'lib/csl/node.rb', line 236 def initialize_copy(other) @parent, @ancestors, @descendants, @siblings, @root, @depth = nil initialize(other.attributes) end |
#inspect ⇒ Object
503 504 505 |
# File 'lib/csl/node.rb', line 503 def inspect "#<#{[self.class.name, *attribute_assignments].join(' ')} children=[#{children.count}]>" end |
#match?(name = nodename, conditions = {}) ⇒ Boolean Also known as: matches?
Tests whether or not the Name matches the passed-in node name and attribute conditions; if a Hash is passed as a single argument, it is taken as the conditions parameter (the name parameter automatically matches in this case).
Whether or not the arguments match the node is determined as follows:
-
The name must match Treelike#nodename
-
All attribute name/value pairs passed as conditions must match the corresponding attributes of the node
Note that only attributes present in the passed-in conditions influence the match – if you want to match only nodes that contain no other attributes than specified by the conditions, #exact_match? should be used instead.
372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/csl/node.rb', line 372 def match?(name = nodename, conditions = {}) name, conditions = match_conditions_for(name, conditions) return false unless name === nodename return true if conditions.empty? conditions.values.zip( attributes.values_at(*conditions.keys)).all? do |condition, value| condition === value end end |
#merge!(options) ⇒ Object
251 252 253 254 |
# File 'lib/csl/node.rb', line 251 def merge!() attributes.merge!() self end |
#page_range_format ⇒ Object
464 465 466 467 |
# File 'lib/csl/node.rb', line 464 def page_range_format return unless format_page_ranges? root.page_range_format end |
#quotes? ⇒ Boolean
473 474 475 |
# File 'lib/csl/node.rb', line 473 def quotes? attribute?(:'quotes') && !!(attributes[:'quotes'].to_s =~ /^true$/i) end |
#reverse_merge!(options) ⇒ Object
256 257 258 259 260 261 262 |
# File 'lib/csl/node.rb', line 256 def reverse_merge!() .each_pair do |key, value| attributes[key] = value unless attribute? key end self end |
#save_to(path, options = {}) ⇒ Object
335 336 337 338 339 340 341 |
# File 'lib/csl/node.rb', line 335 def save_to(path, = {}) File.open(path, 'w:UTF-8') do |f| f << ([:compact] ? to_xml : pretty_print) end self end |
#strip_periods? ⇒ Boolean
469 470 471 |
# File 'lib/csl/node.rb', line 469 def strip_periods? attribute?(:'strip-periods') && !!(attributes[:'strip-periods'].to_s =~ /^true$/i) end |
#tags ⇒ Object
Returns the node’ XML tags (including attribute assignments) as an array of strings.
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
# File 'lib/csl/node.rb', line 487 def if has_children? = [] << "<#{[nodename, *attribute_assignments].join(' ')}>" << children.map { |node| node.respond_to?(:tags) ? node. : [node.to_s] }.flatten(1) << "</#{nodename}>" else ["<#{[nodename, *attribute_assignments].join(' ')}/>"] end end |
#textnode? ⇒ Boolean Also known as: has_text?
330 331 332 |
# File 'lib/csl/node.rb', line 330 def textnode? false end |