metanorma-plugin-lutaml 0.7.38 → 0.7.40

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +5 -1
  3. data/.gitignore +2 -1
  4. data/.rubocop.yml +11 -2
  5. data/.rubocop_todo.yml +238 -0
  6. data/CLAUDE.md +82 -0
  7. data/Gemfile +15 -13
  8. data/Gemfile.devel +2 -0
  9. data/README.adoc +3 -0
  10. data/Rakefile +17 -0
  11. data/docs/usages/express.adoc +55 -0
  12. data/docs/usages/lutaml-xsd.adoc +94 -0
  13. data/lib/metanorma/plugin/lutaml/base_preprocessor.rb +221 -0
  14. data/lib/metanorma/plugin/lutaml/base_structured_text_preprocessor.rb +5 -5
  15. data/lib/metanorma/plugin/lutaml/data2_text_preprocessor.rb +1 -0
  16. data/lib/metanorma/plugin/lutaml/express_remarks_decorator.rb +1 -1
  17. data/lib/metanorma/plugin/lutaml/json2_text_preprocessor.rb +1 -0
  18. data/lib/metanorma/plugin/lutaml/liquid/multiply_local_file_system.rb +2 -2
  19. data/lib/metanorma/plugin/lutaml/liquid_templates/_klass_table.liquid +6 -6
  20. data/lib/metanorma/plugin/lutaml/lutaml_ea_diagram_block_macro.rb +1 -1
  21. data/lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb +135 -15
  22. data/lib/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor.rb +2 -2
  23. data/lib/metanorma/plugin/lutaml/lutaml_enum_table_block_macro.rb +1 -3
  24. data/lib/metanorma/plugin/lutaml/lutaml_gml_dictionary_block.rb +1 -0
  25. data/lib/metanorma/plugin/lutaml/lutaml_klass_table_block_macro.rb +2 -3
  26. data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +47 -212
  27. data/lib/metanorma/plugin/lutaml/lutaml_table_inline_macro.rb +1 -0
  28. data/lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb +2 -2
  29. data/lib/metanorma/plugin/lutaml/lutaml_xmi_uml_preprocessor.rb +2 -2
  30. data/lib/metanorma/plugin/lutaml/lutaml_xsd_preprocessor.rb +95 -0
  31. data/lib/metanorma/plugin/lutaml/source_extractor.rb +3 -3
  32. data/lib/metanorma/plugin/lutaml/utils.rb +58 -21
  33. data/lib/metanorma/plugin/lutaml/version.rb +1 -1
  34. data/lib/metanorma/plugin/lutaml/yaml2_text_preprocessor.rb +1 -0
  35. data/lib/metanorma-plugin-lutaml.rb +2 -0
  36. data/metanorma-plugin-lutaml.gemspec +6 -5
  37. metadata +43 -12
  38. data/.hound.yml +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb242e5ff7bfcfa7b4baec472a6fc0ecf0be94558913c8bb39bcf19655640e12
4
- data.tar.gz: 81455de9a154af7534d43830562613fbee00bd8ce2c252ce13be79fc790efaec
3
+ metadata.gz: ab934a775aa2b0aa6abeb544d5dcaf3c4c8fcf37daa75119d5ba9d57a09196e8
4
+ data.tar.gz: ca930ec2f902c975ffaecc0b5bdd2fb15ad8e68f4dfb72cce3626cd54d9cc560
5
5
  SHA512:
6
- metadata.gz: c84b7143c72c6bbb6334bc9c27faea196a516edd34c67607579f61b0a371be648c9087e5b297159f98d60654f43ffc9a2c736a5e5c546196f7251917cc042d28
7
- data.tar.gz: b68b53795e9576abc2e1beb3746219ae2ca0ab8e888ab15f0c79430f94eedb870a568fe425e9a3ae503ba34e03d603436cc2dcb0cd64068500d30db421e079e5
6
+ metadata.gz: a6b32f1e6a256f7c548578fc324d25bfdf0c0a389233c02836178b95af7dca009723f72407fd8dab9f18761535915da9b665ab819bd6fdd8ee67ceae290d1139
7
+ data.tar.gz: dece27d9189a6b36ec3a0e80aa6c376eabcd8af181f52409f1d5ae559a85a7611eee30c4146a598a751dc26bbb7cf85482f540ca38dc767465a99013e914dee0
@@ -10,6 +10,10 @@ on:
10
10
 
11
11
  jobs:
12
12
  rake:
13
- uses: metanorma/ci/.github/workflows/graphviz-rake.yml@main
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
@@ -5,4 +5,5 @@ test.err
5
5
 
6
6
  .rubocop-https--*
7
7
  .DS_Store
8
- .vscode
8
+ .vscode
9
+ *.log.txt
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/master/ci/rubocop.yml
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: 2.5
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,82 @@
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
+ - `BasePreprocessor` — abstract base for EXPRESS and XSD preprocessors. Uses Template Method pattern: subclasses implement `lutaml_liquid?`, `load_lutaml_file`, `index_type_name` and may override `update_repo`, `template`, `reorder_schemas`.
43
+ - `LutamlPreprocessor` < `BasePreprocessor` — handles `[lutaml]`, `[lutaml_express]`, `[lutaml_express_liquid]` blocks. Adds EXPRESS-specific `update_repo` (cache unwrap, remark decoration), Liquid environment with custom tags/filters, schema reordering.
44
+ - `LutamlXsdPreprocessor` < `BasePreprocessor` — handles `[lutaml_xsd]` blocks. Parses XSD files via `lutaml-model`, double-newline template joins for Asciidoctor paragraph breaks.
45
+ - `LutamlUmlDatamodelDescriptionPreprocessor` and `LutamlEaXmiPreprocessor` — both include `LutamlEaXmiBase`, which handles XMI parsing via `lutaml` gem and renders using bundled Liquid templates.
46
+ - `LutamlXmiUmlPreprocessor` — another XMI-based preprocessor with its own macro regex.
47
+ - `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).
48
+
49
+ ### Key Shared Modules
50
+
51
+ - `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.
52
+ - `LutamlEaXmiBase` — shared logic for XMI-based preprocessors: XMI document loading/caching, config YAML parsing, package filtering/sorting, Liquid context building, nested macro collection.
53
+ - `LutamlDiagramBase` — shared logic for diagram block extensions: parses LutaML DSL, renders via Graphviz to PNG.
54
+ - `LutamlGmlDictionaryBase` — parses GML XML via `ogc-gml` gem, renders via Liquid.
55
+ - `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.
56
+
57
+ ### Liquid Template System
58
+
59
+ The plugin uses Liquid templates extensively. Key components:
60
+
61
+ - **Custom Liquid environment** with registered `keyiterator` tag and custom filters (`html2adoc`, `values`, `replace_regex`, `loadfile`, `file_exist`).
62
+ - **`Liquid::LocalFileSystem`** subclass (`multiply_local_file_system.rb`) resolves includes from multiple paths.
63
+ - **Liquid Drops** (`liquid_drops/`) wrap domain objects (e.g., `GmlDictionaryDrop`) for template rendering.
64
+ - **Bundled templates** live in `lib/metanorma/plugin/lutaml/liquid_templates/` for XMI/EA rendering.
65
+
66
+ ### Config System
67
+
68
+ 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.
69
+
70
+ ### Testing Pattern
71
+
72
+ 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/`.
73
+
74
+ ## Key Dependencies
75
+
76
+ - `lutaml` — core LutaML parser/model library (EXPRESS, UML, XMI, XSD formats)
77
+ - `lutaml-model` — LutaML serialization framework (provides XSD parsing, Liquid drops)
78
+ - `expressir` — EXPRESS schema parser
79
+ - `ogc-gml` — OGC GML dictionary parser
80
+ - `liquid` — template rendering engine
81
+ - `asciidoctor` — document processing framework
82
+ - `canon` — semantic XML comparison for test assertions
data/Gemfile CHANGED
@@ -12,18 +12,20 @@ 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
- gem "rake", "~> 13"
21
- gem "rspec", "~> 3.6"
15
+ gem "canon"
16
+ gem "html2doc", github: "metanorma/html2doc", branch: "main"
17
+ gem "lutaml"
18
+ gem "metanorma", github: "metanorma/metanorma", branch: "main"
19
+ gem "metanorma-standoc", github: "metanorma/metanorma-standoc", branch: "main"
20
+ gem "rake"
21
+ gem "rspec"
22
22
  gem "rspec-html-matchers"
23
- gem "rubocop", "~> 1.58"
24
- gem "rubocop-performance", "~> 1.19"
25
- gem "simplecov", "~> 0.15"
26
- gem "timecop", "~> 0.9"
27
- gem "vcr", "~> 6.1.0"
23
+ gem "rubocop"
24
+ gem "rubocop-performance"
25
+ gem "rubocop-rake"
26
+ gem "rubocop-rspec"
27
+ gem "simplecov"
28
+ gem "timecop"
29
+ gem "vcr"
28
30
  gem "webmock"
29
- gem "xml-c14n"
31
+
data/Gemfile.devel ADDED
@@ -0,0 +1,2 @@
1
+ gem "metanorma-standoc", github: "metanorma/metanorma-standoc", branch: "main"
2
+ gem "metanorma", github: "metanorma/metanorma", branch: "main"
data/README.adoc CHANGED
@@ -14,6 +14,7 @@ within a Metanorma document:
14
14
  * Enterprise Architect exported UML files in XMI format (`*.xmi`)
15
15
  * LutaML GML Dictionary files (`*.xml`)
16
16
  * JSON or YAML files (`*.json|*.yml|*.yaml`)
17
+ * XML Schema files (`*.xsd`)
17
18
 
18
19
  == Installation
19
20
 
@@ -34,6 +35,8 @@ link:docs/usages/lutaml-gml.adoc[Usage with LutaML GML Dictionary by lutaml_gml_
34
35
 
35
36
  link:docs/usages/json_yaml.adoc[Usage with JSON or YAML files by data2text, yaml2text or json2text]
36
37
 
38
+ link:docs/usages/lutaml-xsd.adoc[Usage with XML Schema files by lutaml_xsd]
39
+
37
40
  == Documentation
38
41
 
39
42
  Please refer to https://www.metanorma.org.
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
@@ -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
+
@@ -0,0 +1,94 @@
1
+ == Usage with LutaML XSD
2
+
3
+ === Overview
4
+
5
+ The `lutaml_xsd` macro parses *XML Schema (XSD)* files through `lutaml-model`
6
+ and exposes the parsed schema object to *Liquid* templates.
7
+
8
+ === Syntax
9
+
10
+ [source,adoc]
11
+ -----
12
+ [lutaml_xsd,<path_to_xsd>,<context_name>[, option1=value1, option2=value2, ...]]
13
+ ----
14
+ <your Liquid template here>
15
+ ----
16
+ -----
17
+
18
+ * `<path_to_xsd>`: Path to the XSD file to be processed.
19
+ * `<context_name>`: The name of the context variable to use in the template.
20
+ * `option1=value1, ...`: Optional parameters (<<options,supported options>>).
21
+
22
+ [[options]]
23
+ === Options
24
+
25
+ * `location`: Base URL or path for resolving `<xs:import>` and `<xs:include>`
26
+ statements in the XSD. When omitted, the directory of `<path_to_xsd>` is used.
27
+
28
+ === Liquid Template Context
29
+
30
+ The context variable (e.g., `unitsml`) exposes the parsed
31
+ `Lutaml::Xml::Schema::Xsd::Schema` object through its Liquid drop.
32
+
33
+ Commonly used schema collections:
34
+
35
+ * `element`: List of elements defined in the XSD.
36
+ * `complex_type`: List of complex types defined in the XSD.
37
+ * `simple_type`, `attribute`, `attribute_group`, `group`, `import`, and
38
+ `include`: Other schema components exposed by `lutaml-model`.
39
+
40
+ Commonly used helpers:
41
+
42
+ * `elements_sorted_by_name`, `complex_types_sorted_by_name`,
43
+ `attribute_groups_sorted_by_name`: Sorted schema collections.
44
+ * `used_by`, `child_elements`, `attribute_elements`, and `referenced_type`:
45
+ Component helpers exposed by parsed XSD objects.
46
+
47
+ === Example: Listing Elements and Complex Types
48
+
49
+ [source,adoc]
50
+ -----
51
+ = Elements
52
+ [lutaml_xsd,path/to/unitsml.xsd,unitsml]
53
+ ----
54
+ {% for element in unitsml.elements_sorted_by_name %}
55
+ Name: *{{ element.name }}*
56
+ Type: *{{ element.type }}*
57
+ Used by: {{ element.used_by | map: "name" | join: ", " }}
58
+ {% endfor %}
59
+ ----
60
+
61
+ = ComplexTypes
62
+ [lutaml_xsd,path/to/unitsml.xsd,unitsml]
63
+ ----
64
+ {% for complex_type in unitsml.complex_types_sorted_by_name %}
65
+ Name: *{{ complex_type.name }}*
66
+ Children: {{ complex_type.child_elements | map: "name" | join: ", " }}
67
+ Attributes: {{ complex_type.attribute_elements | map: "name" | join: ", " }}
68
+ {% endfor %}
69
+ ----
70
+ -----
71
+
72
+ === Example: Using with Remote XSD and Options
73
+
74
+ [source,adoc]
75
+ -----
76
+ [lutaml_xsd,path/to/omml.xsd,omml, location=https://raw.githubusercontent.com/t-yuki/ooxml-xsd/refs/heads/master]
77
+ ----
78
+ {% for element in omml.element %}
79
+ Name: *{{ element.name }}*
80
+ Type: *{{ element.type }}*
81
+ {% endfor %}
82
+ ----
83
+ -----
84
+
85
+ === Use Cases
86
+
87
+ * Generate documentation for XML schemas.
88
+ * Extract and list schema elements and types or other details.
89
+ * Customize output using Liquid templates.
90
+
91
+ === Notes
92
+
93
+ * The macro supports local files at `<path_to_xsd>`.
94
+ * You can use all standard *Liquid* template features for formatting and logic.