ucd 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/TODO.md +79 -0
- data/VERSION +1 -1
- data/examples/composite.dot +2 -2
- data/examples/composite.png +0 -0
- data/examples/composite.ucd +1 -1
- data/examples/generic.dot +1 -1
- data/examples/relationships.dot +111 -0
- data/examples/relationships.png +0 -0
- data/examples/relationships.ucd +15 -0
- data/lib/ucd.rb +1 -0
- data/lib/ucd/attribute_parser.rb +46 -0
- data/lib/ucd/formatter/graphviz.rb +30 -23
- data/lib/ucd/interface/command_line.rb +83 -46
- data/lib/ucd/parser.rb +2 -2
- metadata +6 -3
- data/examples/composite - minimal.ucd +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51f6cac1d8dcdafd6a3eb3ea5a6bff3de73d9f01
|
4
|
+
data.tar.gz: cf78554c75c52b667d85f53736532c72dbad7b83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc0fac2e3548521b2caf6029570af69c61c80ef976825966a45f744d62f83725ae41e7a553974de8a854becfc1b5355cef7787f62ecd24e8c880f79ca27a215c
|
7
|
+
data.tar.gz: 5241b9c7058b17535f35a0c6827240451c840cb0058b87752ab8a5613898c2fb13b15ea93bd33b8e6a03fc29a818001f09a9376c08596f767d5c2d185c35ce2a
|
data/TODO.md
CHANGED
@@ -2,3 +2,82 @@
|
|
2
2
|
|
3
3
|
* Atom, VIM, etc color schemes/snippets
|
4
4
|
* Use https://github.com/glejeune/Ruby-Graphviz
|
5
|
+
* "interface class" feels weird.
|
6
|
+
* Pass multiple types:
|
7
|
+
ucd examples/alias.ucd -o examples -t png,dot,svg
|
8
|
+
* Reopen class:
|
9
|
+
class Foo {
|
10
|
+
field name: String
|
11
|
+
}
|
12
|
+
class Foo {
|
13
|
+
field email: String
|
14
|
+
}
|
15
|
+
* Define outside class:
|
16
|
+
class Foo
|
17
|
+
interface class Bar
|
18
|
+
Foo field name : String
|
19
|
+
Foo realizes Bar
|
20
|
+
* Auto define missing classes
|
21
|
+
* Empty classes
|
22
|
+
Right now: class A {}
|
23
|
+
TODO: class A
|
24
|
+
* Pass formatter arguments to formatter
|
25
|
+
Graphviz: Graph, node, edge attributes..
|
26
|
+
* System and user config files, mostly for formatter default settings
|
27
|
+
* Comments
|
28
|
+
* Support all 3 styles: #, //, /* ... \*/
|
29
|
+
* Pros
|
30
|
+
* Users can guess and always be correct
|
31
|
+
* Cons
|
32
|
+
* Looks messy
|
33
|
+
* More complex parser definition
|
34
|
+
* Option to add relationship's fields and methods (Not class relationships)
|
35
|
+
* class Animal {
|
36
|
+
field name : String
|
37
|
+
}
|
38
|
+
|
39
|
+
class Dog {
|
40
|
+
method bark
|
41
|
+
|
42
|
+
generalizes Animal
|
43
|
+
}
|
44
|
+
|
45
|
+
dog.methods => [:name, :bark]
|
46
|
+
|
47
|
+
* Aliases?
|
48
|
+
* Pros
|
49
|
+
* Less to type
|
50
|
+
* Cons
|
51
|
+
* No autocomplete for defined aliases in editors
|
52
|
+
* Examples
|
53
|
+
* alias name_field as field name : String
|
54
|
+
|
55
|
+
class Cat {
|
56
|
+
name_field
|
57
|
+
}
|
58
|
+
|
59
|
+
class Dog {
|
60
|
+
name_field
|
61
|
+
}
|
62
|
+
* Macros?
|
63
|
+
|
64
|
+
* Examples
|
65
|
+
* macro has_many(name, type) {
|
66
|
+
field {{name}} : Array({{type}})
|
67
|
+
|
68
|
+
aggregation {{type}} {{name}} *
|
69
|
+
}
|
70
|
+
|
71
|
+
class Dog {
|
72
|
+
has_many toys, Toy
|
73
|
+
}
|
74
|
+
|
75
|
+
# Same as:
|
76
|
+
# class Dog {
|
77
|
+
# field toys : Array(Toy)
|
78
|
+
#
|
79
|
+
# aggregation Toy toys *
|
80
|
+
# }
|
81
|
+
|
82
|
+
class Toy {
|
83
|
+
}
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/examples/composite.dot
CHANGED
@@ -62,5 +62,5 @@ digraph G {
|
|
62
62
|
ClassLeaf -> ClassComponent [arrowhead="onormal"]
|
63
63
|
ClassComposite -> ClassComponent [arrowhead="onormal"]
|
64
64
|
|
65
|
-
ClassComposite -> ClassComponent [dir="back"
|
66
|
-
}
|
65
|
+
ClassComposite -> ClassComponent [dir="back" taillabel="1" headlabel="*" arrowtail="odiamond"]
|
66
|
+
}
|
data/examples/composite.png
CHANGED
Binary file
|
data/examples/composite.ucd
CHANGED
data/examples/generic.dot
CHANGED
@@ -0,0 +1,111 @@
|
|
1
|
+
digraph G {
|
2
|
+
graph [splines="ortho" rankdir="BT"]
|
3
|
+
edge [color="gray50"]
|
4
|
+
node [shape="plain"]
|
5
|
+
|
6
|
+
ClassNode [label=<
|
7
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
8
|
+
<TR>
|
9
|
+
<TD><B>Node</B></TD>
|
10
|
+
</TR>
|
11
|
+
<TR>
|
12
|
+
<TD></TD>
|
13
|
+
</TR>
|
14
|
+
<TR>
|
15
|
+
<TD></TD>
|
16
|
+
</TR>
|
17
|
+
</TABLE>
|
18
|
+
>]
|
19
|
+
|
20
|
+
ClassA [label=<
|
21
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
22
|
+
<TR>
|
23
|
+
<TD><B>A</B></TD>
|
24
|
+
</TR>
|
25
|
+
<TR>
|
26
|
+
<TD></TD>
|
27
|
+
</TR>
|
28
|
+
<TR>
|
29
|
+
<TD></TD>
|
30
|
+
</TR>
|
31
|
+
</TABLE>
|
32
|
+
>]
|
33
|
+
|
34
|
+
ClassB [label=<
|
35
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
36
|
+
<TR>
|
37
|
+
<TD><B>B</B></TD>
|
38
|
+
</TR>
|
39
|
+
<TR>
|
40
|
+
<TD></TD>
|
41
|
+
</TR>
|
42
|
+
<TR>
|
43
|
+
<TD></TD>
|
44
|
+
</TR>
|
45
|
+
</TABLE>
|
46
|
+
>]
|
47
|
+
|
48
|
+
ClassC [label=<
|
49
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
50
|
+
<TR>
|
51
|
+
<TD><B>C</B></TD>
|
52
|
+
</TR>
|
53
|
+
<TR>
|
54
|
+
<TD></TD>
|
55
|
+
</TR>
|
56
|
+
<TR>
|
57
|
+
<TD></TD>
|
58
|
+
</TR>
|
59
|
+
</TABLE>
|
60
|
+
>]
|
61
|
+
|
62
|
+
ClassD [label=<
|
63
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
64
|
+
<TR>
|
65
|
+
<TD><B>D</B></TD>
|
66
|
+
</TR>
|
67
|
+
<TR>
|
68
|
+
<TD></TD>
|
69
|
+
</TR>
|
70
|
+
<TR>
|
71
|
+
<TD></TD>
|
72
|
+
</TR>
|
73
|
+
</TABLE>
|
74
|
+
>]
|
75
|
+
|
76
|
+
ClassE [label=<
|
77
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
78
|
+
<TR>
|
79
|
+
<TD><B>E</B></TD>
|
80
|
+
</TR>
|
81
|
+
<TR>
|
82
|
+
<TD></TD>
|
83
|
+
</TR>
|
84
|
+
<TR>
|
85
|
+
<TD></TD>
|
86
|
+
</TR>
|
87
|
+
</TABLE>
|
88
|
+
>]
|
89
|
+
|
90
|
+
ClassF [label=<
|
91
|
+
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
|
92
|
+
<TR>
|
93
|
+
<TD><B>F</B></TD>
|
94
|
+
</TR>
|
95
|
+
<TR>
|
96
|
+
<TD></TD>
|
97
|
+
</TR>
|
98
|
+
<TR>
|
99
|
+
<TD></TD>
|
100
|
+
</TR>
|
101
|
+
</TABLE>
|
102
|
+
>]
|
103
|
+
|
104
|
+
ClassNode -> ClassA [arrowhead="onormal" style="dashed"]
|
105
|
+
ClassNode -> ClassB [arrowhead="onormal"]
|
106
|
+
|
107
|
+
ClassNode -> ClassC [style="dashed"]
|
108
|
+
ClassNode -> ClassD
|
109
|
+
ClassNode -> ClassE [dir="back" arrowtail="odiamond"]
|
110
|
+
ClassNode -> ClassF [dir="back" arrowtail="diamond"]
|
111
|
+
}
|
Binary file
|
data/lib/ucd.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "parslet"
|
2
|
+
|
3
|
+
module UCD
|
4
|
+
class AttributeParser < Parslet::Parser
|
5
|
+
|
6
|
+
class Transform < Parslet::Transform
|
7
|
+
rule(:integer => simple(:x)) { Integer(x) }
|
8
|
+
rule(:float => simple(:x)) { Float(x) }
|
9
|
+
rule(:string => simple(:x)) { String(x) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.parse(io, options={})
|
13
|
+
new.parse(io, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(io, options={})
|
17
|
+
tree = Transform.new.apply(super)
|
18
|
+
tree = tree[:assignments].each_with_object({}) { |assignment, memo| memo[assignment[:name].to_s] = assignment[:value] }
|
19
|
+
|
20
|
+
tree
|
21
|
+
end
|
22
|
+
|
23
|
+
rule(:spaces) { match("\s").repeat(1) }
|
24
|
+
rule(:spaces?) { spaces.maybe }
|
25
|
+
|
26
|
+
rule(:digits) { match["0-9"].repeat(1) }
|
27
|
+
|
28
|
+
rule(:integer) { (str("-").maybe >> digits >> str(".").absent?).as(:integer) }
|
29
|
+
rule(:float) { (str("-").maybe >> digits >> str(".") >> digits).as(:float) }
|
30
|
+
|
31
|
+
rule(:string_single_quoted) { str(%q{'}) >> (str(%q{'}).absent? >> any).repeat.as(:string) >> str(%q{'}) }
|
32
|
+
rule(:string_double_quoted) { str(%q{"}) >> (str(%q{"}).absent? >> any).repeat.as(:string) >> str(%q{"}) }
|
33
|
+
|
34
|
+
rule(:string) { string_single_quoted | string_double_quoted }
|
35
|
+
|
36
|
+
rule(:assignment_name) { (match["=\s"].absent? >> any).repeat.as(:name) }
|
37
|
+
rule(:assignment_value) { (integer | float | string).as(:value) }
|
38
|
+
rule(:assignment) { assignment_name >> spaces? >> str("=") >> spaces? >> assignment_value }
|
39
|
+
|
40
|
+
rule(:attribute) { spaces? >> assignment >> spaces? }
|
41
|
+
rule(:attributes) { (attribute >> (str(",") >> attribute).repeat).repeat.as(:assignments) }
|
42
|
+
|
43
|
+
root(:attributes)
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -22,22 +22,22 @@ module UCD
|
|
22
22
|
def initialize(attributes={})
|
23
23
|
super
|
24
24
|
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@
|
25
|
+
@graph = Attributes.new
|
26
|
+
@graph["splines"] = "ortho"
|
27
|
+
@graph["rankdir"] = "BT"
|
28
28
|
|
29
|
-
@
|
30
|
-
@
|
29
|
+
@edge = Attributes.new
|
30
|
+
@edge["color"] = "gray50"
|
31
31
|
|
32
|
-
@
|
33
|
-
@
|
32
|
+
@node = Attributes.new
|
33
|
+
@node["shape"] = "plain"
|
34
34
|
|
35
35
|
@type = :dot
|
36
36
|
end
|
37
37
|
|
38
|
-
attr_reader :
|
39
|
-
attr_reader :
|
40
|
-
attr_reader :
|
38
|
+
attr_reader :graph
|
39
|
+
attr_reader :edge
|
40
|
+
attr_reader :node
|
41
41
|
|
42
42
|
def type=(value)
|
43
43
|
super
|
@@ -76,23 +76,29 @@ module UCD
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def format_relationship(node)
|
79
|
-
|
80
|
-
arrow = "odiamond" if "aggregation"
|
81
|
-
dir = "back" if %w[aggregation composition].include?(node.type)
|
79
|
+
dir = "back" if %w[aggregation composition].include?(node.type)
|
82
80
|
arrow_key = dir == "back" ? "arrowtail" : "arrowhead"
|
81
|
+
from_key = dir == "back" ? "taillabel" : "headlabel"
|
82
|
+
to_key = dir == "back" ? "headlabel" : "taillabel"
|
83
83
|
|
84
84
|
attributes = Attributes.new
|
85
85
|
|
86
|
-
attributes["style"]
|
87
|
-
attributes["dir"]
|
88
|
-
attributes[
|
89
|
-
attributes[
|
90
|
-
|
86
|
+
attributes["style"] = "dashed" if node.type == "dependency"
|
87
|
+
attributes["dir"] = dir if dir
|
88
|
+
attributes[from_key] = node.from if node.from
|
89
|
+
attributes[to_key] = node.to if node.to
|
90
|
+
|
91
|
+
if %w[aggregation composition].include?(node.type)
|
92
|
+
arrow = "diamond" if node.type == "composition"
|
93
|
+
arrow = "odiamond" if node.type == "aggregation"
|
94
|
+
attributes[arrow_key] = arrow
|
95
|
+
end
|
91
96
|
|
92
97
|
graph_parent_name = generate_graph_name(node.parent.name)
|
93
|
-
graph_node_name
|
98
|
+
graph_node_name = generate_graph_name(node.name)
|
99
|
+
graph_attributes = " [#{attributes}]" unless attributes.empty?
|
94
100
|
|
95
|
-
%Q{Class#{graph_parent_name} -> Class#{graph_node_name}
|
101
|
+
%Q{Class#{graph_parent_name} -> Class#{graph_node_name}#{graph_attributes}}
|
96
102
|
end
|
97
103
|
|
98
104
|
def format_class_relationship(node)
|
@@ -110,6 +116,7 @@ module UCD
|
|
110
116
|
def format_class(node)
|
111
117
|
name = "<B>#{node.name}</B>"
|
112
118
|
name = "«abstract»<BR/><I>#{name}</I>" if node.modifier == "abstract"
|
119
|
+
name = "«interface»<BR/>#{name}" if node.modifier == "interface"
|
113
120
|
|
114
121
|
unless node.fields.empty?
|
115
122
|
field_rows = node.fields.map { |field| %Q{<TR><TD ALIGN="LEFT">#{format_field(field)}</TD></TR>}}
|
@@ -167,9 +174,9 @@ Class#{graph_node_name} [label=<
|
|
167
174
|
|
168
175
|
<<-HEREDOC
|
169
176
|
digraph G {
|
170
|
-
graph [#{@
|
171
|
-
edge [#{@
|
172
|
-
node [#{@
|
177
|
+
graph [#{@graph}]
|
178
|
+
edge [#{@edge}]
|
179
|
+
node [#{@node}]
|
173
180
|
|
174
181
|
#{classes}
|
175
182
|
|
@@ -2,6 +2,7 @@ require "optparse"
|
|
2
2
|
require "pathname"
|
3
3
|
require "ucd/interface/base"
|
4
4
|
require "ucd/parser"
|
5
|
+
require "ucd/attribute_parser"
|
5
6
|
require "ucd/formatter"
|
6
7
|
|
7
8
|
module UCD
|
@@ -12,9 +13,11 @@ module UCD
|
|
12
13
|
class FileError < Error; end
|
13
14
|
|
14
15
|
def initialize(attributes={})
|
15
|
-
@formatter
|
16
|
-
@verbose
|
17
|
-
|
16
|
+
@formatter = Formatter::Graphviz.new
|
17
|
+
@verbose = false
|
18
|
+
@option_parser = OptionParser.new
|
19
|
+
|
20
|
+
setup_parser_options
|
18
21
|
|
19
22
|
super
|
20
23
|
end
|
@@ -36,8 +39,12 @@ module UCD
|
|
36
39
|
end
|
37
40
|
|
38
41
|
def run
|
42
|
+
args = ARGV.dup # TODO: This is hacky
|
43
|
+
@option_parser.parse!(args) rescue nil
|
44
|
+
setup_parser_formatter_options
|
39
45
|
@option_parser.parse!
|
40
|
-
|
46
|
+
|
47
|
+
self.paths = ARGV
|
41
48
|
@formatter.type = @type
|
42
49
|
|
43
50
|
raise Error, "Output path must be a directory if multiple input files are given" if @output_path && @output_path.file? && @paths.length > 1
|
@@ -90,76 +97,106 @@ module UCD
|
|
90
97
|
"\e[0m"
|
91
98
|
end
|
92
99
|
|
93
|
-
def
|
94
|
-
@option_parser =
|
95
|
-
|
96
|
-
|
100
|
+
def setup_parser_options
|
101
|
+
@option_parser.banner = ""
|
102
|
+
@option_parser.on("-f", "--formatter VALUE", "The output formatter (Default: '#{@formatter.name}')") { |value| self.formatter = value }
|
103
|
+
@option_parser.on("-t", "--type VALUE", "The output format type") { |value| @type = value }
|
104
|
+
@option_parser.on("-o", "--output VALUE", "The output path") { |value| self.output_path = value }
|
105
|
+
@option_parser.on("-h", "--help", "Prints this help") do
|
106
|
+
print_help
|
107
|
+
|
108
|
+
exit
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def setup_parser_formatter_options
|
113
|
+
case @formatter.name
|
114
|
+
when :graphviz
|
115
|
+
@option_parser.on("-g", "--graph VALUE") do |value|
|
116
|
+
AttributeParser.parse(value).each { |key, value| @formatter.graph[key] = value }
|
117
|
+
end
|
118
|
+
|
119
|
+
@option_parser.on("-e", "--edge VALUE") do |value|
|
120
|
+
AttributeParser.parse(value).each { |key, value| @formatter.edge[key] = value }
|
121
|
+
end
|
122
|
+
|
123
|
+
@option_parser.on("-n", "--node VALUE") do |value|
|
124
|
+
AttributeParser.parse(value).each { |key, value| @formatter.node[key] = value }
|
125
|
+
end
|
97
126
|
|
98
|
-
|
127
|
+
@option_parser.on("-a", "--all VALUE") do |value|
|
128
|
+
AttributeParser.parse(value).each do |key, value|
|
129
|
+
@formatter.graph[key] = value
|
130
|
+
@formatter.edge[key] = value
|
131
|
+
@formatter.node[key] = value
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
99
136
|
|
100
|
-
|
137
|
+
def print_help
|
138
|
+
puts <<~HELP
|
139
|
+
#{text_bold("Usage:")} ucd [options] PATHS
|
101
140
|
|
102
|
-
|
141
|
+
#{text_bold("Overview:")} Generate output from UML Class Diagram language files
|
103
142
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
parser.on("-h", "--help", "Prints this help") do
|
108
|
-
puts parser
|
109
|
-
puts <<~HELP
|
143
|
+
#{text_bold("Options:")}
|
144
|
+
#{@option_parser}
|
145
|
+
#{text_bold("Paths:")}
|
110
146
|
|
111
|
-
|
147
|
+
UCD can accept multiple paths for parsing for easier batch processing.
|
112
148
|
|
113
|
-
|
149
|
+
The location of the output by default is standard output.
|
114
150
|
|
115
|
-
|
151
|
+
The output can be directed to a path with #{text_bold_italic("--output")}, which can be a file or a directory.
|
152
|
+
If the output path is a directory, then the filename will be the same as the input filename,
|
153
|
+
with it's file extension substituted with the #{text_bold_italic("--type")}.
|
116
154
|
|
117
|
-
|
118
|
-
If the output path is a directory, then the filename will be the same as the input filename,
|
119
|
-
with it's file extension substituted with the #{text_bold_italic("--type")}.
|
155
|
+
#{text_underline("Examples")}
|
120
156
|
|
121
|
-
|
157
|
+
`ucd project.ucd`
|
122
158
|
|
123
|
-
|
159
|
+
Produces DOT notation, sent to standard output
|
124
160
|
|
125
|
-
|
161
|
+
`ucd -o . project.ucd`
|
126
162
|
|
127
|
-
|
163
|
+
Produces DOT notation, written to #{text_italic("./project.dot")}
|
128
164
|
|
129
|
-
|
165
|
+
`ucd -o ./diagram.dot project.ucd`
|
130
166
|
|
131
|
-
|
167
|
+
Produces DOT notation, written to #{text_italic("./diagram.dot")}
|
132
168
|
|
133
|
-
|
169
|
+
`ucd -o ./diagram.png project.ucd`
|
134
170
|
|
135
|
-
|
171
|
+
Produces PNG image, written to #{text_italic("./diagram.png")}
|
136
172
|
|
137
|
-
|
173
|
+
`ucd -t png -o . project.ucd`
|
138
174
|
|
139
|
-
|
175
|
+
Produces PNG image, written to #{text_italic("./project.png")}
|
140
176
|
|
141
|
-
|
177
|
+
`ucd -t png -o . project.ucd core_ext.ucd`
|
142
178
|
|
143
|
-
|
179
|
+
Produces PNG images, written to #{text_italic("./project.png")} and #{text_italic("./core_ext.png")}
|
144
180
|
|
145
|
-
|
181
|
+
#{text_bold("Formatters:")}
|
146
182
|
|
147
|
-
#{
|
183
|
+
#{text_underline("Graphviz")}
|
148
184
|
|
149
|
-
|
185
|
+
Generates DOT notation and can use the DOT notation to generate any format Graphviz can produce.
|
150
186
|
|
151
|
-
|
187
|
+
The output format is based on #{text_bold_italic("--type")}, which by default is "dot".
|
188
|
+
If #{text_bold_italic("--type")} is not given and #{text_bold_italic("--output")} is, the file extension of the #{text_bold_italic("--output")} path will be used.
|
152
189
|
|
153
|
-
|
154
|
-
If #{text_bold_italic("--type")} is not given and #{text_bold_italic("--output")} is, the file extension of the #{text_bold_italic("--output")} path will be used.
|
190
|
+
Valid types/extensions are: #{Formatter::Graphviz::VALID_TYPES.join(", ")}
|
155
191
|
|
156
|
-
|
192
|
+
#{text_bold("Options:")}
|
157
193
|
|
158
|
-
|
194
|
+
-g, --graph VALUE The graph attributes
|
195
|
+
-e, --edge VALUE The edge attributes
|
196
|
+
-n, --node VALUE The node attributes
|
197
|
+
-a, --all VALUE Set attributes for graph, edge, and node
|
159
198
|
|
160
|
-
|
161
|
-
end
|
162
|
-
end
|
199
|
+
HELP
|
163
200
|
end
|
164
201
|
|
165
202
|
end
|
data/lib/ucd/parser.rb
CHANGED
@@ -77,8 +77,8 @@ module UCD
|
|
77
77
|
|
78
78
|
rule(:relationship_directionality) { (kw_relationship_directionality.as(:directionality) >> spaces).maybe }
|
79
79
|
rule(:relationship_type) { kw_relationship_type.as(:type) >> spaces }
|
80
|
-
rule(:relationship_from) { (spaces >> (name
|
81
|
-
rule(:relationship_to) { (spaces >> (name
|
80
|
+
rule(:relationship_from) { (spaces >> (name | str("*").repeat(1)).as(:from)).maybe }
|
81
|
+
rule(:relationship_to) { (spaces >> (name | str("*").repeat(1)).as(:to)).maybe }
|
82
82
|
rule(:relationship_definition) { (relationship_directionality >> relationship_type >> class_name.as(:name) >> relationship_from >> relationship_to).as(:relationship) }
|
83
83
|
|
84
84
|
# -- Class
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ucd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Scott Lewis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parslet
|
@@ -101,15 +101,18 @@ files:
|
|
101
101
|
- VERSION
|
102
102
|
- bin/console
|
103
103
|
- bin/setup
|
104
|
-
- examples/composite - minimal.ucd
|
105
104
|
- examples/composite.dot
|
106
105
|
- examples/composite.png
|
107
106
|
- examples/composite.ucd
|
108
107
|
- examples/generic.dot
|
109
108
|
- examples/generic.png
|
110
109
|
- examples/generic.ucd
|
110
|
+
- examples/relationships.dot
|
111
|
+
- examples/relationships.png
|
112
|
+
- examples/relationships.ucd
|
111
113
|
- exe/ucd
|
112
114
|
- lib/ucd.rb
|
115
|
+
- lib/ucd/attribute_parser.rb
|
113
116
|
- lib/ucd/formatter.rb
|
114
117
|
- lib/ucd/formatter/base.rb
|
115
118
|
- lib/ucd/formatter/graphviz.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
abstract class Component {
|
2
|
-
method operation
|
3
|
-
}
|
4
|
-
|
5
|
-
class Leaf {
|
6
|
-
generalizes Component
|
7
|
-
}
|
8
|
-
|
9
|
-
class Composite {
|
10
|
-
protected field children
|
11
|
-
method addChild(child)
|
12
|
-
method removeChild(child)
|
13
|
-
method getChild(index)
|
14
|
-
|
15
|
-
generalizes Component
|
16
|
-
aggregation Component
|
17
|
-
}
|