duxml 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|