duxml 0.8.8 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/bin/validate_xml +30 -30
  3. data/lib/duxml.rb +76 -76
  4. data/lib/duxml/doc.rb +108 -91
  5. data/lib/duxml/doc/element.rb +250 -250
  6. data/lib/duxml/doc/lazy_ox.rb +167 -167
  7. data/lib/duxml/doc/node_set.rb +38 -38
  8. data/lib/duxml/meta.rb +72 -72
  9. data/lib/duxml/meta/grammar.rb +133 -133
  10. data/lib/duxml/meta/grammar/pattern.rb +111 -111
  11. data/lib/duxml/meta/grammar/pattern/attr_name_pattern.rb +36 -36
  12. data/lib/duxml/meta/grammar/pattern/attr_val_pattern.rb +36 -36
  13. data/lib/duxml/meta/grammar/pattern/child_pattern.rb +60 -60
  14. data/lib/duxml/meta/grammar/pattern/text_pattern.rb +31 -31
  15. data/lib/duxml/meta/grammar/pattern_maker.rb +68 -68
  16. data/lib/duxml/meta/grammar/relax_ng.rb +39 -39
  17. data/lib/duxml/meta/grammar/relax_ng/attrs_rule.rb +58 -58
  18. data/lib/duxml/meta/grammar/relax_ng/children_rule.rb +82 -82
  19. data/lib/duxml/meta/grammar/relax_ng/value_rule.rb +44 -44
  20. data/lib/duxml/meta/grammar/rule.rb +58 -58
  21. data/lib/duxml/meta/grammar/rule/attrs_rule.rb +77 -77
  22. data/lib/duxml/meta/grammar/rule/children_rule.rb +135 -135
  23. data/lib/duxml/meta/grammar/rule/text_rule.rb +39 -39
  24. data/lib/duxml/meta/grammar/rule/value_rule.rb +110 -110
  25. data/lib/duxml/meta/grammar/spreadsheet.rb +34 -34
  26. data/lib/duxml/meta/history.rb +88 -88
  27. data/lib/duxml/meta/history/add.rb +30 -30
  28. data/lib/duxml/meta/history/change.rb +70 -70
  29. data/lib/duxml/meta/history/change_attr.rb +33 -33
  30. data/lib/duxml/meta/history/change_text.rb +32 -32
  31. data/lib/duxml/meta/history/error.rb +24 -24
  32. data/lib/duxml/meta/history/new_attr.rb +32 -32
  33. data/lib/duxml/meta/history/new_text.rb +36 -36
  34. data/lib/duxml/meta/history/qualify_error.rb +21 -21
  35. data/lib/duxml/meta/history/remove.rb +27 -27
  36. data/lib/duxml/meta/history/undo.rb +23 -23
  37. data/lib/duxml/meta/history/validate_error.rb +20 -20
  38. data/lib/duxml/reportable.rb +28 -28
  39. data/lib/duxml/ruby_ext/fixnum.rb +55 -55
  40. data/lib/duxml/ruby_ext/module.rb +11 -11
  41. data/lib/duxml/ruby_ext/object.rb +13 -13
  42. data/lib/duxml/ruby_ext/regexp.rb +19 -19
  43. data/lib/duxml/ruby_ext/string.rb +37 -37
  44. data/lib/duxml/saxer.rb +75 -75
  45. metadata +12 -12
@@ -1,40 +1,40 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../rule')
4
-
5
- module Duxml
6
- module TextRule; end
7
-
8
- class TextRuleClass < RuleClass
9
- include TextRule
10
- end
11
-
12
- module TextRule
13
- # @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
14
- # @return [Boolean] whether this rule does in fact apply
15
- def applies_to?(change_or_pattern)
16
- super(change_or_pattern) &&
17
- change_or_pattern.respond_to?(:text)
18
- end
19
-
20
- # applies Regexp statement to text content of this node; returns false if content has XML
21
- def qualify(change_or_pattern)
22
- @object = change_or_pattern
23
- result = pass
24
- super change_or_pattern unless result
25
- @object = nil
26
- result
27
- end
28
-
29
- private
30
-
31
- def pass
32
- return false unless object.text.is_a?(String)
33
- get_scanner.match(object.text).to_s == object.text
34
- end
35
-
36
- def get_scanner
37
- Regexp.new(statement)
38
- end
39
- end # module TextRule
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../rule')
4
+
5
+ module Duxml
6
+ module TextRule; end
7
+
8
+ class TextRuleClass < RuleClass
9
+ include TextRule
10
+ end
11
+
12
+ module TextRule
13
+ # @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
14
+ # @return [Boolean] whether this rule does in fact apply
15
+ def applies_to?(change_or_pattern)
16
+ super(change_or_pattern) &&
17
+ change_or_pattern.respond_to?(:text)
18
+ end
19
+
20
+ # applies Regexp statement to text content of this node; returns false if content has XML
21
+ def qualify(change_or_pattern)
22
+ @object = change_or_pattern
23
+ result = pass
24
+ super change_or_pattern unless result
25
+ @object = nil
26
+ result
27
+ end
28
+
29
+ private
30
+
31
+ def pass
32
+ return false unless object.text.is_a?(String)
33
+ get_scanner.match(object.text).to_s == object.text
34
+ end
35
+
36
+ def get_scanner
37
+ Regexp.new(statement)
38
+ end
39
+ end # module TextRule
40
40
  end # module Duxml
@@ -1,111 +1,111 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../rule')
4
-
5
- module Duxml
6
- module ValueRule; end
7
-
8
- # rule that states what values a given attribute name is allowed to have
9
- class ValueRuleClass < RuleClass
10
- include ValueRule
11
-
12
- # @param _attr_name [String] the attribute name
13
- # @param _statement [String] data type or expression of the rule for the given attribute's value
14
- def initialize(_attr_name, _statement)
15
- @attr_name, @statement = _attr_name, _statement
16
- end
17
-
18
- attr_reader :attr_name
19
- end
20
-
21
- module ValueRule
22
- CDATA_EXPR = /(\]\]>)/
23
- ENTITY_EXPR = /(\b[\S]+\b)/
24
- ID_EXPR = Regexp.nmtoken
25
- NMTOKEN_EXPR = ID_EXPR
26
- NOTATION_EXPR = //
27
-
28
- # @return [true]
29
- def abstract?
30
- true
31
- end
32
-
33
- # @return [String] description of this rule
34
- def description
35
- %(#{relationship.capitalize} Rule that @#{attr_name}'s #{relationship} must match '#{statement}')
36
- end
37
-
38
- # @param change_or_pattern [Duxml::Pattern, Duxml::Change] change or pattern to be evaluated
39
- # @return [Boolean] whether change_or_pattern#subject is allowed to have value of type #object
40
- # if false, reports Error to History
41
- def qualify(change_or_pattern)
42
- value = change_or_pattern.value
43
- s = change_or_pattern.subject
44
- raise Exception if value.nil?
45
- result = pass value
46
- super change_or_pattern unless result
47
- result
48
- end
49
-
50
- # @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
51
- # @return [Boolean] whether this rule does in fact apply
52
- def applies_to?(change_or_pattern)
53
- return false unless change_or_pattern.respond_to?(:attr_name)
54
- return false unless change_or_pattern.respond_to?(:value)
55
- change_or_pattern.attr_name == attr_name
56
- end
57
-
58
- private
59
-
60
- def pass(value)
61
- matcher = find_method_or_expr
62
- if matcher.respond_to?(:match)
63
- matcher.match(value).to_s == value
64
- else
65
- matcher.call(value)
66
- end
67
- end
68
-
69
- def find_method_or_expr
70
- s = statement
71
- case s
72
- when 'CDATA' # unparsed character data e.g. '<not-xml>'; may not contain string ']]>'
73
- proc do |val| val.match(CDATA_EXPR).nil? end
74
- when 'ID' then ID_EXPR # does not check for uniqueness!
75
- when 'IDREF' # id of another doc
76
- proc do |val| val.match(ID_EXPR) && resolve_ref(val, subject.meta) end
77
- when 'IDREFS' # ids of other elements
78
- proc do |val|
79
- separate_list val do |sub_val|
80
- sub_val.match(ID_EXPR) && resolve_ref(sub_val, subject.meta)
81
- end
82
- end
83
- when 'NMTOKEN' then NMTOKEN_EXPR # valid XML name
84
- when 'NMTOKENS' # a list of valid XML names
85
- proc do |val|
86
- separate_list val do |sub_val|
87
- sub_val.match NMTOKEN_EXPR
88
- end
89
- end
90
- when 'ENTITY' then ENTITY_EXPR # an entity
91
- when 'ENTITIES' # list of entities
92
- proc do |val|
93
- separate_list val do |sub_val|
94
- sub_val.match ENTITY_EXPR
95
- end
96
- end
97
- when 'NOTATION' then // # TODO name of a notation
98
- when 'xml:' then // # TODO predefined XML value
99
- else # '|'-separated list of allowable values i.e. Regexp-style DTD declaration
100
- Regexp.new(s)
101
- end
102
- end # def find_method_or_expr
103
-
104
- def separate_list(spc_sep_vals, &block)
105
- spc_sep_vals.split(' ').any? do |sub_val|
106
- result = block.call sub_val
107
- !result
108
- end
109
- end
110
- end # module ValueRule
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../rule')
4
+
5
+ module Duxml
6
+ module ValueRule; end
7
+
8
+ # rule that states what values a given attribute name is allowed to have
9
+ class ValueRuleClass < RuleClass
10
+ include ValueRule
11
+
12
+ # @param _attr_name [String] the attribute name
13
+ # @param _statement [String] data type or expression of the rule for the given attribute's value
14
+ def initialize(_attr_name, _statement)
15
+ @attr_name, @statement = _attr_name, _statement
16
+ end
17
+
18
+ attr_reader :attr_name
19
+ end
20
+
21
+ module ValueRule
22
+ CDATA_EXPR = /(\]\]>)/
23
+ ENTITY_EXPR = /(\b[\S]+\b)/
24
+ ID_EXPR = Regexp.nmtoken
25
+ NMTOKEN_EXPR = ID_EXPR
26
+ NOTATION_EXPR = //
27
+
28
+ # @return [true]
29
+ def abstract?
30
+ true
31
+ end
32
+
33
+ # @return [String] description of this rule
34
+ def description
35
+ %(#{relationship.capitalize} Rule that @#{attr_name}'s #{relationship} must match '#{statement}')
36
+ end
37
+
38
+ # @param change_or_pattern [Duxml::Pattern, Duxml::Change] change or pattern to be evaluated
39
+ # @return [Boolean] whether change_or_pattern#subject is allowed to have value of type #object
40
+ # if false, reports Error to History
41
+ def qualify(change_or_pattern)
42
+ value = change_or_pattern.value
43
+ s = change_or_pattern.subject
44
+ raise Exception if value.nil?
45
+ result = pass value
46
+ super change_or_pattern unless result
47
+ result
48
+ end
49
+
50
+ # @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
51
+ # @return [Boolean] whether this rule does in fact apply
52
+ def applies_to?(change_or_pattern)
53
+ return false unless change_or_pattern.respond_to?(:attr_name)
54
+ return false unless change_or_pattern.respond_to?(:value)
55
+ change_or_pattern.attr_name == attr_name
56
+ end
57
+
58
+ private
59
+
60
+ def pass(value)
61
+ matcher = find_method_or_expr
62
+ if matcher.respond_to?(:match)
63
+ matcher.match(value).to_s == value
64
+ else
65
+ matcher.call(value)
66
+ end
67
+ end
68
+
69
+ def find_method_or_expr
70
+ s = statement
71
+ case s
72
+ when 'CDATA' # unparsed character data e.g. '<not-xml>'; may not contain string ']]>'
73
+ proc do |val| val.match(CDATA_EXPR).nil? end
74
+ when 'ID' then ID_EXPR # does not check for uniqueness!
75
+ when 'IDREF' # id of another doc
76
+ proc do |val| val.match(ID_EXPR) && resolve_ref(val, subject.meta) end
77
+ when 'IDREFS' # ids of other elements
78
+ proc do |val|
79
+ separate_list val do |sub_val|
80
+ sub_val.match(ID_EXPR) && resolve_ref(sub_val, subject.meta)
81
+ end
82
+ end
83
+ when 'NMTOKEN' then NMTOKEN_EXPR # valid XML name
84
+ when 'NMTOKENS' # a list of valid XML names
85
+ proc do |val|
86
+ separate_list val do |sub_val|
87
+ sub_val.match NMTOKEN_EXPR
88
+ end
89
+ end
90
+ when 'ENTITY' then ENTITY_EXPR # an entity
91
+ when 'ENTITIES' # list of entities
92
+ proc do |val|
93
+ separate_list val do |sub_val|
94
+ sub_val.match ENTITY_EXPR
95
+ end
96
+ end
97
+ when 'NOTATION' then // # TODO name of a notation
98
+ when 'xml:' then // # TODO predefined XML value
99
+ else # '|'-separated list of allowable values i.e. Regexp-style DTD declaration
100
+ Regexp.new(s)
101
+ end
102
+ end # def find_method_or_expr
103
+
104
+ def separate_list(spc_sep_vals, &block)
105
+ spc_sep_vals.split(' ').any? do |sub_val|
106
+ result = block.call sub_val
107
+ !result
108
+ end
109
+ end
110
+ end # module ValueRule
111
111
  end # module Duxml
@@ -1,35 +1,35 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require 'rubyXL'
4
-
5
- module Duxml
6
- # contains helper methods to convert spreadsheet of DTD rules into Duxml::Rules
7
- module Spreadsheet
8
- private
9
- # @param path [String] spreadsheet file
10
- def self.sheet_to_xml(path)
11
- worksheet = RubyXL::Parser.parse(path)[0]
12
- attr_val_rule_hash = {}
13
- g = GrammarClass.new
14
- worksheet.each_with_index do |row, index|
15
- next if index == 0
16
- break if row[3].nil? || row[4].nil?
17
- element_name = row[3].value
18
- statement_str = row[4].value
19
- g << ChildrenRuleClass.new(element_name, statement_str)
20
- attribute_rules = row[5].value.split(/\n/)
21
- attribute_rules.each_with_index do |rule, i|
22
- next if i == 0 or rule.empty?
23
- attr_name, value_expr, attr_req = *rule.split
24
- next if [attr_name, value_expr, attr_req].any? do |s| s.empty? or s.match(/\w/).nil? end
25
- g << AttrsRuleClass.new(element_name, attr_name, attr_req)
26
- unless attr_val_rule_hash[attr_name]
27
- g << ValueRuleClass.new(attr_name, value_expr)
28
- attr_val_rule_hash[attr_name] = true
29
- end
30
- end # attribute_rules.each_with_index
31
- end # worksheet.each_with_index
32
- g
33
- end # def sheet_to_xml(path)
34
- end # module Spreadsheet
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require 'rubyXL'
4
+
5
+ module Duxml
6
+ # contains helper methods to convert spreadsheet of DTD rules into Duxml::Rules
7
+ module Spreadsheet
8
+ private
9
+ # @param path [String] spreadsheet file
10
+ def self.sheet_to_xml(path)
11
+ worksheet = RubyXL::Parser.parse(path)[0]
12
+ attr_val_rule_hash = {}
13
+ g = GrammarClass.new
14
+ worksheet.each_with_index do |row, index|
15
+ next if index == 0
16
+ break if row[3].nil? || row[4].nil?
17
+ element_name = row[3].value
18
+ statement_str = row[4].value
19
+ g << ChildrenRuleClass.new(element_name, statement_str)
20
+ attribute_rules = row[5].value.split(/\n/)
21
+ attribute_rules.each_with_index do |rule, i|
22
+ next if i == 0 or rule.empty?
23
+ attr_name, value_expr, attr_req = *rule.split
24
+ next if [attr_name, value_expr, attr_req].any? do |s| s.empty? or s.match(/\w/).nil? end
25
+ g << AttrsRuleClass.new(element_name, attr_name, attr_req)
26
+ unless attr_val_rule_hash[attr_name]
27
+ g << ValueRuleClass.new(attr_name, value_expr)
28
+ attr_val_rule_hash[attr_name] = true
29
+ end
30
+ end # attribute_rules.each_with_index
31
+ end # worksheet.each_with_index
32
+ g
33
+ end # def sheet_to_xml(path)
34
+ end # module Spreadsheet
35
35
  end # module Duxml
@@ -1,89 +1,89 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/history/add')
4
- require File.expand_path(File.dirname(__FILE__) + '/history/remove')
5
- require File.expand_path(File.dirname(__FILE__) + '/history/validate_error')
6
- require File.expand_path(File.dirname(__FILE__) + '/history/qualify_error')
7
- require File.expand_path(File.dirname(__FILE__) + '/history/new_attr')
8
- require File.expand_path(File.dirname(__FILE__) + '/history/change_attr')
9
- require File.expand_path(File.dirname(__FILE__) + '/history/new_text')
10
- require File.expand_path(File.dirname(__FILE__) + '/history/change_text')
11
- require File.expand_path(File.dirname(__FILE__) + '/history/undo')
12
- require File.expand_path(File.dirname(__FILE__) + '/../doc')
13
- require 'forwardable'
14
-
15
- module Duxml
16
- # monitors XML Elements for changes and GrammarClass for errors, recording them and saving to Meta file
17
- module History
18
- include Duxml
19
- include Reportable
20
- end
21
-
22
- # as an object, HistoryClass holds events latest first, earliest last
23
- # it also has delegators that allow the use of Array-style notation e.g. '[]' and #each to search the history.
24
- class HistoryClass
25
- include History
26
- extend Forwardable
27
-
28
- def_delegators :@nodes, :[], :each
29
-
30
- # @param strict_or_false [Boolean] by default strict i.e. true so that if this History detects an error it will raise an Exception; otherwise not
31
- def initialize(strict_or_false = true)
32
- @nodes = []
33
- @strict = strict_or_false
34
- end
35
-
36
- attr_reader :nodes
37
- alias_method :events, :nodes
38
- end
39
-
40
- module History
41
- # used when creating a new metadata file for a static XML file
42
- #
43
- # @return [Doc] returns self as XML document
44
- def xml
45
- h = Element.new('history')
46
- events.each do |event| h << event.xml end
47
- h
48
- end
49
-
50
- # @return [Boolean] toggles (true by default) whether History will raise exception or tolerate qualify errors
51
- def strict?(strict_or_false=nil)
52
- @strict = strict_or_false.nil? ? @strict : strict_or_false
53
- end
54
-
55
- # @return [ChangeClass, ErrorClass] the latest event
56
- def latest
57
- events[0]
58
- end
59
-
60
- # @return [GrammarClass] grammar that is observing this history's events
61
- def grammar
62
- @observer_peers.first.first if @observer_peers and @observer_peers.any? and @observer_peers.first.any?
63
- end
64
-
65
- # @return [String] shortened self description for debugging
66
- def inspect
67
- "#<#{self.class.to_s} #{object_id}: @events=#{nodes.size}>"
68
- end
69
-
70
- # @return [String] returns entire history, calling #description on each event in chronological order
71
- def description
72
- "history follows: \n" +
73
- events.reverse.collect do |change_or_error|
74
- change_or_error.description
75
- end.join("\n")
76
- end
77
-
78
- # @param type [Symbol] category i.e. class symbol of changes/errors reported
79
- # @param *args [*several_variants] information needed to accurately log the event; varies by change/error class
80
- def update(type, *args)
81
- change_class = Duxml::const_get "#{type.to_s}Class".to_sym
82
- change_comp = change_class.new *args
83
- @nodes.unshift change_comp
84
- changed
85
- notify_observers(change_comp) unless change_comp.respond_to?(:error?)
86
- raise(Exception, change_comp.description) if strict? && type == :QualifyError
87
- end
88
- end # module History
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/history/add')
4
+ require File.expand_path(File.dirname(__FILE__) + '/history/remove')
5
+ require File.expand_path(File.dirname(__FILE__) + '/history/validate_error')
6
+ require File.expand_path(File.dirname(__FILE__) + '/history/qualify_error')
7
+ require File.expand_path(File.dirname(__FILE__) + '/history/new_attr')
8
+ require File.expand_path(File.dirname(__FILE__) + '/history/change_attr')
9
+ require File.expand_path(File.dirname(__FILE__) + '/history/new_text')
10
+ require File.expand_path(File.dirname(__FILE__) + '/history/change_text')
11
+ require File.expand_path(File.dirname(__FILE__) + '/history/undo')
12
+ require File.expand_path(File.dirname(__FILE__) + '/../doc')
13
+ require 'forwardable'
14
+
15
+ module Duxml
16
+ # monitors XML Elements for changes and GrammarClass for errors, recording them and saving to Meta file
17
+ module History
18
+ include Duxml
19
+ include Reportable
20
+ end
21
+
22
+ # as an object, HistoryClass holds events latest first, earliest last
23
+ # it also has delegators that allow the use of Array-style notation e.g. '[]' and #each to search the history.
24
+ class HistoryClass
25
+ include History
26
+ extend Forwardable
27
+
28
+ def_delegators :@nodes, :[], :each
29
+
30
+ # @param strict_or_false [Boolean] by default strict i.e. true so that if this History detects an error it will raise an Exception; otherwise not
31
+ def initialize(strict_or_false = true)
32
+ @nodes = []
33
+ @strict = strict_or_false
34
+ end
35
+
36
+ attr_reader :nodes
37
+ alias_method :events, :nodes
38
+ end
39
+
40
+ module History
41
+ # used when creating a new metadata file for a static XML file
42
+ #
43
+ # @return [Doc] returns self as XML document
44
+ def xml
45
+ h = Element.new('history')
46
+ events.each do |event| h << event.xml end
47
+ h
48
+ end
49
+
50
+ # @return [Boolean] toggles (true by default) whether History will raise exception or tolerate qualify errors
51
+ def strict?(strict_or_false=nil)
52
+ @strict = strict_or_false.nil? ? @strict : strict_or_false
53
+ end
54
+
55
+ # @return [ChangeClass, ErrorClass] the latest event
56
+ def latest
57
+ events[0]
58
+ end
59
+
60
+ # @return [GrammarClass] grammar that is observing this history's events
61
+ def grammar
62
+ @observer_peers.first.first if @observer_peers and @observer_peers.any? and @observer_peers.first.any?
63
+ end
64
+
65
+ # @return [String] shortened self description for debugging
66
+ def inspect
67
+ "#<#{self.class.to_s} #{object_id}: @events=#{nodes.size}>"
68
+ end
69
+
70
+ # @return [String] returns entire history, calling #description on each event in chronological order
71
+ def description
72
+ "history follows: \n" +
73
+ events.reverse.collect do |change_or_error|
74
+ change_or_error.description
75
+ end.join("\n")
76
+ end
77
+
78
+ # @param type [Symbol] category i.e. class symbol of changes/errors reported
79
+ # @param *args [*several_variants] information needed to accurately log the event; varies by change/error class
80
+ def update(type, *args)
81
+ change_class = Duxml::const_get "#{type.to_s}Class".to_sym
82
+ change_comp = change_class.new *args
83
+ @nodes.unshift change_comp
84
+ changed
85
+ notify_observers(change_comp) unless change_comp.respond_to?(:error?)
86
+ raise(Exception, change_comp.description) if strict? && type == :QualifyError
87
+ end
88
+ end # module History
89
89
  end # module Duxml