duxml 0.7.2 → 0.8.0

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.
@@ -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
@@ -50,9 +50,9 @@ module Duxml
50
50
  end
51
51
  end
52
52
 
53
- # @return [Element] returns self as XML element e.g. '<duxml:grammar/>'
54
- def self.xml
55
- Element.new(name.nmtokenize).extend self
53
+ # @return [Doc] returns self as XML document
54
+ def xml
55
+ Element.new('grammar') << rules.collect do |rule| rule.xml end
56
56
  end
57
57
 
58
58
  # @return [History] history that this grammar is currently reporting to
@@ -27,10 +27,10 @@ module Duxml
27
27
 
28
28
  def_delegators :@nodes, :[], :each
29
29
 
30
- # @param harsh_or_kind [Boolean] by default harsh i.e. true so that if this History detects an error it will raise an Exception; otherwise not
31
- def initialize(harsh_or_kind = true)
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
32
  @nodes = []
33
- @strict = harsh_or_kind
33
+ @strict = strict_or_false
34
34
  end
35
35
 
36
36
  attr_reader :nodes
@@ -40,15 +40,16 @@ module Duxml
40
40
  module History
41
41
  # used when creating a new metadata file for a static XML file
42
42
  #
43
- # @return [Element] XML element for a new <duxml:history> node
44
- def self.xml
45
- Element.new(name.nmtokenize).extend self
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
46
48
  end
47
49
 
48
50
  # @return [Boolean] toggles (true by default) whether History will raise exception or tolerate qualify errors
49
- def strict?(harsh_or_kind=nil)
50
- @strict = harsh_or_kind.nil? ? @strict : harsh_or_kind
51
- @strict
51
+ def strict?(strict_or_false=nil)
52
+ @strict = strict_or_false.nil? ? @strict : strict_or_false
52
53
  end
53
54
 
54
55
  # @return [ChangeClass, ErrorClass] the latest event
data/lib/duxml/meta.rb CHANGED
@@ -22,17 +22,10 @@ module Duxml
22
22
  @grammar_path = grammar_path
23
23
  end
24
24
 
25
- attr_reader :history, :grammar
25
+ attr_reader :history, :grammar, :grammar_path
26
26
  end
27
27
 
28
28
  module Meta
29
- # @return [Doc] metadata document
30
- def self.xml
31
- d = Doc.new << (Element.new(name.nmtokenize) << Grammar.xml << History.xml)
32
- d.root.grammar[:ref] = @grammar_path if @grammar_path
33
- d
34
- end
35
-
36
29
  # @param path [String] path of XML-content file
37
30
  # @return [String] full path of metadata file based on content file's name e.g.
38
31
  # 'design.xml' => '.design.xml.duxml'
@@ -41,11 +34,29 @@ module Duxml
41
34
  "#{dir}/.#{File.basename(path)}#{FILE_EXT}"
42
35
  end
43
36
 
37
+ # @param g [String, GrammarClass] either a grammar object or path to one
38
+ # @return [GrammarClass] grammar object
44
39
  def grammar=(g)
45
- @grammar = g.is_a?(GrammarClass) ? g : Grammar.import(g)
40
+ @grammar = if g.is_a?(GrammarClass)
41
+ g
42
+ else
43
+ @grammar_path = g if File.exists?(g)
44
+ Grammar.import(g)
45
+ end
46
46
  history.delete_observers if history.respond_to?(:delete_observers)
47
47
  history.add_observer(grammar, :qualify)
48
48
  grammar.add_observer history
49
+ grammar
50
+ end
51
+
52
+ def xml
53
+ if grammar_path
54
+ g = Duxml::Element.new('grammar')
55
+ g[:ref] = grammar_path
56
+ else
57
+ g = grammar.xml
58
+ end
59
+ Duxml::Element.new('meta') << g << history.xml
49
60
  end
50
61
  end # module Meta
51
62
  end # module Duxml
@@ -1,27 +1,29 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require 'observer'
4
-
5
- module Reportable
6
- include Observable
7
-
8
- # @param obs [Object] observer to add to this Element as well as its NodeSet
9
- def add_observer(obs, sym=nil)
10
- super(obs, sym || :update)
11
- nodes.add_observer(obs) if self.respond_to?(:nodes) and nodes.respond_to?(:add_observer)
12
- end
13
-
14
- private
15
-
16
- # all public methods that alter XML must call #report in the full scope of that public method
17
- # in order to correctly acquire name of method that called #report
18
- #
19
- # @param *args [*several_variants]
20
- def report(*args)
21
- return nil if @observer_peers.nil?
22
- changed
23
- new_args = [args.first, self]
24
- args[1..-1].each do |a| new_args << a end if args.size > 1
25
- notify_observers(*new_args)
26
- end
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require 'observer'
4
+
5
+ module Reportable
6
+ include Observable
7
+
8
+ # @param obs [Object] observer to add to this Element as well as its NodeSet
9
+ def add_observer(obs, sym=nil)
10
+ super(obs, sym || :update)
11
+ nodes.add_observer(obs) if self.respond_to?(:nodes) and nodes.respond_to?(:add_observer)
12
+ end
13
+
14
+ attr_reader :observer_peers
15
+
16
+ private
17
+
18
+ # all public methods that alter XML must call #report in the full scope of that public method
19
+ # in order to correctly acquire name of method that called #report
20
+ #
21
+ # @param *args [*several_variants]
22
+ def report(*args)
23
+ return nil if @observer_peers.nil?
24
+ changed
25
+ new_args = [args.first, self]
26
+ args[1..-1].each do |a| new_args << a end if args.size > 1
27
+ notify_observers(*new_args)
28
+ end
27
29
  end
data/lib/duxml/saxer.rb CHANGED
@@ -14,7 +14,8 @@ module Duxml
14
14
  saxer = DocuLiner.new(Duxml::Doc.new, obs)
15
15
  Ox.sax_parse(saxer, io, {convert_special: true, symbolize: false})
16
16
  doc = saxer.cursor
17
- doc.add_observer obs if obs
17
+ doc.add_observer obs if obs and doc.count_observers < 1
18
+ doc.path = path
18
19
  doc
19
20
  end
20
21
 
@@ -37,7 +38,7 @@ module Duxml
37
38
  attr_accessor :cursor_stack
38
39
 
39
40
  def start_element(name)
40
- cursor << Duxml::Element.new(name, line, column)
41
+ cursor.nodes.insert(-1, Duxml::Element.new(name, line, column))
41
42
  cursor_stack << cursor.nodes.last
42
43
  end
43
44
 
@@ -46,7 +47,7 @@ module Duxml
46
47
  end
47
48
 
48
49
  def text(str)
49
- cursor << str
50
+ cursor.nodes.insert(-1, str)
50
51
  end
51
52
 
52
53
  def end_element(name)
data/lib/duxml.rb CHANGED
@@ -1,51 +1,46 @@
1
1
  # Copyright (c) 2016 Freescale Semiconductor Inc.
2
2
 
3
3
  require File.expand_path(File.dirname(__FILE__) + '/duxml/saxer')
4
- require File.expand_path(File.dirname(__FILE__) + '/duxml/meta')
5
4
 
6
5
  module Duxml
7
- DITA_GRAMMAR = File.expand_path(File.dirname(__FILE__) + '/../xml/dita_grammar.xml')
8
6
  include Saxer
9
- include Meta
10
7
 
11
- # path to XML file
12
- @file
13
- # current document
8
+ # most recently processed document - default location for validated documents that are not loaded explicitly
14
9
  @doc
15
- # meta data document
16
- @meta
17
10
 
18
- attr_reader :meta, :file, :doc
11
+ attr_reader :doc
19
12
 
20
- # @param file [String, Doc] loads or creates given file or document and finds or creates corresponding metadata file e.g. '.xml_file.duxml'
13
+ # @param _file [String] loads XML file from given path and finds or creates corresponding metadata file e.g. '.xml_file.duxml'
21
14
  # @param grammar_path [nil, String, Duxml::Grammar] optional - provide an external grammar file or object
22
- # @return [Duxml::Meta] combined Object tree from metadata root (metadata and content's XML documents are kept separate)
15
+ # @return [Doc] XML document as Ruby object
23
16
  def load(_file, grammar_path=nil)
24
- if _file.is_a?(String) and File.exists?(_file)
25
- @file = _file
17
+ meta_path = Meta.meta_path(_file)
18
+
19
+ if File.exists?(meta_path)
20
+ meta = Ox.parse_obj(File.read meta_path)
21
+ meta.grammar = grammar_path unless grammar_path.nil? or meta.grammar.defined?
26
22
  else
27
- @file = "#{(_file.respond_to?(:name) ? _file.name : _file.class.to_s) + _file.object_id.to_s}"
28
- File.write file, ''
23
+ meta = MetaClass.new(grammar_path)
29
24
  end
30
25
 
31
- set_metadata!(grammar_path)
32
- set_doc!
33
- end # def load
34
-
35
- # @param file [String] creates new XML file at given path
36
- # @param content [Doc, Element] XML content with which to initialize new file
37
- def create(file, content=nil)
38
- File.write(file, content.to_s)
39
- @doc = content.is_a?(Doc) ? content : Doc.new
40
- end
26
+ if File.exists?(_file)
27
+ @doc = sax(_file, meta.history)
28
+ else
29
+ @doc = Doc.new
30
+ @doc.path = _file
41
31
 
42
- # @param file [String] saves current content XML to given file path (Duxml@file by default)
43
- def save(file)
44
- meta_path = Meta.meta_path(file)
45
- unless File.exists?(meta_path)
46
- File.new meta_path, 'w+'
47
- File.write(meta_path, Meta.xml)
32
+ doc.delete_observers if doc.count_observers > 0 and doc.observer_peers.first.object_id != meta.history.object_id
33
+ doc.add_observer meta.history if doc.count_observers < 1
48
34
  end
35
+ doc.set_meta meta
36
+ end # def load
37
+
38
+ # @param file [String] saves current content XML to given file path
39
+ # @param xml [Doc, Element] current Doc by default, but can also be unattached XML Element
40
+ def save(file, xml=doc)
41
+ @doc = xml.respond_to?(:root) ? xml : Doc.new << xml
42
+ doc.write_to file
43
+ File.write(Meta.meta_path(file), Ox.dump(doc.meta, circular: true))
49
44
  end
50
45
 
51
46
  # @param file [String] output file path for logging human-readable validation error messages
@@ -53,45 +48,29 @@ module Duxml
53
48
  File.write(file, meta.history.description)
54
49
  end
55
50
 
56
- # @param *Args [*several_variants] @see #load
51
+ # @param *Args [String, Doc] if string then path to load Doc, else Doc to validate
52
+ # @param options [Hash, Symbol] currently just supports suppression of console output of results with :quiet
57
53
  # @return [Boolean] whether file passed validation
58
- def validate(*args)
59
- load(*args) unless args.empty?
60
- raise Exception, "grammar not defined!" unless meta.grammar.defined?
61
- raise Exception, "document not loaded!" unless doc.root
54
+ def validate(path_or_doc, options={})
55
+ doc = path_or_doc.is_a?(Doc) ? path_or_doc : load(path_or_doc)
56
+ unless doc.grammar.defined?
57
+ raise Exception, "grammar not defined!" unless options[:grammar]
58
+ doc.grammar = options[:grammar]
59
+ end
60
+ raise Exception, "XML document has no root element!" unless doc.root
62
61
  results = []
63
- doc.root.traverse do |n| results << meta.grammar.validate(n) unless n.is_a?(String) end
62
+ doc.root.traverse do |n| results << doc.grammar.validate(n) unless n.is_a?(String) end
63
+ puts(doc.history.description) unless options[:quiet]
64
64
  !results.any? do |r| !r end
65
65
  end # def validate
66
66
 
67
- # @return [Nokogiri::XML::RelaxNG] current metadata's grammar as a relaxng file
68
- def relaxng
69
- #meta.grammar.relaxng
70
- end
71
-
72
67
  private
73
-
74
- # @return [Doc] @doc is set to either file given by user or new Doc
75
- def set_doc!
76
- @doc ||= if file.nil?
77
- f = Doc.new
78
- f.add_observer meta.history
79
- f
80
- else
81
- f = File.open file
82
- sax(f, meta.history)
83
- end
68
+ # @param g_path [String, GrammarClass] grammar to associate with @doc, which must be set to a Doc and not nil
69
+ def associate_grammar(g_path)
70
+ doc.grammar = g_path if g_path
84
71
  end
85
72
 
86
- # @return [MetaClass] @meta is set to either file extrapolated from path of XML-content file or new MetaClass
87
- def set_metadata!(grammar_path=nil)
88
- meta_path = Meta.meta_path(file)
89
- if file and File.exists?(meta_path)
90
- @meta = sax(File.open(meta_path)).root
91
- meta.grammar=grammar_path unless grammar_path.nil? or meta.grammar.defined?
92
- else
93
- @meta = MetaClass.new(grammar_path)
94
- end
95
- meta
73
+ def find_meta
74
+
96
75
  end
97
76
  end # module Duxml
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Kong
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-24 00:00:00.000000000 Z
11
+ date: 2016-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ox
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.3'
41
- description: execute 'validate_xml --help' for more info
41
+ description: see README.md
42
42
  email:
43
43
  - peter.kong@nxp.com
44
44
  executables:
@@ -88,7 +88,6 @@ files:
88
88
  - lib/duxml/ruby_ext/string.rb
89
89
  - lib/duxml/saxer.rb
90
90
  - lib/duxml.rb
91
- - xml/dita_grammar.xml
92
91
  - bin/validate_xml
93
92
  homepage: http://www.github.com/ruby-dita/duxml
94
93
  licenses: