metanorma-plugin-lutaml 0.7.37 → 0.7.39
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 +4 -4
- data/.github/workflows/rake.yml +5 -1
- data/.gitignore +2 -1
- data/.rubocop.yml +11 -2
- data/.rubocop_todo.yml +238 -0
- data/CLAUDE.md +78 -0
- data/Gemfile +8 -12
- data/Gemfile.devel +2 -0
- data/Rakefile +17 -0
- data/docs/usages/enterprise_architect.adoc +17 -0
- data/docs/usages/express.adoc +55 -0
- data/lib/metanorma/plugin/lutaml/base_structured_text_preprocessor.rb +6 -6
- data/lib/metanorma/plugin/lutaml/data2_text_preprocessor.rb +1 -0
- data/lib/metanorma/plugin/lutaml/express_remarks_decorator.rb +2 -2
- data/lib/metanorma/plugin/lutaml/json2_text_preprocessor.rb +1 -0
- data/lib/metanorma/plugin/lutaml/liquid/multiply_local_file_system.rb +2 -2
- data/lib/metanorma/plugin/lutaml/liquid_templates/_klass_table.liquid +6 -6
- data/lib/metanorma/plugin/lutaml/lutaml_ea_diagram_block_macro.rb +1 -1
- data/lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb +164 -15
- data/lib/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor.rb +2 -2
- data/lib/metanorma/plugin/lutaml/lutaml_enum_table_block_macro.rb +8 -42
- data/lib/metanorma/plugin/lutaml/lutaml_gml_dictionary_block.rb +1 -0
- data/lib/metanorma/plugin/lutaml/lutaml_klass_table_block_macro.rb +9 -42
- data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +8 -6
- data/lib/metanorma/plugin/lutaml/lutaml_table_inline_macro.rb +1 -0
- data/lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb +2 -2
- data/lib/metanorma/plugin/lutaml/lutaml_xmi_uml_preprocessor.rb +2 -2
- data/lib/metanorma/plugin/lutaml/source_extractor.rb +3 -3
- data/lib/metanorma/plugin/lutaml/utils.rb +52 -8
- data/lib/metanorma/plugin/lutaml/version.rb +1 -1
- data/lib/metanorma/plugin/lutaml/yaml2_text_preprocessor.rb +1 -0
- data/metanorma-plugin-lutaml.gemspec +4 -4
- metadata +25 -11
- data/.hound.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ad20f1059d6fb886f3b8f8e209a5eb2053bd84cf197b4df0a6f28c32ceb05b76
|
|
4
|
+
data.tar.gz: ea0e8cdfdc56ada195921fbefff8256f67e702dba4685a001ba22051031bfc74
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a72753313c88e6a7bc1388c764fe2f315faf4ff7447690dd5d6a8851f5fe15285d1b53629ff6c79db3ba53ec20e7cdb9d05242e1ef2b5e9fe7b6e69076cedad0
|
|
7
|
+
data.tar.gz: 98fbf0c36b867aae35acf710853ea74506bfc7835e8ed4368e9acedc84fe9f622f2cc44aae66fabc75bd49c9242487027d94239cec948972cf0e6117941e1ac2
|
data/.github/workflows/rake.yml
CHANGED
|
@@ -10,6 +10,10 @@ on:
|
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
12
|
rake:
|
|
13
|
-
uses: metanorma/ci/.github/workflows/
|
|
13
|
+
uses: metanorma/ci/.github/workflows/generic-rake.yml@main
|
|
14
|
+
with:
|
|
15
|
+
setup-tools: graphviz
|
|
16
|
+
submodules: true
|
|
17
|
+
choco-cache: true
|
|
14
18
|
secrets:
|
|
15
19
|
pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
# Auto-generated by Cimas: Do not edit it manually!
|
|
2
2
|
# See https://github.com/metanorma/cimas
|
|
3
3
|
inherit_from:
|
|
4
|
-
- https://raw.githubusercontent.com/riboseinc/oss-guides/
|
|
4
|
+
- https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
|
|
5
|
+
- .rubocop_todo.yml
|
|
6
|
+
|
|
7
|
+
inherit_mode:
|
|
8
|
+
merge:
|
|
9
|
+
- Exclude
|
|
5
10
|
|
|
6
11
|
# local repo-specific modifications
|
|
7
12
|
# ...
|
|
13
|
+
plugins:
|
|
14
|
+
- rubocop-rspec
|
|
15
|
+
- rubocop-performance
|
|
16
|
+
- rubocop-rake
|
|
8
17
|
|
|
9
18
|
AllCops:
|
|
10
|
-
TargetRubyVersion:
|
|
19
|
+
TargetRubyVersion: 3.0
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2026-05-12 14:53:16 UTC using RuboCop version 1.86.1.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 1
|
|
10
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
+
Gemspec/RequireMFA:
|
|
12
|
+
Exclude:
|
|
13
|
+
- 'metanorma-plugin-lutaml.gemspec'
|
|
14
|
+
|
|
15
|
+
# Offense count: 1
|
|
16
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
17
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
18
|
+
# SupportedStyles: with_first_argument, with_fixed_indentation
|
|
19
|
+
Layout/ArgumentAlignment:
|
|
20
|
+
Exclude:
|
|
21
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_klass_table_block_macro.rb'
|
|
22
|
+
|
|
23
|
+
# Offense count: 1
|
|
24
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
25
|
+
Layout/ClosingParenthesisIndentation:
|
|
26
|
+
Exclude:
|
|
27
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
28
|
+
|
|
29
|
+
# Offense count: 1
|
|
30
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
31
|
+
Layout/EmptyLines:
|
|
32
|
+
Exclude:
|
|
33
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
34
|
+
|
|
35
|
+
# Offense count: 1
|
|
36
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
37
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
38
|
+
# SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
|
|
39
|
+
Layout/FirstArgumentIndentation:
|
|
40
|
+
Exclude:
|
|
41
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
42
|
+
|
|
43
|
+
# Offense count: 9
|
|
44
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
45
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
46
|
+
# URISchemes: http, https
|
|
47
|
+
Layout/LineLength:
|
|
48
|
+
Exclude:
|
|
49
|
+
- 'Rakefile'
|
|
50
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
51
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_klass_table_block_macro.rb'
|
|
52
|
+
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
53
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb'
|
|
54
|
+
- 'spec/support/shared_examples/structured_data_2_text_preprocessor.rb'
|
|
55
|
+
|
|
56
|
+
# Offense count: 1
|
|
57
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
58
|
+
# Configuration parameters: EnforcedStyle.
|
|
59
|
+
# SupportedStyles: symmetrical, new_line, same_line
|
|
60
|
+
Layout/MultilineMethodCallBraceLayout:
|
|
61
|
+
Exclude:
|
|
62
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
63
|
+
|
|
64
|
+
# Offense count: 3
|
|
65
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
66
|
+
# Configuration parameters: AllowInHeredoc.
|
|
67
|
+
Layout/TrailingWhitespace:
|
|
68
|
+
Exclude:
|
|
69
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
70
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_klass_table_block_macro.rb'
|
|
71
|
+
|
|
72
|
+
# Offense count: 1
|
|
73
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
74
|
+
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
|
75
|
+
# NotImplementedExceptions: NotImplementedError
|
|
76
|
+
Lint/UnusedMethodArgument:
|
|
77
|
+
Exclude:
|
|
78
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
79
|
+
|
|
80
|
+
# Offense count: 1
|
|
81
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
82
|
+
Metrics/AbcSize:
|
|
83
|
+
Exclude:
|
|
84
|
+
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
85
|
+
|
|
86
|
+
# Offense count: 2
|
|
87
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
88
|
+
Metrics/CyclomaticComplexity:
|
|
89
|
+
Exclude:
|
|
90
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
91
|
+
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
92
|
+
|
|
93
|
+
# Offense count: 3
|
|
94
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
95
|
+
Metrics/MethodLength:
|
|
96
|
+
Max: 19
|
|
97
|
+
|
|
98
|
+
# Offense count: 2
|
|
99
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
100
|
+
Metrics/PerceivedComplexity:
|
|
101
|
+
Exclude:
|
|
102
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
103
|
+
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
104
|
+
|
|
105
|
+
# Offense count: 1
|
|
106
|
+
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
|
107
|
+
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
|
|
108
|
+
Naming/MethodParameterName:
|
|
109
|
+
Exclude:
|
|
110
|
+
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
111
|
+
|
|
112
|
+
# Offense count: 2
|
|
113
|
+
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
|
114
|
+
# AllowedMethods: call
|
|
115
|
+
# WaywardPredicates: infinite?, nonzero?
|
|
116
|
+
Naming/PredicateMethod:
|
|
117
|
+
Exclude:
|
|
118
|
+
- 'lib/metanorma/plugin/lutaml/asciidoctor/preprocessor.rb'
|
|
119
|
+
- 'lib/metanorma/plugin/lutaml/liquid/custom_filters/file_exist.rb'
|
|
120
|
+
|
|
121
|
+
# Offense count: 1
|
|
122
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
123
|
+
Performance/AncestorsInclude:
|
|
124
|
+
Exclude:
|
|
125
|
+
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
126
|
+
|
|
127
|
+
# Offense count: 86
|
|
128
|
+
# Configuration parameters: Prefixes, AllowedPatterns.
|
|
129
|
+
# Prefixes: when, with, without
|
|
130
|
+
RSpec/ContextWording:
|
|
131
|
+
Exclude:
|
|
132
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor_spec.rb'
|
|
133
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_enum_table_block_macro_spec.rb'
|
|
134
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_gml_dictionary_block_macro_spec.rb'
|
|
135
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_gml_dictionary_block_spec.rb'
|
|
136
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_klass_table_block_macro_spec.rb'
|
|
137
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_text_preprocessor_spec.rb'
|
|
138
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb'
|
|
139
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb'
|
|
140
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_uml_preprocessor_spec.rb'
|
|
141
|
+
- 'spec/metanorma/plugin/lutaml/macros_data2text_spec.rb'
|
|
142
|
+
- 'spec/support/shared_examples/structured_data_2_text_preprocessor.rb'
|
|
143
|
+
|
|
144
|
+
# Offense count: 37
|
|
145
|
+
# Configuration parameters: CountAsOne.
|
|
146
|
+
RSpec/ExampleLength:
|
|
147
|
+
Max: 26
|
|
148
|
+
|
|
149
|
+
# Offense count: 13
|
|
150
|
+
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
|
151
|
+
RSpec/IndexedLet:
|
|
152
|
+
Exclude:
|
|
153
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_ea_diagram_block_macro_spec.rb'
|
|
154
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb'
|
|
155
|
+
- 'spec/metanorma/plugin/lutaml/macros_data2text_spec.rb'
|
|
156
|
+
- 'spec/support/shared_examples/structured_data_2_text_preprocessor.rb'
|
|
157
|
+
|
|
158
|
+
# Offense count: 4
|
|
159
|
+
# Configuration parameters: AssignmentOnly.
|
|
160
|
+
RSpec/InstanceVariable:
|
|
161
|
+
Exclude:
|
|
162
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_express_preprocessor_spec.rb'
|
|
163
|
+
|
|
164
|
+
# Offense count: 44
|
|
165
|
+
RSpec/LeakyLocalVariable:
|
|
166
|
+
Exclude:
|
|
167
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor_spec.rb'
|
|
168
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_klass_table_block_macro_spec.rb'
|
|
169
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb'
|
|
170
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb'
|
|
171
|
+
|
|
172
|
+
# Offense count: 14
|
|
173
|
+
RSpec/MultipleExpectations:
|
|
174
|
+
Max: 6
|
|
175
|
+
|
|
176
|
+
# Offense count: 9
|
|
177
|
+
# Configuration parameters: AllowSubject.
|
|
178
|
+
RSpec/MultipleMemoizedHelpers:
|
|
179
|
+
Max: 8
|
|
180
|
+
|
|
181
|
+
# Offense count: 41
|
|
182
|
+
# Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
|
|
183
|
+
# SupportedStyles: always, named_only
|
|
184
|
+
RSpec/NamedSubject:
|
|
185
|
+
Exclude:
|
|
186
|
+
- 'spec/metanorma/plugin/lutaml/config/root_spec.rb'
|
|
187
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor_spec.rb'
|
|
188
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_gml_dictionary_block_macro_spec.rb'
|
|
189
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_gml_dictionary_block_spec.rb'
|
|
190
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb'
|
|
191
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb'
|
|
192
|
+
- 'spec/metanorma/plugin/lutaml/source_extractor_spec.rb'
|
|
193
|
+
|
|
194
|
+
# Offense count: 117
|
|
195
|
+
# Configuration parameters: AllowedGroups.
|
|
196
|
+
RSpec/NestedGroups:
|
|
197
|
+
Max: 7
|
|
198
|
+
|
|
199
|
+
# Offense count: 1
|
|
200
|
+
RSpec/PendingWithoutReason:
|
|
201
|
+
Exclude:
|
|
202
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_text_preprocessor_spec.rb'
|
|
203
|
+
|
|
204
|
+
# Offense count: 2
|
|
205
|
+
RSpec/RepeatedExampleGroupBody:
|
|
206
|
+
Exclude:
|
|
207
|
+
- 'spec/metanorma/plugin/lutaml/macros_yaml2text_spec.rb'
|
|
208
|
+
|
|
209
|
+
# Offense count: 6
|
|
210
|
+
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
|
|
211
|
+
# SupportedInflectors: default, active_support
|
|
212
|
+
RSpec/SpecFilePathFormat:
|
|
213
|
+
Exclude:
|
|
214
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_express_preprocessor_spec.rb'
|
|
215
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_text_preprocessor_spec.rb'
|
|
216
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb'
|
|
217
|
+
- 'spec/metanorma/plugin/lutaml/macros_data2text_spec.rb'
|
|
218
|
+
- 'spec/metanorma/plugin/lutaml/macros_json2text_spec.rb'
|
|
219
|
+
- 'spec/metanorma/plugin/lutaml/macros_yaml2text_spec.rb'
|
|
220
|
+
|
|
221
|
+
# Offense count: 1
|
|
222
|
+
RSpec/SubjectDeclaration:
|
|
223
|
+
Exclude:
|
|
224
|
+
- 'spec/metanorma/plugin/lutaml/config/root_spec.rb'
|
|
225
|
+
|
|
226
|
+
# Offense count: 1
|
|
227
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
228
|
+
Style/RedundantBegin:
|
|
229
|
+
Exclude:
|
|
230
|
+
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
231
|
+
|
|
232
|
+
# Offense count: 1
|
|
233
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
234
|
+
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
|
235
|
+
# SupportedStyles: single_quotes, double_quotes
|
|
236
|
+
Style/StringLiterals:
|
|
237
|
+
Exclude:
|
|
238
|
+
- 'metanorma-plugin-lutaml.gemspec'
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`metanorma-plugin-lutaml` is a Ruby gem that provides Asciidoctor extensions for the Metanorma document publishing system. It enables Metanorma documents to embed and render data models from multiple formats: EXPRESS (ISO 10303), LutaML DSL, Enterprise Architect XMI, GML Dictionaries, JSON, and YAML.
|
|
8
|
+
|
|
9
|
+
## Build and Test Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install dependencies
|
|
13
|
+
bundle install
|
|
14
|
+
|
|
15
|
+
# Run all tests
|
|
16
|
+
bundle exec rake
|
|
17
|
+
|
|
18
|
+
# Run a single test file
|
|
19
|
+
bundle exec rspec spec/metanorma/plugin/lutaml/lutaml_preprocessor_spec.rb
|
|
20
|
+
|
|
21
|
+
# Run a specific test by line number
|
|
22
|
+
bundle exec rspec spec/metanorma/plugin/lutaml/lutaml_preprocessor_spec.rb:42
|
|
23
|
+
|
|
24
|
+
# Lint
|
|
25
|
+
bundle exec rubocop
|
|
26
|
+
|
|
27
|
+
# Build the gem
|
|
28
|
+
bundle exec rake build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Architecture
|
|
32
|
+
|
|
33
|
+
### Asciidoctor Extension Pattern
|
|
34
|
+
|
|
35
|
+
All extensions follow the Asciidoctor extension API. The two main extension types are:
|
|
36
|
+
|
|
37
|
+
- **Preprocessors** (`::Asciidoctor::Extensions::Preprocessor`): Process document text before rendering. They read input lines, detect custom block syntax (e.g., `[lutaml_express, ...]`), and replace them with rendered content via Liquid templates.
|
|
38
|
+
- **Block/BlockMacro/InlineMacro extensions**: Handle `lutaml_diagram`, `lutaml_ea_diagram`, `lutaml_gml_dictionary`, `lutaml_klass_table`, `lutaml_enum_table`, `lutaml_table`, `lutaml_figure` — these are Asciidoctor block-level or inline macros.
|
|
39
|
+
|
|
40
|
+
### Preprocessor Inheritance Hierarchy
|
|
41
|
+
|
|
42
|
+
- `LutamlPreprocessor` — handles `[lutaml]`, `[lutaml_express]`, `[lutaml_express_liquid]` blocks. Parses EXPRESS files via the `lutaml`/`expressir` gems, builds Liquid contexts, and renders templates.
|
|
43
|
+
- `LutamlUmlDatamodelDescriptionPreprocessor` and `LutamlEaXmiPreprocessor` — both include `LutamlEaXmiBase`, which handles XMI parsing via `lutaml` gem and renders using bundled Liquid templates.
|
|
44
|
+
- `LutamlXmiUmlPreprocessor` — another XMI-based preprocessor with its own macro regex.
|
|
45
|
+
- `BaseStructuredTextPreprocessor` — base for `[yaml2text]`, `[json2text]`, `[data2text]` blocks. Its subclasses (`Yaml2TextPreprocessor`, `Json2TextPreprocessor`, `Data2TextPreprocessor`) differ only in how they load content (YAML vs JSON vs auto-detect). The `Content` module provides the actual parsing logic.
|
|
46
|
+
|
|
47
|
+
### Key Shared Modules
|
|
48
|
+
|
|
49
|
+
- `Utils` (`lib/metanorma/plugin/lutaml/utils.rb`) — shared helpers: file path resolution relative to document, Liquid template rendering with custom environment/filters, EXPRESS repository loading with caching, parsing document-level `:lutaml-express-index:` attributes.
|
|
50
|
+
- `LutamlEaXmiBase` — shared logic for XMI-based preprocessors: XMI document loading/caching, config YAML parsing, package filtering/sorting, Liquid context building, nested macro collection.
|
|
51
|
+
- `LutamlDiagramBase` — shared logic for diagram block extensions: parses LutaML DSL, renders via Graphviz to PNG.
|
|
52
|
+
- `LutamlGmlDictionaryBase` — parses GML XML via `ogc-gml` gem, renders via Liquid.
|
|
53
|
+
- `SourceExtractor` — scans document lines for anchors (`[[id]]`, `[#id]`, `[id=...]`) and `include::`/`embed::` directives, extracting source blocks into `document.attributes["source_blocks"]` for later use by preprocessors.
|
|
54
|
+
|
|
55
|
+
### Liquid Template System
|
|
56
|
+
|
|
57
|
+
The plugin uses Liquid templates extensively. Key components:
|
|
58
|
+
|
|
59
|
+
- **Custom Liquid environment** with registered `keyiterator` tag and custom filters (`html2adoc`, `values`, `replace_regex`, `loadfile`, `file_exist`).
|
|
60
|
+
- **`Liquid::LocalFileSystem`** subclass (`multiply_local_file_system.rb`) resolves includes from multiple paths.
|
|
61
|
+
- **Liquid Drops** (`liquid_drops/`) wrap domain objects (e.g., `GmlDictionaryDrop`) for template rendering.
|
|
62
|
+
- **Bundled templates** live in `lib/metanorma/plugin/lutaml/liquid_templates/` for XMI/EA rendering.
|
|
63
|
+
|
|
64
|
+
### Config System
|
|
65
|
+
|
|
66
|
+
The `Config` module (`lib/metanorma/plugin/lutaml/config.rb`) uses `lutaml/model` (LutaML::Model) to define config schemas: `Root`, `Package`, `Guidance`, `GuidanceKlass`, `GuidanceAttribute`. Config YAML files control which packages/entities to render from XMI documents.
|
|
67
|
+
|
|
68
|
+
### Testing Pattern
|
|
69
|
+
|
|
70
|
+
Tests use `metanorma-standoc` as the backend. The spec helper registers all extensions with Asciidoctor, then tests call `metanorma_convert(input)` which converts AsciiDoc input through the pipeline and compares XML output. Test fixtures (`.exp`, `.lutaml`, `.xmi`, `.xml`, `.liquid` files) are in `spec/fixtures/lutaml/` and `spec/assets/lutaml/`.
|
|
71
|
+
|
|
72
|
+
## Key Dependencies
|
|
73
|
+
|
|
74
|
+
- `lutaml` — core LutaML parser/model library (EXPRESS, UML, XMI formats)
|
|
75
|
+
- `expressir` — EXPRESS schema parser
|
|
76
|
+
- `ogc-gml` — OGC GML dictionary parser
|
|
77
|
+
- `liquid` — template rendering engine
|
|
78
|
+
- `asciidoctor` — document processing framework
|
data/Gemfile
CHANGED
|
@@ -12,18 +12,14 @@ rescue StandardError
|
|
|
12
12
|
nil
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
gem "byebug"
|
|
16
|
-
gem "debug"
|
|
17
|
-
gem "equivalent-xml"
|
|
18
|
-
gem "metanorma"
|
|
19
|
-
gem "metanorma-standoc", "~> 3.0.8"
|
|
20
15
|
gem "rake", "~> 13"
|
|
21
|
-
gem "rspec"
|
|
16
|
+
gem "rspec"
|
|
22
17
|
gem "rspec-html-matchers"
|
|
23
|
-
gem "rubocop"
|
|
24
|
-
gem "rubocop-performance"
|
|
25
|
-
gem "
|
|
26
|
-
gem "
|
|
27
|
-
gem "
|
|
18
|
+
gem "rubocop"
|
|
19
|
+
gem "rubocop-performance"
|
|
20
|
+
gem "rubocop-rake"
|
|
21
|
+
gem "rubocop-rspec"
|
|
22
|
+
gem "simplecov"
|
|
23
|
+
gem "timecop"
|
|
24
|
+
gem "vcr"
|
|
28
25
|
gem "webmock"
|
|
29
|
-
gem "xml-c14n"
|
data/Gemfile.devel
ADDED
data/Rakefile
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
|
3
3
|
|
|
4
|
+
XMI_SPEC_FILES = %w[
|
|
5
|
+
spec/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor_spec.rb
|
|
6
|
+
spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb
|
|
7
|
+
spec/metanorma/plugin/lutaml/lutaml_klass_table_block_macro_spec.rb
|
|
8
|
+
spec/metanorma/plugin/lutaml/lutaml_enum_table_block_macro_spec.rb
|
|
9
|
+
spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb
|
|
10
|
+
spec/metanorma/plugin/lutaml/lutaml_xmi_uml_preprocessor_spec.rb
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
4
13
|
RSpec::Core::RakeTask.new(:spec)
|
|
5
14
|
|
|
15
|
+
RSpec::Core::RakeTask.new(:fast) do |t|
|
|
16
|
+
t.pattern = FileList["spec/**/*_spec.rb"] - XMI_SPEC_FILES
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
RSpec::Core::RakeTask.new(:xmi) do |t|
|
|
20
|
+
t.pattern = FileList[XMI_SPEC_FILES]
|
|
21
|
+
end
|
|
22
|
+
|
|
6
23
|
task default: :spec
|
|
@@ -184,6 +184,15 @@ The command accepts the options listed below:
|
|
|
184
184
|
`lib/metanorma/plugin/lutaml/templates`. This template can be customized by
|
|
185
185
|
changing the template path in the `template` option.
|
|
186
186
|
|
|
187
|
+
* `external_data="context_name:/path/to/my_data.yml"` specifies the path of
|
|
188
|
+
the YAML/JSON file of the external data to be used in the liquid template.
|
|
189
|
+
(Optional)
|
|
190
|
+
You can specify multiple external data by separating them with `;`.
|
|
191
|
+
(e.g. `external_data="my_data:/path/to/my_data.yml;second_data:/path/to/my_second_data.yml"`)
|
|
192
|
+
In the liquid template, you can access the data by using `context_name`.
|
|
193
|
+
(e.g. `my_data` or `second_data` in the above example)
|
|
194
|
+
The external data file should be in YAML/JSON format.
|
|
195
|
+
|
|
187
196
|
* `guidance="/path/to/my_guidance.yml"` specifies the path of
|
|
188
197
|
the yaml file of the guidance. (Optional)
|
|
189
198
|
|
|
@@ -240,6 +249,14 @@ The command accepts the options listed below:
|
|
|
240
249
|
`lib/metanorma/plugin/lutaml/templates`. This template can be customized by
|
|
241
250
|
changing the template path in the `template` option.
|
|
242
251
|
|
|
252
|
+
* `external_data="context_name:/path/to/my_data.yml"` specifies the path of
|
|
253
|
+
the YAML/JSON file of the external data to be used in the liquid template.
|
|
254
|
+
(Optional)
|
|
255
|
+
You can specify multiple external data by separating them with `;`.
|
|
256
|
+
(e.g. `external_data="my_data:/path/to/my_data.yml;second_data:/path/to/my_second_data.yml"`)
|
|
257
|
+
In the liquid template, you can access the data by using `context_name`.
|
|
258
|
+
(e.g. `my_data` or `second_data` in the above example)
|
|
259
|
+
The external data file should be in YAML/JSON format.
|
|
243
260
|
|
|
244
261
|
=== Usage of `lutaml_ea_xmi` command
|
|
245
262
|
|
data/docs/usages/express.adoc
CHANGED
|
@@ -297,3 +297,58 @@ from the paths other than the location of the document.
|
|
|
297
297
|
The resulting block adds the `include_path` to the Liquid renderer. The path is
|
|
298
298
|
resolved based on the location of the document. You can add multiple paths by
|
|
299
299
|
separating them with commas.
|
|
300
|
+
|
|
301
|
+
=== Using `loadfile` filter in templates
|
|
302
|
+
|
|
303
|
+
This functionality allows `[lutaml_express_liquid]` blocks to load data from
|
|
304
|
+
a yaml or json file from the specified path.
|
|
305
|
+
|
|
306
|
+
For example, you have the Metanorma document file (.adoc) with the following
|
|
307
|
+
content:
|
|
308
|
+
|
|
309
|
+
[source,adoc]
|
|
310
|
+
-----
|
|
311
|
+
:lutaml-express-index: all_schemas; ../schemas_all.yaml;
|
|
312
|
+
|
|
313
|
+
[lutaml_express_liquid,all_schemas,context,config_yaml=schemas.yaml,include_path=../templates]
|
|
314
|
+
---
|
|
315
|
+
{% assign all_schemas = repo.schemas %}
|
|
316
|
+
{% render "templates/resources/schema" for ordered_schemas as schema %}
|
|
317
|
+
...
|
|
318
|
+
----
|
|
319
|
+
-----
|
|
320
|
+
|
|
321
|
+
You have the liquid template file
|
|
322
|
+
`templates/resources/schema.liquid` with the following content:
|
|
323
|
+
|
|
324
|
+
[source,liquid]
|
|
325
|
+
-----
|
|
326
|
+
{% assign data = "my_file.yaml" | loadfile: "." %}
|
|
327
|
+
This is {{ data.shape }} with color {{ data.color }}.
|
|
328
|
+
-----
|
|
329
|
+
|
|
330
|
+
Where:
|
|
331
|
+
|
|
332
|
+
* `loadfile:` is a liquid filter that loads the file content based on the path
|
|
333
|
+
`my_file.yaml` with argument `.`.
|
|
334
|
+
The argument is the path of the parent folder, which is the
|
|
335
|
+
current directory of the Metanorma document.
|
|
336
|
+
|
|
337
|
+
And the content of the yaml file `my_file.yaml` looks like:
|
|
338
|
+
|
|
339
|
+
[source,yaml]
|
|
340
|
+
----
|
|
341
|
+
---
|
|
342
|
+
shape: square
|
|
343
|
+
color: blue
|
|
344
|
+
corners: 4
|
|
345
|
+
----
|
|
346
|
+
|
|
347
|
+
Will render as:
|
|
348
|
+
[source,asciidoc]
|
|
349
|
+
----
|
|
350
|
+
...
|
|
351
|
+
This is square with color blue.
|
|
352
|
+
...
|
|
353
|
+
----
|
|
354
|
+
|
|
@@ -15,9 +15,9 @@ module Metanorma
|
|
|
15
15
|
::Asciidoctor::Extensions::Preprocessor
|
|
16
16
|
include Utils
|
|
17
17
|
|
|
18
|
-
BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}
|
|
19
|
-
BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z
|
|
20
|
-
LOAD_FILE_REGEXP = /{% assign (.*) = (.*) \| load_file %}
|
|
18
|
+
BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/
|
|
19
|
+
BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/
|
|
20
|
+
LOAD_FILE_REGEXP = /{% assign (.*) = (.*) \| load_file %}/
|
|
21
21
|
INCLUDE_PATH_OPTION = "include_path"
|
|
22
22
|
TEMPLATE_OPTION = "template"
|
|
23
23
|
|
|
@@ -63,7 +63,7 @@ module Metanorma
|
|
|
63
63
|
load_file_match = block_line.match(LOAD_FILE_REGEXP)
|
|
64
64
|
|
|
65
65
|
# Add parent folder as argument to loadfile filter
|
|
66
|
-
block_line = "{% assign #{load_file_match[1]} = "\
|
|
66
|
+
block_line = "{% assign #{load_file_match[1]} = " \
|
|
67
67
|
"#{load_file_match[2]} | loadfile: " \
|
|
68
68
|
"\"#{document.attributes['docdir']}\" %}"
|
|
69
69
|
end
|
|
@@ -106,7 +106,7 @@ module Metanorma
|
|
|
106
106
|
)
|
|
107
107
|
multiple_contexts
|
|
108
108
|
elsif block_match[1].start_with?("#")
|
|
109
|
-
anchor = block_match[1].split(",").first.strip[1
|
|
109
|
+
anchor = block_match[1].split(",").first.strip[1..]
|
|
110
110
|
{
|
|
111
111
|
block_match[1].split(",").last.strip =>
|
|
112
112
|
content_from_anchor(document, anchor),
|
|
@@ -153,7 +153,7 @@ module Metanorma
|
|
|
153
153
|
end
|
|
154
154
|
line
|
|
155
155
|
.gsub(/(?<!{){(?!%)([^{}]{1,900})(?<!%)}(?!})/, '{{\1}}')
|
|
156
|
-
.gsub(/[a-z
|
|
156
|
+
.gsub(/[a-z.]{1,900}\#/, "index")
|
|
157
157
|
.gsub(/{{([^}]{1,900})\s+\+\s+(\d+)\s*?}}/, '{{ \1 | plus: \2 }}')
|
|
158
158
|
.gsub(/{{([^}]{1,900})\s+-\s+(\d+)\s*?}}/, '{{ \1 | minus: \2 }}')
|
|
159
159
|
.gsub(/{{([^}]{1,500})\.values([^}]{0,500})}}/,
|
|
@@ -9,14 +9,14 @@ module Metanorma
|
|
|
9
9
|
(link|image|video|audio|include) # Capture group 1: content type
|
|
10
10
|
(:+)? # Capture group 2: optional colons
|
|
11
11
|
(?! # Negative lookahead
|
|
12
|
-
[
|
|
12
|
+
[^/:]+://| # Don't match URLs (http://, etc.)
|
|
13
13
|
[A-Z]:/| # Don't match Windows paths
|
|
14
14
|
/ # Don't match absolute paths
|
|
15
15
|
) # End negative lookahead
|
|
16
16
|
([^:\[]+) # Capture group 3: the path/name
|
|
17
17
|
(\[.*\])? # Capture group 4: optional attribute
|
|
18
18
|
$ # End of line
|
|
19
|
-
}x
|
|
19
|
+
}x
|
|
20
20
|
|
|
21
21
|
attr_reader :remark, :options
|
|
22
22
|
|
|
@@ -52,8 +52,8 @@ module Metanorma
|
|
|
52
52
|
|
|
53
53
|
if result_path.nil?
|
|
54
54
|
raise ::Liquid::FileSystemError,
|
|
55
|
-
"No documents in template path:
|
|
56
|
-
"
|
|
55
|
+
"No documents in template path: " \
|
|
56
|
+
"#{File.expand_path(template_path)}"
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
unless roots.any? do |root|
|
|
@@ -22,7 +22,7 @@ h| Stereotype 2+| {{ stereotype }}
|
|
|
22
22
|
3+h| Inherited Properties
|
|
23
23
|
h| Property Name h| Property Type and Multiplicity h| Definition
|
|
24
24
|
{% for attr in root.inherited_props %}
|
|
25
|
-
{%-
|
|
25
|
+
{%- unless attr.has_association? -%}
|
|
26
26
|
{%- capture name_col -%}
|
|
27
27
|
{{ attr.name_ns }}:{{ attr.name }}
|
|
28
28
|
({{ attr.gen_name }})
|
|
@@ -30,13 +30,13 @@ h| Property Name h| Property Type and Multiplicity h| Definition
|
|
|
30
30
|
| {{ name_col | newline_to_br }}
|
|
31
31
|
| {{ attr.type }} [{{ attr.cardinality.min }}..{{ attr.cardinality.max }}]
|
|
32
32
|
| {{ attr.definition }}
|
|
33
|
-
{%-
|
|
33
|
+
{%- endunless -%}
|
|
34
34
|
{% endfor %}
|
|
35
35
|
|
|
36
36
|
3+h| Self-defined Properties
|
|
37
37
|
h| Property Name h| Property Type and Multiplicity h| Definition
|
|
38
38
|
{% for attr in root.owned_props %}
|
|
39
|
-
{%-
|
|
39
|
+
{%- unless attr.has_association? -%}
|
|
40
40
|
{%- capture name_col -%}
|
|
41
41
|
{{ attr.name_ns }}:{{ attr.name }}
|
|
42
42
|
({{ attr.gen_name }})
|
|
@@ -44,13 +44,13 @@ h| Property Name h| Property Type and Multiplicity h| Definition
|
|
|
44
44
|
| {{ name_col | newline_to_br }}
|
|
45
45
|
| {{ attr.type }} [{{ attr.cardinality.min }}..{{ attr.cardinality.max }}]
|
|
46
46
|
| {{ attr.definition }}
|
|
47
|
-
{%-
|
|
47
|
+
{%- endunless -%}
|
|
48
48
|
{% endfor %}
|
|
49
49
|
|
|
50
50
|
3+h| Properties Inherited from Association
|
|
51
51
|
h| Property Name h| Property Type and Multiplicity h| Definition
|
|
52
52
|
{% for attr in root.inherited_assoc_props %}
|
|
53
|
-
{%- if attr.has_association?
|
|
53
|
+
{%- if attr.has_association? -%}
|
|
54
54
|
{%- capture name_col -%}
|
|
55
55
|
{{ attr.name_ns }}:{{ attr.name }}
|
|
56
56
|
({{ attr.gen_name }})
|
|
@@ -64,7 +64,7 @@ h| Property Name h| Property Type and Multiplicity h| Definition
|
|
|
64
64
|
3+h| Properties Defined in Association
|
|
65
65
|
h| Property Name h| Property Type and Multiplicity h| Definition
|
|
66
66
|
{% for attr in root.assoc_props %}
|
|
67
|
-
{%- if attr.has_association?
|
|
67
|
+
{%- if attr.has_association? -%}
|
|
68
68
|
{%- capture name_col -%}
|
|
69
69
|
{{ attr.name_ns }}:{{ attr.name }}
|
|
70
70
|
({{ attr.gen_name }})
|