requidef 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +22 -4
- data/bin/Makefile +11 -6
- data/bin/requidef +11 -2
- data/bin/requidef.rb +11 -2
- data/bin/sample.rd +9 -4
- data/bin/sample2.rd +2 -0
- data/lib/generic/tree.rb +7 -0
- data/lib/rd2rdnodes.rb +36 -4
- data/lib/rdtree.rb +120 -1
- data/lib/rdtree2dot.rb +2 -34
- metadata +24 -11
data/ChangeLog.md
CHANGED
@@ -1,14 +1,32 @@
|
|
1
|
-
#
|
1
|
+
# ChangeLog
|
2
|
+
ChangeLogs for Milestones.
|
3
|
+
|
4
|
+
## Version 0.1.0 (Aug. 21, 2011)
|
2
5
|
The consequence of 10H rapid developement.
|
3
6
|
It had many bugs so we could not use the command after 'gem install'ing.
|
4
7
|
|
5
|
-
|
6
|
-
(Below describes the future which is not happened still.)
|
7
|
-
|
8
|
+
## Version 0.2.0 (Aug. 22, 2011)
|
8
9
|
We found that the .rd file is not as easy to edit as we had expected.
|
9
10
|
So we decided to edit file in XMind, a free MindMap tool, export it to HTML to translate to .rd file.
|
10
11
|
Other features,
|
12
|
+
|
11
13
|
* The commandline I/F is changed.
|
12
14
|
* Fixed the flashed bugs in 0.1.0.
|
13
15
|
* Provides some converter functionality.
|
14
16
|
* It is now ready to get started by just gem installing.
|
17
|
+
|
18
|
+
## Version 0.3.0 (Forecast)
|
19
|
+
* Add more format to translate (TGF, GML, ..).
|
20
|
+
* Parser Enhancement (Hopefully all but few would be eliminated).
|
21
|
+
Comment Out,
|
22
|
+
Line Breaking,
|
23
|
+
Empty Line,
|
24
|
+
[[tagname]] -> [[tagname:tagname]] for DRY.
|
25
|
+
* Not all the (>>dest) does not have the real destination. Even in that case, works fine.
|
26
|
+
Imagine if all the link must have definitly the real desitination. What could be happened?
|
27
|
+
* Code Clean
|
28
|
+
Testing will be automated so that the future development will be saved.
|
29
|
+
* Design Issue
|
30
|
+
rationalize! method in rdtree is quite wierd. fix it or not.
|
31
|
+
|
32
|
+
|
data/bin/Makefile
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
-
sample :
|
1
|
+
sample : rd_sample mm_sample csv_sample rd_composition_sample
|
2
2
|
|
3
|
-
|
4
|
-
cat sample.
|
5
|
-
|
3
|
+
rd_sample :
|
4
|
+
cat sample.rd | requidef --parse-lenient --from=rd --to=dot | dot -Tjpg -o rd.jpg
|
5
|
+
|
6
|
+
rd_composition_sample :
|
7
|
+
cat sample.rd sample2.rd | requidef --parse-lenient --from=rd --to=dot | dot -Tjpg -o rd_composition.jpg
|
8
|
+
|
9
|
+
mm_sample :
|
10
|
+
cat sample.mm | requidef --from=mm --to=rd | requidef --from=rd --to=dot | dot -Tjpg -o mm.jpg
|
6
11
|
|
7
12
|
csv_sample :
|
8
|
-
cat sample.html | requidef --from=html --to=rd | requidef --from=rd --to=csv >
|
13
|
+
cat sample.html | requidef --from=html --to=rd | requidef --from=rd --to=csv > html.csv
|
9
14
|
|
10
15
|
clean_sample :
|
11
|
-
rm
|
16
|
+
rm rd.jpg mm.jpg html.csv rd_composition.jpg
|
12
17
|
|
data/bin/requidef
CHANGED
@@ -21,16 +21,25 @@ opt.on("--from=FromType") do |v|
|
|
21
21
|
from = v
|
22
22
|
end
|
23
23
|
|
24
|
+
opt.on("--parse-lenient", "parse all text nodes as link nodes.") do |v|
|
25
|
+
# NOTE: Design Issue
|
26
|
+
# This uses global env table. If Ruby process has its own table, use it instead.
|
27
|
+
ENV["REQUIDEF_PARSE_LENIENT"] = "true"
|
28
|
+
end
|
29
|
+
|
24
30
|
opt.parse!(ARGV)
|
25
31
|
|
26
32
|
def usage_msg
|
27
|
-
"""
|
28
|
-
Usage:
|
33
|
+
"""Usage:
|
29
34
|
requidef supports translations from one file format to another one.
|
30
35
|
You usually first create standard input and pipe it to requidef command and continue piping.
|
31
36
|
|
32
37
|
Clear Example,
|
33
38
|
cat input.mm | requidef --from=mm --to=rd | requidef --from=rd --to=dot > output.dot
|
39
|
+
|
40
|
+
For more details, see help.
|
41
|
+
|
42
|
+
Enjoy!
|
34
43
|
"""
|
35
44
|
end
|
36
45
|
|
data/bin/requidef.rb
CHANGED
@@ -21,16 +21,25 @@ opt.on("--from=FromType") do |v|
|
|
21
21
|
from = v
|
22
22
|
end
|
23
23
|
|
24
|
+
opt.on("--parse-lenient", "parse all text nodes as link nodes.") do |v|
|
25
|
+
# NOTE: Design Issue
|
26
|
+
# This uses global env table. If Ruby process has its own table, use it instead.
|
27
|
+
ENV["REQUIDEF_PARSE_LENIENT"] = "true"
|
28
|
+
end
|
29
|
+
|
24
30
|
opt.parse!(ARGV)
|
25
31
|
|
26
32
|
def usage_msg
|
27
|
-
"""
|
28
|
-
Usage:
|
33
|
+
"""Usage:
|
29
34
|
requidef supports translations from one file format to another one.
|
30
35
|
You usually first create standard input and pipe it to requidef command and continue piping.
|
31
36
|
|
32
37
|
Clear Example,
|
33
38
|
cat input.mm | requidef --from=mm --to=rd | requidef --from=rd --to=dot > output.dot
|
39
|
+
|
40
|
+
For more details, see help.
|
41
|
+
|
42
|
+
Enjoy!
|
34
43
|
"""
|
35
44
|
end
|
36
45
|
|
data/bin/sample.rd
CHANGED
data/bin/sample2.rd
ADDED
data/lib/generic/tree.rb
CHANGED
@@ -49,6 +49,13 @@ class Tree
|
|
49
49
|
@values[id] = value
|
50
50
|
end
|
51
51
|
|
52
|
+
def update_value(id, value)
|
53
|
+
# In current version,
|
54
|
+
# update_value is just a wrapper of add_node.
|
55
|
+
# but in future version, this may need modification.
|
56
|
+
add_node(id, value)
|
57
|
+
end
|
58
|
+
|
52
59
|
def add_edge(from, to)
|
53
60
|
register_edge(from, to)
|
54
61
|
register_parent(to, from)
|
data/lib/rd2rdnodes.rb
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
require_relative "rdnode"
|
2
2
|
|
3
|
+
def rd2lines(rd)
|
4
|
+
all_lines = rd.split("\n")
|
5
|
+
all_lines
|
6
|
+
.delete_if do |line|
|
7
|
+
line.empty?
|
8
|
+
end
|
9
|
+
.delete_if do |line|
|
10
|
+
line.start_with? "//"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
3
14
|
def rd2rdnodes( rd)
|
4
|
-
lines = rd
|
15
|
+
lines = rd2lines(rd)
|
5
16
|
nodes = lines2nodes(lines)
|
6
17
|
nodes
|
7
18
|
end
|
@@ -19,6 +30,10 @@ def lines2nodes(lines)
|
|
19
30
|
xs
|
20
31
|
end
|
21
32
|
|
33
|
+
def parse_lenient?
|
34
|
+
ENV["REQUIDEF_PARSE_LENIENT"] == "true"
|
35
|
+
end
|
36
|
+
|
22
37
|
# Example,
|
23
38
|
# --- aaa => Text(3, "aaa")
|
24
39
|
# -- >>bbb => Link(2, "bbb")
|
@@ -35,22 +50,39 @@ def line2node(line)
|
|
35
50
|
ss = parse_tag(rest)
|
36
51
|
return Tag.new(depth, ss[0], ss[1])
|
37
52
|
else
|
53
|
+
# NOTE: Design Issue
|
54
|
+
# If REQUIDEF_PARSE_LENIENT flag is on,
|
55
|
+
# This software understands every text nodes as link nodes whose dest is text.
|
56
|
+
if parse_lenient?
|
57
|
+
$stderr << "parse_lenient? true"
|
58
|
+
ss = parse_text(rest)
|
59
|
+
return Link.new(depth, ss)
|
60
|
+
end
|
38
61
|
ss = parse_text(rest)
|
39
62
|
return Text.new(depth, ss)
|
40
63
|
end
|
41
64
|
end
|
42
65
|
|
43
|
-
# NOTE:
|
66
|
+
# NOTE: Under Engineering
|
44
67
|
def parse_link(s)
|
45
68
|
# Fix: Delete only the first >>
|
46
69
|
s.delete ">>"
|
47
70
|
end
|
48
71
|
|
49
|
-
# NOTE:
|
72
|
+
# NOTE: Under Engineering
|
50
73
|
def parse_tag(s)
|
51
74
|
ss = s.delete("[[").delete("]]")
|
52
75
|
# Fix: What happen if having two colons
|
53
|
-
|
76
|
+
# In current version, if haveing two colons will cause unexpected output or runtime error.
|
77
|
+
xs = ss.split(":")
|
78
|
+
case xs.size
|
79
|
+
when 1
|
80
|
+
return [xs[0], xs[0]]
|
81
|
+
when 2
|
82
|
+
return xs
|
83
|
+
end
|
84
|
+
# In current version, if more than two colons will raise exception.
|
85
|
+
raise "Parse Erorr. The line #{s} contains more than two colons"
|
54
86
|
end
|
55
87
|
|
56
88
|
def parse_text(s)
|
data/lib/rdtree.rb
CHANGED
@@ -4,7 +4,38 @@ require_relative "rdtree2dot"
|
|
4
4
|
|
5
5
|
class Tree
|
6
6
|
|
7
|
+
# NOTE: About Design. In current design,
|
8
|
+
# a link node that can not find the tag node it points to
|
9
|
+
# is treated as text node.
|
10
|
+
def not_found_link2text!
|
11
|
+
list_link_nodes.each do |id|
|
12
|
+
if can_not_find_tag(id)
|
13
|
+
modify_link2text(id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# NOTE: Crazy Design
|
19
|
+
# Akira Hayakawa, Aug 23, 2011
|
20
|
+
# This method must be called wherever it needs the rationalized state.
|
21
|
+
# For exmaple, a Link node that can not find the tag in the tree should be altered to Text node.
|
22
|
+
# But, this is innately a bad design.
|
23
|
+
# Because of my incapable of not coming up with a good idea to solve this issue elegantly.
|
24
|
+
# The version 2.0.2 scattered this method to to_csv and to_dot.
|
25
|
+
# But I do not know if this is sufficient.
|
26
|
+
# To solve this issue theoritically, embed this method into every single mutate methods of the instance mattered.
|
27
|
+
#
|
28
|
+
# If you embed this method, please leave comment "# CRAZY" there
|
29
|
+
# so that you can remove after I find a better solution.
|
30
|
+
#
|
31
|
+
# A solution is to simplify the design that lets every paths through RDTree structure.
|
32
|
+
# Then call rationalize only one time before it is needed, case of conversion for example.
|
33
|
+
def rationalize!
|
34
|
+
not_found_link2text!
|
35
|
+
end
|
36
|
+
|
7
37
|
def to_csv
|
38
|
+
rationalize! # CRAZY
|
8
39
|
m = tree2matrix(self)
|
9
40
|
|
10
41
|
range = [
|
@@ -21,11 +52,99 @@ class Tree
|
|
21
52
|
end
|
22
53
|
c
|
23
54
|
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def modify_link2text(id)
|
59
|
+
linknode = value(id)
|
60
|
+
textnode = link2text(linknode)
|
61
|
+
update_value(id, textnode)
|
62
|
+
end
|
63
|
+
|
64
|
+
# NOTE: Maybe Under-Engineering.
|
65
|
+
# id of node, tmp field are not copied but
|
66
|
+
# this time, I decided not because I considered unnessessary.
|
67
|
+
def link2text(linknode)
|
68
|
+
depth = linknode.depth
|
69
|
+
text = linknode.dest
|
70
|
+
Text.new(depth, text)
|
71
|
+
end
|
72
|
+
|
73
|
+
# NOTE: Performance Issue
|
74
|
+
# The following methods call mk_xxx method
|
75
|
+
# everytime they need the information.
|
76
|
+
# Current version adopts lazy evaluation technique
|
77
|
+
# to always keep the state of RDTree new.
|
78
|
+
#
|
79
|
+
# Now, my consideration is this is OK.
|
80
|
+
# Because the mk_xxx functions have complexity of O(N)
|
81
|
+
# where N is the number of nodes in the tree.
|
82
|
+
# Therefore, for small input, the performance will not
|
83
|
+
# go too bad.
|
84
|
+
#
|
85
|
+
# If, performance is found bad,
|
86
|
+
# first consider lazy instantiation technique.
|
87
|
+
def list_link_nodes
|
88
|
+
mk_id2tag.keys
|
89
|
+
end
|
90
|
+
|
91
|
+
def can_not_find_tag(id)
|
92
|
+
tag = mk_id2tag[id]
|
93
|
+
! mk_tag2id.include? tag
|
94
|
+
end
|
95
|
+
|
96
|
+
def link_node?(id)
|
97
|
+
n = value(id)
|
98
|
+
n.class == Link
|
99
|
+
end
|
100
|
+
|
101
|
+
def mk_linkmap
|
102
|
+
# NOTE: is this use of warn method correct?
|
103
|
+
warn "Warning: mk_linkmap should not be used. mk_id2id instead."
|
104
|
+
mk_id2id
|
105
|
+
end
|
106
|
+
|
107
|
+
def mk_id2id
|
108
|
+
id2tag = mk_id2tag
|
109
|
+
tag2id = mk_tag2id
|
110
|
+
id2id = {}
|
111
|
+
id2tag.keys.each do |id|
|
112
|
+
tag = id2tag[id]
|
113
|
+
if tag2id.include?( tag)
|
114
|
+
id2id[id] = tag2id[tag]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
id2id
|
118
|
+
end
|
119
|
+
|
120
|
+
def mk_tag2id
|
121
|
+
tag2id = {}
|
122
|
+
for i in 0...size
|
123
|
+
n = value(i)
|
124
|
+
if n.class == Tag
|
125
|
+
tag2id[n.tag] = i
|
126
|
+
end
|
127
|
+
end
|
128
|
+
tag2id
|
129
|
+
end
|
130
|
+
|
131
|
+
def mk_id2tag
|
132
|
+
id2tag = {}
|
133
|
+
for i in 0...size
|
134
|
+
n = value(i)
|
135
|
+
if n.class == Link
|
136
|
+
id2tag[i] = n.dest
|
137
|
+
end
|
138
|
+
end
|
139
|
+
id2tag
|
140
|
+
end
|
24
141
|
end
|
25
142
|
|
26
143
|
require_relative "rd2rdtree"
|
27
144
|
if __FILE__ == $0
|
28
145
|
t = rd2rdtree( File.read("sample.rd"))
|
29
|
-
|
146
|
+
t.not_found_link2text!
|
147
|
+
# p t
|
148
|
+
# puts t.to_csv
|
30
149
|
puts t.to_dot
|
31
150
|
end
|
data/lib/rdtree2dot.rb
CHANGED
@@ -3,13 +3,14 @@ require_relative "generic/tree"
|
|
3
3
|
class Tree
|
4
4
|
|
5
5
|
def to_dot
|
6
|
+
rationalize! # CRAZY
|
6
7
|
elems = []
|
7
8
|
for i in 0...size
|
8
9
|
unless link_node?(i)
|
9
10
|
elems << dot_node_desc(i)
|
10
11
|
end
|
11
12
|
end
|
12
|
-
linkmap =
|
13
|
+
linkmap = mk_id2id
|
13
14
|
for i in 0...size
|
14
15
|
if link_node?(i)
|
15
16
|
to = linkmap[i]
|
@@ -43,37 +44,4 @@ private
|
|
43
44
|
def dot_edge_desc(from, to)
|
44
45
|
"v#{from} -> v#{to};"
|
45
46
|
end
|
46
|
-
|
47
|
-
def link_node?(id)
|
48
|
-
n = value(id)
|
49
|
-
n.class == Link
|
50
|
-
end
|
51
|
-
|
52
|
-
def mk_tag2id
|
53
|
-
tag2id = {}
|
54
|
-
for i in 0...size
|
55
|
-
n = value(i)
|
56
|
-
if n.class == Tag
|
57
|
-
tag2id[n.tag] = i
|
58
|
-
end
|
59
|
-
end
|
60
|
-
tag2id
|
61
|
-
end
|
62
|
-
|
63
|
-
def mk_linkmap
|
64
|
-
id2tag = {}
|
65
|
-
for i in 0...size
|
66
|
-
n = value(i)
|
67
|
-
if n.class == Link
|
68
|
-
id2tag[i] = n.dest
|
69
|
-
end
|
70
|
-
end
|
71
|
-
id2id = {}
|
72
|
-
tag2id = mk_tag2id
|
73
|
-
id2tag.keys.each do |key|
|
74
|
-
tag = id2tag[key]
|
75
|
-
id2id[key] = tag2id[tag]
|
76
|
-
end
|
77
|
-
id2id
|
78
|
-
end
|
79
47
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: requidef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-08-
|
12
|
+
date: 2011-08-23 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &28184820 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.3.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *28184820
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bundler
|
27
|
-
requirement: &
|
27
|
+
requirement: &28184340 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.0.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *28184340
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jeweler
|
38
|
-
requirement: &
|
38
|
+
requirement: &28183860 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.6.4
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *28183860
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rcov
|
49
|
-
requirement: &
|
49
|
+
requirement: &28183380 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,18 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *28183380
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: hpricot
|
60
|
+
requirement: &28182900 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.8.4
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *28182900
|
58
69
|
description: Which do you use for your requirement definition job? MS Excel? MS Word?
|
59
70
|
Uninstall them. Because you will get a better solution.
|
60
71
|
email: ruby.wktk@gmail.com
|
@@ -65,6 +76,7 @@ executables:
|
|
65
76
|
- sample.html
|
66
77
|
- sample.mm
|
67
78
|
- sample.rd
|
79
|
+
- sample2.rd
|
68
80
|
extensions: []
|
69
81
|
extra_rdoc_files:
|
70
82
|
- ChangeLog.md
|
@@ -95,6 +107,7 @@ files:
|
|
95
107
|
- bin/sample.html
|
96
108
|
- bin/sample.mm
|
97
109
|
- bin/sample.rd
|
110
|
+
- bin/sample2.rd
|
98
111
|
homepage: http://github.com/akiradeveloper/requidef
|
99
112
|
licenses:
|
100
113
|
- MIT
|
@@ -110,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
123
|
version: '0'
|
111
124
|
segments:
|
112
125
|
- 0
|
113
|
-
hash:
|
126
|
+
hash: 226265604659266124
|
114
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
128
|
none: false
|
116
129
|
requirements:
|