duxml 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/validate_xml +19 -0
- data/lib/duxml/doc/element.rb +157 -0
- data/lib/duxml/doc/lazy_ox.rb +153 -0
- data/lib/duxml/doc/node_set.rb +39 -0
- data/lib/duxml/doc.rb +26 -0
- data/lib/duxml/meta/grammar/pattern/attr_name_pattern.rb +36 -0
- data/lib/duxml/meta/grammar/pattern/attr_val_pattern.rb +36 -0
- data/lib/duxml/meta/grammar/pattern/child_pattern.rb +72 -0
- data/lib/duxml/meta/grammar/pattern/text_pattern.rb +30 -0
- data/lib/duxml/meta/grammar/pattern.rb +98 -0
- data/lib/duxml/meta/grammar/pattern_maker.rb +69 -0
- data/lib/duxml/meta/grammar/relax_ng/attrs_rule.rb +58 -0
- data/lib/duxml/meta/grammar/relax_ng/children_rule.rb +83 -0
- data/lib/duxml/meta/grammar/relax_ng/value_rule.rb +44 -0
- data/lib/duxml/meta/grammar/relax_ng.rb +40 -0
- data/lib/duxml/meta/grammar/rule/attrs_rule.rb +78 -0
- data/lib/duxml/meta/grammar/rule/children_rule.rb +137 -0
- data/lib/duxml/meta/grammar/rule/text_rule.rb +40 -0
- data/lib/duxml/meta/grammar/rule/value_rule.rb +111 -0
- data/lib/duxml/meta/grammar/rule.rb +59 -0
- data/lib/duxml/meta/grammar/spreadsheet.rb +35 -0
- data/lib/duxml/meta/grammar.rb +134 -0
- data/lib/duxml/meta/history/add.rb +36 -0
- data/lib/duxml/meta/history/change.rb +71 -0
- data/lib/duxml/meta/history/change_attr.rb +34 -0
- data/lib/duxml/meta/history/change_text.rb +33 -0
- data/lib/duxml/meta/history/error.rb +25 -0
- data/lib/duxml/meta/history/new_attr.rb +33 -0
- data/lib/duxml/meta/history/new_text.rb +37 -0
- data/lib/duxml/meta/history/qualify_error.rb +22 -0
- data/lib/duxml/meta/history/remove.rb +28 -0
- data/lib/duxml/meta/history/undo.rb +24 -0
- data/lib/duxml/meta/history/validate_error.rb +21 -0
- data/lib/duxml/meta/history.rb +88 -0
- data/lib/duxml/meta.rb +51 -0
- data/lib/duxml/reportable.rb +27 -0
- data/lib/duxml/ruby_ext/fixnum.rb +56 -0
- data/lib/duxml/ruby_ext/module.rb +12 -0
- data/lib/duxml/ruby_ext/object.rb +14 -0
- data/lib/duxml/ruby_ext/regexp.rb +20 -0
- data/lib/duxml/ruby_ext/string.rb +29 -0
- data/lib/duxml/saxer.rb +71 -0
- data/lib/duxml.rb +97 -0
- data/xml/dita_grammar.xml +2133 -0
- metadata +117 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/pattern')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../reportable')
|
5
|
+
|
6
|
+
module Duxml
|
7
|
+
# scans DTD statements for XML rule operators
|
8
|
+
Struct.new 'Scanner', :match, :operator
|
9
|
+
|
10
|
+
# contains methods to apply Duxml::RuleClass to XML edit or validate events
|
11
|
+
module Rule
|
12
|
+
include Reportable
|
13
|
+
end
|
14
|
+
|
15
|
+
# as an object, Rules consist of a subject, representing the XML Element, and a statement representing the Rule's logic
|
16
|
+
# this class cannot be used alone and is rather subclassed, one for each type of possible XML changes
|
17
|
+
class RuleClass < PatternClass
|
18
|
+
include Rule
|
19
|
+
|
20
|
+
# @param subj [String] NMTOKEN name of element this rule applies to
|
21
|
+
# @param _statement [String, Regexp] string statement of rule in DTD declaration form or Regexp
|
22
|
+
def initialize(subj, _statement)
|
23
|
+
@statement = _statement
|
24
|
+
@object = nil
|
25
|
+
super subj
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :statement, :object
|
29
|
+
end
|
30
|
+
|
31
|
+
module Rule
|
32
|
+
# Duxml::Rule's #qualify is only used to report errors found by its subclasses' #qualify methods
|
33
|
+
# @param change_or_pattern [Duxml::Pattern, Duxml::Change] Change or Pattern to be reported for Rule violation
|
34
|
+
# @return [Boolean] always false; this method should always be subclassed to apply that specific rule type's #qualify
|
35
|
+
def qualify(change_or_pattern)
|
36
|
+
type = (change_or_pattern.respond_to?(:time_stamp)) ? :QualifyError : :ValidateError
|
37
|
+
report(type, change_or_pattern)
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [HistoryClass] history to which this rule will report errors
|
42
|
+
def history
|
43
|
+
@observer_peers.first.first if @observer_peers.any? and @observer_peers.first.any?
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
|
47
|
+
# @return [Boolean] whether this rule does in fact apply
|
48
|
+
def applies_to?(change_or_pattern)
|
49
|
+
pattern_type = change_or_pattern.subject.name
|
50
|
+
subject == pattern_type
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String] default description for a Rule
|
54
|
+
def description
|
55
|
+
statement_str = (statement.is_a?(String) ? statement : statement.inspect).gsub('\b','')
|
56
|
+
%(#{relationship.capitalize} Rule that <#{subject}>'s #{relationship} must match '#{statement_str}')
|
57
|
+
end
|
58
|
+
end # module Rule
|
59
|
+
end # module Duxml
|
@@ -0,0 +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
|
35
|
+
end # module Duxml
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../reportable')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/spreadsheet')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/pattern_maker')
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/children_rule')
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/attrs_rule')
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/value_rule')
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + '/../doc/lazy_ox')
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/rule/text_rule')
|
11
|
+
require File.expand_path(File.dirname(__FILE__) + '/grammar/relax_ng')
|
12
|
+
require 'forwardable'
|
13
|
+
|
14
|
+
module Duxml
|
15
|
+
# module shares name with <grammar> to activate its methods when that XML Element is encountered in a Meta file
|
16
|
+
module Grammar
|
17
|
+
include Reportable
|
18
|
+
include Duxml
|
19
|
+
include Spreadsheet
|
20
|
+
include PatternMaker
|
21
|
+
include LazyOx
|
22
|
+
include RelaxNG
|
23
|
+
end
|
24
|
+
# contains Duxml::Rules and can apply them by validating XML or qualifying user input
|
25
|
+
# reporting Duxml::Errors to History as needed
|
26
|
+
class GrammarClass
|
27
|
+
extend Forwardable
|
28
|
+
include Grammar
|
29
|
+
|
30
|
+
# @param rules [[RuleClass]] optional, can initialize grammar with rules
|
31
|
+
def initialize(rules=[])
|
32
|
+
@rules = rules
|
33
|
+
end
|
34
|
+
|
35
|
+
def_delegators :@rules, :<<, :[], :each
|
36
|
+
attr_reader :rules
|
37
|
+
alias_method :nodes, :rules
|
38
|
+
end
|
39
|
+
|
40
|
+
module Grammar
|
41
|
+
# @param path [String] path of grammar file; can be in .xlsx, .csv or Duxml GrammarClass file
|
42
|
+
# @return [GrammarClass, Element] XML Element named <grammar> and GrammarClass object are functionally equivalent
|
43
|
+
def self.import(path)
|
44
|
+
if %w(.xlsx .csv).include?(File.extname path)
|
45
|
+
doc = Spreadsheet.sheet_to_xml path
|
46
|
+
File.write(File.basename(path)+'.xml', Ox.dump(doc)) #TODO make optional!
|
47
|
+
doc
|
48
|
+
else
|
49
|
+
Ox.parse_obj(File.read path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Element] returns self as XML element e.g. '<duxml:grammar/>'
|
54
|
+
def self.xml
|
55
|
+
Element.new(name.nmtokenize).extend self
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [History] history that this grammar is currently reporting to
|
59
|
+
def history
|
60
|
+
@observer_peers.first.first if @observer_peers and @observer_peers.any? and @observer_peers.first.any?
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Boolean] whether or not any rules have been defined yet in this grammar
|
64
|
+
def defined?
|
65
|
+
!rules.empty?
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param obj [Object] object that will observe this grammar's rules, usually the History
|
69
|
+
def add_observer(obj, sym=nil)
|
70
|
+
super(obj, sym || :update)
|
71
|
+
@rules.each do |r| r.add_observer(obj, :update)end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [String] lists XML schema and content rules in order of precedence
|
75
|
+
def description
|
76
|
+
"grammar follows: \n" +
|
77
|
+
rules.collect do |change_or_error|
|
78
|
+
change_or_error.description
|
79
|
+
end.join("\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [String] formatted to appear in tight spaces e.g. debugger
|
83
|
+
def inspect
|
84
|
+
"#<#{self.class.to_s} #{object_id}: @rules=#{rules.size}>"
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [String] 'grammar'
|
88
|
+
def name
|
89
|
+
'grammar'
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param node [Duxml::Object] applies grammar rules to all relationships of the given object
|
93
|
+
# @result [Boolean] whether all rules qualified
|
94
|
+
def validate(node)
|
95
|
+
rels = get_relationships(node)
|
96
|
+
results = rels.collect do |rel|
|
97
|
+
qualify rel
|
98
|
+
end
|
99
|
+
any_disqualified = results.any? do |qualified| !qualified end
|
100
|
+
!any_disqualified
|
101
|
+
end # def validate
|
102
|
+
|
103
|
+
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] applies applicable rule type and subject
|
104
|
+
# to given change_or_pattern and generates errors when disqualified
|
105
|
+
# @return [Boolean] false if any rule disqualifies; true if they all pass
|
106
|
+
def qualify(change_or_pattern)
|
107
|
+
return true unless self.defined?
|
108
|
+
rules = get_rule(change_or_pattern)
|
109
|
+
|
110
|
+
# define behaviors for when there are no rules applying to a given pattern
|
111
|
+
if rules.empty?
|
112
|
+
|
113
|
+
if change_or_pattern.respond_to?(:text) or
|
114
|
+
change_or_pattern.respond_to?(:value) or
|
115
|
+
change_or_pattern.subject.is_a?(Doc)
|
116
|
+
return true
|
117
|
+
end
|
118
|
+
report(:ValidateError, change_or_pattern)
|
119
|
+
return false
|
120
|
+
end
|
121
|
+
results = rules.collect do |rule|
|
122
|
+
rule.qualify change_or_pattern
|
123
|
+
end
|
124
|
+
!results.any? do |qualified| !qualified end
|
125
|
+
end # def qualify
|
126
|
+
|
127
|
+
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern to be qualified
|
128
|
+
# @return [Array[Duxml::Rule]] rules that match the pattern type (e.g. :change_content => :content_rule)
|
129
|
+
# and subject (e.g. change_or_pattern.subject.type => 'blobs' && rule.subject => 'blobs')
|
130
|
+
def get_rule(change_or_pattern)
|
131
|
+
rules.select do |rule| rule.applies_to?(change_or_pattern) end
|
132
|
+
end # def get_rules
|
133
|
+
end # module Grammar
|
134
|
+
end # module Duxml
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module Add; end
|
7
|
+
|
8
|
+
# created when an doc gains a child
|
9
|
+
class AddClass < ChangeClass
|
10
|
+
include Add
|
11
|
+
|
12
|
+
def initialize(_subject, _index)
|
13
|
+
super _subject
|
14
|
+
@index = _index
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method :parent, :subject
|
18
|
+
attr_reader :subject, :index
|
19
|
+
end
|
20
|
+
|
21
|
+
module Add
|
22
|
+
def description
|
23
|
+
%(#{super} #{child.description} added to #{parent.description}.)
|
24
|
+
end
|
25
|
+
|
26
|
+
def parent
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
|
30
|
+
def child
|
31
|
+
subject.nodes[index]
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :object, :child
|
35
|
+
end # class Add
|
36
|
+
end # module Duxml
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../grammar/pattern')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module Change; end
|
7
|
+
# do not use - only for subclassing
|
8
|
+
# changes represent events i.e. patterns with a fixed position in time,
|
9
|
+
# and can include qualification and validation errors
|
10
|
+
class ChangeClass < PatternClass
|
11
|
+
include Change
|
12
|
+
|
13
|
+
@time_stamp
|
14
|
+
|
15
|
+
# all subclasses of Change must call this super method or implement the same function within their #initialize
|
16
|
+
#
|
17
|
+
# @param _subject [Duxml::Element] parent doc affected by change
|
18
|
+
def initialize(_subject, *args)
|
19
|
+
super _subject
|
20
|
+
@time_stamp = Time.now
|
21
|
+
args.each do |arg|
|
22
|
+
if arg.is_a?(Duxml::Element)
|
23
|
+
@object = arg
|
24
|
+
break
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :time_stamp
|
30
|
+
end # class ChangeClass < PatternClass
|
31
|
+
|
32
|
+
module Change
|
33
|
+
def abstract?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String] gives its time stamp
|
38
|
+
def description
|
39
|
+
"at #{time_stamp}#{line_expr}:"
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [-1,0,1,nil] compares dates of changes
|
43
|
+
def <=>(obj)
|
44
|
+
return nil unless obj.is_a?(Duxml::Change)
|
45
|
+
date <=> obj.date
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Fixnum] line number of changed object; -l if not applicable
|
49
|
+
def line
|
50
|
+
case
|
51
|
+
when object.respond_to?(:line) && object.line.is_a?(Numeric) && object.line >= 0
|
52
|
+
object.line
|
53
|
+
when object.respond_to?(:object) && object.object.respond_to?(:line) && object.object.line.is_a?(Numeric) && object.object.line >= 0
|
54
|
+
object.object.line
|
55
|
+
when object.respond_to?(:subject) && object.subject.respond_to?(:line) && object.subject.line.is_a?(Numeric) && object.subject.line >= 0
|
56
|
+
object.subject.line
|
57
|
+
when subject.respond_to?(:line) && subject.line.is_a?(Numeric) && subject.line >= 0
|
58
|
+
subject.line
|
59
|
+
else
|
60
|
+
-1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# @return [String] string equivalent of object's line number
|
67
|
+
def line_expr
|
68
|
+
line >= 0 ? " on line #{line.to_s}" : ''
|
69
|
+
end
|
70
|
+
end # class Change
|
71
|
+
end # module Duxml
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module ChangeAttr; end
|
7
|
+
|
8
|
+
# created when Element has an attribute already and its value has been changed
|
9
|
+
class ChangeAttrClass < ChangeClass
|
10
|
+
include ChangeAttr
|
11
|
+
|
12
|
+
# @param _subject [Duxml::Element] parent doc whose attribute changed
|
13
|
+
# @param _attr_name [String] name of the changed attribute
|
14
|
+
# @param _old_value [String] old attribute value
|
15
|
+
def initialize(_subject, _attr_name, _old_value)
|
16
|
+
super _subject
|
17
|
+
@attr_name, @old_value = _attr_name, _old_value
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :attr_name, :old_value
|
21
|
+
end # class ChangeAttributeClass
|
22
|
+
|
23
|
+
module ChangeAttr
|
24
|
+
# @return [String] new value of attribute
|
25
|
+
def value
|
26
|
+
subject[attr_name]
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String] self description
|
30
|
+
def description
|
31
|
+
"#{super} #{subject.description}'s @#{attr_name} changed value from '#{old_value}' to '#{value}'."
|
32
|
+
end
|
33
|
+
end # module ChangeAttribute
|
34
|
+
end # module Duxml
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module ChangeText; end
|
7
|
+
# created when doc has text and text has been changed
|
8
|
+
class ChangeTextClass < ChangeClass
|
9
|
+
include ChangeText
|
10
|
+
|
11
|
+
# @param _subject [Duxml::Element] parent doc whose text has changed
|
12
|
+
# @param _index [Fixnum] index of parent's nodes that text is found at
|
13
|
+
# @param _old_text [String] string that was replaced
|
14
|
+
def initialize(_subject, _index, _old_text)
|
15
|
+
super _subject
|
16
|
+
@index, @old_text = _index, _old_text
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :index, :old_text
|
20
|
+
end
|
21
|
+
|
22
|
+
module ChangeText
|
23
|
+
# @return [String] self description
|
24
|
+
def description
|
25
|
+
"#{super} #{subject.description}'s text at index #{index} changed from '#{old_text}' to '#{text}'."
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String] new content (subsequent changes may mean this new content no longer exists in its original form!)
|
29
|
+
def text
|
30
|
+
subject.nodes[index]
|
31
|
+
end
|
32
|
+
end # module ChangeText
|
33
|
+
end # module Duxml
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module Error
|
7
|
+
def error?
|
8
|
+
true
|
9
|
+
end
|
10
|
+
end # class Error
|
11
|
+
|
12
|
+
# do not use except to subclass
|
13
|
+
class ErrorClass < ChangeClass
|
14
|
+
include Error
|
15
|
+
|
16
|
+
# @param _rule [Rule] rule that was violated
|
17
|
+
# @param _change_or_pattern [ChangeClass, PatternClass] can be triggered by a change or a pattern found in a static document
|
18
|
+
def initialize(_rule, _change_or_pattern)
|
19
|
+
super(_rule)
|
20
|
+
@object = _change_or_pattern
|
21
|
+
end
|
22
|
+
alias_method :rule, :subject
|
23
|
+
end
|
24
|
+
|
25
|
+
end # module Duxml
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module NewAttr; end
|
7
|
+
|
8
|
+
# created when doc gains a new attribute
|
9
|
+
class NewAttrClass < ChangeClass
|
10
|
+
include NewAttr
|
11
|
+
|
12
|
+
# @param _subject [Duxml::Element] parent doc
|
13
|
+
# @param _attr_name
|
14
|
+
def initialize(_subject, _attr_name)
|
15
|
+
super(_subject)
|
16
|
+
@attr_name = _attr_name
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :attr_name
|
20
|
+
end
|
21
|
+
|
22
|
+
module NewAttr
|
23
|
+
# @return [String] value of the new attribute
|
24
|
+
def value
|
25
|
+
subject[attr_name]
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String] self description
|
29
|
+
def description
|
30
|
+
"#{super} #{subject.description} given new attribute '#{attr_name}' with value '#{value}'."
|
31
|
+
end
|
32
|
+
end # module NewAttribute
|
33
|
+
end # module Duxml
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module NewText; end
|
7
|
+
|
8
|
+
# created when object had no children or text and text has been added
|
9
|
+
class NewTextClass < ChangeClass
|
10
|
+
include NewText
|
11
|
+
|
12
|
+
# @param _subject [Duxml::Element] doc that has gained new text
|
13
|
+
# @param _index [Fixnum] index of new text node
|
14
|
+
def initialize(_subject, _index)
|
15
|
+
super _subject
|
16
|
+
@index = _index
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :index
|
20
|
+
end
|
21
|
+
|
22
|
+
module NewText
|
23
|
+
def text
|
24
|
+
subject.nodes[index]
|
25
|
+
end
|
26
|
+
alias_method :object, :text
|
27
|
+
|
28
|
+
# @return [String] self description
|
29
|
+
def description
|
30
|
+
"#{super} #{subject.description} given new text '#{text}'."
|
31
|
+
end
|
32
|
+
|
33
|
+
def line_expr
|
34
|
+
subject.line < 0 ? '' : " on line #{subject.line}"
|
35
|
+
end
|
36
|
+
end # class NewContent
|
37
|
+
end # module Duxml
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/error')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module QualifyError; end
|
7
|
+
|
8
|
+
# created when grammar detects error from user input
|
9
|
+
class QualifyErrorClass < ErrorClass
|
10
|
+
include QualifyError
|
11
|
+
|
12
|
+
alias_method :bad_change, :object
|
13
|
+
end
|
14
|
+
|
15
|
+
module QualifyError
|
16
|
+
|
17
|
+
def description
|
18
|
+
rule_str = rule.respond_to?(:validate) ? 'not allowed by this Grammar' : "violates #{rule.description}"
|
19
|
+
"Qualify Error #{super} #{bad_change.description} #{rule_str}."
|
20
|
+
end
|
21
|
+
end # module QualifyError
|
22
|
+
end # module Duxml
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/change')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module Remove; end
|
7
|
+
|
8
|
+
# created when doc loses a child
|
9
|
+
class RemoveClass < ChangeClass
|
10
|
+
include Remove
|
11
|
+
# @param _subject [Dux::Element] parent doc that lost child
|
12
|
+
# @param _child [Dux::Element] removed child; it gets added as child of this Remove object so it never actually goes away
|
13
|
+
def initialize(_subject, _child)
|
14
|
+
super(_subject)
|
15
|
+
@removed = _child
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :removed
|
19
|
+
alias_method :object, :removed
|
20
|
+
end
|
21
|
+
|
22
|
+
module Remove
|
23
|
+
# @return [String] describes removal event
|
24
|
+
def description
|
25
|
+
%(#{super} #{removed.description} removed from #{subject.description}.)
|
26
|
+
end
|
27
|
+
end # module Remove
|
28
|
+
end # module Duxml
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../grammar/pattern')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
# TODO NOT IMPLEMENTED YET!!!
|
7
|
+
module Undo; end
|
8
|
+
|
9
|
+
# created when a previous change is undone
|
10
|
+
class UndoClass < ChangeClass
|
11
|
+
include Undo
|
12
|
+
end
|
13
|
+
|
14
|
+
module Undo
|
15
|
+
def description
|
16
|
+
"#{super} change '#{subject.id}' undone."
|
17
|
+
end
|
18
|
+
|
19
|
+
# returns previous change instance that was undone
|
20
|
+
def undone_change
|
21
|
+
self[:change]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end # module Duxml
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/error')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module ValidateError; end
|
7
|
+
|
8
|
+
# created when grammar detects error from file
|
9
|
+
class ValidateErrorClass < ErrorClass
|
10
|
+
include ValidateError
|
11
|
+
|
12
|
+
alias_method :bad_pattern, :object
|
13
|
+
end
|
14
|
+
|
15
|
+
module ValidateError
|
16
|
+
def description
|
17
|
+
rule_str = rule.respond_to?(:validate) ? 'not allowed by this Grammar' : "violates #{rule.description}"
|
18
|
+
"Validate Error #{super} #{bad_pattern.description} #{rule_str}."
|
19
|
+
end
|
20
|
+
end # module ValidateError
|
21
|
+
end # module Duxml
|