lutaml-uml 0.2.8 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ubuntu.yml +1 -1
- data/README.adoc +9 -10
- data/bin/plantuml2lutaml +1 -0
- data/exe/lutaml-wsd2uml +59 -0
- data/exe/lutaml-yaml2uml +144 -0
- data/lib/lutaml/uml.rb +4 -2
- data/lib/lutaml/uml/parsers/dsl.rb +2 -1
- data/lib/lutaml/uml/version.rb +1 -1
- data/lutaml-uml.gemspec +1 -1
- data/spec/fixtures/dsl/diagram_data_types.lutaml +1 -1
- metadata +7 -7
- data/exe/lutaml-uml +0 -21
- data/lib/lutaml/uml/interface/base.rb +0 -28
- data/lib/lutaml/uml/interface/command_line.rb +0 -265
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e25b300c9a636999a7861a78ea5c677d1c0c6767180a81f8b63cc6f9af2f8aa
|
4
|
+
data.tar.gz: b78902b23e27ec296913e2943c5fb966d17268f6c28e2b1c50409450e0310ed8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 287de7e6b28b6ff2c1dffab0db3a4503257c3b75c00409cd56184629875f3196e9a91dee7acb21a8cf1d1e484a59a9d5188836d33002599d8a4407da4a51f68c
|
7
|
+
data.tar.gz: 14f5782e4d85885c3fca50f486cf8107648fac50e50acdeb2d931dc6a68c4e0e8fe1c9b9927dfd4449a02186ea36a969d1591fd55712334dca72cb49d7fba103
|
data/README.adoc
CHANGED
@@ -8,20 +8,19 @@ Lutaml is a language for specifying UML class diagrams and a tool for converting
|
|
8
8
|
|
9
9
|
### RubyGems: `gem install lutaml-uml`
|
10
10
|
|
11
|
-
##
|
11
|
+
## Language
|
12
12
|
|
13
|
-
[
|
14
|
-
--
|
15
|
-
# Convert example.lutaml to example.png
|
16
|
-
$ lutaml-uml --type png --output . example.lutaml
|
13
|
+
See link:LUTAML.adoc[LUTAML.adoc]
|
17
14
|
|
18
|
-
|
19
|
-
$ lutaml-uml --help
|
20
|
-
--
|
15
|
+
## Usage
|
21
16
|
|
22
|
-
|
17
|
+
Converter executables are available:
|
18
|
+
|
19
|
+
* PlantUML WSD to LutaML UML: `lutaml-wsd2uml`
|
20
|
+
* LutaML YAML to LutaML UML: `lutaml-yaml2uml`
|
21
|
+
|
22
|
+
EXAMPLE: `lutaml-wsd2uml mn/metanorma-model-standoc/models/StandardDoc_Blocks_New.wsd`
|
23
23
|
|
24
|
-
See link:LUTAML.adoc[LUTAML.adoc]
|
25
24
|
|
26
25
|
## Development
|
27
26
|
|
data/bin/plantuml2lutaml
CHANGED
@@ -27,6 +27,7 @@ ASSOCIATION_MAPPINGS = {
|
|
27
27
|
in_comment_block = false
|
28
28
|
|
29
29
|
def transform_line(line)
|
30
|
+
line = line.gsub(/^\s*'/, '** ').gsub(/\|[\sa-zA-Z]+$/, '')
|
30
31
|
return sync_puts(line, 2) if ASSOCIATION_MAPPINGS.keys.none? { |key| line =~ key }
|
31
32
|
|
32
33
|
owner_type, member_type = ASSOCIATION_MAPPINGS.detect { |(key, _value)| line =~ key }.last.split(",")
|
data/exe/lutaml-wsd2uml
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# Script to convert plantuml files into LutaML syntax
|
6
|
+
# Usage: bin/plantuml2lutaml /path/to/plantuml.wsd
|
7
|
+
|
8
|
+
file_path = ARGV[0]
|
9
|
+
FILE_NAME = File.basename(file_path, ".wsd")
|
10
|
+
wsd_file = File.new(ARGV[0])
|
11
|
+
|
12
|
+
def sync_puts(line, level = 0)
|
13
|
+
$stdout.puts("#{''.rjust(level)}#{line}")
|
14
|
+
$stdout.flush
|
15
|
+
end
|
16
|
+
|
17
|
+
SKIPPED_LINES_REGEXP = /^(@startuml|'\*{7}|note|@enduml|\!|'\/)/
|
18
|
+
COMMENT_START = /\/'/
|
19
|
+
COMMENT_END = /'\//
|
20
|
+
ASSOCIATION_MAPPINGS = {
|
21
|
+
/-\|>/ => ",inheritance",
|
22
|
+
/<\|-/ => "inheritance,",
|
23
|
+
/->/ => ",direct",
|
24
|
+
/<-/ => "direct,",
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
in_comment_block = false
|
28
|
+
|
29
|
+
def transform_line(line)
|
30
|
+
line = line.gsub(/^\s*'/, '** ').gsub(/\|[\sa-zA-Z]+$/, '')
|
31
|
+
return sync_puts(line, 2) if ASSOCIATION_MAPPINGS.keys.none? { |key| line =~ key }
|
32
|
+
|
33
|
+
owner_type, member_type = ASSOCIATION_MAPPINGS.detect { |(key, _value)| line =~ key }.last.split(",")
|
34
|
+
blocks = line.split(" ")
|
35
|
+
owner = blocks.first
|
36
|
+
member = blocks.last
|
37
|
+
sync_puts("association {", 2)
|
38
|
+
sync_puts("owner #{owner}", 4)
|
39
|
+
sync_puts("member #{member}", 4)
|
40
|
+
sync_puts("owner_type #{owner_type}", 4) if !owner_type.to_s.empty?
|
41
|
+
sync_puts("member_type #{member_type}", 4) if !member_type.to_s.empty?
|
42
|
+
sync_puts("}", 2)
|
43
|
+
end
|
44
|
+
|
45
|
+
sync_puts("diagram #{FILE_NAME} {")
|
46
|
+
wsd_file.readlines.each do |line|
|
47
|
+
if line.match?(COMMENT_START)
|
48
|
+
in_comment_block = true
|
49
|
+
end
|
50
|
+
|
51
|
+
if line.match?(COMMENT_END)
|
52
|
+
in_comment_block = false
|
53
|
+
end
|
54
|
+
|
55
|
+
next if in_comment_block || line =~ SKIPPED_LINES_REGEXP
|
56
|
+
|
57
|
+
transform_line(line)
|
58
|
+
end
|
59
|
+
sync_puts("}")
|
data/exe/lutaml-yaml2uml
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# Script to convert datamodel yaml files into LutaML syntax
|
6
|
+
# Usage: bin/yaml2lutaml /path/to/datamodel/view/file.yml
|
7
|
+
|
8
|
+
require "yaml"
|
9
|
+
|
10
|
+
view_yaml = YAML.safe_load(File.read(ARGV[0]))
|
11
|
+
models_path = File.expand_path("../../models", ARGV[0])
|
12
|
+
|
13
|
+
def sync_puts(line, level = 0)
|
14
|
+
$stdout.puts("#{''.rjust(level)}#{line}")
|
15
|
+
$stdout.flush
|
16
|
+
end
|
17
|
+
|
18
|
+
encountered_relations = Hash.new { |h, key| h[key] = [] }
|
19
|
+
# relations:
|
20
|
+
# - target: AttributeProfile
|
21
|
+
# relationship:
|
22
|
+
# source:
|
23
|
+
# type: aggregation
|
24
|
+
# attribute:
|
25
|
+
# addressClassProfile:
|
26
|
+
# target:
|
27
|
+
# type: direct
|
28
|
+
# attribute:
|
29
|
+
# attributeProfile:
|
30
|
+
# cardinality:
|
31
|
+
# min: 0
|
32
|
+
# max: '*'
|
33
|
+
def process_association(owner, values, encountered_relations)
|
34
|
+
target_name = values["target"]
|
35
|
+
return if encountered_relations[owner].include?(target_name)
|
36
|
+
|
37
|
+
encountered_relations[owner].push(target_name)
|
38
|
+
sync_puts("association {", 2)
|
39
|
+
|
40
|
+
relationship_block = values["relationship"] || {}
|
41
|
+
|
42
|
+
if relationship_block["source"] && relationship_block["source"]["type"]
|
43
|
+
source = relationship_block["source"]
|
44
|
+
sync_puts("owner_type #{source['type']}", 4)
|
45
|
+
if source["attribute"]
|
46
|
+
source_attribute_name = source["attribute"].keys.first
|
47
|
+
owner += "##{source_attribute_name}"
|
48
|
+
if source["attribute"][source_attribute_name] && source["attribute"][source_attribute_name]["cardinality"]
|
49
|
+
cardinality = source["attribute"][source_attribute_name]["cardinality"]
|
50
|
+
owner += " [#{cardinality['min']}..#{cardinality['max']}]"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
sync_puts("owner #{owner}", 4)
|
55
|
+
|
56
|
+
member = target_name
|
57
|
+
if relationship_block["target"]
|
58
|
+
target = relationship_block["target"]
|
59
|
+
type = target["type"] || "direct"
|
60
|
+
sync_puts("member_type #{type}", 4)
|
61
|
+
if target["attribute"]
|
62
|
+
target_attribute_name = target["attribute"].keys.first
|
63
|
+
member += "##{target_attribute_name}"
|
64
|
+
if target["attribute"][target_attribute_name] && target["attribute"][target_attribute_name]["cardinality"]
|
65
|
+
cardinality = target["attribute"][target_attribute_name]["cardinality"]
|
66
|
+
member += " [#{cardinality['min']}..#{cardinality['max']}]"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
sync_puts("member_type direct", 4)
|
71
|
+
end
|
72
|
+
sync_puts("member #{member}", 4)
|
73
|
+
|
74
|
+
sync_puts("}", 2)
|
75
|
+
end
|
76
|
+
sync_puts("diagram #{File.basename(ARGV[0], 'yml')[0..-2]} {")
|
77
|
+
sync_puts("title '#{view_yaml['title']}'", 2)
|
78
|
+
sync_puts("caption '#{view_yaml['caption']}'", 2)
|
79
|
+
|
80
|
+
# Class associations notations
|
81
|
+
view_yaml["relations"]&.each do |values|
|
82
|
+
process_association(values["source"], values, encountered_relations)
|
83
|
+
end
|
84
|
+
|
85
|
+
view_yaml["imports"].keys.each do |entry|
|
86
|
+
import = YAML.safe_load(File.read(File.join(models_path, "#{entry}.yml")))
|
87
|
+
import_name = import["name"] || File.basename(entry)
|
88
|
+
# Class notation
|
89
|
+
sync_puts("#{import['modelType']} #{import_name} {", 2)
|
90
|
+
if import["definition"]
|
91
|
+
definition = <<~TEXT
|
92
|
+
definition {
|
93
|
+
#{import['definition']}
|
94
|
+
}
|
95
|
+
TEXT
|
96
|
+
sync_puts(definition, 4)
|
97
|
+
end
|
98
|
+
import["values"]&.each_pair do |key, values|
|
99
|
+
result_string = key
|
100
|
+
if values["definition"]
|
101
|
+
result_string += <<~TEXT
|
102
|
+
{
|
103
|
+
definition {
|
104
|
+
#{values['definition']}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
TEXT
|
108
|
+
end
|
109
|
+
sync_puts(result_string, 4)
|
110
|
+
end
|
111
|
+
import["attributes"]&.each_pair do |key, values|
|
112
|
+
definition = values["definition"]
|
113
|
+
cardinality = if values["cardinality"]
|
114
|
+
cardinality_val = values["cardinality"]
|
115
|
+
"[#{cardinality_val['min']}..#{cardinality_val['max']}]"
|
116
|
+
else
|
117
|
+
""
|
118
|
+
end
|
119
|
+
result_string = "+#{key}"
|
120
|
+
if values["type"]
|
121
|
+
result_string += ": #{values['type']}"
|
122
|
+
end
|
123
|
+
if cardinality
|
124
|
+
result_string += " #{cardinality}"
|
125
|
+
end
|
126
|
+
if definition
|
127
|
+
result_string += <<~TEXT
|
128
|
+
{
|
129
|
+
definition
|
130
|
+
#{definition}
|
131
|
+
end definition
|
132
|
+
}
|
133
|
+
TEXT
|
134
|
+
end
|
135
|
+
sync_puts(result_string, 4)
|
136
|
+
end
|
137
|
+
sync_puts("}", 2)
|
138
|
+
|
139
|
+
# Associations notations
|
140
|
+
import["relations"]&.each do |values|
|
141
|
+
process_association(import_name, values, encountered_relations)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
sync_puts("}")
|
data/lib/lutaml/uml.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "lutaml/uml/version"
|
4
|
-
require "lutaml/uml/
|
4
|
+
require "lutaml/uml/parsers/dsl"
|
5
|
+
require "lutaml/uml/parsers/yaml"
|
6
|
+
require "lutaml/uml/parsers/attribute"
|
7
|
+
require "lutaml/uml/formatter"
|
5
8
|
|
6
9
|
module Lutaml
|
7
10
|
module Uml
|
8
11
|
class Error < StandardError; end
|
9
|
-
# Your code goes here...
|
10
12
|
end
|
11
13
|
end
|
@@ -63,7 +63,7 @@ module Lutaml
|
|
63
63
|
rule(:spaces) { match("\s").repeat(1) }
|
64
64
|
rule(:spaces?) { spaces.maybe }
|
65
65
|
rule(:whitespace) do
|
66
|
-
(match("\s") | match("\r?\n") | match("\r") | str(";")).repeat(1)
|
66
|
+
(match("\s") | match(" ") | match("\r?\n") | match("\r") | str(";")).repeat(1)
|
67
67
|
end
|
68
68
|
rule(:whitespace?) { whitespace.maybe }
|
69
69
|
rule(:name) { match["a-zA-Z0-9 _-"].repeat(1) }
|
@@ -322,6 +322,7 @@ module Lutaml
|
|
322
322
|
match['"\''].maybe >>
|
323
323
|
class_name.as(:name) >>
|
324
324
|
match['"\''].maybe >>
|
325
|
+
attribute_keyword? >>
|
325
326
|
enum_body?
|
326
327
|
end
|
327
328
|
|
data/lib/lutaml/uml/version.rb
CHANGED
data/lutaml-uml.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.bindir = "exe"
|
24
24
|
spec.require_paths = ["lib"]
|
25
|
-
spec.executables = %w[lutaml-
|
25
|
+
spec.executables = %w[lutaml-wsd2uml lutaml-yaml2uml]
|
26
26
|
|
27
27
|
spec.add_runtime_dependency "hashie", "~> 4.1.0"
|
28
28
|
spec.add_runtime_dependency "parslet", "~> 1.7.1"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lutaml-uml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -168,7 +168,8 @@ description: UML model module for LutaML.
|
|
168
168
|
email:
|
169
169
|
- open.source@ribose.com'
|
170
170
|
executables:
|
171
|
-
- lutaml-
|
171
|
+
- lutaml-wsd2uml
|
172
|
+
- lutaml-yaml2uml
|
172
173
|
extensions: []
|
173
174
|
extra_rdoc_files: []
|
174
175
|
files:
|
@@ -188,7 +189,8 @@ files:
|
|
188
189
|
- bin/plantuml2lutaml
|
189
190
|
- bin/setup
|
190
191
|
- bin/yaml2lutaml
|
191
|
-
- exe/lutaml-
|
192
|
+
- exe/lutaml-wsd2uml
|
193
|
+
- exe/lutaml-yaml2uml
|
192
194
|
- lib/lutaml/layout/engine.rb
|
193
195
|
- lib/lutaml/layout/graph_viz_engine.rb
|
194
196
|
- lib/lutaml/uml.rb
|
@@ -214,8 +216,6 @@ files:
|
|
214
216
|
- lib/lutaml/uml/has_attributes.rb
|
215
217
|
- lib/lutaml/uml/has_members.rb
|
216
218
|
- lib/lutaml/uml/instance.rb
|
217
|
-
- lib/lutaml/uml/interface/base.rb
|
218
|
-
- lib/lutaml/uml/interface/command_line.rb
|
219
219
|
- lib/lutaml/uml/model.rb
|
220
220
|
- lib/lutaml/uml/node/base.rb
|
221
221
|
- lib/lutaml/uml/node/class_node.rb
|
@@ -319,7 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
319
|
- !ruby/object:Gem::Version
|
320
320
|
version: '0'
|
321
321
|
requirements: []
|
322
|
-
rubygems_version: 3.0.
|
322
|
+
rubygems_version: 3.0.3
|
323
323
|
signing_key:
|
324
324
|
specification_version: 4
|
325
325
|
summary: UML model module for LutaML.
|
data/exe/lutaml-uml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
# frozen_string_literal: true
|
4
|
-
|
5
|
-
# resolve bin path, ignoring symlinks
|
6
|
-
require "pathname"
|
7
|
-
bin_file = Pathname.new(__FILE__).realpath
|
8
|
-
|
9
|
-
# add self to libpath
|
10
|
-
$:.unshift File.expand_path("../../lib", bin_file)
|
11
|
-
|
12
|
-
# Fixes https://github.com/rubygems/rubygems/issues/1420
|
13
|
-
require "rubygems/specification"
|
14
|
-
|
15
|
-
class Gem::Specification
|
16
|
-
def this; self; end
|
17
|
-
end
|
18
|
-
|
19
|
-
require "lutaml/uml/interface/command_line"
|
20
|
-
|
21
|
-
Lutaml::Uml::Interface::CommandLine.run
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "optparse"
|
4
|
-
require "lutaml/uml/has_attributes"
|
5
|
-
|
6
|
-
module Lutaml
|
7
|
-
module Uml
|
8
|
-
module Interface
|
9
|
-
class Base
|
10
|
-
def self.run(attributes = {})
|
11
|
-
new(attributes).run
|
12
|
-
end
|
13
|
-
|
14
|
-
include HasAttributes
|
15
|
-
|
16
|
-
# rubocop:disable Rails/ActiveRecordAliases
|
17
|
-
def initialize(attributes = {})
|
18
|
-
update_attributes(attributes)
|
19
|
-
end
|
20
|
-
# rubocop:enable Rails/ActiveRecordAliases
|
21
|
-
|
22
|
-
def run
|
23
|
-
raise NotImplementedError
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,265 +0,0 @@
|
|
1
|
-
require "optparse"
|
2
|
-
require "pathname"
|
3
|
-
require "lutaml/uml/interface/base"
|
4
|
-
require "lutaml/uml/parsers/dsl"
|
5
|
-
require "lutaml/uml/parsers/yaml"
|
6
|
-
require "lutaml/uml/parsers/attribute"
|
7
|
-
require "lutaml/uml/formatter"
|
8
|
-
|
9
|
-
module Lutaml
|
10
|
-
module Uml
|
11
|
-
module Interface
|
12
|
-
class CommandLine < Base
|
13
|
-
class Error < StandardError; end
|
14
|
-
class FileError < Error; end
|
15
|
-
class NotSupportedInputFormat < Error; end
|
16
|
-
|
17
|
-
SUPPORTED_FORMATS = %w[yaml dsl].freeze
|
18
|
-
DEFAULT_INPUT_FORMAT = "dsl".freeze
|
19
|
-
|
20
|
-
def initialize(attributes = {})
|
21
|
-
@formatter = Formatter::Graphviz.new
|
22
|
-
@verbose = false
|
23
|
-
@option_parser = OptionParser.new
|
24
|
-
|
25
|
-
setup_parser_options
|
26
|
-
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
|
-
def output_path=(value)
|
31
|
-
@output_path = determine_output_path_value(value)
|
32
|
-
end
|
33
|
-
|
34
|
-
def determine_output_path_value(value)
|
35
|
-
unless value.nil? || @output_path = value.is_a?(Pathname)
|
36
|
-
return Pathname.new(value.to_s)
|
37
|
-
end
|
38
|
-
|
39
|
-
value
|
40
|
-
end
|
41
|
-
|
42
|
-
def paths=(values)
|
43
|
-
@paths = values.to_a.map { |path| Pathname.new(path) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def formatter=(value)
|
47
|
-
value = value.to_s.strip.downcase.to_sym
|
48
|
-
value = Formatter.find_by(name: value)
|
49
|
-
raise Error, "Formatter not found: #{value}" if value.nil?
|
50
|
-
|
51
|
-
@formatter = value
|
52
|
-
end
|
53
|
-
|
54
|
-
def input_format=(value)
|
55
|
-
if value.nil?
|
56
|
-
@input_format = DEFAULT_INPUT_FORMAT
|
57
|
-
return
|
58
|
-
end
|
59
|
-
|
60
|
-
@input_format = SUPPORTED_FORMATS.detect { |n| n == value }
|
61
|
-
raise(NotSupportedInputFormat, value) if @input_format.nil?
|
62
|
-
end
|
63
|
-
|
64
|
-
def run
|
65
|
-
args = ARGV.dup # TODO: This is hacky
|
66
|
-
begin
|
67
|
-
@option_parser.parse!(args)
|
68
|
-
rescue StandardError
|
69
|
-
nil
|
70
|
-
end
|
71
|
-
setup_parser_formatter_options
|
72
|
-
@option_parser.parse!
|
73
|
-
|
74
|
-
self.paths = ARGV
|
75
|
-
@formatter.type = @type
|
76
|
-
|
77
|
-
if @output_path&.file? && @paths.length > 1
|
78
|
-
raise Error,
|
79
|
-
'Output path must be a directory \
|
80
|
-
if multiple input files are given'
|
81
|
-
end
|
82
|
-
|
83
|
-
@paths.each do |input_path|
|
84
|
-
unless input_path.exist?
|
85
|
-
raise FileError, "File does not exist: #{input_path}"
|
86
|
-
end
|
87
|
-
|
88
|
-
document = if @input_format == "yaml"
|
89
|
-
Parsers::Yaml.parse(input_path)
|
90
|
-
else
|
91
|
-
Parsers::Dsl.parse(File.new(input_path))
|
92
|
-
end
|
93
|
-
result = @formatter.format(document)
|
94
|
-
|
95
|
-
if @output_path
|
96
|
-
output_path = @output_path
|
97
|
-
if output_path.directory?
|
98
|
-
output_path = output_path.join(input_path
|
99
|
-
.basename(".*").to_s +
|
100
|
-
".#{@formatter.type}")
|
101
|
-
end
|
102
|
-
|
103
|
-
output_path.open("w+") { |file| file.write(result) }
|
104
|
-
else
|
105
|
-
puts result
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
protected
|
111
|
-
|
112
|
-
def text_bold(body = nil)
|
113
|
-
text_effect(1, body)
|
114
|
-
end
|
115
|
-
|
116
|
-
def text_italic(body = nil)
|
117
|
-
text_effect(3, body)
|
118
|
-
end
|
119
|
-
|
120
|
-
def text_bold_italic(body = nil)
|
121
|
-
text_bold(text_italic(body))
|
122
|
-
end
|
123
|
-
|
124
|
-
def text_underline(body = nil)
|
125
|
-
text_effect(4, body)
|
126
|
-
end
|
127
|
-
|
128
|
-
def text_effect(num, body = nil)
|
129
|
-
result = "\e[#{num}m"
|
130
|
-
result << "#{body}#{text_reset}" unless body.nil?
|
131
|
-
|
132
|
-
result
|
133
|
-
end
|
134
|
-
|
135
|
-
def text_reset
|
136
|
-
"\e[0m"
|
137
|
-
end
|
138
|
-
|
139
|
-
def setup_parser_options
|
140
|
-
@option_parser.banner = ""
|
141
|
-
format_desc = "The output formatter (Default: '#{@formatter.name}')"
|
142
|
-
@option_parser
|
143
|
-
.on("-f",
|
144
|
-
"--formatter VALUE",
|
145
|
-
format_desc) do |value|
|
146
|
-
self.formatter = value
|
147
|
-
end
|
148
|
-
@option_parser
|
149
|
-
.on("-t", "--type VALUE", "The output format type") do |value|
|
150
|
-
@type = value
|
151
|
-
end
|
152
|
-
@option_parser
|
153
|
-
.on("-o", "--output VALUE", "The output path") do |value|
|
154
|
-
self.output_path = value
|
155
|
-
end
|
156
|
-
@option_parser
|
157
|
-
.on("-i", "--input-format VALUE", "The input format") do |value|
|
158
|
-
self.input_format = value
|
159
|
-
end
|
160
|
-
@option_parser
|
161
|
-
.on("-h", "--help", "Prints this help") do
|
162
|
-
print_help
|
163
|
-
exit
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def setup_parser_formatter_options
|
168
|
-
case @formatter.name
|
169
|
-
when :graphviz
|
170
|
-
@option_parser.on("-g", "--graph VALUE") do |value|
|
171
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
172
|
-
@formatter.graph[key] = attr_value
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
@option_parser.on("-e", "--edge VALUE") do |value|
|
177
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
178
|
-
@formatter.edge[key] = attr_value
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
@option_parser.on("-n", "--node VALUE") do |value|
|
183
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
184
|
-
@formatter.node[key] = attr_value
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
@option_parser.on("-a", "--all VALUE") do |value|
|
189
|
-
Parsers::Attribute.parse(value).each do |key, attr_value|
|
190
|
-
@formatter.graph[key] = attr_value
|
191
|
-
@formatter.edge[key] = attr_value
|
192
|
-
@formatter.node[key] = attr_value
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def print_help
|
199
|
-
puts <<~HELP
|
200
|
-
#{text_bold('Usage:')} lutaml-uml [options] PATHS
|
201
|
-
|
202
|
-
#{text_bold('Overview:')} Generate output from UML Class Diagram language files
|
203
|
-
|
204
|
-
#{text_bold('Options:')}
|
205
|
-
#{@option_parser}
|
206
|
-
#{text_bold('Paths:')}
|
207
|
-
|
208
|
-
UCD can accept multiple paths for parsing for easier batch processing.
|
209
|
-
|
210
|
-
The location of the output by default is standard output.
|
211
|
-
|
212
|
-
The output can be directed to a path with #{text_bold_italic('--output')}, which can be a file or a directory.
|
213
|
-
If the output path is a directory, then the filename will be the same as the input filename,
|
214
|
-
with it's file extension substituted with the #{text_bold_italic('--type')}.
|
215
|
-
|
216
|
-
#{text_underline('Examples')}
|
217
|
-
|
218
|
-
`lutaml-uml project.lutaml`
|
219
|
-
|
220
|
-
Produces DOT notation, sent to standard output
|
221
|
-
|
222
|
-
`lutaml-uml -o . project.lutaml`
|
223
|
-
|
224
|
-
Produces DOT notation, written to #{text_italic('./project.dot')}
|
225
|
-
|
226
|
-
`lutaml-uml -o ./diagram.dot project.lutaml`
|
227
|
-
|
228
|
-
Produces DOT notation, written to #{text_italic('./diagram.dot')}
|
229
|
-
|
230
|
-
`lutaml-uml -o ./diagram.png project.lutaml`
|
231
|
-
|
232
|
-
Produces PNG image, written to #{text_italic('./diagram.png')}
|
233
|
-
|
234
|
-
`lutaml-uml -t png -o . project.lutaml`
|
235
|
-
|
236
|
-
Produces PNG image, written to #{text_italic('./project.png')}
|
237
|
-
|
238
|
-
`lutaml-uml -t png -o . project.lutaml-uml core_ext.lutaml`
|
239
|
-
|
240
|
-
Produces PNG images, written to #{text_italic('./project.png')} and #{text_italic('./core_ext.png')}
|
241
|
-
|
242
|
-
#{text_bold('Formatters:')}
|
243
|
-
|
244
|
-
#{text_underline('Graphviz')}
|
245
|
-
|
246
|
-
Generates DOT notation and can use the DOT notation to generate any format Graphviz can produce.
|
247
|
-
|
248
|
-
The output format is based on #{text_bold_italic('--type')}, which by default is "dot".
|
249
|
-
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.
|
250
|
-
|
251
|
-
Valid types/extensions are: #{Formatter::Graphviz::VALID_TYPES.join(', ')}
|
252
|
-
|
253
|
-
#{text_bold('Options:')}
|
254
|
-
|
255
|
-
-g, --graph VALUE The graph attributes
|
256
|
-
-e, --edge VALUE The edge attributes
|
257
|
-
-n, --node VALUE The node attributes
|
258
|
-
-a, --all VALUE Set attributes for graph, edge, and node
|
259
|
-
|
260
|
-
HELP
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|