con_duxml 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9cfaa8124d43f54f14711ce08f3cd180b60a68c5
4
- data.tar.gz: 1c7dd21f47d6d784b85bffeb58ec8b4b21091806
3
+ metadata.gz: 50d364878f6e1e1d40c244c26848840a951bc674
4
+ data.tar.gz: 558e088bdd171e165b8b27c1147637a9300a6c0a
5
5
  SHA512:
6
- metadata.gz: f1d9a27f1d8ac62261fc07d1ac9548f06ce284b32f223b7e02c2e508f064995dbe069cc65d09ea119a1ab8f47a93d382de6ac9a1da39ad9728a939c819fd6806
7
- data.tar.gz: 7de90be2f489b27320235aab59523019d0b7a1b0344eeb811e23f0cfa5ee0a3a29de377461cbadc71cd8107e5349c5ec38f4308e4bf5b91fd42d2b1bfba36769
6
+ metadata.gz: 20f7fd97f29bb18c682bc9c41a0908a589c192faab5ef9135bbc7c36ba33d8756855f0ef6675cac6506f2be80567fc0dbe896585f5a27146254ac7114b590d64
7
+ data.tar.gz: 23ad78e7719b3144043756404afb8b7f062acab8e23fd4b39f7abea80bd10f869303c93eda27646a19d958768cfc4a5211d169cdbc4c8496efb4fc2dc20b0ff3
@@ -10,27 +10,21 @@ module ConDuxml
10
10
  include Instance
11
11
  include Enumerable
12
12
 
13
- # reifies pattern by actually copying children and assigning each unique properties derived from iterator value
14
- # TODO do we need argument?
15
- def instantiate(meta=nil)
13
+ # @param block [block] each duplicated node is yielded to block if given
14
+ # @return [Array[Element]] flattened array of all duplicated Elements
15
+ def instantiate(&block)
16
16
  size_expr = size.respond_to?(:to_i) ? size.to_i : size.to_s
17
17
  if size_expr.is_a? Fixnum
18
- iterator_index = 0
19
18
  new_children = []
20
- kids = []
21
- children.each do |kid| kids << kid.detached_subtree_copy end
22
- remove_all!
23
- size_expr.times do
24
- i = Instance.new
25
- i << Parameters.new(nil, iterator: iterator_index)
26
- kids.each do |kid| i << kid.detached_subtree_copy end
27
- i.rename name+iterator_index.to_s
28
- new_children << i
29
- iterator_index += 1
19
+ size_expr.times do |index|
20
+ nodes.each do |node|
21
+ new_child = block_given? ? yield(node.dclone, index) : node.dclone
22
+ new_children << new_child
23
+ end
30
24
  end
31
25
  new_children
32
26
  else
33
- []
27
+ [self]
34
28
  end
35
29
  end # def instantiate
36
30
 
@@ -1,18 +1,20 @@
1
1
  require 'duxml'
2
- require_relative '../con_dux/tabulable'
2
+ require_relative 'linkable'
3
3
 
4
- module ConDuxml
5
- # ConDuxml defines a new Element class by subclassing Duxml's Element and adding #split and #merge transform methods
6
- class Element < ::Duxml::Element
7
- include Tabulable
4
+ module Duxml
5
+ module ElementGuts
6
+ include Linkable
8
7
 
9
8
  # @param &block [Block] calls Enumerable#chunk on this element's nodes to group them by result of &block
10
9
  # @return [Element] a duplicate element of this node initialized with each subset's nodes
11
10
  def split(&block)
12
11
  chunks = nodes.chunk(&block)
13
- chunks.collect do |type, nodes|
12
+ new_nodes = chunks.collect do |type, nodes|
14
13
  self.class.new(name, nodes)
15
14
  end
15
+
16
+ report :Split, new_nodes
17
+ new_nodes
16
18
  end
17
19
 
18
20
  # @param pattern [several_variants] if String/Symbol or array of such, differences between merged entities' instance vars matching pattern are masked; if pattern is a hash, the key is the instance var, and the value becomes the new value for the merged entity
@@ -34,10 +36,13 @@ module ConDuxml
34
36
  self_clone << chunk
35
37
  end
36
38
  end # chunks.each do |type, nodes|
39
+
40
+ report :Merge, self_clone
41
+
37
42
  self_clone
38
43
  end # def merge(pattern, &block)
39
44
 
40
- private
45
+ private
41
46
  def diff_attrs(chunk, pattern)
42
47
  homogeneous = true
43
48
  merged_args = {}
@@ -0,0 +1,9 @@
1
+ module Linkable
2
+ def linked_by
3
+ @observer_peers.select do |obs|
4
+ %w(grammar history).none? do |type|
5
+ obs.name == type
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,11 +1,12 @@
1
1
  # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+ require_relative 'duxml_ext/element'
2
3
 
3
4
  module ConDuxml
4
5
  # Instances are copies of another XML element with a distinct set of parameter values
5
6
  # like Objects in relation to a Class
6
7
  module Instance
7
8
  def ref=(target)
8
- raise Exception unless target.respond_to?(:nodes)
9
+ raise Exception unless target.respond_to?(:nodes) or File.exists?(target)
9
10
  @ref = target
10
11
  end
11
12
 
@@ -20,7 +21,7 @@ module ConDuxml
20
21
  if target.nil?
21
22
  new_kids = nodes
22
23
  else
23
- new_kids << target.clone
24
+ new_kids << target.dclone
24
25
  end
25
26
  new_kids
26
27
  end # def instantiate
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/instance')
4
+
5
+ module ConDuxml
6
+ # links are effectively aliases for an XML node that can exist anywhere outside of that node
7
+ # they confer referencing scope, namespace, and notifications of content changes
8
+ # anything contained by a link element is then dynamically linked to the target
9
+ # this is useful for designs where one element's state depends on another's or where it's important to track a target
10
+ # that may not be in a fixed location
11
+ module Link
12
+ include Instance
13
+
14
+ # strict links will immediately throw an exception if the target becomes invalid for any reason
15
+ # otherwise, errors are simply reported to history
16
+ @strict_or_false
17
+
18
+ def valid?
19
+ !resolve_ref.nil?
20
+ end
21
+
22
+ def ref=(target)
23
+ target.extend Linkable
24
+ @ref = target
25
+ end
26
+
27
+ # @param block [block] each child node is yielded to block if given
28
+ # @return [Array] nodes to replace this link - children by default
29
+ def instantiate(&block)
30
+ resolve_ref.add_observer(self)
31
+ block_given? ? yield(nodes.each) : nodes
32
+ end
33
+
34
+ # @param bool [true, false, nil] if true or false, sets @strict_or_false to this value
35
+ # @return [true, false] returns current value (true by default)
36
+ def strict?(bool=nil)
37
+ bool.nil? ? @strict_or_false ||= true : @strict_or_false = bool
38
+ end
39
+
40
+ # TODO rewrite this!!! at most primitive, updates need to happen when link targets split/merge or are removed
41
+ # @param type [Symbol] category i.e. class symbol of changes/errors reported
42
+ # @param *args [*several_variants] information needed to accurately log the event; varies by change/error class
43
+ def update(type, *args)
44
+ change_class = Duxml::const_get "#{type.to_s}Class".to_sym
45
+ change_comp = change_class.new *args
46
+ @nodes.unshift change_comp
47
+ changed
48
+ notify_observers(change_comp) unless change_comp.respond_to?(:error?)
49
+ raise(Exception, change_comp.description) if strict? && type == :QualifyError
50
+ end
51
+ end
52
+ end # module Dux
@@ -0,0 +1,74 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ # helper methods for converting transform elements into code
4
+ module Transform
5
+ @xform
6
+ @source
7
+
8
+ attr_reader :xform, :source
9
+
10
+ # @param xform [Element] transform element
11
+ # @param _source [Element] XML xform containing content to be transformed
12
+ # @return [Array[Element]] transformed content; always an array of nodes, even if just one
13
+ def activate(xform, _source)
14
+ @source = _source
15
+ get_sources(xform).collect do |subj|
16
+ args = get_args(xform, subj)
17
+ get_method(xform).call(*args)
18
+ end
19
+ end
20
+
21
+ # @param xform [Element] transform element
22
+ # @return [Array] array of elements that match @target, which must be a '/'-separated string
23
+ # if transform element has any children that may need the same source target, target_stack.last remains
24
+ # if transform is a leaf, target_stack is popped
25
+ def get_sources(xform)
26
+ if xform[:source]
27
+ source.locate add_name_space_prefix xform[:source]
28
+ else
29
+ [source]
30
+ end
31
+ end
32
+
33
+ # @param xform [Element] transform element
34
+ # @return [Method] resolves reference to actual transform method
35
+ def get_method(xform)
36
+ words = xform.name.split(':').reverse
37
+ method_name = words[0].to_sym
38
+ maudule = Module
39
+ maudule = Module.const_get(words[1].constantize) if words[1] and Module.const_defined?(words[1].constantize)
40
+ maudule.method(method_name)
41
+ end
42
+
43
+ # @param xform [Element] transform element
44
+ # @param subj [Element] source XML Element
45
+ # @return [Array[String, Element]] string returned by self[:args] is separated by ';' into correctly formatted argument values for transform method
46
+ def get_args(xform, subj)
47
+ args = xform.attributes.keys.sort.collect do |attr|
48
+ if attr.to_s.match(/arg[0-9]/)
49
+ if xform[attr].include?(',')
50
+ xform[attr].split(',').collect do |s|
51
+ if s.match(/'[\s\w]+'/)
52
+ $MATCH.strip[1..-2]
53
+ else
54
+ subj.locate(add_name_space_prefix s.strip).first
55
+ end
56
+ end
57
+ else
58
+ subj.locate(add_name_space_prefix xform[attr]).first
59
+ end
60
+ end
61
+ end.compact
62
+ children = xform.nodes.collect do |child|
63
+ activate(child, subj)
64
+ end
65
+ args << children.flatten if children.any?
66
+ args
67
+ end
68
+
69
+ def add_name_space_prefix(str)
70
+ str.split('/').collect do |w|
71
+ w.match(/\w+/) ? "#{src_ns ? src_ns+':' : ''}#{w}" : w
72
+ end.join('/')
73
+ end
74
+ end
data/lib/con_duxml.rb ADDED
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+ %w(transform array instance link).each do |f| require_relative "con_duxml/#{f}" end
3
+
4
+ module ConDuxml
5
+ include Duxml
6
+ include Transform
7
+
8
+ # hash where each key is concatenation of each instantiation of @doc and values are the Doc instance permutations returned by #instantiate
9
+ @instances
10
+ # double-key hash containing every result of #transform; keys concatenation of source doc's #object_id and transform doc's #object_id
11
+ @transformations
12
+ # namespace prefix for source file
13
+ @src_ns
14
+
15
+ attr_reader :src_ns
16
+
17
+ # @param transforms [String, Doc] transforms file or path to one
18
+ # @param doc_or_path [String, Doc] XML document or path to one that will provide content to be transformed; source file can
19
+ # also contain directives or links to them
20
+ # @return [Doc] result of transform; automatically hashed into @transforms
21
+ def transform(transforms, doc_or_path=nil)
22
+ output = Doc.new
23
+ transforms = case transforms
24
+ when Doc then transforms.root
25
+ when Element then transforms
26
+ when String then sax(transforms).root
27
+ else
28
+ end
29
+ @doc = case doc_or_path
30
+ when Doc then doc_or_path
31
+ when String then sax doc_or_path
32
+ else doc
33
+ end
34
+ @src_ns = transforms[:src_ns]
35
+ source = doc.locate(add_name_space_prefix(transforms[:source])).first
36
+ output.grammar = transforms[:grammar] if transforms[:grammar]
37
+ a = activate(transforms.first, source).first
38
+ output << a
39
+ @transformations ||= {}
40
+ @transformations[doc.object_id+transforms.object_id] = output
41
+ end
42
+
43
+ # instantiation takes a static design file and constructs a dynamic model by identifying certain keyword elements,
44
+ # executing their method on child nodes, then removing the interpolating keyword element. these are:
45
+ #
46
+ # <array> - is replaced by multiple copies of its direct child or referenced XML nodes, allowing for user-defined variations between each copy
47
+ # <instance> - when it contains design elements, it is removed but its reference ID is given to all children creating an XML-invisible arbitrary grouping
48
+ # when it references an XML file, ID or path to an XML element, the target is copied and inserted in place of this element
49
+ # <link> - referenced XML file or nodes provides namespace, contents, and notification of changes to any direct children of this node @see ConDuxml::Link
50
+ #
51
+ # @param source [String, Doc] XML document or path to one that will provide design content
52
+ # @return [Doc] resulting XML document
53
+ def instantiate(source)
54
+
55
+ end
56
+
57
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: con_duxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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-15 00:00:00.000000000 Z
11
+ date: 2016-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: duxml
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.7'
19
+ version: '0.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.7'
26
+ version: '0.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby-dita
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
27
41
  description:
28
42
  email:
29
43
  - peter.kong@nxp.com
@@ -31,17 +45,14 @@ executables: []
31
45
  extensions: []
32
46
  extra_rdoc_files: []
33
47
  files:
34
- - lib/con_dux/describable.rb
35
- - lib/con_dux/design/array.rb
36
- - lib/con_dux/design/instance.rb
37
- - lib/con_dux/design/link.rb
38
- - lib/con_dux/designable.rb
39
- - lib/con_dux/instanciable.rb
40
- - lib/con_dux/mappable.rb
41
- - lib/con_dux/tabulable.rb
42
- - lib/con_dux.rb
43
- - lib/duxml_ext/element.rb
44
- homepage: http://www.github.com/con_duxml
48
+ - lib/con_duxml/array.rb
49
+ - lib/con_duxml/duxml_ext/element.rb
50
+ - lib/con_duxml/duxml_ext/linkable.rb
51
+ - lib/con_duxml/instance.rb
52
+ - lib/con_duxml/link.rb
53
+ - lib/con_duxml/transform.rb
54
+ - lib/con_duxml.rb
55
+ homepage: http://www.github.com/Ludocracy/con_duxml
45
56
  licenses:
46
57
  - MIT
47
58
  metadata: {}
@@ -1,14 +0,0 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- module ConDuxml
4
- module Describable
5
- # TODO make this safer!!! fails too easily
6
- def set_docs(args={})
7
- args = self if args.empty?
8
- @brief_descr = args.is_a?(Hash) ? args[:brief_descr] : (args.brief_description.text || args.brief_descr.text)
9
- @long_descr = args.is_a?(Hash) ? args[:long_descr] : ( args.long_description.nodes || args.long_descr)
10
- end
11
-
12
- attr_reader :brief_descr, :long_descr
13
- end
14
- end
@@ -1,33 +0,0 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/instance')
4
-
5
- module ConDuxml
6
- # links allow parameters to be bound to attribute values or element content in the design objects wrapped by the link
7
- module Link
8
- include Instance
9
-
10
- def valid?
11
- !resolve_ref.nil?
12
- end
13
-
14
- def ref=(target)
15
- target.add_observer(self, :ref=)
16
- super target
17
- end
18
-
19
- def instantiate
20
- [resolve_ref]
21
- end
22
- end
23
-
24
- module Linkable
25
- include Reportable
26
-
27
- def linked_by
28
- @observer_peers.select do |obs|
29
- %w(grammar history).none? do |type| obs.name == type end
30
- end
31
- end
32
- end
33
- end # module Dux
@@ -1,13 +0,0 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require_relative 'describable'
4
- require_relative 'tabulable'
5
- require_relative 'mappable'
6
-
7
- module ConDuxml
8
- module Designable
9
- include Describable
10
- include Tabulable
11
- include Mappable
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- require_relative 'designable'
2
-
3
- module ConDuxml
4
- module Instanciable
5
- include Designable
6
-
7
- def instantiate
8
- sleep 0
9
- end
10
- end
11
- end
@@ -1,30 +0,0 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
- require 'ruby-dita'
3
-
4
- module ConDuxml
5
- module Mappable
6
- include Dita
7
-
8
- def to_map(targets)
9
- # count levels
10
- # assign to targets
11
- # if targets.size < levels,
12
- # if targets.size > levels, match top
13
- end
14
-
15
- # TODO currently returns topic, need to make it return map later!
16
- def dita_map(*targets)
17
- t = Element.new('topic')
18
- t << Element.new('title')
19
- t.title << targets.first if targets.any?
20
- t << Element.new('body')
21
- t[:id] = "topic#{t.object_id.to_s}"
22
- targets[1..-1].compact.each do |x| t.body << x end
23
- t
24
- end
25
-
26
- def depth
27
- 0 # TODO - make this dynamic! Duxml needs to implement tree depth method
28
- end
29
- end
30
- end
@@ -1,114 +0,0 @@
1
- module ConDuxml
2
- module Tabulable
3
- include Enumerable
4
- include ConDuxml
5
-
6
- class << self
7
- def initialize(nodes)
8
- @nodes = nodes
9
- end
10
- end
11
-
12
- extend self
13
-
14
- def each(&block)
15
- yield nodes.each
16
- end
17
-
18
- # @param pattern [Hash, String, Symbol, Array] pattern used to filter attributes to output
19
- # @return [Array] array of values of attributes that pass filter
20
- def to_row(pattern=nil)
21
- entries = []
22
- nodes.each do |n|
23
- if n.nodes.size == 1 && nodes.first.is_a?(String) && !matches?(n.name, pattern)
24
- entries << n.nodes.first
25
- end
26
- end
27
- if instance_variable_defined?(:@attributes)
28
- attributes.each do |k, v| entries << v unless matches?(k, pattern) end
29
- else
30
- instance_variables.each do |var|
31
- entries << instance_variable_get(var) unless matches?(var, pattern)
32
- end
33
- end
34
- entries
35
- end
36
-
37
- # @param pattern [Hash, String, Symbol, Array] @see #to_row @param
38
- # @return [Array] array of names of attributes that pass filter
39
- def to_header(pattern=nil)
40
- headings = []
41
- nodes.each do |n|
42
- if n.nodes.size == 1 && n.nodes.first.is_a?(String) && !matches?(n.name, pattern)
43
- headings << n.name
44
- end
45
- end
46
- if instance_variable_defined?(:@attributes)
47
- attributes.each do |k, v| headings << k unless matches?(k, pattern) end
48
- else
49
- instance_variables.each do |var|
50
- headings << var.to_s[1..-1] unless matches?(var, pattern)
51
- end
52
- end
53
- headings
54
- end
55
-
56
- # @param pattern [Hash, String, Symbol, Array] @see #to_row @param
57
- # @return [Array] 2D array where columns match #to_header and rows are #to_row output of constituent elements
58
- def to_table(pattern=nil)
59
- similar_nodes = nodes.group_by do |n|
60
- n.name
61
- end.find do |type, grp|
62
- grp.size > 1
63
- end.last
64
- table_nodes = similar_nodes.collect do |r|
65
- r.to_row(pattern.is_a?(Array) ? pattern.last : pattern)
66
- end
67
- header = similar_nodes.first.to_header(pattern.is_a?(Array) ? pattern.first : pattern)
68
- raise Exception, "number of header columns (#{header.size}) does not match number of data columns (#{table_nodes.first.size})!" if header.size != table_nodes.first.size
69
- [header, *table_nodes]
70
- end
71
-
72
- # @param *cols [*[]] column information bound to key, each of which must match a header item
73
- def dita_table(pattern=nil, *cols)
74
- src_tbl = to_table(pattern)
75
- t = Element.new('table')
76
- cols.each do |c|
77
- t << Element.new('colspec')
78
- t.nodes.last[:colname] = c.name
79
- # TODO pull other colspec attrs; look them up!!
80
- end
81
- tgroup = Element.new('tgroup')
82
- tgroup << Element.new('thead')
83
- tgroup.thead << Element.new('row')
84
-
85
- src_tbl.first.each do |h|
86
- entry = Element.new('entry')
87
- entry << h
88
- tgroup.thead.row << entry
89
- end
90
-
91
- tgroup[:cols] = src_tbl.first.size.to_s
92
-
93
- tgroup << Element.new('tbody')
94
- src_tbl[1..-1].each do |row|
95
- tgroup.tbody << Element.new('row')
96
- row.each do |e|
97
- entry = Element.new('entry')
98
- entry << e.to_s
99
- tgroup.tbody.nodes.last << entry
100
- end
101
- end
102
- t << tgroup
103
- end # def to_dita(pattern=[], *cols)
104
-
105
- private
106
-
107
- def matches?(attr, pattern)
108
- return false if pattern.nil? or pattern.empty?
109
- var = attr.to_s[0] == '@' ? attr.to_s[1..-1] : attr.to_s
110
- pattern = pattern.keys.collect do |k| k.to_s end if pattern.is_a?(Hash)
111
- var=='nodes' || pattern && var.match(pattern.to_s).to_s == var
112
- end
113
- end # module Tabulable
114
- end
data/lib/con_dux.rb DELETED
@@ -1,40 +0,0 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require_relative 'con_dux/designable'
4
-
5
- module ConDuxml
6
- include Duxml
7
-
8
- @kanseis
9
-
10
- attr_reader :kanseis
11
-
12
- # @param parent [Doc, Element] XML parent of this node
13
- # @return [Doc, Element] instantiated XML copy of this node
14
- def instantiate!
15
- kansei!
16
-
17
- parent = doc
18
- doc.traverse do |n|
19
- next if n.is_a?(String)
20
- parent.replace(n, n.instantiate) if n.respond_to?(:instantiate)
21
- parent = n unless parent === n or parent.nodes.any? do |m| m === n end
22
- end
23
- doc
24
- end
25
-
26
- def template
27
- @kanseis.last
28
- end
29
-
30
- private
31
-
32
- def kansei!
33
- new_root = doc.clone
34
- @kanseis ||= []
35
- save(file) # TODO make this optional!? probably?
36
- @kanseis << doc
37
- @meta = MetaClass.new
38
- @doc = new_root
39
- end
40
- end