metanorma-plugin-lutaml 0.4.20 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -1
- data/lib/metanorma/plugin/lutaml/asciidoctor/preprocessor.rb +14 -0
- data/lib/metanorma/plugin/lutaml/express_remarks_decorator.rb +2 -1
- data/lib/metanorma/plugin/lutaml/lutaml_diagram_base.rb +10 -7
- data/lib/metanorma/plugin/lutaml/lutaml_diagram_block.rb +3 -3
- data/lib/metanorma/plugin/lutaml/lutaml_diagram_block_macro.rb +1 -1
- data/lib/metanorma/plugin/lutaml/lutaml_figure_inline_macro.rb +5 -4
- data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +6 -5
- data/lib/metanorma/plugin/lutaml/lutaml_table_inline_macro.rb +8 -6
- data/lib/metanorma/plugin/lutaml/lutaml_uml_attributes_table_preprocessor.rb +25 -26
- data/lib/metanorma/plugin/lutaml/lutaml_uml_class_preprocessor.rb +55 -50
- data/lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb +115 -84
- data/lib/metanorma/plugin/lutaml/utils.rb +26 -16
- data/lib/metanorma/plugin/lutaml/version.rb +1 -1
- data/lib/metanorma-plugin-lutaml.rb +0 -11
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f93ed9a874aa04de0ff48ccc747a887ad82f5c024b5e688c09c78e2857d20c5
|
4
|
+
data.tar.gz: f42630b6fe28b47fab6041c7a0638bcb5fccc5080315518f7d5f97355a499a94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b38c3de5ad16450a4fca4dc6b6505d9408de9ec8dce3535689f6419a5ada4d4ee9a42ac88d452f95ad8a852bd8579b4afe41f469d81515c4f3e9a37dc795469d
|
7
|
+
data.tar.gz: 4797711cda34aa4473f4314ad25c1a2e6193a892eb65a7a9600a57147556a8dd921ddf2ac00ef691fd5c9606e5aeb518a1ddf9dfa19c19e3e8fdabccc1ca00d8
|
data/Gemfile
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
+
Encoding.default_external = Encoding::UTF_8
|
2
|
+
Encoding.default_internal = Encoding::UTF_8
|
3
|
+
|
1
4
|
source "https://rubygems.org"
|
5
|
+
git_source(:github) { |repo| "https://github.com/#{repo}" }
|
2
6
|
|
3
|
-
# Specify your gem's dependencies in metanorma-plugin-lutaml.gemspec
|
4
7
|
gemspec
|
8
|
+
|
9
|
+
eval_gemfile("Gemfile.devel") rescue nil
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Plugin
|
3
|
+
module Lutaml
|
4
|
+
module Asciidoctor
|
5
|
+
class PreprocessorNoIfdefsReader < ::Asciidoctor::PreprocessorReader
|
6
|
+
def preprocess_conditional_directive(_keyword, _target, _delimiter,
|
7
|
+
_text)
|
8
|
+
false # decline to resolve idefs
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -45,7 +45,8 @@ module Metanorma
|
|
45
45
|
def prefix_relative_paths(line, path_prefix)
|
46
46
|
line.gsub(RELATIVE_PREFIX_MACRO_REGEXP) do |_match|
|
47
47
|
prefixed_path = File.join(path_prefix, $3.strip)
|
48
|
-
# When we are dealing with
|
48
|
+
# When we are dealing with a relative path of a template:
|
49
|
+
# ../path/to/file we need to transform it into
|
49
50
|
# the absolute one because `image::` macro wont understand it other way
|
50
51
|
prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?('../')
|
51
52
|
full_path = File.expand_path(prefixed_path)
|
@@ -13,7 +13,8 @@ module Metanorma
|
|
13
13
|
module Lutaml
|
14
14
|
module LutamlDiagramBase
|
15
15
|
def process(parent, reader, attrs)
|
16
|
-
uml_document = ::Lutaml::Uml::Parsers::Dsl
|
16
|
+
uml_document = ::Lutaml::Uml::Parsers::Dsl
|
17
|
+
.parse(lutaml_file(parent.document, reader))
|
17
18
|
filename = generate_file(parent, reader, uml_document)
|
18
19
|
through_attrs = generate_attrs(attrs)
|
19
20
|
through_attrs["target"] = filename
|
@@ -23,8 +24,8 @@ module Metanorma
|
|
23
24
|
abort(parent, reader, attrs, e.message)
|
24
25
|
end
|
25
26
|
|
26
|
-
def lutaml_file(
|
27
|
-
raise
|
27
|
+
def lutaml_file(_reader)
|
28
|
+
raise "Implement me!"
|
28
29
|
end
|
29
30
|
|
30
31
|
protected
|
@@ -36,7 +37,7 @@ module Metanorma
|
|
36
37
|
create_listing_block(
|
37
38
|
parent,
|
38
39
|
source,
|
39
|
-
attrs.reject { |k, _v| k == 1 }
|
40
|
+
attrs.reject { |k, _v| k == 1 },
|
40
41
|
)
|
41
42
|
end
|
42
43
|
|
@@ -47,14 +48,16 @@ module Metanorma
|
|
47
48
|
|
48
49
|
path_lutaml = "lutaml"
|
49
50
|
imagesdir = if parent.document.attr("imagesdir")
|
50
|
-
File.join(parent.document.attr("imagesdir"),
|
51
|
+
File.join(parent.document.attr("imagesdir"),
|
52
|
+
path_lutaml)
|
51
53
|
else
|
52
54
|
path_lutaml
|
53
55
|
end
|
54
56
|
result_path = Utils.relative_file_path(parent.document, imagesdir)
|
55
57
|
result_pathname = Pathname.new(result_path)
|
56
58
|
result_pathname.mkpath
|
57
|
-
File.writable?(result_pathname) ||
|
59
|
+
File.writable?(result_pathname) ||
|
60
|
+
raise("Destination path #{result_path} not writable for Lutaml!")
|
58
61
|
|
59
62
|
outfile = Tempfile.new(["lutaml", ".png"])
|
60
63
|
outfile.binmode
|
@@ -67,7 +70,7 @@ module Metanorma
|
|
67
70
|
filename = File.basename(outfile.path)
|
68
71
|
FileUtils.cp(outfile, result_pathname) && outfile.unlink
|
69
72
|
|
70
|
-
#File.join(result_pathname, filename)
|
73
|
+
# File.join(result_pathname, filename)
|
71
74
|
File.join(path_lutaml, filename)
|
72
75
|
end
|
73
76
|
|
@@ -5,7 +5,7 @@ require "metanorma/plugin/lutaml/lutaml_diagram_base"
|
|
5
5
|
module Metanorma
|
6
6
|
module Plugin
|
7
7
|
module Lutaml
|
8
|
-
class LutamlDiagramBlock < Asciidoctor::Extensions::BlockProcessor
|
8
|
+
class LutamlDiagramBlock < ::Asciidoctor::Extensions::BlockProcessor
|
9
9
|
include LutamlDiagramBase
|
10
10
|
|
11
11
|
use_dsl
|
@@ -14,14 +14,14 @@ module Metanorma
|
|
14
14
|
parse_content_as :raw
|
15
15
|
|
16
16
|
def lutaml_file(document, reader)
|
17
|
-
|
18
17
|
lutaml_temp(document, reader)
|
19
18
|
end
|
20
19
|
|
21
20
|
private
|
22
21
|
|
23
22
|
def lutaml_temp(document, reader)
|
24
|
-
temp_file = Tempfile.new(["lutaml", ".lutaml"],
|
23
|
+
temp_file = Tempfile.new(["lutaml", ".lutaml"],
|
24
|
+
Utils.relative_file_path(document, ""))
|
25
25
|
temp_file.puts(reader.read)
|
26
26
|
temp_file.rewind
|
27
27
|
temp_file
|
@@ -5,7 +5,7 @@ require "metanorma/plugin/lutaml/lutaml_diagram_base"
|
|
5
5
|
module Metanorma
|
6
6
|
module Plugin
|
7
7
|
module Lutaml
|
8
|
-
class LutamlDiagramBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
|
8
|
+
class LutamlDiagramBlockMacro < ::Asciidoctor::Extensions::BlockMacroProcessor
|
9
9
|
include LutamlDiagramBase
|
10
10
|
|
11
11
|
use_dsl
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Metanorma
|
4
4
|
module Plugin
|
5
5
|
module Lutaml
|
6
|
-
class LutamlFigureInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
6
|
+
class LutamlFigureInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
7
7
|
include LutamlDiagramBase
|
8
8
|
|
9
9
|
use_dsl
|
@@ -11,11 +11,12 @@ module Metanorma
|
|
11
11
|
|
12
12
|
def process(parent, _target, attrs)
|
13
13
|
diagram_key = [attrs["package"], attrs["name"]].compact.join(":")
|
14
|
-
return if parent.document.attributes[
|
15
|
-
|
14
|
+
return if parent.document.attributes["lutaml_figure_id"].nil?
|
15
|
+
|
16
|
+
xmi_id = parent.document.attributes["lutaml_figure_id"][diagram_key]
|
16
17
|
return unless xmi_id
|
17
18
|
|
18
|
-
%
|
19
|
+
%(<xref target="figure-#{xmi_id}"></xref>)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -6,25 +6,26 @@ require "asciidoctor/reader"
|
|
6
6
|
require "lutaml"
|
7
7
|
require "metanorma/plugin/lutaml/utils"
|
8
8
|
require "metanorma/plugin/lutaml/express_remarks_decorator"
|
9
|
+
require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
|
9
10
|
|
10
11
|
module Metanorma
|
11
12
|
module Plugin
|
12
13
|
module Lutaml
|
13
14
|
# Class for processing Lutaml files
|
14
|
-
class LutamlPreprocessor < Asciidoctor::Extensions::Preprocessor
|
15
|
+
class LutamlPreprocessor < ::Asciidoctor::Extensions::Preprocessor
|
15
16
|
REMARKS_ATTRIBUTE = "remarks"
|
16
17
|
|
17
18
|
def process(document, reader)
|
18
|
-
|
19
|
+
r = Asciidoctor::PreprocessorNoIfdefsReader.new document, reader.lines
|
20
|
+
input_lines = r.readlines.to_enum
|
19
21
|
has_lutaml = !input_lines.select { |x| lutaml?(x) }.empty?
|
20
22
|
express_indexes = Utils.parse_document_express_indexes(
|
21
|
-
document,
|
22
|
-
input_lines,
|
23
|
+
document, input_lines
|
23
24
|
)
|
24
25
|
result_content = processed_lines(document, input_lines,
|
25
26
|
express_indexes)
|
26
27
|
has_lutaml and log(document, result_content)
|
27
|
-
Asciidoctor::
|
28
|
+
Asciidoctor::PreprocessorNoIfdefsReader.new(document, result_content)
|
28
29
|
end
|
29
30
|
|
30
31
|
protected
|
@@ -3,21 +3,23 @@
|
|
3
3
|
module Metanorma
|
4
4
|
module Plugin
|
5
5
|
module Lutaml
|
6
|
-
class LutamlTableInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
6
|
+
class LutamlTableInlineMacro < ::Asciidoctor::Extensions::InlineMacroProcessor
|
7
7
|
include LutamlDiagramBase
|
8
|
-
SUPPORTED_OPTIONS = %w[class enum data_type]
|
8
|
+
SUPPORTED_OPTIONS = %w[class enum data_type].freeze
|
9
9
|
|
10
10
|
use_dsl
|
11
11
|
named :lutaml_table
|
12
12
|
|
13
13
|
def process(parent, _target, attrs)
|
14
14
|
keyword = SUPPORTED_OPTIONS.find { |n| attrs[n] }
|
15
|
-
entity_key = [keyword, attrs["package"],
|
16
|
-
|
17
|
-
|
15
|
+
entity_key = [keyword, attrs["package"],
|
16
|
+
attrs[keyword]].compact.join(":")
|
17
|
+
return if parent.document.attributes["lutaml_entity_id"].nil?
|
18
|
+
|
19
|
+
xmi_id = parent.document.attributes["lutaml_entity_id"][entity_key]
|
18
20
|
return unless xmi_id
|
19
21
|
|
20
|
-
%
|
22
|
+
%(<xref target="section-#{xmi_id}"/>)
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
|
4
4
|
|
5
5
|
module Metanorma
|
6
6
|
module Plugin
|
@@ -16,36 +16,35 @@ module Metanorma
|
|
16
16
|
skip_headers = options[:skip_headers]
|
17
17
|
|
18
18
|
<<~TEMPLATE
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
19
|
+
#{'=== {{ definition.name }}' unless skip_headers}
|
20
|
+
{{ definition.definition }}
|
21
|
+
|
22
|
+
{% if definition.attributes %}
|
23
|
+
{% if definition.keyword == 'enumeration' %}
|
24
|
+
.{{ definition.name }} values
|
25
|
+
|===
|
26
|
+
|Name |Definition
|
27
|
+
|
28
|
+
{% for item in definition.attributes %}
|
29
|
+
|{{ item.name }} |{{ item.definition }}
|
30
|
+
{% endfor %}
|
31
|
+
|===
|
32
|
+
{% else %}
|
33
|
+
.{{ definition.name }} attributes
|
34
|
+
|===
|
35
|
+
|Name |Definition |Mandatory / Optional / Conditional |Max Occur |Data Type
|
36
|
+
|
37
|
+
{% for item in definition.attributes %}
|
38
|
+
|{{ item.name }} |{% if item.definition %}{{ item.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 }}`
|
39
|
+
{% endfor %}
|
40
|
+
|===
|
41
|
+
{% endif %}
|
42
|
+
{% endif %}
|
43
43
|
|
44
44
|
TEMPLATE
|
45
45
|
end
|
46
46
|
# rubocop:enable Layout/IndentHeredoc
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
50
49
|
end
|
51
50
|
end
|
@@ -6,13 +6,14 @@ require "asciidoctor/reader"
|
|
6
6
|
require "lutaml"
|
7
7
|
require "lutaml/uml"
|
8
8
|
require "metanorma/plugin/lutaml/utils"
|
9
|
+
require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
|
9
10
|
|
10
11
|
module Metanorma
|
11
12
|
module Plugin
|
12
13
|
module Lutaml
|
13
14
|
# Macro for quick rendering of datamodel attributes/values table
|
14
15
|
# @example [lutaml_uml_class,path/to/lutaml,EntityName]
|
15
|
-
class LutamlUmlClassPreprocessor < Asciidoctor::Extensions::Preprocessor
|
16
|
+
class LutamlUmlClassPreprocessor < ::Asciidoctor::Extensions::Preprocessor
|
16
17
|
MACRO_REGEXP =
|
17
18
|
/\[lutaml_uml_class,([^,]+),?([^,]+),?(.+?)?\]/
|
18
19
|
|
@@ -24,8 +25,10 @@ module Metanorma
|
|
24
25
|
# read include derectives that goes after that in block and transform
|
25
26
|
# into yaml2text blocks
|
26
27
|
def process(document, reader)
|
27
|
-
|
28
|
-
|
28
|
+
r = Asciidoctor::PreprocessorNoIfdefsReader.new document, reader.lines
|
29
|
+
input_lines = r.readlines.to_enum
|
30
|
+
Asciidoctor::PreprocessorNoIfdefsReader
|
31
|
+
.new(document, processed_lines(document, input_lines))
|
29
32
|
end
|
30
33
|
|
31
34
|
private
|
@@ -34,17 +37,18 @@ module Metanorma
|
|
34
37
|
::Lutaml::Parser.parse(
|
35
38
|
File.new(
|
36
39
|
Utils.relative_file_path(document, file_path),
|
37
|
-
encoding: "UTF-8"
|
38
|
-
)
|
40
|
+
encoding: "UTF-8",
|
41
|
+
),
|
42
|
+
).first
|
39
43
|
end
|
40
44
|
|
41
|
-
DEFAULT_OPTIONS = {
|
42
|
-
|
43
|
-
}
|
45
|
+
DEFAULT_OPTIONS = { depth: 2 }.freeze
|
46
|
+
|
44
47
|
def parse_options_to_hash(options_string)
|
45
|
-
return DEFAULT_OPTIONS.dup if options_string.nil? ||
|
48
|
+
return DEFAULT_OPTIONS.dup if options_string.nil? ||
|
49
|
+
options_string.empty?
|
46
50
|
|
47
|
-
opts = options_string.split(",").inject({}) do |acc,pair|
|
51
|
+
opts = options_string.split(",").inject({}) do |acc, pair|
|
48
52
|
key, value = pair.split("=")
|
49
53
|
key = key.to_sym
|
50
54
|
value = true if value.nil?
|
@@ -63,7 +67,8 @@ module Metanorma
|
|
63
67
|
entity_name = match[2]
|
64
68
|
options = parse_options_to_hash(match[3])
|
65
69
|
|
66
|
-
result.push(*parse_marco(lutaml_path, entity_name, document,
|
70
|
+
result.push(*parse_marco(lutaml_path, entity_name, document,
|
71
|
+
options))
|
67
72
|
else
|
68
73
|
result.push(line)
|
69
74
|
end
|
@@ -87,7 +92,7 @@ module Metanorma
|
|
87
92
|
template_string: template(options),
|
88
93
|
context_items: entity_definition,
|
89
94
|
context_name: "definition",
|
90
|
-
document: document
|
95
|
+
document: document,
|
91
96
|
)
|
92
97
|
Utils.notify_render_errors(document, errors)
|
93
98
|
render_result.split("\n")
|
@@ -103,56 +108,56 @@ module Metanorma
|
|
103
108
|
depth = options[:depth]
|
104
109
|
|
105
110
|
<<~TEMPLATE
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
{% if definition.keyword == 'enumeration' %}
|
112
|
+
#{equalsigns(depth) + ' Enumeration: {{ definition.name }}' unless skip_headers}
|
113
|
+
{% else %}
|
114
|
+
#{equalsigns(depth) + ' Class: {{ definition.name }}' unless skip_headers}
|
115
|
+
{% endif %}
|
111
116
|
|
112
|
-
|
117
|
+
#{equalsigns(depth + 1)} Description
|
113
118
|
|
114
|
-
|
119
|
+
{{ definition.definition }}
|
115
120
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
121
|
+
{% if definition.attributes %}
|
122
|
+
{% if definition.keyword == 'enumeration' %}
|
123
|
+
{% for item in definition.attributes %}
|
124
|
+
#{equalsigns(depth + 1)} Enumeration value: {{item.name}}
|
120
125
|
|
121
|
-
|
122
|
-
|
123
|
-
|
126
|
+
{% if item.definition %}
|
127
|
+
{{ item.definition }}
|
128
|
+
{% endif %}
|
124
129
|
|
125
|
-
|
130
|
+
{% endfor %}
|
126
131
|
|
127
|
-
|
132
|
+
{% else %}
|
128
133
|
|
129
|
-
|
130
|
-
|
134
|
+
{% for item in definition.attributes %}
|
135
|
+
#{equalsigns(depth + 1)} Attribute: {{item.name}}
|
131
136
|
|
132
|
-
|
133
|
-
|
134
|
-
|
137
|
+
{% if item.definition %}
|
138
|
+
{{ item.definition }}
|
139
|
+
{% endif %}
|
135
140
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
141
|
+
Value type and multiplicity:
|
142
|
+
{% if item.type -%}{{ item.type }}{% else -%}(no type specified){% endif %}
|
143
|
+
{% if item.cardinality.min -%}
|
144
|
+
{% if item.cardinality.max -%}
|
145
|
+
{blank}[{{item.cardinality.min}}..{{item.cardinality.max}}]
|
146
|
+
{% else -%}
|
147
|
+
{blank}[{{item.cardinality.min}}]
|
148
|
+
{% endif -%}
|
149
|
+
{% else -%}
|
150
|
+
(multiplicity unspecified)
|
151
|
+
{% endif %}
|
147
152
|
|
148
|
-
|
149
|
-
|
150
|
-
|
153
|
+
{% if item.origin %}
|
154
|
+
Origin: <<{{ item.origin }}>>
|
155
|
+
{% endif %}
|
151
156
|
|
152
|
-
|
157
|
+
{% endfor %}
|
153
158
|
|
154
|
-
|
155
|
-
|
159
|
+
{% endif %}
|
160
|
+
{% endif %}
|
156
161
|
|
157
162
|
TEMPLATE
|
158
163
|
end
|
@@ -6,6 +6,7 @@ require "asciidoctor/reader"
|
|
6
6
|
require "lutaml"
|
7
7
|
require "lutaml/uml"
|
8
8
|
require "metanorma/plugin/lutaml/utils"
|
9
|
+
require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
|
9
10
|
|
10
11
|
module Metanorma
|
11
12
|
module Plugin
|
@@ -13,45 +14,48 @@ module Metanorma
|
|
13
14
|
# Macro for quick rendering of datamodel attributes/values table
|
14
15
|
# @example [lutaml_uml_attributes_table,path/to/lutaml,EntityName]
|
15
16
|
class LutamlUmlDatamodelDescriptionPreprocessor <
|
16
|
-
Asciidoctor::Extensions::Preprocessor
|
17
|
+
::Asciidoctor::Extensions::Preprocessor
|
17
18
|
MACRO_REGEXP =
|
18
19
|
/\[lutaml_uml_datamodel_description,([^,]+),?(.+)?\]/
|
19
20
|
LIQUID_INCLUDE_PATH = File.join(
|
20
21
|
Gem.loaded_specs["metanorma-plugin-lutaml"].full_gem_path,
|
21
22
|
"lib", "metanorma", "plugin", "lutaml", "liquid_templates"
|
22
23
|
)
|
23
|
-
DEFAULT_RENDER_INCLUDE =
|
24
|
+
DEFAULT_RENDER_INCLUDE = "packages"
|
24
25
|
RENDER_STYLES_INCLUDES = {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
"default" => "packages",
|
27
|
+
"entity_list" => "packages_entity_list",
|
28
|
+
"entity_list_class" => "packages_entity_list_class",
|
29
|
+
"data_dictionary" => "packages_data_dictionary",
|
29
30
|
}.freeze
|
30
|
-
RENDER_STYLE_ATTRIBUTE =
|
31
|
+
RENDER_STYLE_ATTRIBUTE = "render_style"
|
31
32
|
SUPPORTED_NESTED_MACRO = %w[
|
32
|
-
before diagram_include_block after include_block package_text
|
33
|
+
before diagram_include_block after include_block package_text
|
34
|
+
].freeze
|
33
35
|
# search document for block `lutaml_uml_datamodel_description`
|
34
36
|
# read include derectives that goes after that in block and transform
|
35
37
|
# into yaml2text blocks
|
36
38
|
def process(document, reader)
|
37
|
-
|
38
|
-
|
39
|
+
r = Asciidoctor::PreprocessorNoIfdefsReader.new document, reader.lines
|
40
|
+
input_lines = r.readlines.to_enum
|
41
|
+
Asciidoctor::PreprocessorNoIfdefsReader
|
42
|
+
.new(document, processed_lines(document, input_lines))
|
39
43
|
end
|
40
44
|
|
41
45
|
private
|
42
46
|
|
43
47
|
def lutaml_document_from_file_or_cache(document, file_path)
|
44
48
|
full_path = Utils.relative_file_path(document, file_path)
|
45
|
-
if document.attributes[
|
46
|
-
document.attributes[
|
47
|
-
return document.attributes[
|
49
|
+
if document.attributes["lutaml_xmi_cache"] &&
|
50
|
+
document.attributes["lutaml_xmi_cache"][full_path]
|
51
|
+
return document.attributes["lutaml_xmi_cache"][full_path]
|
48
52
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
document.attributes[
|
54
|
-
document.attributes[
|
53
|
+
|
54
|
+
result_document = ::Lutaml::Parser
|
55
|
+
.parse(File.new(full_path, encoding: "UTF-8")).first
|
56
|
+
result_document
|
57
|
+
document.attributes["lutaml_xmi_cache"] ||= {}
|
58
|
+
document.attributes["lutaml_xmi_cache"][full_path] = result_document
|
55
59
|
result_document
|
56
60
|
end
|
57
61
|
|
@@ -59,7 +63,7 @@ module Metanorma
|
|
59
63
|
return {} if file_path.nil?
|
60
64
|
|
61
65
|
relative_file_path = Utils.relative_file_path(document, file_path)
|
62
|
-
YAML.
|
66
|
+
YAML.safe_load(File.read(relative_file_path, encoding: "UTF-8"))
|
63
67
|
end
|
64
68
|
|
65
69
|
def processed_lines(document, input_lines)
|
@@ -75,19 +79,22 @@ module Metanorma
|
|
75
79
|
block_match = line.match(MACRO_REGEXP)
|
76
80
|
return [line] if block_match.nil?
|
77
81
|
|
78
|
-
lutaml_document = lutaml_document_from_file_or_cache(document,
|
82
|
+
lutaml_document = lutaml_document_from_file_or_cache(document,
|
83
|
+
block_match[1])
|
79
84
|
fill_in_diagrams_attributes(document, lutaml_document)
|
80
85
|
model_representation(
|
81
|
-
lutaml_document,
|
82
|
-
document,
|
86
|
+
lutaml_document, document,
|
83
87
|
collect_additional_context(document, input_lines, input_lines.next),
|
84
|
-
parse_yaml_config_file(document, block_match[2])
|
88
|
+
parse_yaml_config_file(document, block_match[2])
|
89
|
+
)
|
85
90
|
end
|
86
91
|
|
87
|
-
def fill_in_entities_refs_attributes(document, lutaml_document_wrapper,
|
92
|
+
def fill_in_entities_refs_attributes(document, lutaml_document_wrapper,
|
93
|
+
options)
|
88
94
|
lutaml_document = lutaml_document_wrapper.original_document
|
89
|
-
render_style = options.fetch(RENDER_STYLE_ATTRIBUTE,
|
90
|
-
all_children_packages = lutaml_document.packages
|
95
|
+
render_style = options.fetch(RENDER_STYLE_ATTRIBUTE, "default")
|
96
|
+
all_children_packages = lutaml_document.packages
|
97
|
+
.map(&:children_packages).flatten
|
91
98
|
package_flat_packages = lambda do |pks|
|
92
99
|
pks.each_with_object({}) do |package, res|
|
93
100
|
res[package.name] = package.xmi_id
|
@@ -95,7 +102,7 @@ module Metanorma
|
|
95
102
|
end
|
96
103
|
children_pks = package_flat_packages.call(all_children_packages)
|
97
104
|
ref_dictionary = package_flat_packages.call(lutaml_document.packages)
|
98
|
-
|
105
|
+
.merge(children_pks)
|
99
106
|
%w[class enum data_type].each do |type|
|
100
107
|
package_flat = lambda do |pks|
|
101
108
|
pks.each_with_object({}) do |package, res|
|
@@ -106,46 +113,57 @@ module Metanorma
|
|
106
113
|
end
|
107
114
|
end
|
108
115
|
children_pks_daigs = package_flat.call(all_children_packages)
|
109
|
-
|
110
|
-
|
111
|
-
|
116
|
+
ref_dictionary = ref_dictionary
|
117
|
+
.merge(package_flat.call(lutaml_document.packages)
|
118
|
+
.merge(children_pks_daigs))
|
112
119
|
end
|
113
|
-
document.attributes[
|
120
|
+
document.attributes["lutaml_entity_id"] = ref_dictionary
|
114
121
|
end
|
115
122
|
|
116
123
|
def fill_in_diagrams_attributes(document, lutaml_document_wrapper)
|
117
124
|
lutaml_document = lutaml_document_wrapper.original_document
|
118
125
|
package_flat_diagrams = lambda do |pks|
|
119
126
|
pks.each_with_object({}) do |package, res|
|
120
|
-
package.diagrams.map
|
127
|
+
package.diagrams.map do |diag|
|
128
|
+
res["#{package.name}:#{diag.name}"] = diag.xmi_id
|
129
|
+
end
|
121
130
|
end
|
122
131
|
end
|
123
|
-
children_pks_daigs = package_flat_diagrams.call(
|
124
|
-
|
125
|
-
|
132
|
+
children_pks_daigs = package_flat_diagrams.call(
|
133
|
+
lutaml_document.packages.map(&:children_packages).flatten,
|
134
|
+
)
|
135
|
+
document.attributes["lutaml_figure_id"] = package_flat_diagrams
|
136
|
+
.call(lutaml_document.packages)
|
137
|
+
.merge(children_pks_daigs)
|
126
138
|
end
|
127
139
|
|
128
140
|
def collect_additional_context(document, input_lines, end_mark)
|
129
141
|
additional_context = Hash.new { |hash, key| hash[key] = [] }
|
130
|
-
additional_context[
|
142
|
+
additional_context["all_macros"] = []
|
131
143
|
block_lines = []
|
132
144
|
while (block_line = input_lines.next) != end_mark
|
133
145
|
block_lines.push(block_line)
|
134
146
|
end
|
135
|
-
processed_lines =
|
136
|
-
|
137
|
-
|
138
|
-
|
147
|
+
processed_lines =
|
148
|
+
process(document, ::Asciidoctor::PreprocessorReader.new(
|
149
|
+
document, block_lines
|
150
|
+
))
|
151
|
+
.read_lines
|
152
|
+
block_document = ::Asciidoctor::Document
|
153
|
+
.new(processed_lines, {}).parse
|
139
154
|
block_document.blocks.each do |block|
|
140
|
-
next unless SUPPORTED_NESTED_MACRO.include?(block.attributes[
|
155
|
+
next unless SUPPORTED_NESTED_MACRO.include?(block.attributes["role"])
|
141
156
|
|
142
157
|
attrs = block.attributes
|
143
|
-
name = attrs.delete(
|
144
|
-
package = attrs.delete(
|
158
|
+
name = attrs.delete("role")
|
159
|
+
package = attrs.delete("package")
|
145
160
|
macro_keyword = [name, package].compact.join(";")
|
146
|
-
block_text = block.lines.length
|
147
|
-
additional_context[macro_keyword]
|
148
|
-
|
161
|
+
block_text = block.lines.length.positive? ? block.lines.join("\n") : ""
|
162
|
+
additional_context[macro_keyword]
|
163
|
+
.push({ "text" => block_text }.merge(attrs))
|
164
|
+
additional_context["all_macros"]
|
165
|
+
.push({ "text" => block_text,
|
166
|
+
"type" => name, "package" => package }.merge(attrs))
|
149
167
|
end
|
150
168
|
additional_context
|
151
169
|
end
|
@@ -153,71 +171,80 @@ module Metanorma
|
|
153
171
|
def package_level(lutaml_document, level)
|
154
172
|
return lutaml_document if level <= 0
|
155
173
|
|
156
|
-
package_level(lutaml_document[
|
174
|
+
package_level(lutaml_document["packages"].first, level - 1)
|
157
175
|
end
|
158
176
|
|
159
177
|
def create_context_object(lutaml_document, additional_context, options)
|
160
|
-
root_package = package_level(lutaml_document.to_liquid,
|
161
|
-
|
178
|
+
root_package = package_level(lutaml_document.to_liquid,
|
179
|
+
options["package_root_level"] || 1)
|
180
|
+
if options.empty? || options["packages"].nil?
|
162
181
|
return {
|
163
|
-
|
164
|
-
"packages" => root_package[
|
182
|
+
"render_nested_packages" => true,
|
183
|
+
"packages" => root_package["packages"],
|
165
184
|
"root_packages" => [root_package],
|
166
|
-
"additional_context" => additional_context
|
167
|
-
|
185
|
+
"additional_context" => additional_context
|
186
|
+
.merge("external_classes" => options["external_classes"]),
|
187
|
+
"name" => root_package["name"],
|
168
188
|
}
|
169
189
|
end
|
170
190
|
|
171
|
-
all_packages = [root_package, *root_package[
|
191
|
+
all_packages = [root_package, *root_package["children_packages"]]
|
172
192
|
{
|
173
193
|
"packages" => sort_and_filter_out_packages(all_packages, options),
|
174
194
|
"package_entities" => package_entities(options),
|
175
195
|
"package_skip_sections" => package_skip_sections(options),
|
176
|
-
"additional_context" => additional_context
|
196
|
+
"additional_context" => additional_context
|
197
|
+
.merge("external_classes" => options["external_classes"]),
|
177
198
|
"root_packages" => [root_package],
|
178
|
-
"name" => root_package[
|
199
|
+
"name" => root_package["name"],
|
179
200
|
}
|
180
201
|
end
|
181
202
|
|
182
203
|
def package_entities(options)
|
183
|
-
return {}
|
184
|
-
|
185
|
-
|
186
|
-
.
|
187
|
-
|
204
|
+
options["packages"] or return {}
|
205
|
+
options["packages"]
|
206
|
+
.find_all { |entity| entity.is_a?(Hash) && entity.values.first["render_entities"] }
|
207
|
+
.map do |entity|
|
208
|
+
[entity.keys.first,
|
209
|
+
entity.values.first["render_entities"].map { |n| [n, true] }.to_h]
|
210
|
+
end.to_h
|
188
211
|
end
|
189
212
|
|
190
213
|
def package_skip_sections(options)
|
191
|
-
return {} unless options[
|
214
|
+
return {} unless options["packages"]
|
192
215
|
|
193
|
-
options[
|
194
|
-
.find_all { |entity| entity.is_a?(Hash) && entity.values.first[
|
195
|
-
.map
|
216
|
+
options["packages"]
|
217
|
+
.find_all { |entity| entity.is_a?(Hash) && entity.values.first["skip_tables"] }
|
218
|
+
.map do |entity|
|
219
|
+
[entity.keys.first, entity.values.first["skip_tables"].map do |n|
|
220
|
+
[n, true]
|
221
|
+
end.to_h]
|
222
|
+
end.to_h
|
196
223
|
end
|
197
224
|
|
198
225
|
def sort_and_filter_out_packages(all_packages, options)
|
199
|
-
return all_packages if options[
|
226
|
+
return all_packages if options["packages"].nil?
|
200
227
|
|
201
228
|
result = []
|
202
229
|
# Step one - filter out all skipped packages
|
203
|
-
options[
|
204
|
-
.find_all { |entity| entity.is_a?(Hash) && entity[
|
230
|
+
options["packages"]
|
231
|
+
.find_all { |entity| entity.is_a?(Hash) && entity["skip"] }
|
205
232
|
.each do |entity|
|
206
|
-
entity_regexp = config_entity_regexp(entity[
|
233
|
+
entity_regexp = config_entity_regexp(entity["skip"])
|
207
234
|
all_packages
|
208
|
-
.delete_if {|package| package[
|
235
|
+
.delete_if { |package| package["name"] =~ entity_regexp }
|
209
236
|
end
|
210
237
|
# Step two - select supplied packages by pattern
|
211
|
-
options[
|
212
|
-
.find_all { |entity| entity.is_a?(String) || (entity.is_a?(Hash) && !entity[
|
238
|
+
options["packages"]
|
239
|
+
.find_all { |entity| entity.is_a?(String) || (entity.is_a?(Hash) && !entity["skip"]) }
|
213
240
|
.each do |entity_obj|
|
214
241
|
entity = entity_obj.is_a?(String) ? entity_obj : entity_obj.keys.first
|
215
242
|
entity_regexp = config_entity_regexp(entity)
|
216
|
-
all_packages.each
|
217
|
-
if package[
|
243
|
+
all_packages.each do |package|
|
244
|
+
if package["name"]&.match?(entity_regexp)
|
218
245
|
result.push(package)
|
219
246
|
all_packages
|
220
|
-
.delete_if {|nest_package| nest_package[
|
247
|
+
.delete_if { |nest_package| nest_package["name"] == package["name"] }
|
221
248
|
end
|
222
249
|
end
|
223
250
|
end
|
@@ -225,34 +252,38 @@ module Metanorma
|
|
225
252
|
end
|
226
253
|
|
227
254
|
def config_entity_regexp(entity)
|
228
|
-
additional_sym =
|
255
|
+
additional_sym = ".*" if /\*$/.match?(entity)
|
229
256
|
%r{^#{Regexp.escape(entity.gsub('*', ''))}#{additional_sym}$}
|
230
257
|
end
|
231
258
|
|
232
|
-
def model_representation(lutaml_document, document, additional_context,
|
259
|
+
def model_representation(lutaml_document, document, additional_context,
|
260
|
+
options)
|
233
261
|
fill_in_entities_refs_attributes(document, lutaml_document, options)
|
234
262
|
render_result, errors = Utils.render_liquid_string(
|
235
|
-
template_string: template(options[
|
263
|
+
template_string: template(options["section_depth"] || 2,
|
264
|
+
options["render_style"],
|
265
|
+
options["include_root"]),
|
236
266
|
context_items: create_context_object(lutaml_document,
|
237
|
-
|
238
|
-
|
267
|
+
additional_context,
|
268
|
+
options),
|
239
269
|
context_name: "context",
|
240
270
|
document: document,
|
241
|
-
include_path: LIQUID_INCLUDE_PATH
|
271
|
+
include_path: LIQUID_INCLUDE_PATH,
|
242
272
|
)
|
243
273
|
Utils.notify_render_errors(document, errors)
|
244
274
|
render_result.split("\n")
|
245
275
|
end
|
246
276
|
|
247
277
|
def template(section_depth, render_style, include_root)
|
248
|
-
include_name = RENDER_STYLES_INCLUDES.fetch(render_style,
|
278
|
+
include_name = RENDER_STYLES_INCLUDES.fetch(render_style,
|
279
|
+
DEFAULT_RENDER_INCLUDE)
|
249
280
|
result = ""
|
250
281
|
if include_root
|
251
282
|
result += <<~LIQUID
|
252
283
|
{% include "#{include_name}", package_skip_sections: context.package_skip_sections, package_entities: context.package_entities, context: context.root_packages, additional_context: context.additional_context, render_nested_packages: false %}
|
253
284
|
LIQUID
|
254
285
|
end
|
255
|
-
result
|
286
|
+
result + <<~LIQUID
|
256
287
|
{% include "#{include_name}", depth: #{section_depth}, package_skip_sections: context.package_skip_sections, package_entities: context.package_entities, context: context, additional_context: context.additional_context, render_nested_packages: context.render_nested_packages %}
|
257
288
|
LIQUID
|
258
289
|
end
|
@@ -17,7 +17,7 @@ module Metanorma
|
|
17
17
|
|
18
18
|
def relative_file_path(document, file_path)
|
19
19
|
docfile_directory = File.dirname(
|
20
|
-
document.attributes["docfile"] || "."
|
20
|
+
document.attributes["docfile"] || ".",
|
21
21
|
)
|
22
22
|
document
|
23
23
|
.path_resolver
|
@@ -28,8 +28,11 @@ module Metanorma
|
|
28
28
|
context_name:, document:, include_path: nil)
|
29
29
|
liquid_template = ::Liquid::Template.parse(template_string)
|
30
30
|
# Allow includes for the template
|
31
|
-
include_paths = [Utils.relative_file_path(document, ""),
|
32
|
-
|
31
|
+
include_paths = [Utils.relative_file_path(document, ""),
|
32
|
+
include_path].compact
|
33
|
+
liquid_template.registers[:file_system] =
|
34
|
+
::Metanorma::Plugin::Lutaml::Liquid::LocalFileSystem
|
35
|
+
.new(include_paths, ["_%s.liquid", "_%s.adoc"])
|
33
36
|
rendered_string = liquid_template
|
34
37
|
.render(context_name => context_items,
|
35
38
|
strict_variables: true,
|
@@ -45,8 +48,12 @@ module Metanorma
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
|
-
def process_express_index(path, cache_path, document,
|
49
|
-
|
51
|
+
def process_express_index(path, cache_path, document,
|
52
|
+
force_read = false)
|
53
|
+
if cache_path
|
54
|
+
cache_full_path = Utils.relative_file_path(document,
|
55
|
+
cache_path)
|
56
|
+
end
|
50
57
|
if !force_read && cache_full_path && File.file?(cache_full_path)
|
51
58
|
return express_from_cache(cache_full_path)
|
52
59
|
end
|
@@ -54,7 +61,8 @@ module Metanorma
|
|
54
61
|
full_path = Utils.relative_file_path(document, path)
|
55
62
|
wrapper = express_from_path(document, full_path)
|
56
63
|
if cache_full_path && !File.file?(cache_full_path)
|
57
|
-
express_write_cache(cache_full_path, wrapper.original_document,
|
64
|
+
express_write_cache(cache_full_path, wrapper.original_document,
|
65
|
+
document)
|
58
66
|
end
|
59
67
|
wrapper
|
60
68
|
rescue Expressir::Error
|
@@ -87,14 +95,17 @@ module Metanorma
|
|
87
95
|
end
|
88
96
|
|
89
97
|
def express_from_folder(folder)
|
90
|
-
files = Dir["#{folder}/*.exp"].map
|
98
|
+
files = Dir["#{folder}/*.exp"].map do |nested_path|
|
99
|
+
File.new(nested_path, encoding: "UTF-8")
|
100
|
+
end
|
91
101
|
::Lutaml::Parser.parse(files)
|
92
102
|
end
|
93
103
|
|
94
104
|
def express_decorate_wrapper(wrapper, document)
|
95
105
|
serialized = wrapper.to_liquid
|
96
106
|
serialized["schemas"] = serialized["schemas"].map do |j|
|
97
|
-
j.merge("relative_path_prefix" => Utils
|
107
|
+
j.merge("relative_path_prefix" => Utils
|
108
|
+
.relative_file_path(document, File.dirname(j["file"])))
|
98
109
|
end
|
99
110
|
serialized
|
100
111
|
end
|
@@ -105,14 +116,12 @@ module Metanorma
|
|
105
116
|
schemas_paths = yaml_content
|
106
117
|
.fetch("schemas")
|
107
118
|
.map do |(schema_name, schema_values)|
|
108
|
-
|
109
|
-
|
110
|
-
else
|
111
|
-
File.join(root_path.to_s, "#{schema_name}.exp")
|
112
|
-
end
|
119
|
+
schema_values["path"] || File.join(root_path.to_s,
|
120
|
+
"#{schema_name}.exp")
|
113
121
|
end
|
114
122
|
files_to_load = schemas_paths.map do |path|
|
115
|
-
File.new(Utils.relative_file_path(document, path),
|
123
|
+
File.new(Utils.relative_file_path(document, path),
|
124
|
+
encoding: "UTF-8")
|
116
125
|
end
|
117
126
|
::Lutaml::Parser.parse(files_to_load)
|
118
127
|
end
|
@@ -121,7 +130,7 @@ module Metanorma
|
|
121
130
|
express_indexes = {}
|
122
131
|
loop do
|
123
132
|
line = input_lines.next
|
124
|
-
break if line.
|
133
|
+
break if line.empty?
|
125
134
|
|
126
135
|
match = line.match(LUTAML_EXP_IDX_TAG)
|
127
136
|
if match
|
@@ -130,7 +139,8 @@ module Metanorma
|
|
130
139
|
cache = match[:cache_path]
|
131
140
|
repositories = process_express_index(path.strip, cache, document)
|
132
141
|
if repositories
|
133
|
-
express_indexes[name.strip] =
|
142
|
+
express_indexes[name.strip] =
|
143
|
+
express_decorate_wrapper(repositories, document)
|
134
144
|
end
|
135
145
|
end
|
136
146
|
end
|
@@ -13,15 +13,4 @@ module Metanorma
|
|
13
13
|
module Lutaml
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
17
|
-
Asciidoctor::Extensions.register do
|
18
|
-
preprocessor Metanorma::Plugin::Lutaml::LutamlPreprocessor
|
19
|
-
preprocessor Metanorma::Plugin::Lutaml::LutamlUmlAttributesTablePreprocessor
|
20
|
-
preprocessor Metanorma::Plugin::Lutaml::LutamlUmlDatamodelDescriptionPreprocessor
|
21
|
-
preprocessor Metanorma::Plugin::Lutaml::LutamlUmlClassPreprocessor
|
22
|
-
inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
|
23
|
-
inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
|
24
|
-
block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
|
25
|
-
block Metanorma::Plugin::Lutaml::LutamlDiagramBlock
|
26
|
-
end
|
27
16
|
end
|
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.
|
4
|
+
version: 0.5.0
|
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: 2024-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -256,6 +256,7 @@ files:
|
|
256
256
|
- bin/console
|
257
257
|
- bin/setup
|
258
258
|
- lib/metanorma-plugin-lutaml.rb
|
259
|
+
- lib/metanorma/plugin/lutaml/asciidoctor/preprocessor.rb
|
259
260
|
- lib/metanorma/plugin/lutaml/express_remarks_decorator.rb
|
260
261
|
- lib/metanorma/plugin/lutaml/liquid/custom_filters.rb
|
261
262
|
- lib/metanorma/plugin/lutaml/liquid/multiply_local_file_system.rb
|