lutaml-uml 0.2.8 → 0.2.9

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
  SHA256:
3
- metadata.gz: ef28b2562bcae4b385b3be898a71d6c326c59d5167c94ee1231932df060d5eee
4
- data.tar.gz: 39519359dc16f9532379b5ce15aef7e8ed6d37a1ae5afa2e22253c025505d0ab
3
+ metadata.gz: 7e25b300c9a636999a7861a78ea5c677d1c0c6767180a81f8b63cc6f9af2f8aa
4
+ data.tar.gz: b78902b23e27ec296913e2943c5fb966d17268f6c28e2b1c50409450e0310ed8
5
5
  SHA512:
6
- metadata.gz: 8b2464f9bc2d0f95a3baf5025ca2853537e6abd175a62be6f4f427e7f5f3e13f75f7ec9d2f7c9a675bd17be67b913da3a0b690c806e63a12f0633187471a6ec6
7
- data.tar.gz: 72a944718bd7c57c8146197f10810b40a4026cf71150f65b0ce7c17158bf046815ce71da1845c8b9d6d720521fa693fb006a50c8e02fac31b44ad8ae2b521fc3
6
+ metadata.gz: 287de7e6b28b6ff2c1dffab0db3a4503257c3b75c00409cd56184629875f3196e9a91dee7acb21a8cf1d1e484a59a9d5188836d33002599d8a4407da4a51f68c
7
+ data.tar.gz: 14f5782e4d85885c3fca50f486cf8107648fac50e50acdeb2d931dc6a68c4e0e8fe1c9b9927dfd4449a02186ea36a969d1591fd55712334dca72cb49d7fba103
@@ -18,7 +18,7 @@ jobs:
18
18
  strategy:
19
19
  fail-fast: false
20
20
  matrix:
21
- ruby: [ '2.6', '2.5', '2.4' ]
21
+ ruby: [ '2.6', '2.5' ]
22
22
  experimental: [false]
23
23
  include:
24
24
  - ruby: '2.7'
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
- ## Executable
11
+ ## Language
12
12
 
13
- [source,sh]
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
- # Display detailed help message
19
- $ lutaml-uml --help
20
- --
15
+ ## Usage
21
16
 
22
- ## Language
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(",")
@@ -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("}")
@@ -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/interface/command_line"
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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Uml
5
- VERSION = "0.2.8"
5
+ VERSION = "0.2.9"
6
6
  end
7
7
  end
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-uml]
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"
@@ -3,7 +3,7 @@ diagram MyView {
3
3
 
4
4
  enum MyEnum {}
5
5
 
6
- enum AddressClassProfile {
6
+ enum AddressClassProfile <<my_keyword>> {
7
7
  +addressClassProfile: CharacterString
8
8
  }
9
9
 
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.8
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: 2020-11-29 00:00:00.000000000 Z
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-uml
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-uml
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.6
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