con_duxml 0.1.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 +7 -0
- data/lib/con_dux/describable.rb +14 -0
- data/lib/con_dux/design/array.rb +48 -0
- data/lib/con_dux/design/instance.rb +32 -0
- data/lib/con_dux/design/link.rb +33 -0
- data/lib/con_dux/designable.rb +13 -0
- data/lib/con_dux/instanciable.rb +11 -0
- data/lib/con_dux/mappable.rb +30 -0
- data/lib/con_dux/tabulable.rb +114 -0
- data/lib/con_dux.rb +40 -0
- data/lib/duxml_ext/element.rb +76 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9cfaa8124d43f54f14711ce08f3cd180b60a68c5
|
4
|
+
data.tar.gz: 1c7dd21f47d6d784b85bffeb58ec8b4b21091806
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f1d9a27f1d8ac62261fc07d1ac9548f06ce284b32f223b7e02c2e508f064995dbe069cc65d09ea119a1ab8f47a93d382de6ac9a1da39ad9728a939c819fd6806
|
7
|
+
data.tar.gz: 7de90be2f489b27320235aab59523019d0b7a1b0344eeb811e23f0cfa5ee0a3a29de377461cbadc71cd8107e5349c5ec38f4308e4bf5b91fd42d2b1bfba36769
|
@@ -0,0 +1,14 @@
|
|
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
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/instance')
|
4
|
+
|
5
|
+
module ConDuxml
|
6
|
+
# XML object array
|
7
|
+
# represents a pattern of copies of a this object's children or referents
|
8
|
+
# differentiates between copies using iterator Parameter
|
9
|
+
module Array
|
10
|
+
include Instance
|
11
|
+
include Enumerable
|
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)
|
16
|
+
size_expr = size.respond_to?(:to_i) ? size.to_i : size.to_s
|
17
|
+
if size_expr.is_a? Fixnum
|
18
|
+
iterator_index = 0
|
19
|
+
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
|
30
|
+
end
|
31
|
+
new_children
|
32
|
+
else
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
end # def instantiate
|
36
|
+
|
37
|
+
# size can be Fixnum or a Parameter expression
|
38
|
+
def size
|
39
|
+
self[:size]
|
40
|
+
end
|
41
|
+
|
42
|
+
# overriding #each to only traverse children and return self on completion, not Enumerator
|
43
|
+
def each &block
|
44
|
+
@children.each &block
|
45
|
+
self
|
46
|
+
end
|
47
|
+
end # class Array
|
48
|
+
end # module Dux
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
module ConDuxml
|
4
|
+
# Instances are copies of another XML element with a distinct set of parameter values
|
5
|
+
# like Objects in relation to a Class
|
6
|
+
module Instance
|
7
|
+
def ref=(target)
|
8
|
+
raise Exception unless target.respond_to?(:nodes)
|
9
|
+
@ref = target
|
10
|
+
end
|
11
|
+
|
12
|
+
def resolve_ref(attr=nil)
|
13
|
+
@ref ||= self[attr || :ref]
|
14
|
+
end
|
15
|
+
|
16
|
+
# creates copy of referent (found from context given by 'meta') at this element's location
|
17
|
+
def instantiate
|
18
|
+
new_kids = []
|
19
|
+
target = resolve_ref
|
20
|
+
if target.nil?
|
21
|
+
new_kids = nodes
|
22
|
+
else
|
23
|
+
new_kids << target.clone
|
24
|
+
end
|
25
|
+
new_kids
|
26
|
+
end # def instantiate
|
27
|
+
end # module Instance
|
28
|
+
|
29
|
+
class InstanceClass
|
30
|
+
include Instance
|
31
|
+
end
|
32
|
+
end # module Dux
|
@@ -0,0 +1,33 @@
|
|
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
|
@@ -0,0 +1,13 @@
|
|
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
|
@@ -0,0 +1,30 @@
|
|
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
|
@@ -0,0 +1,114 @@
|
|
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
ADDED
@@ -0,0 +1,40 @@
|
|
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
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'duxml'
|
2
|
+
require_relative '../con_dux/tabulable'
|
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
|
8
|
+
|
9
|
+
# @param &block [Block] calls Enumerable#chunk on this element's nodes to group them by result of &block
|
10
|
+
# @return [Element] a duplicate element of this node initialized with each subset's nodes
|
11
|
+
def split(&block)
|
12
|
+
chunks = nodes.chunk(&block)
|
13
|
+
chunks.collect do |type, nodes|
|
14
|
+
self.class.new(name, nodes)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# @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
|
19
|
+
# @param &block [block] groups nodes by &block then merges each group into a single row @see #chunk
|
20
|
+
def merge(pattern=nil, &block)
|
21
|
+
self_clone = self.clone
|
22
|
+
self_clone.nodes = []
|
23
|
+
chunks = block_given? ? nodes.chunk(&block) : [nil, nodes.dup]
|
24
|
+
chunks.each do |type, chunk|
|
25
|
+
if chunk.size == 1
|
26
|
+
self_clone.nodes << chunk.first
|
27
|
+
next
|
28
|
+
end
|
29
|
+
|
30
|
+
merged_args, homogeneous = diff_attrs(chunk, pattern)
|
31
|
+
if homogeneous
|
32
|
+
self_clone.nodes << chunk.first.class.new(chunk.first.name, merged_args)
|
33
|
+
else
|
34
|
+
self_clone << chunk
|
35
|
+
end
|
36
|
+
end # chunks.each do |type, nodes|
|
37
|
+
self_clone
|
38
|
+
end # def merge(pattern, &block)
|
39
|
+
|
40
|
+
private
|
41
|
+
def diff_attrs(chunk, pattern)
|
42
|
+
homogeneous = true
|
43
|
+
merged_args = {}
|
44
|
+
chunk.each do |node|
|
45
|
+
node.attributes.each do |attr, val|
|
46
|
+
case
|
47
|
+
when pattern && pattern.is_a?(Hash)
|
48
|
+
pattern.each do |k,v|
|
49
|
+
if attr.match(k.to_s).to_s == attr
|
50
|
+
merged_args[k] = v
|
51
|
+
else
|
52
|
+
merged_args[attr] ||= val
|
53
|
+
end
|
54
|
+
end
|
55
|
+
when pattern && pattern.is_a?(Array)
|
56
|
+
pattern.each do |p|
|
57
|
+
merged_args.merge! diff_attrs(chunk, p) if matches?(attr, p)
|
58
|
+
end
|
59
|
+
when pattern && matches?(attr, pattern) then merged_args[attr] ||= val
|
60
|
+
when pattern && !matches?(attr, pattern) then merged_args[attr] ||= val
|
61
|
+
when chunk.any? do |n| val != n[attr] end then homogeneous = false; next
|
62
|
+
else
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
return merged_args, homogeneous
|
67
|
+
end
|
68
|
+
|
69
|
+
# TODO add !pattern or at least rewrite to work with XML
|
70
|
+
def matches?(attr, pattern)
|
71
|
+
var = attr.to_s[0] == '@' ? attr.to_s[1..-1] : attr.to_s
|
72
|
+
pattern = pattern.keys.collect do |k| k.to_s end if pattern.is_a?(Hash)
|
73
|
+
var=='nodes' || pattern && var.match(pattern.to_s).to_s == var
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: con_duxml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Kong
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: duxml
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
- peter.kong@nxp.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
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
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.9.3
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.8.11
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.0.14.1
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: Construct Universal XML
|
68
|
+
test_files: []
|