metanorma-plugin-lutaml 0.1.0 → 0.2.4.alpha

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: 0e854f55d18dbd63e113f74e940689320384a8840912ef16f7a6880e13672ee6
4
- data.tar.gz: ebf477f3262b209fc4edad4b1908b911d7737d343c2eb42383207de0aeb30b2d
3
+ metadata.gz: c060a247f01300f4fe46b58671a07a8f0e3a80f53e64974ccd07208e181e0eaa
4
+ data.tar.gz: dcf58ee6f298d24ad2493bd65c62a549a2673717ce8a9404695caad20d32e069
5
5
  SHA512:
6
- metadata.gz: e530b0648b11116825ac6f1435f5c8d533102bbd212b6e4ab4d4c81d3378d67cb2c39ce32dffe5585d8801b34e2b8a647809fd2eafbdd879e27a01b975f3888e
7
- data.tar.gz: 5a216d14209e1183b19c1301c7273639f379ab1d7e025a7ded83f135a46a5834568bb154335d8bd7cfc33c967825ae5d7b38c96289d0047c8c74cee3b9b2f0ca
6
+ metadata.gz: 5061cc833de5a8d4742095e5491f66ab608bdac3042ecc601cdc26e89f5ff258aa34650b3b19e3eb3b38b50be01b3f866e18f15adda02000278e6a5864cf1b34
7
+ data.tar.gz: 3be917c68c0fd6b0157f6578e40f61da433b262629950f76d09b2b2cf9e4cc5f7955d9066a0930f337ec7beb9426790d650bfb632cf9abf570f3431360855ca6
@@ -0,0 +1,65 @@
1
+ name: rake
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ tags: [ v* ]
7
+ pull_request:
8
+
9
+ jobs:
10
+ rake:
11
+ name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
12
+ runs-on: ${{ matrix.os }}
13
+ continue-on-error: ${{ matrix.experimental }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ ruby: [ '2.6', '2.5', '2.4' ]
18
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
19
+ experimental: [ false ]
20
+ include:
21
+ - ruby: '2.7'
22
+ os: 'ubuntu-latest'
23
+ experimental: true
24
+ - ruby: '2.7'
25
+ os: 'windows-latest'
26
+ experimental: true
27
+ - ruby: '2.7'
28
+ os: 'macos-latest'
29
+ experimental: true
30
+ steps:
31
+ - uses: actions/checkout@master
32
+
33
+ - name: Use Ruby
34
+ uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: ${{ matrix.ruby }}
37
+ bundler-cache: true
38
+
39
+ - name: Update gems
40
+ run: bundle install --jobs 4 --retry 3
41
+
42
+ - name: Install Grpahviz Ubuntu
43
+ if: matrix.os == 'ubuntu-latest'
44
+ run: sudo apt-get install graphviz
45
+
46
+ - name: Install Grpahviz macOS
47
+ if: matrix.os == 'macos-latest'
48
+ run: brew install graphviz
49
+
50
+ - name: Install Grpahviz Windows
51
+ if: matrix.os == 'windows-latest'
52
+ uses: nick-invision/retry@v1
53
+ with:
54
+ polling_interval_seconds: 5
55
+ timeout_minutes: 5
56
+ max_attempts: 3
57
+ command: choco install --no-progress graphviz
58
+
59
+ - name: Check dot command
60
+ if: matrix.os == 'windows-latest'
61
+ run: |
62
+ dot -?
63
+
64
+ - name: Run specs
65
+ run: bundle exec rake
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  Gemfile.lock
2
2
  .rspec_status
3
+ spec/assets/lutaml
4
+ test.err
data/README.adoc CHANGED
@@ -1,5 +1,7 @@
1
1
  = metanorma-plugin-lutaml
2
2
 
3
+ image:https://github.com/metanorma/metanorma-plugin-lutaml/workflows/rake/badge.svg["Build Status", link="https://github.com/metanorma/metanorma-plugin-lutaml/actions?workflow=rake"]
4
+
3
5
  == Functionality
4
6
 
5
7
  Metanorma plugin that allows you to access lutaml objects from a Metanorma document
@@ -11,7 +13,7 @@ Metanorma plugin that allows you to access lutaml objects from a Metanorma docum
11
13
  $ gem install metanorma-plugin-lutaml
12
14
  ----
13
15
 
14
- === Usage
16
+ === Usage, `lutaml` macro
15
17
 
16
18
  Given `example.exp` file with the content:
17
19
 
@@ -58,6 +60,14 @@ And the `lutaml` macro block:
58
60
  ----
59
61
  -----
60
62
 
63
+ Where:
64
+
65
+ * content within the block is called the "`template`";
66
+
67
+ * `{example.exp}` is the location of the exp schema file that contains data to be loaded. Location of the file is computed relative to the source directory that `[lutaml]` is used (e.g., if `[lutaml,example.exp,my_context]` is invoked in an `.adoc` file located at `/foo/bar/doc.adoc`, the data file is expected to be found at `/foo/bar/example.exp`);
68
+
69
+ * `{my_context}` is the name where the EXPRESS Repository read from the .exp file can be accessed with. Context object is a serialized Expressir::Model::Repository object with all variable names available. See https://github.com/lutaml/expressir[Expressir] docs for reference. `{my_context}` has `schemas` method to access Expressir https://github.com/lutaml/expressir/blob/master/lib/expressir/model/schema.rb[schemas]
70
+
61
71
  Will produce this output:
62
72
 
63
73
  [source,adoc]
@@ -71,6 +81,82 @@ Will produce this output:
71
81
  === my_type5
72
82
  -----
73
83
 
84
+ This macro also supports `.lutaml` files.
85
+
86
+ === Usage, `lutaml_uml_attributes_table` macro
87
+
88
+ This macro allows to quickly render datamodel attributes/values tables. Given `example.lutaml` file with the content:
89
+
90
+ [source,java]
91
+ ----
92
+ diagram MyView {
93
+ title "my diagram"
94
+
95
+ enum AddressClassProfile {
96
+ imlicistAttributeProfile: CharacterString [0..1] {
97
+ definition
98
+ this is multiline with `ascidoc`
99
+ end definition
100
+ }
101
+ }
102
+
103
+ class AttributeProfile {
104
+ +addressClassProfile: CharacterString [0..1]
105
+ imlicistAttributeProfile: CharacterString [0..1] {
106
+ definition this is attribute definition
107
+ }
108
+ }
109
+ }
110
+ ----
111
+
112
+ And the `lutaml_uml_attributes_table` macro:
113
+
114
+ [source,adoc]
115
+ -----
116
+ [lutaml_uml_attributes_table, example.lutaml, AttributeProfile]
117
+ -----
118
+
119
+ Will produce this output:
120
+
121
+ [source,adoc]
122
+ -----
123
+ === AttributeProfile
124
+
125
+
126
+ .AttributeProfile attributes
127
+ |===
128
+ |Name |Definition |Mandatory/ Optional/ Conditional |Max Occur |Data Type
129
+
130
+ |addressClassProfile |TODO: enum 's definition |M |1 | `CharacterString`
131
+
132
+ |imlicistAttributeProfile |this is attribute definition with multiply lines |M |1 | `CharacterString`
133
+
134
+ |===
135
+ -----
136
+
137
+ In case of "enumeration"(AddressClassProfile) entity:
138
+
139
+ [source,adoc]
140
+ -----
141
+ [lutaml_uml_attributes_table, example.lutaml, AddressClassProfile]
142
+ -----
143
+
144
+ Will produce this output:
145
+
146
+ [source,adoc]
147
+ -----
148
+ === AddressClassProfile
149
+
150
+
151
+ .AddressClassProfile values
152
+ |===
153
+ |Name |Definition
154
+
155
+ |imlicistAttributeProfile |this is multiline with `ascidoc`
156
+
157
+ |===
158
+ -----
159
+
74
160
  == Documentation
75
161
 
76
162
  See https://www.metanorma.com.
@@ -1,5 +1,7 @@
1
1
  require "metanorma/plugin/lutaml/version"
2
2
  require "metanorma/plugin/lutaml/lutaml_preprocessor"
3
+ require "metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor"
4
+ require "metanorma/plugin/lutaml/lutaml_diagram_block"
3
5
 
4
6
  module Metanorma
5
7
  module Plugin
@@ -0,0 +1,73 @@
1
+ module Metanorma
2
+ module Plugin
3
+ module Lutaml
4
+ class ExpressRemarksDecorator
5
+ RELATIVE_PREFIX_MACRO_REGEXP = /^(\* <<express.+?>>;|link|image|video|audio|include)(:+)?(?![^\/:]+:\/\/|[A-Z]:\/|\/)([^:\[]+)(\[.*\])?$/.freeze
6
+
7
+ attr_reader :remark, :options
8
+
9
+ def self.call(remark, options)
10
+ new(remark, options).call
11
+ end
12
+
13
+ def initialize(remark, options)
14
+ @remark = remark
15
+ @options = options
16
+ end
17
+
18
+ def call
19
+ result = remark
20
+ if options["leveloffset"]
21
+ result = process_remark_offsets(result, options["leveloffset"].to_i)
22
+ end
23
+ if options["relative_path_prefix"]
24
+ result = update_relative_paths(result,
25
+ options["relative_path_prefix"])
26
+ end
27
+ result
28
+ end
29
+
30
+ private
31
+
32
+ def update_relative_paths(string, path_prefix)
33
+ string
34
+ .split("\n")
35
+ .map do |line|
36
+ if line.match?(RELATIVE_PREFIX_MACRO_REGEXP)
37
+ prefix_relative_paths(line, path_prefix)
38
+ else
39
+ line
40
+ end
41
+ end
42
+ .join("\n")
43
+ end
44
+
45
+ def prefix_relative_paths(line, path_prefix)
46
+ line.gsub(RELATIVE_PREFIX_MACRO_REGEXP) do |_match|
47
+ prefixed_path = File.join(path_prefix, $3.strip)
48
+ "#{$1}#{$2}#{prefixed_path}#{$4}"
49
+ end
50
+ end
51
+
52
+ def process_remark_offsets(string, offset)
53
+ string
54
+ .split("\n")
55
+ .map do |line|
56
+ if line.match?(/^=/)
57
+ set_string_offsets(line, offset)
58
+ else
59
+ line
60
+ end
61
+ end
62
+ .join("\n")
63
+ end
64
+
65
+ def set_string_offsets(string, offset)
66
+ return "#{'=' * offset}#{string}" if offset.positive?
67
+
68
+ string.gsub(/^={#{offset * -1}}/, "")
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "liquid"
4
+ require "asciidoctor"
5
+ require "asciidoctor/reader"
6
+ require "lutaml"
7
+ require "lutaml/uml"
8
+ require "metanorma/plugin/lutaml/utils"
9
+
10
+ module Metanorma
11
+ module Plugin
12
+ module Lutaml
13
+ class LutamlDiagramBlock < Asciidoctor::Extensions::BlockProcessor
14
+ use_dsl
15
+ named :lutaml_diagram
16
+ on_context :literal
17
+ parse_content_as :raw
18
+
19
+ def abort(parent, reader, attrs, msg)
20
+ warn(msg)
21
+ attrs["language"] = "lutaml"
22
+ create_listing_block(
23
+ parent,
24
+ reader.source,
25
+ attrs.reject { |k, _v| k == 1 }
26
+ )
27
+ end
28
+
29
+ def process(parent, reader, attrs)
30
+ uml_document = ::Lutaml::Uml::Parsers::Dsl.parse(lutaml_temp(reader))
31
+ filename = generate_file(parent, reader, uml_document)
32
+ through_attrs = generate_attrs(attrs)
33
+ through_attrs["target"] = filename
34
+ through_attrs["title"] = uml_document.caption
35
+ create_image_block(parent, through_attrs)
36
+ rescue StandardError => e
37
+ abort(parent, reader, attrs, e.message)
38
+ end
39
+
40
+ private
41
+
42
+ def lutaml_temp(reader)
43
+ temp_file = Tempfile.new(["lutaml", ".lutaml"])
44
+ temp_file.puts(reader.read)
45
+ temp_file.rewind
46
+ temp_file
47
+ end
48
+
49
+ # if no :imagesdir: leave image file in lutaml
50
+ def generate_file(parent, _reader, uml_document)
51
+ formatter = ::Lutaml::Uml::Formatter::Graphviz.new
52
+ formatter.type = :png
53
+
54
+ imagesdir = if parent.document.attr("imagesdir")
55
+ File.join(parent.document.attr("imagesdir"), "lutaml")
56
+ else
57
+ "lutaml"
58
+ end
59
+ result_path = Utils.relative_file_path(parent.document, imagesdir)
60
+ result_pathname = Pathname.new(result_path)
61
+ result_pathname.mkpath
62
+ File.writable?(result_pathname) || raise("Destination path #{result_path} not writable for Lutaml!")
63
+
64
+ outfile = Tempfile.new(["lutaml", ".png"])
65
+ outfile.binmode
66
+ outfile.puts(formatter.format(uml_document))
67
+
68
+ # Warning: metanorma/metanorma-standoc#187
69
+ # Windows Ruby 2.4 will crash if a Tempfile is "mv"ed.
70
+ # This is why we need to copy and then unlink.
71
+ filename = File.basename(outfile.path)
72
+ FileUtils.cp(outfile, result_pathname) && outfile.unlink
73
+
74
+ File.join(result_pathname, filename)
75
+ end
76
+
77
+ def generate_attrs(attrs)
78
+ %w(id align float title role width height alt)
79
+ .reduce({}) do |memo, key|
80
+ memo[key] = attrs[key] if attrs.has_key? key
81
+ memo
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -4,48 +4,53 @@ require "liquid"
4
4
  require "asciidoctor"
5
5
  require "asciidoctor/reader"
6
6
  require "lutaml"
7
+ require "metanorma/plugin/lutaml/utils"
8
+ require "metanorma/plugin/lutaml/utils"
9
+ require "metanorma/plugin/lutaml/express_remarks_decorator"
7
10
 
8
11
  module Metanorma
9
12
  module Plugin
10
13
  module Lutaml
11
14
  # Class for processing Lutaml files
12
15
  class LutamlPreprocessor < Asciidoctor::Extensions::Preprocessor
16
+ REMARKS_ATTRIBUTE = "remarks".freeze
13
17
 
14
18
  def process(document, reader)
15
19
  input_lines = reader.readlines.to_enum
16
- Asciidoctor::Reader.new(processed_lines(document, input_lines))
20
+ express_indexes = Utils.parse_document_express_indexes(
21
+ document,
22
+ input_lines
23
+ )
24
+ Asciidoctor::Reader
25
+ .new(processed_lines(document, input_lines, express_indexes))
17
26
  end
18
27
 
19
28
  protected
20
29
 
21
30
  def content_from_file(document, file_path)
22
31
  ::Lutaml::Parser
23
- .parse(File.new(relative_file_path(document, file_path),
32
+ .parse(File.new(Utils.relative_file_path(document, file_path),
24
33
  encoding: "UTF-8"))
25
34
  end
26
35
 
27
36
  private
28
37
 
29
- def processed_lines(document, input_lines)
38
+ def processed_lines(document, input_lines, express_indexes)
30
39
  result = []
31
40
  loop do
32
- result.push(*process_text_blocks(document, input_lines))
41
+ result
42
+ .push(*process_text_blocks(
43
+ document,
44
+ input_lines,
45
+ express_indexes
46
+ ))
33
47
  end
34
48
  result
35
49
  end
36
50
 
37
- def relative_file_path(document, file_path)
38
- docfile_directory = File.dirname(
39
- document.attributes["docfile"] || "."
40
- )
41
- document
42
- .path_resolver
43
- .system_path(file_path, docfile_directory)
44
- end
45
-
46
- def process_text_blocks(document, input_lines)
51
+ def process_text_blocks(document, input_lines, express_indexes)
47
52
  line = input_lines.next
48
- block_match = line.match(/^\[lutaml,(.+?),(.+?)\]/)
53
+ block_match = line.match(/^\[lutaml,([^,]+)?,?([^,]+)?,?([^,]+)?\]/)
49
54
  return [line] if block_match.nil?
50
55
 
51
56
  end_mark = input_lines.next
@@ -53,7 +58,8 @@ module Metanorma
53
58
  collect_internal_block_lines(document,
54
59
  input_lines,
55
60
  end_mark),
56
- block_match)
61
+ block_match,
62
+ express_indexes)
57
63
  end
58
64
 
59
65
  def collect_internal_block_lines(_document, input_lines, end_mark)
@@ -64,49 +70,74 @@ module Metanorma
64
70
  current_block
65
71
  end
66
72
 
67
- def parse_template(document, current_block, block_match)
68
- context_items = content_from_file(document, block_match[1])
69
- parse_context_block(document: document,
70
- context_lines: current_block,
71
- context_items: context_items,
72
- context_name: block_match[2].strip)
73
+ def contexts_items(block_match, document, express_indexes)
74
+ contexts_names = block_match[1].split(";").map(&:strip)
75
+ contexts_names.each_with_object([]) do |path, res|
76
+ if express_indexes[path]
77
+ res.push(*express_indexes[path])
78
+ else
79
+ res.push(content_from_file(document, path).to_liquid)
80
+ end
81
+ end
82
+ end
83
+
84
+ def parse_template(document, current_block, block_match, express_indexes)
85
+ options = parse_options(block_match[3])
86
+ .merge("relative_path_prefix" => File.dirname(block_match[1]))
87
+ contexts_items(block_match, document, express_indexes)
88
+ .map do |context_items|
89
+ parse_context_block(document: document,
90
+ context_lines: current_block,
91
+ context_items: decorate_context_items(context_items, options),
92
+ context_name: block_match[2].strip)
93
+ end.flatten
73
94
  rescue StandardError => e
74
- document.logger
75
- .warn("Failed to parse lutaml \
76
- block: #{e.message}")
95
+ document.logger.warn("Failed to parse lutaml block: #{e.message}")
77
96
  []
78
97
  end
79
98
 
99
+ def parse_options(options_string)
100
+ options_string
101
+ .to_s
102
+ .scan(/(.+?)=(\s?[^\s]+)/)
103
+ .map { |elem| elem.map(&:strip) }
104
+ .to_h
105
+ end
106
+
107
+ def decorate_context_items(context_items, options)
108
+ return context_items if !context_items.is_a?(Hash)
109
+
110
+ context_items
111
+ .map do |(key, val)|
112
+ if val.is_a?(Hash)
113
+ [key, decorate_context_items(val, options)]
114
+ elsif key == REMARKS_ATTRIBUTE
115
+ [key,
116
+ val&.map do |remark|
117
+ Metanorma::Plugin::Lutaml::ExpressRemarksDecorator
118
+ .call(remark, options)
119
+ end]
120
+ elsif val.is_a?(Array)
121
+ [key, val.map { |n| decorate_context_items(n, options) }]
122
+ else
123
+ [key, val]
124
+ end
125
+ end
126
+ .to_h
127
+ end
128
+
80
129
  def parse_context_block(context_lines:,
81
130
  context_items:,
82
131
  context_name:,
83
132
  document:)
84
- render_result, errors = render_liquid_string(
133
+ render_result, errors = Utils.render_liquid_string(
85
134
  template_string: context_lines.join("\n"),
86
135
  context_items: context_items,
87
136
  context_name: context_name
88
137
  )
89
- notify_render_errors(document, errors)
138
+ Utils.notify_render_errors(document, errors)
90
139
  render_result.split("\n")
91
140
  end
92
-
93
- def render_liquid_string(template_string:, context_items:,
94
- context_name:)
95
- liquid_template = Liquid::Template.parse(template_string)
96
- rendered_string = liquid_template
97
- .render(context_name => context_items,
98
- strict_variables: true,
99
- error_mode: :warn)
100
- [rendered_string, liquid_template.errors]
101
- end
102
-
103
- def notify_render_errors(document, errors)
104
- errors.each do |error_obj|
105
- document
106
- .logger
107
- .warn("Liquid render error: #{error_obj.message}")
108
- end
109
- end
110
141
  end
111
142
  end
112
143
  end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "liquid"
4
+ require "asciidoctor"
5
+ require "asciidoctor/reader"
6
+ require "lutaml"
7
+ require "lutaml/uml"
8
+ require "metanorma/plugin/lutaml/utils"
9
+
10
+ module Metanorma
11
+ module Plugin
12
+ module Lutaml
13
+ # Macro for quick rendering of datamodel attributes/values table
14
+ # @example [lutaml_uml_attributes_table,path/to/lutaml,EntityName]
15
+ class LutamlUmlAttributesTablePreprocessor < Asciidoctor::Extensions::Preprocessor
16
+ MARCO_REGEXP =
17
+ /\[lutaml_uml_attributes_table,([^,]+),?(.+)?,([^,]+),?(.+)?\]/
18
+ # search document for block `datamodel_attributes_table`
19
+ # read include derectives that goes after that in block and transform
20
+ # into yaml2text blocks
21
+ def process(document, reader)
22
+ input_lines = reader.readlines.to_enum
23
+ Asciidoctor::Reader.new(processed_lines(document, input_lines))
24
+ end
25
+
26
+ private
27
+
28
+ def lutaml_document_from_file(document, file_path)
29
+ ::Lutaml::Parser
30
+ .parse(File.new(Utils.relative_file_path(document, file_path),
31
+ encoding: "UTF-8"))
32
+ end
33
+
34
+ def processed_lines(document, input_lines)
35
+ input_lines.each_with_object([]) do |line, result|
36
+ if match = line.match(MARCO_REGEXP)
37
+ lutaml_path = match[1]
38
+ entity_name = match[3]
39
+ result.push(*parse_marco(lutaml_path, entity_name, document))
40
+ else
41
+ result.push(line)
42
+ end
43
+ end
44
+ end
45
+
46
+ def parse_marco(lutaml_path, entity_name, document)
47
+ lutaml_document = lutaml_document_from_file(document, lutaml_path)
48
+ .serialized_document
49
+ entities = [lutaml_document["classes"], lutaml_document["enums"]]
50
+ .compact
51
+ .flatten
52
+ entity_definition = entities.detect do |klass|
53
+ klass["name"] == entity_name.strip
54
+ end
55
+ model_representation(entity_definition, document)
56
+ end
57
+
58
+ def model_representation(entity_definition, document)
59
+ render_result, errors = Utils.render_liquid_string(
60
+ template_string: table_template,
61
+ context_items: entity_definition,
62
+ context_name: "definition"
63
+ )
64
+ Utils.notify_render_errors(document, errors)
65
+ render_result.split("\n")
66
+ end
67
+
68
+ # rubocop:disable Layout/IndentHeredoc
69
+ def table_template
70
+ <<~TEMPLATE
71
+ === {{ definition.name }}
72
+ {{ definition.definition }}
73
+
74
+ {% if definition.attributes %}
75
+ {% if definition.keyword == 'enumeration' %}
76
+ .{{ definition.name }} values
77
+ |===
78
+ |Name |Definition
79
+
80
+ {% for item in definition.attributes %}
81
+ |{{ item.name }} |{{ item.definition }}
82
+ {% endfor %}
83
+ |===
84
+ {% else %}
85
+ .{{ definition.name }} attributes
86
+ |===
87
+ |Name |Definition |Mandatory/ Optional/ Conditional |Max Occur |Data Type
88
+
89
+ {% for item in definition.attributes %}
90
+ |{{ item.name }} |{% if item.definition %}{{ item.definition }}{% else %}TODO: enum {{ key }}'s definition{% endif %} |{% if item.cardinality.min == "0" %}O{% else %}M{% endif %} |{% if item.cardinality.max == "*" %}N{% else %}1{% endif %} |{% if item.origin %}<<{{ item.origin }}>>{% endif %} `{{ item.type }}`
91
+ {% endfor %}
92
+ |===
93
+ {% endif %}
94
+ {% endif %}
95
+
96
+ TEMPLATE
97
+ end
98
+ # rubocop:enable Layout/IndentHeredoc
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,74 @@
1
+ module Metanorma
2
+ module Plugin
3
+ module Lutaml
4
+ # Helpers for lutaml macroses
5
+ module Utils
6
+ module_function
7
+
8
+ def relative_file_path(document, file_path)
9
+ docfile_directory = File.dirname(
10
+ document.attributes["docfile"] || "."
11
+ )
12
+ document
13
+ .path_resolver
14
+ .system_path(file_path, docfile_directory)
15
+ end
16
+
17
+ def render_liquid_string(template_string:, context_items:,
18
+ context_name:)
19
+ liquid_template = Liquid::Template.parse(template_string)
20
+ rendered_string = liquid_template
21
+ .render(context_name => context_items,
22
+ strict_variables: true,
23
+ error_mode: :warn)
24
+ [rendered_string, liquid_template.errors]
25
+ end
26
+
27
+ def notify_render_errors(document, errors)
28
+ errors.each do |error_obj|
29
+ document
30
+ .logger
31
+ .warn("Liquid render error: #{error_obj.message}")
32
+ end
33
+ end
34
+
35
+ def process_express_index(folder, name, idxs, document)
36
+ idxs[name] = []
37
+ Dir["#{Utils.relative_file_path(document, folder)}/*"].each do |path|
38
+ next if [".", ".."].include?(path)
39
+
40
+ begin
41
+ idxs[name]
42
+ .push(::Lutaml::Parser.parse(File.new(path, encoding: "UTF-8")).to_liquid)
43
+ rescue StandardError => e
44
+ document.logger.warn("Failed to load #{path}: #{e.message}")
45
+ end
46
+ end
47
+ end
48
+
49
+ def parse_document_express_indexes(document, input_lines)
50
+ express_indexes = {}
51
+ loop do
52
+ line = input_lines.next
53
+ break if line.length.zero?
54
+
55
+ _, name, folder = line.match(/^:lutaml-express-index:(.+?);(.+?)$/)&.to_a
56
+ if folder && name
57
+ process_express_index(
58
+ folder.strip.gsub(";", ""),
59
+ name.strip,
60
+ express_indexes,
61
+ document
62
+ )
63
+ end
64
+ end
65
+ express_indexes
66
+ rescue StopIteration
67
+ express_indexes
68
+ ensure
69
+ input_lines.rewind
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,7 +1,7 @@
1
1
  module Metanorma
2
2
  module Plugin
3
3
  module Lutaml
4
- VERSION = "0.1.0".freeze
4
+ VERSION = "0.2.4.alpha".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ["lib"]
25
25
 
26
26
  spec.add_dependency "liquid"
27
- spec.add_dependency "lutaml", "~> 0.3.0"
27
+ spec.add_dependency "lutaml", "0.4.1.pre.alpha"
28
28
  spec.add_dependency "lutaml-uml", "~> 0.2.0"
29
29
  spec.add_dependency "metanorma"
30
30
  spec.add_dependency "relaton-cli"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-plugin-lutaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.4.alpha
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-10-28 00:00:00.000000000 Z
11
+ date: 2021-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: lutaml
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.0
33
+ version: 0.4.1.pre.alpha
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.0
40
+ version: 0.4.1.pre.alpha
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: lutaml-uml
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -241,6 +241,7 @@ executables: []
241
241
  extensions: []
242
242
  extra_rdoc_files: []
243
243
  files:
244
+ - ".github/workflows/rake.yml"
244
245
  - ".gitignore"
245
246
  - CODE_OF_CONDUCT.md
246
247
  - Gemfile
@@ -250,9 +251,14 @@ files:
250
251
  - bin/console
251
252
  - bin/setup
252
253
  - lib/metanorma-plugin-lutaml.rb
254
+ - lib/metanorma/plugin/lutaml/express_remarks_decorator.rb
255
+ - lib/metanorma/plugin/lutaml/lutaml_diagram_block.rb
253
256
  - lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb
257
+ - lib/metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor.rb
258
+ - lib/metanorma/plugin/lutaml/utils.rb
254
259
  - lib/metanorma/plugin/lutaml/version.rb
255
260
  - metanorma-plugin-lutaml.gemspec
261
+ - pkg/metanorma-plugin-lutaml-0.2.0.gem
256
262
  homepage: https://github.com/metanorma/metanorma-plugin-lutaml
257
263
  licenses:
258
264
  - BSD-2-Clause
@@ -268,9 +274,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
268
274
  version: '0'
269
275
  required_rubygems_version: !ruby/object:Gem::Requirement
270
276
  requirements:
271
- - - ">="
277
+ - - ">"
272
278
  - !ruby/object:Gem::Version
273
- version: '0'
279
+ version: 1.3.1
274
280
  requirements: []
275
281
  rubygems_version: 3.0.3
276
282
  signing_key: