arboretum 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42a7d24be72182eafaad9b254b40ff5738423389
4
- data.tar.gz: 5e0fc2574eb3bbc059c94dd9213dd7f7283c35d4
3
+ metadata.gz: 53ab23c0b718279ac0f58181b1b57cc75a610aa1
4
+ data.tar.gz: 964672ec600783cb39cad917b61deba000bd544f
5
5
  SHA512:
6
- metadata.gz: 44b8504954777d1d5090fd11cbeba70dcd462d47a117d9b27a1b08de0b491fa74c41062cfa76cfb1e28f709a74779d0c9023ab48922392b61e1fac92ff92a95d
7
- data.tar.gz: ee812ae2721613864054cd0d605f217bff0495e34021c0e77e2d597ca65b35763024b9f5a5d38c9b2a84fe404a523ec4e25540e3e685a25703949528fc3ef740
6
+ metadata.gz: 0f141ef672014ac90376357b7edad9335e6653d27eebd23620bdce06e4f5bc58ce8da6890c1cf6f0255de622f52b08129b88dff9932e6ff5e36b6dfe48a9c837
7
+ data.tar.gz: d1f8c0b8e694062e19ca877c1fcb3a4c1aae57eb8856615660f7f6a33d26cde5d0e37d8356f948e2ced718668ded81c52c8fead8bdb3c3ed49a3fd317cc932ec
@@ -1,3 +1,3 @@
1
- require_relative 'arboretum/xml'
1
+ require_relative 'arboretum/scandent'
2
2
  require_relative 'arboretum/doctree'
3
- require_relative 'arboretum/scandent'
3
+ require_relative 'arboretum/xml'
@@ -0,0 +1,49 @@
1
+ require 'fiber'
2
+
3
+ class ArboretumFiber
4
+ def self.ROOT_FIBER
5
+ @@ROOT_FIBER
6
+ end
7
+ def self.set_root_fiber(fiber)
8
+ @@ROOT_FIBER = fiber
9
+ end
10
+ end
11
+
12
+ ArboretumFiber.set_root_fiber(Fiber.current)
13
+
14
+ class Debtor
15
+ def initialize
16
+ @resource = nil
17
+ @locked = true
18
+ @creditors = Array.new
19
+ end
20
+ def set_resource(rsc)
21
+ @resource = rsc
22
+ end
23
+ alias_method :set, :set_resource
24
+ def resource
25
+ begin
26
+ if locked?
27
+ @creditors << Fiber.current
28
+ Fiber.yield
29
+ end
30
+ rescue FiberError
31
+ puts "Warning: Tried to yield the root Fiber on a locked resource call. Returning resource anyways..."
32
+ end
33
+ @resource
34
+ end
35
+ def resource!
36
+ @resource
37
+ end
38
+ def locked?
39
+ @locked
40
+ end
41
+ def free?
42
+ !@locked
43
+ end
44
+ def free
45
+ @locked = false
46
+ @creditors.each {|c| c.resume }
47
+ @creditors = Array.new
48
+ end
49
+ end
@@ -1,3 +1,7 @@
1
+ require 'promise'
2
+ require 'forwardable'
3
+ require 'securerandom'
4
+
1
5
  module Arboretum
2
6
  module DocTree
3
7
  module Counters
@@ -60,21 +64,21 @@ module Arboretum
60
64
  end # Counters
61
65
 
62
66
  module Elements
63
- require 'forwardable'
64
- require 'securerandom'
65
- require_relative 'scandent'
66
-
67
67
  # Tree is a representation of a tree data structure consisting of elements
68
68
  # A Tree holds only reference to the root Element of the tree
69
69
  # A tree is useful for contextual operations on elements with the root as an ancestor
70
70
  class Tree
71
71
  include Enumerable
72
72
 
73
- attr_accessor :root
73
+ attr_accessor :root, :id_cache
74
74
 
75
75
  def initialize(root=nil)
76
- @root = root # Element
77
- @listeners = [] # Array of GroupListeners
76
+ @root = root # Element
77
+ @listeners = Array.new # Array of GroupListeners
78
+
79
+ @id_cache = Hash.new # Hash: String => Element
80
+
81
+ root.update_tree_residence(self)
78
82
  end
79
83
 
80
84
  # Redefine the `each` method to iterate through all elements in the tree in depth-first order
@@ -94,6 +98,24 @@ module Arboretum
94
98
  Array.new.tap {|list| self.each {|element| list << element}}
95
99
  end
96
100
 
101
+ def id_cache_add(id, element)
102
+ @id_cache[id] = element
103
+ end
104
+
105
+ def id_cache_remove(id)
106
+ @id_cache.delete(id)
107
+ end
108
+
109
+ def id_cache_get(id)
110
+ @id_cache[id].tap {|element| yield element if block_given?}
111
+ end
112
+ alias_method :element_from_id, :id_cache_get
113
+
114
+ def element_from_id_hash(hash_id)
115
+ raise IndexError.new("Tried to get element from hash id with no hash: #{hash_id}") if !hash_id[0].eql?("#")
116
+ self.id_cache_get(hash_id[1..-1]).tap {|element| yield element if block_given?}
117
+ end
118
+
97
119
  # Find any and all elements in the tree that match a given ScandentRule string
98
120
  def scan(rule_string)
99
121
  selected = []
@@ -387,6 +409,7 @@ module Arboretum
387
409
  element = Element.create(element) if element.is_a?(Hash)
388
410
  element.graft_onto(self.parent, self.index_in_parent)
389
411
  self.graft_onto(element, index)
412
+ yield element if block_given?
390
413
  element
391
414
  end
392
415
  end
@@ -424,7 +447,7 @@ module Arboretum
424
447
  attr_writer :parent, :children, :sibling_prev, :sibling_next, :incrementers, :resetters, :library
425
448
 
426
449
  public
427
- attr_reader :parent, :children, :sibling_prev, :sibling_next, :incrementers, :resetters, :library
450
+ attr_reader :parent, :children, :sibling_prev, :sibling_next, :incrementers, :resetters, :library, :tree_residence
428
451
  attr_accessor :break_within, :history
429
452
 
430
453
  # Class method to stitch together two elements as siblings, ordered
@@ -461,7 +484,7 @@ module Arboretum
461
484
  end
462
485
  created_element = TaggedElement.new(namespace, tag, sanitary_attrs)
463
486
  if !text.nil?
464
- raise TypeError.new("Text must be a string or TextElement") if !(text.is_a?(String) or text.is_a?(TextElement))
487
+ raise TypeError.new("Text must be a String or TextElement") if !(text.is_a?(String) or text.is_a?(TextElement))
465
488
  if text.is_a?(String)
466
489
  text_child = TextElement.new(text)
467
490
  created_element.append_child(text_child)
@@ -484,6 +507,9 @@ module Arboretum
484
507
  @sibling_next = nil # Element
485
508
  @children = [] # Array of Elements
486
509
 
510
+ # Tree residence
511
+ @tree_residence = nil # Tree
512
+
487
513
  # Properties, references, and counters
488
514
  @break_within = false # Boolean
489
515
  @incrementers = Hash.new # Hash with key: Symbol (name), value: Incrementer
@@ -535,7 +561,7 @@ module Arboretum
535
561
  alias_method :unshift, :prepend_child
536
562
 
537
563
  # Insert an element as a child at a specified index it this element's children
538
- def insert_child(*elements)
564
+ def insert_child(*elements, index)
539
565
  placed = Array.new
540
566
  elements.each do |element|
541
567
  if !element.nil?
@@ -659,19 +685,15 @@ module Arboretum
659
685
  # Add an element to a category in this element's library
660
686
  def lib_add(other, category)
661
687
  raise TypeError.new("Cannot create a record for a non-element") if !other.is_a?(Element) and !other.is_a?(ElementGroup)
688
+ category = category.to_sym if !category.is_a?(Symbol)
662
689
  if @library.has_key?(category)
663
- record = @library[category]
664
- if record.is_a?(Element) and other.is_a?(Element)
665
- @library[category] = ElementGroup.new([record, other])
666
- elsif record.is_a?(ElementGroup) and other.is_a?(Element)
690
+ if other.is_a?(Element)
667
691
  @library[category] << other
668
- elsif record.is_a?(Element) and other.is_a?(ElementGroup)
669
- @library[category] = ElementGroup.new([record]) + other
670
- elsif record.is_a?(ElementGroup) and other.is_a?(ElementGroup)
671
- @library[category] = record + other
692
+ else
693
+ @library[category] = @library[category] + other
672
694
  end
673
695
  else
674
- @library[category] = other
696
+ @library[category] = ElementGroup.new([other])
675
697
  end
676
698
 
677
699
  end
@@ -680,6 +702,7 @@ module Arboretum
680
702
 
681
703
  # Get record from the given category in this element's library
682
704
  def lib_get(category)
705
+ category = category.to_sym if !category.is_a?(Symbol)
683
706
  @library[category]
684
707
  end
685
708
  alias_method :[], :lib_get
@@ -697,6 +720,11 @@ module Arboretum
697
720
  element_copy
698
721
  end
699
722
 
723
+ def update_tree_residence(update_tree)
724
+ @tree_residence = update_tree
725
+ @children.each {|child| child.update_tree_residence(update_tree)}
726
+ end
727
+
700
728
  # Detach from current parent/siblings
701
729
  def detach
702
730
  Element.stitch!(@sibling_prev, @sibling_next)
@@ -705,6 +733,8 @@ module Arboretum
705
733
  end
706
734
  alias_method :prune, :detach
707
735
  alias_method :delete, :detach
736
+ alias_method :clear, :detach
737
+ alias_method :remove, :detach
708
738
 
709
739
  # Graft onto another element of the tree at any index of its children
710
740
  # By default, it will graft as the last element of the other element's children
@@ -730,6 +760,8 @@ module Arboretum
730
760
  next_child = graft_parent.children[index]
731
761
  Element.stitch!(self, next_child)
732
762
 
763
+ self.update_tree_residence(graft_parent.tree_residence) if !self.tree_residence.eql?(graft_parent.tree_residence)
764
+
733
765
  # Graft group at index
734
766
  graft_parent.children.insert(index, self)
735
767
  end
@@ -747,6 +779,8 @@ module Arboretum
747
779
  Element.stitch!(nil, self)
748
780
  Element.stitch!(self, next_child)
749
781
 
782
+ self.update_tree_residence(graft_parent.tree_residence) if !self.tree_residence.eql?(graft_parent.tree_residence)
783
+
750
784
  # Insert graft group at the beginning of parent children
751
785
  graft_parent.children.insert(0, self)
752
786
  end
@@ -763,6 +797,8 @@ module Arboretum
763
797
  Element.stitch!(previous_child, self)
764
798
  Element.stitch!(self, nil)
765
799
 
800
+ self.update_tree_residence(graft_parent.tree_residence) if !self.tree_residence.eql?(graft_parent.tree_residence)
801
+
766
802
  # Push graft group onto parent children
767
803
  graft_parent.children.push(self)
768
804
  end
@@ -850,18 +886,18 @@ module Arboretum
850
886
  end
851
887
 
852
888
  # Finds elements in relation to this one that fit a ScandentRule string
853
- def find(rule_string)
889
+ def find(rule_string, silent: false)
854
890
  rule = Arboretum::Scandent::Parser.parse_rule_string(rule_string, :PATH_LOCATOR)
855
891
  selected = rule.locate(self) {|found_element| yield found_element if block_given?}
856
- puts "--Warning: Rule #{rule} did not match any elements!--" if selected.empty?
892
+ puts "--Warning: Rule #{rule} did not match any elements!--" if selected.empty? and !silent
857
893
  ElementGroup.new(selected)
858
894
  end
859
895
  alias_method :locate, :find
860
896
 
861
897
  # Finds up to `n` elements in relation to this one that fit a ScandentRule string
862
- def find_first_n(rule_string, limit)
898
+ def find_first_n(rule_string, limit, silent: false)
863
899
  if limit.zero?
864
- puts "--Warning: Rule #{rule} was given limit '0'. Returning nil...--" if selected.empty?
900
+ puts "--Warning: Rule #{rule} was given limit '0'. Returning nil...--" if selected.empty? and !silent
865
901
  return nil
866
902
  end
867
903
  selected = []
@@ -871,14 +907,14 @@ module Arboretum
871
907
  yield found_element if block_given?
872
908
  selected << found_element
873
909
  end
874
- puts "--Warning: Rule #{rule} did not match any elements!--" if selected.empty?
910
+ puts "--Warning: Rule #{rule} on #{self.to_s} did not match any elements!--" if selected.empty? and !silent
875
911
  ElementGroup.new(selected)
876
912
  end
877
913
  alias_method :locate_first_n, :find_first_n
878
914
 
879
915
  # Find the first element in relation to this one that fits a ScandentRule string
880
- def find_first(rule_string)
881
- self.find_first_n(rule_string, 1) {|found_element| yield found_element if block_given?}.first
916
+ def find_first(rule_string, silent: false)
917
+ self.find_first_n(rule_string, 1, :silent => silent) {|found_element| yield found_element if block_given?}.first
882
918
  end
883
919
  alias_method :locate_first, :find_first
884
920
 
@@ -970,7 +1006,6 @@ module Arboretum
970
1006
  class TaggedElement < Element
971
1007
  @@unpaired_tags = [:'DOCTYPE', :'!DOCTYPE', :'area', :'base', :'br', :'col', :'command', :'embed', :'hr', :'img',
972
1008
  :'input', :'keygen', :'link', :'meta', :'param', :'source', :'track', :'wbr']
973
- @@need_valid_xml = true
974
1009
 
975
1010
  attr_accessor :namespace, :tag, :attrs
976
1011
 
@@ -980,7 +1015,7 @@ module Arboretum
980
1015
  # Element tag and attributes
981
1016
  @namespace = namespace # Symbol
982
1017
  @tag = tag # Symbol
983
- @attrs = attrs # Hash with key: Symbol, String: Array of Strings
1018
+ @attrs = attrs # Hash: Symbol => Array of Strings
984
1019
  end
985
1020
 
986
1021
  def self.paired?(tag)
@@ -994,6 +1029,15 @@ module Arboretum
994
1029
  element_copy
995
1030
  end
996
1031
 
1032
+ def update_tree_residence(update_tree)
1033
+ # Update old and new tree id cache
1034
+ if self.has_attr?(:id)
1035
+ self.tree_residence&.id_cache_remove(self.attr_value_str(:id))
1036
+ update_tree&.id_cache_add(self.attr_value_str(:id), self)
1037
+ end
1038
+ super(update_tree)
1039
+ end
1040
+
997
1041
  # Returns the id of this element, or an auto-assigned one if none exists
998
1042
  def ref
999
1043
  if !self.has_attr?(:id) or self.attr_value_str(:id).nil?
@@ -1005,6 +1049,7 @@ module Arboretum
1005
1049
  end
1006
1050
  end
1007
1051
 
1052
+ # Returns the '#'-prefixed id of this element, or an auto-assigned one if none exists
1008
1053
  def href
1009
1054
  "#" << self.ref
1010
1055
  end
@@ -1018,6 +1063,10 @@ module Arboretum
1018
1063
 
1019
1064
  def del_attr(attr_name)
1020
1065
  attr_name = attr_name.to_sym if !attr_name.is_a?(Symbol)
1066
+
1067
+ # Update tree id cache
1068
+ self.tree_residence&.id_cache_remove(self.attr_value_str(:id)) if attr_name.eql?(:id)
1069
+
1021
1070
  self.attrs.delete(attr_name)
1022
1071
  end
1023
1072
 
@@ -1029,7 +1078,13 @@ module Arboretum
1029
1078
  raise TypeError.new("Attribute value must be a String or Array of Strings") if !attr_value.is_a?(Array)
1030
1079
  attr_value.each{|sub_val| raise TypeError.new("Each attribute value in an array must be a String") if !sub_val.is_a?(String)}
1031
1080
 
1081
+ # Update tree id cache
1082
+ self.tree_residence&.id_cache_remove(self.attr_value_str(:id)) if attr_name.eql?(:id)
1083
+
1032
1084
  self.attrs[attr_name] = attr_value
1085
+
1086
+ # Update tree id cache
1087
+ self.tree_residence&.id_cache_add(self.attr_value_str(:id), self) if attr_name.eql?(:id)
1033
1088
  end
1034
1089
 
1035
1090
  def del_attr_value(attr_name, attr_value)
@@ -1040,7 +1095,13 @@ module Arboretum
1040
1095
  raise TypeError.new("Attribute value must be a String or Array of Strings") if !attr_value.is_a?(Array)
1041
1096
  attr_value.each{|sub_val| raise TypeError.new("Each attribute value in an array must be a String") if !sub_val.is_a?(String)}
1042
1097
 
1098
+ # Update tree id cache
1099
+ self.tree_residence&.id_cache_remove(self.attr_value_str(:id)) if attr_name.eql?(:id)
1100
+
1043
1101
  self.attrs[attr_name].delete_if {|sub_val| attr_value.include?(sub_val)}
1102
+
1103
+ # Update tree id cache
1104
+ self.tree_residence&.id_cache_add(self.attr_value_str(:id), self) if (attr_name.eql?(:id) and !self.attr_value_str.nil?)
1044
1105
  end
1045
1106
 
1046
1107
  def add_attr_value(attr_name, attr_value)
@@ -1055,6 +1116,8 @@ module Arboretum
1055
1116
  else
1056
1117
  self.attrs[attr_name] = attr_value
1057
1118
  end
1119
+ # Update tree id cache
1120
+ self.tree_residence&.id_cache_add(self.attr_value_str(:id), self) if attr_name.eql?(:id)
1058
1121
  end
1059
1122
 
1060
1123
  def set_tag(new_tag)
@@ -1112,9 +1175,7 @@ module Arboretum
1112
1175
  values.each do |v|
1113
1176
  element_string << "#{v.gsub('&','&amp;').gsub('<', '&lt;').gsub('>','&gt;')} "
1114
1177
  end
1115
- if not values.empty?
1116
- element_string = element_string[0..-2]
1117
- end
1178
+ element_string = element_string.chop unless values.empty?
1118
1179
  element_string << "\""
1119
1180
  end
1120
1181
  # Close the tag if document must have valid xml
@@ -1135,21 +1196,11 @@ module Arboretum
1135
1196
  self.attrs.each do |key, values|
1136
1197
  element_string << " #{key}"
1137
1198
  element_string << "=\""
1138
- values.each do |v|
1139
- element_string << "#{v} "
1140
- end
1141
- if not values.empty?
1142
- element_string = element_string[0..-2]
1143
- end
1199
+ values.each {|v| element_string << "#{v} "}
1200
+ element_string = element_string.chop unless values.empty?
1144
1201
  element_string << "\""
1145
1202
  end
1146
- # Close the tag if document must have xml/xhtml
1147
- if self.paired? or not @@need_valid_xml
1148
- element_string << ">"
1149
- else
1150
- element_string << " />"
1151
- end
1152
- element_string
1203
+ element_string << (self.paired? ? ">" : "/>")
1153
1204
  end
1154
1205
 
1155
1206
  def to_s_close
@@ -1283,10 +1334,17 @@ module Arboretum
1283
1334
  @group
1284
1335
  end
1285
1336
 
1337
+ def only
1338
+ raise IndexError.new("Element is not the only in its group") if not @group.length == 1
1339
+ @group.first
1340
+ end
1341
+
1286
1342
  def text_string
1287
- full_string = ''
1288
- @group.each {|element| full_string << element.text_string}
1289
- full_string
1343
+ String.new.tap{|full_string| @group.each {|element| full_string << element.text_string} }
1344
+ end
1345
+
1346
+ def text_elements
1347
+ Array.new.tap{|full_list| @group.each {|element| full_list << element.text_elements} }
1290
1348
  end
1291
1349
 
1292
1350
  def +(other)
@@ -36,7 +36,7 @@ module Arboretum
36
36
  def to_s
37
37
  rule_str = ''
38
38
  @paths.each do |path|
39
- rule_str << ', ' if !rule_str.empty?
39
+ rule_str << ', ' unless rule_str.empty?
40
40
  rule_str << path.to_s
41
41
  end
42
42
  rule_str
@@ -226,8 +226,8 @@ module Arboretum
226
226
  !@attrs[:matches].empty? or
227
227
  (element_ref == :ELEMENT_ROOT and !element.parent.nil?)
228
228
  end
229
- @pseudo_exps.each do |psuedo_name, pseudo_arg|
230
- return false if !PseudoElements.match(element, pseudo_name, pseudo_arg)
229
+ @pseudo_exps.each do |pseudo_name, pseudo_arg|
230
+ return false if !PseudoClasses.match(element, pseudo_name, pseudo_arg)
231
231
  end
232
232
  @valid_rules.each do |rule|
233
233
  return false if !rule.valid_on?(element)
@@ -361,9 +361,18 @@ module Arboretum
361
361
  end
362
362
  end
363
363
 
364
- class PseudoElements
364
+ class PseudoClasses
365
+ # Call a pseudo class function
365
366
  def self.match(element, pseudo_name, pseudo_arg)
366
- PseudoElements.public_send(:pseudo_name, element, pseudo_arg)
367
+ PseudoClasses.public_send(pseudo_name.to_sym, element, pseudo_arg)
368
+ end
369
+
370
+ # Pseudo class functions start here
371
+ def self.header(element, pseudo_arg)
372
+ (element.is_a?(Arboretum::DocTree::Elements::TaggedElement) and !(/h\d+/.match(element.tag.to_s).nil?))
373
+ end
374
+ def self.not(element, pseudo_arg)
375
+ !element.matches_rule?(pseudo_arg)
367
376
  end
368
377
  end
369
378
 
@@ -372,14 +381,14 @@ module Arboretum
372
381
  # ScandentRules can then be matched to Elements in a DocTree
373
382
  class Parser
374
383
  @@actions = {
375
- :T_SLASH => :ACTION_CHILD,
376
- :T_SLASH2 => :ACTION_DESCENDANT,
377
- :T_SLASHDOT2 => :ACTION_PARENT,
378
- :T_SLASHDOT3 => :ACTION_ANCESTOR,
379
- :T_SLASHGT => :ACTION_FOLLOWING_SIBLING,
380
- :T_SLASHGT2 => :ACTION_FOLLOWING,
381
- :T_SLASHLT => :ACTION_PRECEDING_SIBLING,
382
- :T_SLASHLT2 => :ACTION_PRECEDING
384
+ :T_SLASH => :ACTION_CHILD,
385
+ :T_SLASH2 => :ACTION_DESCENDANT,
386
+ :T_SLASHDOT2 => :ACTION_PARENT,
387
+ :T_SLASHDOT3 => :ACTION_ANCESTOR,
388
+ :T_SLASHGT => :ACTION_FOLLOWING_SIBLING,
389
+ :T_SLASHGT2 => :ACTION_FOLLOWING,
390
+ :T_SLASHLT => :ACTION_PRECEDING_SIBLING,
391
+ :T_SLASHLT2 => :ACTION_PRECEDING
383
392
  }
384
393
 
385
394
  # Parse a Scandent string by giving it to the Tokenizer and then parsing the results
@@ -444,6 +453,7 @@ module Arboretum
444
453
  raise ParseException.new("Unknown step type")
445
454
  end
446
455
 
456
+ # Initialize all of the components that a step uses to match an element
447
457
  element_ref = []
448
458
  tag = []
449
459
  namespace = []
@@ -457,124 +467,103 @@ module Arboretum
457
467
  pseudo_exps = []
458
468
  valid_rules = []
459
469
 
460
- index = 0
470
+ # Walk through the tokens of this step one at a time to parse grammar
471
+ index = -1
461
472
  state = :STATE_ROOT_PATH
462
- while index < step_tokens.length
463
- # Consume current token and increment
464
- index_token = step_tokens[index]
465
- index += 1
473
+ while (index + 1) < step_tokens.length
474
+ # Consume next token
475
+ index_token = step_tokens[index+=1]
466
476
 
467
477
  case index_token[0]
468
478
  when :T_PCT
469
- following_token = step_tokens[index]
470
- index += 1
471
- raise InvalidExpressionException.new if following_token[0] != :LITERAL_IDENT
472
- tag << following_token[1]
479
+ next_token = step_tokens[index+=1]
480
+ raise InvalidExpressionException.new if next_token[0] != :LITERAL_IDENT
481
+ tag << next_token[1]
473
482
  when :T_AT
474
- following_token = step_tokens[index]
475
- index += 1
476
- raise InvalidExpressionException.new if following_token[0] != :LITERAL_IDENT
477
- namespace << following_token[1]
483
+ next_token = step_tokens[index+=1]
484
+ raise InvalidExpressionException.new if next_token[0] != :LITERAL_IDENT
485
+ namespace << next_token[1]
478
486
  when :T_PND
479
- following_token = step_tokens[index]
480
- index += 1
481
- raise InvalidExpressionException.new if following_token[0] != :LITERAL_IDENT
482
- id << following_token[1]
487
+ next_token = step_tokens[index+=1]
488
+ raise InvalidExpressionException.new if next_token[0] != :LITERAL_IDENT
489
+ id << next_token[1]
483
490
  when :T_COLON
484
- following_token = step_tokens[index]
485
- index += 1
486
- raise InvalidExpressionException.new if following_token[0] != :LITERAL_IDENT
487
- pseudo_name = following_token[1].to_sym
491
+ next_token = step_tokens[index+=1]
492
+ raise InvalidExpressionException.new if next_token[0] != :LITERAL_IDENT
493
+ pseudo_name = next_token[1].to_sym
488
494
  arg_tokens = []
489
495
 
490
- following_token = step_tokens[index]
491
- if following_token[0] == :T_LPAREN
492
- index += 1 # To consume the LPAREN
493
- following_token = step_tokens[index]
494
- index += 1
495
- until following_token[0] == :T_RPAREN or index > step_tokens.length
496
- arg_tokens << following_token
497
- following_token = step_tokens[index]
498
- index += 1
496
+ next_token = step_tokens[index+=1]
497
+ if next_token[0] == :T_LPAREN
498
+ next_token = step_tokens[index+=1]
499
+ until next_token[0] == :T_RPAREN or index > step_tokens.length
500
+ arg_tokens << next_token
501
+ next_token = step_tokens[index+=1]
499
502
  end
500
503
  raise InvalidExpressionException.new if index > step_tokens.length # Undesirable exit condition to above loop
501
- index += 1 # To consume the RPAREN
502
504
  end
503
505
  pseudo_exps << [pseudo_name, Parser.parse_arg(arg_tokens)]
504
- when :T_ASTERISK # Adds no restrictions, so do nothing
506
+ when :T_ASTERISK
507
+ # Adds no restrictions, so do nothing
505
508
  when :T_TILDE
506
509
  element_ref << :ELEMENT_ROOT
507
510
  when :T_DOT
508
511
  element_ref << :ELEMENT_SELF
509
512
  when :T_LBRAK
510
- following_token = step_tokens[index]
511
- index += 1
512
- raise InvalidExpressionException.new if following_token[0] != :LITERAL_IDENT
513
- attr_name = following_token[1].to_sym
513
+ next_token = step_tokens[index+=1]
514
+ raise InvalidExpressionException.new if next_token[0] != :LITERAL_IDENT
515
+ attr_name = next_token[1].to_sym
514
516
  attr_value = nil
515
517
  operation = nil
516
518
 
517
- following_token = step_tokens[index]
518
- index += 1
519
- case following_token[0]
519
+ next_token = step_tokens[index+=1]
520
+ case next_token[0]
520
521
  when :T_EQL
521
522
  operation = :contains
522
523
 
523
- following_token = step_tokens[index]
524
- index += 1
525
- raise InvalidExpressionException.new("Expected a string after '='") if ![:T_DQUOTE, :T_SQUOTE].include?(following_token[0])
526
- string_limiter = following_token[0]
524
+ next_token = step_tokens[index+=1]
525
+ raise InvalidExpressionException.new("Expected a string after '='") if ![:T_DQUOTE, :T_SQUOTE].include?(next_token[0])
526
+ string_limiter = next_token[0]
527
527
 
528
- following_token = step_tokens[index]
529
- index += 1
530
- raise InvalidExpressionException.new if not [:LITERAL_IDENT, :LITERAL_STRING, :LITERAL_INT, :LITERAL_FLOAT].include?(following_token[0])
531
- attr_value = following_token[1]
528
+ next_token = step_tokens[index+=1]
529
+ raise InvalidExpressionException.new if not [:LITERAL_IDENT, :LITERAL_STRING, :LITERAL_INT, :LITERAL_FLOAT].include?(next_token[0])
530
+ attr_value = next_token[1]
532
531
 
533
- following_token = step_tokens[index]
534
- index += 1
535
- raise InvalidExpressionException.new if following_token[0] != string_limiter
532
+ next_token = step_tokens[index+=1]
533
+ raise InvalidExpressionException.new if next_token[0] != string_limiter
536
534
 
537
- following_token = step_tokens[index]
538
- index += 1
539
- raise InvalidExpressionException.new if following_token[0] != :T_RBRAK
535
+ next_token = step_tokens[index+=1]
536
+ raise InvalidExpressionException.new if next_token[0] != :T_RBRAK
540
537
  when :T_EQL2
541
538
  operation = :equals
542
- following_token = step_tokens[index]
543
- index += 1
544
- raise InvalidExpressionException.new if ![:T_DQUOTE, :T_SQUOTE].include?(following_token[0])
545
- string_limiter = following_token[0]
546
-
547
- following_token = step_tokens[index]
548
- index += 1
549
- raise InvalidExpressionException.new if not [:LITERAL_IDENT, :LITERAL_STRING, :LITERAL_INT, :LITERAL_FLOAT].include?(following_token[0])
550
- attr_value = following_token[1].split
551
-
552
- following_token = step_tokens[index]
553
- index += 1
554
- raise InvalidExpressionException.new if following_token[0] != string_limiter
555
-
556
- following_token = step_tokens[index]
557
- index += 1
558
- raise InvalidExpressionException.new if following_token[0] != :T_RBRAK
539
+ next_token = step_tokens[index+=1]
540
+ raise InvalidExpressionException.new if ![:T_DQUOTE, :T_SQUOTE].include?(next_token[0])
541
+ string_limiter = next_token[0]
542
+
543
+ next_token = step_tokens[index+=1]
544
+ raise InvalidExpressionException.new if not [:LITERAL_IDENT, :LITERAL_STRING, :LITERAL_INT, :LITERAL_FLOAT].include?(next_token[0])
545
+ attr_value = next_token[1].split
546
+
547
+ next_token = step_tokens[index+=1]
548
+ raise InvalidExpressionException.new if next_token[0] != string_limiter
549
+
550
+ next_token = step_tokens[index+=1]
551
+ raise InvalidExpressionException.new if next_token[0] != :T_RBRAK
559
552
  when :T_TILDE_EQL
560
553
  operation = :matches
561
554
 
562
- following_token = step_tokens[index]
563
- index += 1
564
- raise InvalidExpressionException.new if following_token[0] != :T_VBARSLASH
555
+ next_token = step_tokens[index+=1]
556
+ raise InvalidExpressionException.new if next_token[0] != :T_VBARSLASH
565
557
 
566
- following_token = step_tokens[index]
567
- index += 1
568
- raise InvalidExpressionException.new if not [:LITERAL_IDENT, :LITERAL_STRING, :LITERAL_INT, :LITERAL_FLOAT].include?(following_token[0])
569
- attr_value = Regexp.new(following_token[1])
558
+ next_token = step_tokens[index+=1]
559
+ raise InvalidExpressionException.new if not [:LITERAL_IDENT, :LITERAL_STRING, :LITERAL_INT, :LITERAL_FLOAT].include?(next_token[0])
560
+ attr_value = Regexp.new(next_token[1])
570
561
 
571
- following_token = step_tokens[index]
572
- index += 1
573
- raise InvalidExpressionException.new if following_token[0] != :T_SLASHVBAR
562
+ next_token = step_tokens[index+=1]
563
+ raise InvalidExpressionException.new if next_token[0] != :T_SLASHVBAR
574
564
 
575
- following_token = step_tokens[index]
576
- index += 1
577
- raise InvalidExpressionException.new if following_token[0] != :T_RBRAK
565
+ next_token = step_tokens[index+=1]
566
+ raise InvalidExpressionException.new if next_token[0] != :T_RBRAK
578
567
  when :T_RBRAK
579
568
  operation = nil
580
569
  else
@@ -588,18 +577,17 @@ module Arboretum
588
577
  when :T_LBRACE
589
578
  equilibrium = 1
590
579
  reformed_path_string = ''
591
- following_token = step_tokens[index]
592
- index += 1
593
- until (following_token[0] == :T_RBRACE and equilibrium.zero?) or index > step_tokens.length
594
- reformed_path_string << following_token[1]
595
- following_token = step_tokens[index]
596
- index += 1
597
- equilibrium += 1 if following_token[0] == :T_LBRACE
598
- equilibrium -= 1 if following_token[0] == :T_RBRACE
580
+ next_token = step_tokens[index+=1]
581
+ until (next_token[0] == :T_RBRACE and equilibrium.zero?) or index > step_tokens.length
582
+ reformed_path_string << next_token[1]
583
+ next_token = step_tokens[index+=1]
584
+ equilibrium += 1 if next_token[0] == :T_LBRACE
585
+ equilibrium -= 1 if next_token[0] == :T_RBRACE
599
586
  end
600
587
  raise InvalidExpressionException.new("Could not find matching R_BRACE in #{reformed_path_string}") if index > step_tokens.length # Undesirable exit condition to above loop
601
588
  valid_rules << Parser.parse_rule_string(reformed_path_string, :PATH_LOCATOR)
602
589
  when :T_SLASH, :T_SLASH2, :T_SLASHDOT2, :T_SLASHDOT3, :T_SLASHGT, :T_SLASHGT2, :T_SLASHLT, :T_SLASHLT2
590
+ # Do nothing since the action has already been determined
603
591
  else
604
592
  raise ParseException.new("Consumed unexpected token: #{index_token}")
605
593
  end
@@ -1,9 +1,8 @@
1
+ require 'ox'
2
+
1
3
  module Arboretum
2
4
  module XML
3
5
  module IO
4
- require 'ox'
5
- require_relative 'doctree'
6
-
7
6
  class XMLParseException < StandardError
8
7
  def initialize(msg="An error occurred while parsing XML")
9
8
  super(msg)
@@ -87,7 +86,7 @@ module Arboretum
87
86
 
88
87
  # Add TaggedElement to tree
89
88
  opened_element = TaggedElement.new(element_ns, element_tag)
90
- @open_elements.last.append_child(opened_element)
89
+ opened_element.graft_last_onto(@open_elements.last)
91
90
 
92
91
  # Open the element if paired
93
92
  @open_elements.push(opened_element)
@@ -101,7 +100,7 @@ module Arboretum
101
100
  def comment(str)
102
101
  # Add CommentElement to tree
103
102
  comment_element = CommentElement.new(str)
104
- @open_elements.last.append_child(comment_element)
103
+ comment_element.graft_last_onto(@open_elements.last)
105
104
  # Do not open the element (no children)
106
105
  end
107
106
  def text(str)
@@ -111,13 +110,13 @@ module Arboretum
111
110
 
112
111
  # Add TextElement to tree
113
112
  text_element = TextElement.new(str)
114
- @open_elements.last.append_child(text_element)
113
+ text_element.graft_last_onto(@open_elements.last)
115
114
  # Do not open the element (no children)
116
115
 
117
116
  elsif @style == :preserve
118
117
  # Add TextElement to tree
119
118
  text_element = TextElement.new(str)
120
- @open_elements.last.append_child(text_element)
119
+ text_element.graft_last_onto(@open_elements.last)
121
120
  # Do not open the element (no children)
122
121
  end
123
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arboretum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - tomjw64
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-26 00:00:00.000000000 Z
11
+ date: 2017-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ox
@@ -37,6 +37,7 @@ extensions: []
37
37
  extra_rdoc_files: []
38
38
  files:
39
39
  - lib/arboretum.rb
40
+ - lib/arboretum/debtor.rb
40
41
  - lib/arboretum/doctree.rb
41
42
  - lib/arboretum/scandent.rb
42
43
  - lib/arboretum/xml.rb