suma 0.1.13 → 0.1.14
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/README.adoc +85 -4
- data/lib/suma/cli/extract_terms.rb +286 -0
- data/lib/suma/cli/generate_schemas.rb +141 -0
- data/lib/suma/cli.rb +20 -0
- data/lib/suma/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d52aaad6ea81bb43e193cdf0c8e190dfe02f71791e218314a401ae3bea254cd3
|
4
|
+
data.tar.gz: a573936a7eabfad21a4768e6c32869ecc286a2980feeaf8350720b674c604f34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7278d60481858a6507bf97f738df21f0168c60c6453f9de4479545c589450f63c148923be20b31a8bb88e50344adbf8521cfe12a826dbff3103e492782727f3
|
7
|
+
data.tar.gz: b37f9d1f0676607011f6f2059f0b639a563273930eb7961ee52866c04b30df14a7b88076752f4bf2ff4cfd4911a402b547b1c486c42cd9cc381d4e631bc6aac4
|
data/README.adoc
CHANGED
@@ -37,10 +37,12 @@ $ gem install suma
|
|
37
37
|
# Defaults to `suma help`
|
38
38
|
$ suma
|
39
39
|
Commands:
|
40
|
-
suma build METANORMA_SITE_MANIFEST
|
41
|
-
suma reformat EXPRESS_FILE_PATH
|
42
|
-
suma validate SUBCOMMAND ...ARGS
|
43
|
-
suma
|
40
|
+
suma build METANORMA_SITE_MANIFEST # Build collection specified in site manifest (`metanorma*.yml`)
|
41
|
+
suma reformat EXPRESS_FILE_PATH # Reformat EXPRESS files
|
42
|
+
suma validate SUBCOMMAND ...ARGS # Validate express documents
|
43
|
+
suma generate_schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE # Generate schemas manifest file from Metanorma manifest YAML file
|
44
|
+
suma extract_terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH # Extract terms from schema manifest file
|
45
|
+
suma help [COMMAND] # Describe available commands or one specific command
|
44
46
|
----
|
45
47
|
|
46
48
|
=== Build command
|
@@ -287,6 +289,85 @@ Replacement: AsciiMath: xx
|
|
287
289
|
----
|
288
290
|
|
289
291
|
|
292
|
+
=== Generate schemas command
|
293
|
+
|
294
|
+
The `suma generate_schemas` command generates a schema manifest file containing
|
295
|
+
all schemas defined in the Metanorma manifest file.
|
296
|
+
|
297
|
+
[source,sh]
|
298
|
+
----
|
299
|
+
$ suma generate_schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE [options]
|
300
|
+
----
|
301
|
+
|
302
|
+
Parameters:
|
303
|
+
|
304
|
+
`METANORMA_MANIFEST_FILE`:: Path to the Metanorma manifest file
|
305
|
+
(e.g.: "metanorma-smrl-all.yml")
|
306
|
+
|
307
|
+
Options:
|
308
|
+
|
309
|
+
`--exclude_path`, `-e`:: Exclude schemas by pattern (e.g. `*_lf.exp`)
|
310
|
+
|
311
|
+
[example]
|
312
|
+
====
|
313
|
+
.To generate schemas manifest file from Metanorma manifest file
|
314
|
+
[source,sh]
|
315
|
+
----
|
316
|
+
$ bundle exec suma generate_schemas metanorma-smrl-all.yml schemas-smrl-all.yml
|
317
|
+
# => generates schemas-smrl-all.yml
|
318
|
+
----
|
319
|
+
|
320
|
+
.To generate schemas manifest file from Metanorma manifest file and exclude schemas with names like `*_lf.exp`
|
321
|
+
[source,sh]
|
322
|
+
----
|
323
|
+
$ bundle exec suma generate_schemas metanorma-smrl-all.yml schemas-smrl-all.yml -e *_lf.exp
|
324
|
+
# => generates schemas-smrl-all.yml without schemas with names like *_lf.exp
|
325
|
+
----
|
326
|
+
====
|
327
|
+
|
328
|
+
All documents need to have a `schemas.yaml` in their document root that lists
|
329
|
+
out which schemas the document includes.
|
330
|
+
|
331
|
+
|
332
|
+
=== Extract terms command
|
333
|
+
|
334
|
+
The `suma extract_terms` command extracts terms from SCHEMA_MANIFEST_FILE and
|
335
|
+
generates Glossarist v2 dataset in the output directory.
|
336
|
+
|
337
|
+
[source,sh]
|
338
|
+
----
|
339
|
+
$ suma extract_terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH [options]
|
340
|
+
----
|
341
|
+
|
342
|
+
Parameters:
|
343
|
+
|
344
|
+
`SCHEMA_MANIFEST_FILE`:: Path to SCHEMA_MANIFEST_FILE
|
345
|
+
|
346
|
+
`GLOSSARIST_OUTPUT_PATH`:: Path to the output directory for the Glossarist v2
|
347
|
+
dataset
|
348
|
+
|
349
|
+
Options:
|
350
|
+
|
351
|
+
`language_code`:: Language code for the Glossarist (default: "eng")
|
352
|
+
|
353
|
+
[example]
|
354
|
+
====
|
355
|
+
.To extract terms from SCHEMA_MANIFEST_FILE
|
356
|
+
[source,sh]
|
357
|
+
----
|
358
|
+
$ bundle exec suma extract_terms path/to/schemas-smrl-all.yml glossarist_output
|
359
|
+
# => generates glossarist_output/concept/foo.yaml and glossarist_output/localized_concept/bar.yaml
|
360
|
+
----
|
361
|
+
|
362
|
+
.To extract terms from SCHEMA_MANIFEST_FILE with language code "fra"
|
363
|
+
[source,sh]
|
364
|
+
----
|
365
|
+
$ bundle exec suma extract_terms path/to/schemas-smrl-all.yml glossarist_output -l fra
|
366
|
+
# => generates glossarist_output/concept/foo.yaml and glossarist_output/localized_concept/bar.yaml
|
367
|
+
----
|
368
|
+
====
|
369
|
+
|
370
|
+
|
290
371
|
== Usage: Ruby
|
291
372
|
|
292
373
|
=== General
|
@@ -0,0 +1,286 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
require_relative "../thor_ext"
|
5
|
+
require "fileutils"
|
6
|
+
require "expressir"
|
7
|
+
require "yaml"
|
8
|
+
require "securerandom"
|
9
|
+
require "glossarist"
|
10
|
+
|
11
|
+
module Suma
|
12
|
+
module Cli
|
13
|
+
# ExtractTerms command using Expressir to extract terms into the
|
14
|
+
# Glossarist v2 format
|
15
|
+
class ExtractTerms < Thor
|
16
|
+
desc "extract_terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH",
|
17
|
+
"Extract terms from SCHEMA_MANIFEST_FILE into " \
|
18
|
+
"Glossarist v2 format"
|
19
|
+
option :language_code, type: :string, default: "eng", aliases: "-l",
|
20
|
+
desc: "Language code for the Glossarist"
|
21
|
+
|
22
|
+
YAML_FILE_EXTENSIONS = [".yaml", ".yml"].freeze
|
23
|
+
|
24
|
+
def extract_terms(schema_manifest_file, output_path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
25
|
+
language_code = options[:language_code]
|
26
|
+
schema_manifest_file = File.expand_path(schema_manifest_file)
|
27
|
+
|
28
|
+
if File.file?(schema_manifest_file)
|
29
|
+
unless File.exist?(schema_manifest_file)
|
30
|
+
raise Errno::ENOENT, "Specified SCHEMA_MANIFEST_FILE " \
|
31
|
+
"`#{schema_manifest_file}` not found."
|
32
|
+
end
|
33
|
+
|
34
|
+
if !YAML_FILE_EXTENSIONS.include?(File.extname(schema_manifest_file))
|
35
|
+
raise ArgumentError, "Specified SCHEMA_MANIFEST_FILE " \
|
36
|
+
"`#{schema_manifest_file}` " \
|
37
|
+
"is not a YAML file."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
run(schema_manifest_file, output_path, language_code)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def run(schema_manifest_file, output_path, language_code = "eng")
|
47
|
+
exp_files = get_exp_files(schema_manifest_file)
|
48
|
+
|
49
|
+
exp_files.map do |exp_file|
|
50
|
+
extract(exp_file, output_path, language_code)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_exp_files(schema_manifest_file)
|
55
|
+
data = YAML.safe_load(
|
56
|
+
File.read(schema_manifest_file, encoding: "UTF-8"),
|
57
|
+
permitted_classes: [Date, Time, Symbol],
|
58
|
+
permitted_symbols: [],
|
59
|
+
aliases: true,
|
60
|
+
)
|
61
|
+
|
62
|
+
paths = data["schemas"].values.filter_map { |v| v["path"] }
|
63
|
+
|
64
|
+
if paths.empty?
|
65
|
+
raise Errno::ENOENT, "No EXPRESS files found in " \
|
66
|
+
"`#{schema_manifest_file}`."
|
67
|
+
end
|
68
|
+
|
69
|
+
# resolve paths relative to the directory of the schema manifest file
|
70
|
+
paths.map do |path|
|
71
|
+
File.expand_path(path, File.dirname(schema_manifest_file))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def extract(exp_file, output_path, language_code) # rubocop:disable Metrics/AbcSize
|
76
|
+
puts "Processing EXPRESS file: #{exp_file}"
|
77
|
+
repo = Expressir::Express::Parser.from_file(exp_file)
|
78
|
+
schema = get_default_schema(repo)
|
79
|
+
|
80
|
+
collection = build_managed_concept_collection(
|
81
|
+
schema, language_code
|
82
|
+
)
|
83
|
+
|
84
|
+
output_data(collection, output_path, exp_file)
|
85
|
+
end
|
86
|
+
|
87
|
+
def output_data(collection, output_path, exp_file)
|
88
|
+
unless File.exist?(output_path)
|
89
|
+
FileUtils.mkdir_p(File.expand_path(output_path))
|
90
|
+
end
|
91
|
+
|
92
|
+
puts "Saving collection to files in: #{File.expand_path(output_path)}"
|
93
|
+
collection.save_to_files(File.expand_path(output_path))
|
94
|
+
|
95
|
+
puts "Processing EXPRESS file: #{exp_file}...Done."
|
96
|
+
collection
|
97
|
+
end
|
98
|
+
|
99
|
+
def build_managed_concept_collection(schema, language_code) # rubocop:disable Metrics/AbcSize
|
100
|
+
managed_concept_data = Glossarist::ManagedConceptData.new
|
101
|
+
managed_concept_data.id = get_identifier(schema)
|
102
|
+
|
103
|
+
localized_concept_id = SecureRandom.uuid
|
104
|
+
localized_concept = build_localized_concept(
|
105
|
+
schema, language_code, localized_concept_id
|
106
|
+
)
|
107
|
+
|
108
|
+
managed_concept_data
|
109
|
+
.localizations[localized_concept.language_code] = localized_concept
|
110
|
+
|
111
|
+
managed_concept_data.localized_concepts = {
|
112
|
+
localized_concept.language_code => localized_concept_id,
|
113
|
+
}
|
114
|
+
|
115
|
+
managed_concept = Glossarist::ManagedConcept.new
|
116
|
+
managed_concept.uuid = SecureRandom.uuid
|
117
|
+
managed_concept.data = managed_concept_data
|
118
|
+
|
119
|
+
collection = Glossarist::ManagedConceptCollection.new
|
120
|
+
collection.store(managed_concept)
|
121
|
+
collection
|
122
|
+
end
|
123
|
+
|
124
|
+
def build_localized_concept(schema, language_code, localized_concept_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
|
125
|
+
schema_domain = get_domain(schema)
|
126
|
+
|
127
|
+
localized_concept_data = Glossarist::ConceptData.new
|
128
|
+
localized_concept_data.terms = get_terms(schema) || []
|
129
|
+
localized_concept_data.definition = get_definitions(schema) || []
|
130
|
+
localized_concept_data.notes = get_notes(schema, schema_domain) || []
|
131
|
+
localized_concept_data.examples = get_examples(schema,
|
132
|
+
schema_domain) || []
|
133
|
+
localized_concept_data.language_code = language_code
|
134
|
+
localized_concept_data.domain = schema_domain
|
135
|
+
localized_concept_data.sources = get_source_ref(schema) || []
|
136
|
+
|
137
|
+
localized_concept = Glossarist::LocalizedConcept.new
|
138
|
+
localized_concept.data = localized_concept_data
|
139
|
+
|
140
|
+
localized_concept.uuid = localized_concept_id
|
141
|
+
localized_concept
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_default_schema(repo)
|
145
|
+
repo.schemas.first
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_identifier(schema)
|
149
|
+
remark_item = schema.remark_items.find do |s|
|
150
|
+
s.id == "__identifier"
|
151
|
+
end
|
152
|
+
remark_item.remarks.first || SecureRandom.uuid
|
153
|
+
end
|
154
|
+
|
155
|
+
def get_title(schema)
|
156
|
+
remark_item = schema.remark_items.find do |s|
|
157
|
+
s.id == "__title"
|
158
|
+
end
|
159
|
+
remark_item.remarks.first
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_source_ref(schema)
|
163
|
+
remark_item = schema.remark_items.find do |s|
|
164
|
+
s.id == "__published_in"
|
165
|
+
end
|
166
|
+
ref = remark_item&.remarks&.first
|
167
|
+
|
168
|
+
if ref
|
169
|
+
Glossarist::ConceptSource.new(
|
170
|
+
type: "authoritative",
|
171
|
+
origin: Glossarist::Citation.new(ref: ref),
|
172
|
+
)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def get_domain(schema)
|
177
|
+
prefix = module?(schema) ? "application module" : "resource"
|
178
|
+
"#{prefix}: #{schema.id}"
|
179
|
+
end
|
180
|
+
|
181
|
+
def module?(schema)
|
182
|
+
remark_item = schema.remark_items.find do |s|
|
183
|
+
s.id == "__schema_file"
|
184
|
+
end
|
185
|
+
|
186
|
+
File.basename(remark_item.remarks.first, ".*") == "module"
|
187
|
+
end
|
188
|
+
|
189
|
+
def arm?(schema_id)
|
190
|
+
schema_id.end_with?("_arm")
|
191
|
+
end
|
192
|
+
|
193
|
+
def get_terms(schema)
|
194
|
+
schema_title = get_title(schema)
|
195
|
+
if schema_title
|
196
|
+
[
|
197
|
+
Glossarist::Designation::Base.new(
|
198
|
+
designation: schema_title,
|
199
|
+
type: "expression",
|
200
|
+
normative_status: "preferred",
|
201
|
+
),
|
202
|
+
]
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def get_schema_type(schema)
|
207
|
+
return "resource" if !module?(schema)
|
208
|
+
|
209
|
+
return "arm" if arm?(schema.id)
|
210
|
+
|
211
|
+
"min"
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_definitions(schema)
|
215
|
+
type = get_schema_type(schema)
|
216
|
+
subtype = get_subtype_of(schema)
|
217
|
+
|
218
|
+
represent_str = "that represents the #{get_title(schema)} {{entity}}"
|
219
|
+
if subtype
|
220
|
+
represent_str = "that is a type of #{subtype} #{represent_str}"
|
221
|
+
end
|
222
|
+
|
223
|
+
definition = case type
|
224
|
+
when "arm"
|
225
|
+
"{{application object}} #{represent_str}"
|
226
|
+
else
|
227
|
+
"{{entity data type}} #{represent_str}"
|
228
|
+
end
|
229
|
+
[Glossarist::DetailedDefinition.new(content: definition)]
|
230
|
+
end
|
231
|
+
|
232
|
+
def get_subtype_of(schema)
|
233
|
+
schema.entities.first&.subtype_of&.first&.id # rubocop:disable Style/SafeNavigationChainLength
|
234
|
+
end
|
235
|
+
|
236
|
+
# get entities remarks and remark items with id `__note` as notes
|
237
|
+
def get_notes(schema, schema_domain) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
|
238
|
+
notes = schema.entities&.map do |entity|
|
239
|
+
[
|
240
|
+
entity.remarks,
|
241
|
+
entity.remark_items&.select do |ri|
|
242
|
+
ri.id == "__note"
|
243
|
+
end&.map(&:remarks),
|
244
|
+
]
|
245
|
+
end&.flatten&.compact
|
246
|
+
|
247
|
+
notes&.map do |note|
|
248
|
+
Glossarist::DetailedDefinition.new(
|
249
|
+
content: convert_express_xref(note, schema_domain),
|
250
|
+
)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# get entities remark items with id `__example` as examples
|
255
|
+
def get_examples(schema, schema_domain) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
|
256
|
+
examples = schema.entities&.map do |entity|
|
257
|
+
entity.remark_items&.select do |ri|
|
258
|
+
ri.id == "__example"
|
259
|
+
end&.map(&:remarks)
|
260
|
+
end&.flatten&.compact
|
261
|
+
|
262
|
+
examples&.map do |example|
|
263
|
+
Glossarist::DetailedDefinition.new(
|
264
|
+
content: convert_express_xref(example, schema_domain),
|
265
|
+
)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def convert_express_xref(content, schema_domain)
|
270
|
+
content.gsub(/<<express:(.*),(.*)>>/) do
|
271
|
+
"{{<#{schema_domain}>" \
|
272
|
+
"#{Regexp.last_match(1).split('.').last},#{Regexp.last_match(2)}}}"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def get_concept_filename(concept)
|
277
|
+
identifier = concept["data"]["identifier"]
|
278
|
+
"#{sanitize_string(identifier)}.yaml"
|
279
|
+
end
|
280
|
+
|
281
|
+
def sanitize_string(str)
|
282
|
+
str.gsub(" ", "_").gsub("/", "_").gsub(":", "_")
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require "thor"
|
2
|
+
require_relative "../thor_ext"
|
3
|
+
require "fileutils"
|
4
|
+
require "yaml"
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
module Suma
|
8
|
+
module Cli
|
9
|
+
# GenerateSchemas command to generate Schemas YAML by Metanorma YAML
|
10
|
+
class GenerateSchemas < Thor
|
11
|
+
desc "generate_schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE",
|
12
|
+
"Generate EXPRESS schema manifest file from Metanorma site manifest"
|
13
|
+
option :exclude_paths, type: :string, default: nil, aliases: "-e",
|
14
|
+
desc: "Exclude schemas paths by pattern " \
|
15
|
+
"(e.g. `*_lf.exp`)"
|
16
|
+
|
17
|
+
YAML_FILE_EXTENSIONS = [".yaml", ".yml"].freeze
|
18
|
+
|
19
|
+
def generate_schemas(metanorma_manifest_file, schema_manifest_file) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
20
|
+
metanorma_manifest_file = File.expand_path(metanorma_manifest_file)
|
21
|
+
|
22
|
+
unless File.exist?(metanorma_manifest_file)
|
23
|
+
raise Errno::ENOENT, "Specified file `#{metanorma_manifest_file}` " \
|
24
|
+
"not found."
|
25
|
+
end
|
26
|
+
|
27
|
+
unless File.file?(metanorma_manifest_file)
|
28
|
+
raise ArgumentError, "Specified path `#{metanorma_manifest_file}` " \
|
29
|
+
"is not a file."
|
30
|
+
end
|
31
|
+
|
32
|
+
[metanorma_manifest_file, schema_manifest_file].each do |file|
|
33
|
+
if !YAML_FILE_EXTENSIONS.include?(File.extname(file))
|
34
|
+
raise ArgumentError, "Specified file `#{file}` is not a YAML file."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
run(
|
39
|
+
metanorma_manifest_file, schema_manifest_file,
|
40
|
+
exclude_paths: options[:exclude_paths]
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def run(metanorma_manifest_file, schema_manifest_file, exclude_paths: nil)
|
47
|
+
metanorma_data = load_yaml(metanorma_manifest_file)
|
48
|
+
collection_files = metanorma_data["metanorma"]["source"]["files"]
|
49
|
+
manifest_files = load_manifest_files(collection_files)
|
50
|
+
all_schemas = load_project_schemas(manifest_files, exclude_paths,
|
51
|
+
schema_manifest_file)
|
52
|
+
all_schemas["schemas"] = all_schemas["schemas"].sort.to_h
|
53
|
+
output_data(all_schemas, schema_manifest_file)
|
54
|
+
end
|
55
|
+
|
56
|
+
def output_data(all_schemas, path)
|
57
|
+
puts "Writing the Schemas YAML file to #{File.expand_path(path)}..."
|
58
|
+
# debug use only
|
59
|
+
# puts all_schemas.to_yaml
|
60
|
+
File.write(File.expand_path(path), all_schemas.to_yaml)
|
61
|
+
puts "Writing the Schemas YAML file to #{File.expand_path(path)}...Done"
|
62
|
+
end
|
63
|
+
|
64
|
+
def load_yaml(file_path)
|
65
|
+
YAML.safe_load(
|
66
|
+
File.read(file_path, encoding: "UTF-8"),
|
67
|
+
permitted_classes: [Date, Time, Symbol],
|
68
|
+
permitted_symbols: [],
|
69
|
+
aliases: true,
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def load_manifest_files(collection_files)
|
74
|
+
manifest_files = collection_files.map do |c|
|
75
|
+
collection_data = load_yaml(c)
|
76
|
+
collection_data["manifest"]["docref"].map { |docref| docref["file"] }
|
77
|
+
end
|
78
|
+
manifest_files.flatten
|
79
|
+
end
|
80
|
+
|
81
|
+
def load_project_schemas( # rubocop:disable Metrics/AbcSize
|
82
|
+
manifest_files, exclude_paths, schema_manifest_file
|
83
|
+
)
|
84
|
+
all_schemas = { "schemas" => {} }
|
85
|
+
|
86
|
+
manifest_files.each do |file|
|
87
|
+
# load schemas.yaml from the location of the collection.yml file
|
88
|
+
schemas_file_path = File.expand_path(
|
89
|
+
file.gsub("collection.yml", "schemas.yaml"),
|
90
|
+
)
|
91
|
+
unless File.exist?(schemas_file_path)
|
92
|
+
puts "Schemas file not found: #{schemas_file_path}"
|
93
|
+
next
|
94
|
+
end
|
95
|
+
|
96
|
+
schemas_data = load_yaml(schemas_file_path)
|
97
|
+
|
98
|
+
if schemas_data["schemas"]
|
99
|
+
schemas_data["schemas"] = fix_path(
|
100
|
+
schemas_data,
|
101
|
+
schemas_file_path,
|
102
|
+
schema_manifest_file,
|
103
|
+
)
|
104
|
+
all_schemas["schemas"].merge!(schemas_data["schemas"])
|
105
|
+
end
|
106
|
+
|
107
|
+
if exclude_paths
|
108
|
+
all_schemas["schemas"].delete_if do |_key, value|
|
109
|
+
value["path"].match?(
|
110
|
+
Regexp.new(exclude_paths.gsub("*", "(.*){1,999}")),
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
all_schemas
|
117
|
+
end
|
118
|
+
|
119
|
+
def fix_path(schemas_data, schemas_file_path, schema_manifest_file) # rubocop:disable Metrics/AbcSize
|
120
|
+
schema_manifest_path = File.expand_path(schema_manifest_file, Dir.pwd)
|
121
|
+
|
122
|
+
schemas_data["schemas"].each do |key, value|
|
123
|
+
# resolve the path in the schema file by the path in the schemas.yaml
|
124
|
+
path_in_schema = File.expand_path(
|
125
|
+
value["path"],
|
126
|
+
File.dirname(schemas_file_path),
|
127
|
+
)
|
128
|
+
|
129
|
+
# calculate the relative path from the schema manifest file
|
130
|
+
fixed_path = Pathname.new(path_in_schema).relative_path_from(
|
131
|
+
Pathname.new(File.dirname(schema_manifest_path)),
|
132
|
+
)
|
133
|
+
|
134
|
+
{ key => value.merge!("path" => fixed_path.to_s) }
|
135
|
+
end
|
136
|
+
|
137
|
+
schemas_data["schemas"]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/suma/cli.rb
CHANGED
@@ -23,6 +23,16 @@ module Suma
|
|
23
23
|
Cli::Build.start
|
24
24
|
end
|
25
25
|
|
26
|
+
desc "generate_schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE",
|
27
|
+
"Generate EXPRESS schema manifest file from Metanorma site manifest"
|
28
|
+
option :exclude_paths, type: :string, default: nil, aliases: "-e",
|
29
|
+
desc: "Exclude schemas paths by pattern " \
|
30
|
+
"(e.g. `*_lf.exp`)"
|
31
|
+
def generate_schemas(_metanorma_manifest_file, _schema_manifest_file)
|
32
|
+
require_relative "cli/generate_schemas"
|
33
|
+
Cli::GenerateSchemas.start
|
34
|
+
end
|
35
|
+
|
26
36
|
desc "reformat EXPRESS_FILE_PATH",
|
27
37
|
"Reformat EXPRESS files"
|
28
38
|
option :recursive, type: :boolean, default: false, aliases: "-r",
|
@@ -33,6 +43,16 @@ module Suma
|
|
33
43
|
Cli::Reformat.start
|
34
44
|
end
|
35
45
|
|
46
|
+
desc "extract_terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH",
|
47
|
+
"Extract terms from SCHEMA_MANIFEST_FILE into " \
|
48
|
+
"Glossarist v2 format"
|
49
|
+
option :language_code, type: :string, default: "eng", aliases: "-l",
|
50
|
+
desc: "Language code for the Glossarist"
|
51
|
+
def extract_terms(_schema_manifest_file, _glossarist_output_path)
|
52
|
+
require_relative "cli/extract_terms"
|
53
|
+
Cli::ExtractTerms.start
|
54
|
+
end
|
55
|
+
|
36
56
|
desc "validate SUBCOMMAND ...ARGS", "Validate express documents"
|
37
57
|
subcommand "validate", Cli::Validate
|
38
58
|
|
data/lib/suma/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: suma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: expressir
|
@@ -134,6 +134,8 @@ files:
|
|
134
134
|
- lib/suma.rb
|
135
135
|
- lib/suma/cli.rb
|
136
136
|
- lib/suma/cli/build.rb
|
137
|
+
- lib/suma/cli/extract_terms.rb
|
138
|
+
- lib/suma/cli/generate_schemas.rb
|
137
139
|
- lib/suma/cli/reformat.rb
|
138
140
|
- lib/suma/cli/validate.rb
|
139
141
|
- lib/suma/cli/validate_ascii.rb
|