suma 0.2.6 → 0.4.0
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/.gitignore +7 -1
- data/.rubocop_todo.yml +170 -13
- data/CLAUDE.md +37 -11
- data/Gemfile +3 -3
- data/README.adoc +127 -13
- data/exe/suma +1 -1
- data/lib/suma/cli/build.rb +0 -5
- data/lib/suma/cli/check_svg_quality.rb +82 -97
- data/lib/suma/cli/compare.rb +0 -1
- data/lib/suma/cli/convert_jsdai.rb +0 -2
- data/lib/suma/cli/core.rb +119 -0
- data/lib/suma/cli/export.rb +37 -22
- data/lib/suma/cli/extract_terms.rb +5 -8
- data/lib/suma/cli/generate_register.rb +34 -0
- data/lib/suma/cli/generate_schemas.rb +0 -2
- data/lib/suma/cli/reformat.rb +39 -64
- data/lib/suma/cli/validate.rb +14 -7
- data/lib/suma/cli/validate_links.rb +11 -157
- data/lib/suma/cli.rb +12 -141
- data/lib/suma/collection_config.rb +0 -2
- data/lib/suma/collection_manifest.rb +7 -110
- data/lib/suma/eengine/wrapper.rb +0 -1
- data/lib/suma/eengine.rb +8 -0
- data/lib/suma/express_reformatter.rb +94 -0
- data/lib/suma/express_schema.rb +0 -1
- data/lib/suma/jsdai/figure.rb +0 -3
- data/lib/suma/jsdai.rb +5 -2
- data/lib/suma/link_validation.rb +144 -0
- data/lib/suma/link_validator.rb +17 -8
- data/lib/suma/manifest_traverser.rb +92 -0
- data/lib/suma/processor.rb +5 -8
- data/lib/suma/register_manifest_generator.rb +163 -0
- data/lib/suma/schema_category.rb +83 -0
- data/lib/suma/schema_collection.rb +30 -34
- data/lib/suma/schema_comparer.rb +4 -3
- data/lib/suma/schema_compiler.rb +86 -0
- data/lib/suma/schema_discovery.rb +75 -0
- data/lib/suma/schema_exporter.rb +14 -42
- data/lib/suma/schema_manifest_generator.rb +14 -6
- data/lib/suma/schema_naming.rb +111 -0
- data/lib/suma/schema_template/document.rb +141 -0
- data/lib/suma/schema_template/plain.rb +46 -0
- data/lib/suma/schema_template.rb +19 -0
- data/lib/suma/svg_quality/batch_report.rb +0 -2
- data/lib/suma/svg_quality/formatters.rb +12 -0
- data/lib/suma/svg_quality/scanner.rb +61 -0
- data/lib/suma/svg_quality.rb +4 -1
- data/lib/suma/term_classification.rb +78 -0
- data/lib/suma/term_extractor.rb +125 -81
- data/lib/suma/urn.rb +61 -0
- data/lib/suma/version.rb +1 -1
- data/lib/suma.rb +35 -3
- data/suma.gemspec +1 -1
- metadata +28 -6
- data/lib/suma/schema_attachment.rb +0 -103
- data/lib/suma/schema_document.rb +0 -118
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "pathname"
|
|
4
|
-
require_relative "../svg_quality"
|
|
5
|
-
require_relative "../svg_quality/report"
|
|
6
|
-
require_relative "../svg_quality/batch_report"
|
|
7
|
-
require_relative "../svg_quality/formatters/terminal_formatter"
|
|
8
|
-
require_relative "../svg_quality/formatters/json_formatter"
|
|
9
|
-
require_relative "../svg_quality/formatters/yaml_formatter"
|
|
10
4
|
|
|
11
5
|
module Suma
|
|
12
6
|
module Cli
|
|
13
|
-
# Check SVG quality
|
|
7
|
+
# Check SVG quality. Thin adapter around +Suma::SvgQuality::Scanner+:
|
|
8
|
+
# argument parsing, file discovery, sorting, filtering, output
|
|
9
|
+
# formatting. The deep scanner module owns validation orchestration
|
|
10
|
+
# and is reachable from specs without invoking Thor.
|
|
14
11
|
class CheckSvgQuality
|
|
15
12
|
DATA_PATH = "schemas"
|
|
16
13
|
DEFAULT_PATTERN = "**/*.svg"
|
|
17
14
|
DEFAULT_PROFILE = :metanorma
|
|
18
15
|
|
|
19
16
|
def initialize(pattern: DEFAULT_PATTERN, profile: DEFAULT_PROFILE,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
format: "terminal", output: nil, min_errors: nil,
|
|
18
|
+
summary_only: false, progress: false, limit: nil,
|
|
19
|
+
sort: "errors")
|
|
23
20
|
@options = {
|
|
24
21
|
pattern: pattern,
|
|
25
22
|
profile: profile,
|
|
@@ -37,71 +34,42 @@ module Suma
|
|
|
37
34
|
require "svg_conform"
|
|
38
35
|
|
|
39
36
|
path_obj = Pathname.new(path).expand_path
|
|
40
|
-
|
|
41
|
-
# Enable progress by default when outputting to terminal
|
|
42
37
|
show_progress = options[:progress] || ($stdout.tty? && !options[:output])
|
|
43
|
-
if show_progress
|
|
44
|
-
$stdout.sync = true
|
|
45
|
-
$stderr.sync = true
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
if path_obj.file?
|
|
49
|
-
# Single file mode - show detailed errors
|
|
50
|
-
analyze_single_file(path_obj)
|
|
51
|
-
else
|
|
52
|
-
# Directory mode - show batch report
|
|
53
|
-
svg_files = find_svg_files(path_obj)
|
|
54
|
-
|
|
55
|
-
if svg_files.empty?
|
|
56
|
-
puts "No SVG files found in #{path}"
|
|
57
|
-
return
|
|
58
|
-
end
|
|
38
|
+
sync_stdio! if show_progress
|
|
59
39
|
|
|
60
|
-
|
|
61
|
-
|
|
40
|
+
files = discover_files(path_obj)
|
|
41
|
+
return if files.empty?
|
|
62
42
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
43
|
+
if single_file?(path_obj, files)
|
|
44
|
+
print_single_report(scan_single(files.first))
|
|
45
|
+
else
|
|
46
|
+
scan_and_output(files, show_progress)
|
|
67
47
|
end
|
|
68
48
|
end
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
validator = SvgConform::Validator.new
|
|
72
|
-
result = validator.validate_file(path.to_s, profile: options[:profile])
|
|
73
|
-
|
|
74
|
-
puts "📄 SVG Quality Report: #{path}"
|
|
75
|
-
puts ""
|
|
76
|
-
puts " Valid: #{result.valid? ? 'YES ✅' : 'NO ❌'}"
|
|
77
|
-
puts " Errors: #{result.error_count}"
|
|
78
|
-
puts ""
|
|
50
|
+
private
|
|
79
51
|
|
|
80
|
-
|
|
81
|
-
puts " 📋 Error Details"
|
|
82
|
-
puts ""
|
|
52
|
+
attr_reader :options
|
|
83
53
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
by_req.each do |req_id, errors|
|
|
88
|
-
puts " #{req_id} (#{errors.size} occurrences)"
|
|
89
|
-
errors.first(5).each do |e|
|
|
90
|
-
puts " - #{e.message}"
|
|
91
|
-
end
|
|
92
|
-
if errors.size > 5
|
|
93
|
-
puts " ... and #{errors.size - 5} more"
|
|
94
|
-
end
|
|
95
|
-
puts ""
|
|
96
|
-
end
|
|
97
|
-
end
|
|
54
|
+
def single_file?(path_obj, files)
|
|
55
|
+
path_obj.file? && files.size == 1
|
|
98
56
|
end
|
|
99
57
|
|
|
100
|
-
|
|
58
|
+
def scan_and_output(files, show_progress)
|
|
59
|
+
puts "🔍 Scanning #{files.size} SVG files..." if show_progress
|
|
60
|
+
batch = SvgQuality::Scanner.new(
|
|
61
|
+
profile: options[:profile],
|
|
62
|
+
progress: progress_adapter(show_progress),
|
|
63
|
+
).scan(files)
|
|
64
|
+
output_report(sort_report(batch))
|
|
65
|
+
end
|
|
101
66
|
|
|
102
|
-
|
|
67
|
+
def sync_stdio!
|
|
68
|
+
$stdout.sync = true
|
|
69
|
+
$stderr.sync = true
|
|
70
|
+
end
|
|
103
71
|
|
|
104
|
-
def
|
|
72
|
+
def discover_files(path)
|
|
105
73
|
if path.directory?
|
|
106
74
|
Pathname.glob(path.join(options[:pattern])).select(&:file?)
|
|
107
75
|
elsif path.file? && path.extname == ".svg"
|
|
@@ -111,34 +79,47 @@ module Suma
|
|
|
111
79
|
end
|
|
112
80
|
end
|
|
113
81
|
|
|
114
|
-
def
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
82
|
+
def scan_single(path)
|
|
83
|
+
SvgQuality::Scanner.new(profile: options[:profile]).scan_file(path)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def print_single_report(report)
|
|
87
|
+
result = report
|
|
88
|
+
puts "📄 SVG Quality Report: #{result.file_path}"
|
|
89
|
+
puts ""
|
|
90
|
+
puts " Valid: #{result.valid? ? 'YES ✅' : 'NO ❌'}"
|
|
91
|
+
puts " Errors: #{result.error_count}"
|
|
92
|
+
puts ""
|
|
93
|
+
|
|
94
|
+
return unless result.errors.any?
|
|
95
|
+
|
|
96
|
+
puts " 📋 Error Details"
|
|
97
|
+
puts ""
|
|
98
|
+
by_req = result.errors.group_by(&:requirement_id)
|
|
99
|
+
by_req.each do |req_id, errors|
|
|
100
|
+
puts " #{req_id} (#{errors.size} occurrences)"
|
|
101
|
+
errors.first(5).each { |e| puts " - #{e.message}" }
|
|
102
|
+
puts " ... and #{errors.size - 5} more" if errors.size > 5
|
|
103
|
+
puts ""
|
|
131
104
|
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def progress_adapter(enabled)
|
|
108
|
+
return SvgQuality::Scanner::NullProgress.new unless enabled
|
|
132
109
|
|
|
133
|
-
|
|
110
|
+
->(_index, _total, report) do
|
|
111
|
+
tier = report.quality_tier
|
|
112
|
+
status = report.valid? ? "✅" : "❌"
|
|
113
|
+
$stderr.print " #{tier[:emoji]} #{report.error_count} errors " \
|
|
114
|
+
"#{status} #{shorten_path(report.file_path)}\n"
|
|
115
|
+
$stderr.flush
|
|
116
|
+
end
|
|
134
117
|
end
|
|
135
118
|
|
|
136
119
|
def sort_report(batch_report)
|
|
137
120
|
case options[:sort]
|
|
138
|
-
when :quality
|
|
139
|
-
|
|
140
|
-
else
|
|
141
|
-
batch_report.sort_by_errors
|
|
121
|
+
when :quality then batch_report.sort_by_quality
|
|
122
|
+
else batch_report.sort_by_errors
|
|
142
123
|
end
|
|
143
124
|
end
|
|
144
125
|
|
|
@@ -146,21 +127,25 @@ module Suma
|
|
|
146
127
|
filtered = batch_report.filter_by_min_errors(options[:min_errors])
|
|
147
128
|
limited = filtered.limit(options[:limit])
|
|
148
129
|
|
|
149
|
-
formatter =
|
|
150
|
-
when :json
|
|
151
|
-
SvgQuality::Formatters::JsonFormatter.new(limited,
|
|
152
|
-
output: options[:output])
|
|
153
|
-
when :yaml
|
|
154
|
-
SvgQuality::Formatters::YamlFormatter.new(limited,
|
|
155
|
-
output: options[:output])
|
|
156
|
-
else
|
|
157
|
-
SvgQuality::Formatters::TerminalFormatter.new(limited,
|
|
158
|
-
output: options[:output], sort: options[:sort])
|
|
159
|
-
end
|
|
160
|
-
|
|
130
|
+
formatter = formatter_for(limited)
|
|
161
131
|
puts formatter.format
|
|
162
132
|
end
|
|
163
133
|
|
|
134
|
+
def formatter_for(batch_report)
|
|
135
|
+
case options[:format].to_sym
|
|
136
|
+
when :json
|
|
137
|
+
SvgQuality::Formatters::JsonFormatter.new(batch_report,
|
|
138
|
+
output: options[:output])
|
|
139
|
+
when :yaml
|
|
140
|
+
SvgQuality::Formatters::YamlFormatter.new(batch_report,
|
|
141
|
+
output: options[:output])
|
|
142
|
+
else
|
|
143
|
+
SvgQuality::Formatters::TerminalFormatter.new(batch_report,
|
|
144
|
+
output: options[:output],
|
|
145
|
+
sort: options[:sort])
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
164
149
|
def shorten_path(path)
|
|
165
150
|
p = Pathname.new(path)
|
|
166
151
|
if p.absolute?
|
data/lib/suma/cli/compare.rb
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thor"
|
|
4
|
+
require "expressir"
|
|
5
|
+
require "expressir/cli"
|
|
6
|
+
|
|
7
|
+
module Suma
|
|
8
|
+
module Cli
|
|
9
|
+
# Top-level CLI entrypoint.
|
|
10
|
+
#
|
|
11
|
+
# Each command delegates to a dedicated Thor class under +Suma::Cli::+,
|
|
12
|
+
# which reparses ARGV and therefore owns the canonical +option+
|
|
13
|
+
# declarations. Re-declaring options here would duplicate the inner
|
|
14
|
+
# classes' declarations and cause help text and validation logic to
|
|
15
|
+
# drift. Options are declared in exactly one place (the inner class).
|
|
16
|
+
#
|
|
17
|
+
# The exception is +check_svg_quality+, which constructs its analyzer
|
|
18
|
+
# inline (no inner Thor class), so its options belong here.
|
|
19
|
+
class Core < Thor
|
|
20
|
+
extend ThorExt::Start
|
|
21
|
+
|
|
22
|
+
desc "build METANORMA_SITE_MANIFEST",
|
|
23
|
+
"Build collection specified in site manifest (`metanorma*.yml`)"
|
|
24
|
+
def build(_site_manifest)
|
|
25
|
+
Cli::Build.start
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
desc "generate-schemas METANORMA_MANIFEST_FILE SCHEMA_MANIFEST_FILE",
|
|
29
|
+
"Generate EXPRESS schema manifest file from Metanorma site manifest"
|
|
30
|
+
def generate_schemas(_metanorma_manifest_file, _schema_manifest_file)
|
|
31
|
+
Cli::GenerateSchemas.start
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc "reformat EXPRESS_FILE_PATH",
|
|
35
|
+
"Reformat EXPRESS files"
|
|
36
|
+
def reformat(_express_file_path)
|
|
37
|
+
Cli::Reformat.start
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
desc "extract-terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH",
|
|
41
|
+
"Extract terms from SCHEMA_MANIFEST_FILE into " \
|
|
42
|
+
"Glossarist v3 format"
|
|
43
|
+
def extract_terms(_schema_manifest_file, _glossarist_output_path)
|
|
44
|
+
Cli::ExtractTerms.start
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
desc "generate-register SCHEMA_MANIFEST_FILE OUTPUT_PATH",
|
|
48
|
+
"Generate a Glossarist register.yaml with hierarchical sections"
|
|
49
|
+
def generate_register(_schema_manifest_file, _output_path)
|
|
50
|
+
Cli::GenerateRegister.start
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "convert-jsdai XML_FILE IMAGE_FILE OUTPUT_DIR",
|
|
54
|
+
"Convert JSDAI XML and image files to SVG and EXP files"
|
|
55
|
+
def convert_jsdai(_xml_file, _image_file, _output_dir)
|
|
56
|
+
Cli::ConvertJsdai.start
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desc "export *FILES",
|
|
60
|
+
"Export EXPRESS schemas from manifest files or " \
|
|
61
|
+
"standalone EXPRESS files"
|
|
62
|
+
def export(*_files)
|
|
63
|
+
Cli::Export.start
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
desc "compare TRIAL_SCHEMA REFERENCE_SCHEMA",
|
|
67
|
+
"Compare EXPRESS schemas using eengine and generate Change YAML"
|
|
68
|
+
def compare(_trial_schema, _reference_schema)
|
|
69
|
+
Cli::Compare.start
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc "validate SUBCOMMAND ...ARGS", "Validate express documents"
|
|
73
|
+
subcommand "validate", Cli::Validate
|
|
74
|
+
|
|
75
|
+
desc "check_svg_quality [PATH]",
|
|
76
|
+
"Check SVG quality and sort by severity (critical files first)"
|
|
77
|
+
option :pattern, type: :string, default: Cli::CheckSvgQuality::DEFAULT_PATTERN,
|
|
78
|
+
desc: "Glob pattern for finding SVG files"
|
|
79
|
+
option :profile, type: :string,
|
|
80
|
+
default: Cli::CheckSvgQuality::DEFAULT_PROFILE,
|
|
81
|
+
desc: "Validation profile to use (metanorma, svg_1_2_rfc, etc.)"
|
|
82
|
+
option :format, type: :string, default: "terminal",
|
|
83
|
+
desc: "Output format: terminal, yaml, json"
|
|
84
|
+
option :output, type: :string, aliases: "-o",
|
|
85
|
+
desc: "Output file path"
|
|
86
|
+
option :min_errors, type: :numeric,
|
|
87
|
+
desc: "Minimum error count threshold"
|
|
88
|
+
option :limit, type: :numeric, default: nil,
|
|
89
|
+
desc: "Maximum number of files to show (default: unlimited)"
|
|
90
|
+
option :sort, type: :string, default: "errors",
|
|
91
|
+
desc: "Sort by: errors (most errors first) or quality (lowest scores first)"
|
|
92
|
+
option :progress, type: :boolean, default: false,
|
|
93
|
+
desc: "Show progress during processing"
|
|
94
|
+
option :summary_only, type: :boolean, default: false,
|
|
95
|
+
desc: "Show only summary"
|
|
96
|
+
def check_svg_quality(path = Cli::CheckSvgQuality::DATA_PATH)
|
|
97
|
+
analyzer = Cli::CheckSvgQuality.new(
|
|
98
|
+
pattern: options[:pattern],
|
|
99
|
+
profile: options[:profile],
|
|
100
|
+
format: options[:format],
|
|
101
|
+
output: options[:output],
|
|
102
|
+
min_errors: options[:min_errors],
|
|
103
|
+
summary_only: options[:summary_only],
|
|
104
|
+
progress: options[:progress],
|
|
105
|
+
limit: options[:limit],
|
|
106
|
+
sort: options[:sort],
|
|
107
|
+
)
|
|
108
|
+
analyzer.run(path)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
desc "expressir SUBCOMMAND ...ARGS", "Expressir commands"
|
|
112
|
+
subcommand "expressir", Expressir::Cli
|
|
113
|
+
|
|
114
|
+
def self.exit_on_failure?
|
|
115
|
+
true
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
data/lib/suma/cli/export.rb
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "thor"
|
|
4
|
-
|
|
4
|
+
require "pathname"
|
|
5
5
|
|
|
6
6
|
module Suma
|
|
7
7
|
module Cli
|
|
8
|
-
# Export command
|
|
8
|
+
# Export command. Thin Thor adapter that constructs
|
|
9
|
+
# +Suma::ExpressSchema+ instances from manifest entries or
|
|
10
|
+
# standalone +.exp+ files, then delegates the actual writing to
|
|
11
|
+
# +Suma::SchemaExporter+.
|
|
12
|
+
#
|
|
13
|
+
# The schema-type → output-subdirectory mapping lives in
|
|
14
|
+
# +Suma::SchemaCategory+, the single source of truth. The exporter
|
|
15
|
+
# itself never classifies — it consumes loaded ExpressSchema
|
|
16
|
+
# objects whose output paths were set by this adapter.
|
|
9
17
|
class Export < Thor
|
|
10
18
|
desc "export *FILES",
|
|
11
19
|
"Export EXPRESS schemas from manifest files or " \
|
|
@@ -18,8 +26,6 @@ module Suma
|
|
|
18
26
|
desc: "Create ZIP archive of exported schemas"
|
|
19
27
|
|
|
20
28
|
def export(*files)
|
|
21
|
-
require_relative "../schema_exporter"
|
|
22
|
-
require_relative "../utils"
|
|
23
29
|
require "expressir"
|
|
24
30
|
|
|
25
31
|
validate_files(files)
|
|
@@ -41,7 +47,7 @@ module Suma
|
|
|
41
47
|
end
|
|
42
48
|
|
|
43
49
|
def run(files, options)
|
|
44
|
-
schemas =
|
|
50
|
+
schemas = files.flat_map { |file| build_schemas(file) }
|
|
45
51
|
|
|
46
52
|
exporter = SchemaExporter.new(
|
|
47
53
|
schemas: schemas,
|
|
@@ -55,22 +61,12 @@ module Suma
|
|
|
55
61
|
exporter.export
|
|
56
62
|
end
|
|
57
63
|
|
|
58
|
-
def
|
|
59
|
-
all_schemas = []
|
|
60
|
-
|
|
61
|
-
files.each do |file|
|
|
62
|
-
all_schemas += process_file(file)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
all_schemas
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def process_file(file)
|
|
64
|
+
def build_schemas(file)
|
|
69
65
|
case File.extname(file).downcase
|
|
70
66
|
when ".yml", ".yaml"
|
|
71
|
-
|
|
67
|
+
build_from_manifest(file)
|
|
72
68
|
when ".exp"
|
|
73
|
-
[
|
|
69
|
+
[build_standalone(file)]
|
|
74
70
|
else
|
|
75
71
|
raise ArgumentError, "Unsupported file type: #{file}. " \
|
|
76
72
|
"Only .yml, .yaml, and .exp files are " \
|
|
@@ -78,13 +74,32 @@ module Suma
|
|
|
78
74
|
end
|
|
79
75
|
end
|
|
80
76
|
|
|
81
|
-
def
|
|
77
|
+
def build_from_manifest(file)
|
|
82
78
|
manifest = Expressir::SchemaManifest.from_file(file)
|
|
83
|
-
manifest.schemas
|
|
79
|
+
manifest.schemas.map { |entry| build_from_manifest_entry(entry) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def build_from_manifest_entry(entry)
|
|
83
|
+
category = SchemaCategory.for_schema(id: entry.id, path: entry.path)
|
|
84
|
+
ExpressSchema.new(
|
|
85
|
+
id: entry.id,
|
|
86
|
+
path: entry.path.to_s,
|
|
87
|
+
output_path: output_root.join(category.directory).to_s,
|
|
88
|
+
is_standalone_file: false,
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def build_standalone(exp_file)
|
|
93
|
+
ExpressSchema.new(
|
|
94
|
+
id: nil,
|
|
95
|
+
path: File.expand_path(exp_file),
|
|
96
|
+
output_path: output_root.to_s,
|
|
97
|
+
is_standalone_file: true,
|
|
98
|
+
)
|
|
84
99
|
end
|
|
85
100
|
|
|
86
|
-
def
|
|
87
|
-
|
|
101
|
+
def output_root
|
|
102
|
+
Pathname.new(options[:output]).expand_path
|
|
88
103
|
end
|
|
89
104
|
|
|
90
105
|
def self.exit_on_failure?
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "thor"
|
|
4
|
-
require_relative "../thor_ext"
|
|
5
|
-
require_relative "../term_extractor"
|
|
6
4
|
|
|
7
5
|
module Suma
|
|
8
6
|
module Cli
|
|
9
7
|
class ExtractTerms < Thor
|
|
10
8
|
desc "extract_terms SCHEMA_MANIFEST_FILE GLOSSARIST_OUTPUT_PATH",
|
|
11
9
|
"Extract terms from SCHEMA_MANIFEST_FILE into " \
|
|
12
|
-
"Glossarist
|
|
10
|
+
"Glossarist v3 format"
|
|
13
11
|
option :language_code, type: :string, default: "eng", aliases: "-l",
|
|
14
12
|
desc: "Language code for the Glossarist"
|
|
13
|
+
option :urn, type: :string, required: true, aliases: "-u",
|
|
14
|
+
desc: "URN for the dataset source " \
|
|
15
|
+
"(used for section references)"
|
|
15
16
|
|
|
16
17
|
def extract_terms(schema_manifest_file, output_path)
|
|
17
|
-
unless File.exist?(File.expand_path(schema_manifest_file))
|
|
18
|
-
raise Errno::ENOENT, "Specified SCHEMA_MANIFEST_FILE " \
|
|
19
|
-
"`#{schema_manifest_file}` not found."
|
|
20
|
-
end
|
|
21
|
-
|
|
22
18
|
TermExtractor.new(
|
|
23
19
|
schema_manifest_file,
|
|
24
20
|
output_path,
|
|
25
21
|
language_code: options[:language_code],
|
|
22
|
+
urn: options[:urn],
|
|
26
23
|
).call
|
|
27
24
|
end
|
|
28
25
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thor"
|
|
4
|
+
|
|
5
|
+
module Suma
|
|
6
|
+
module Cli
|
|
7
|
+
class GenerateRegister < Thor
|
|
8
|
+
desc "generate_register SCHEMA_MANIFEST_FILE OUTPUT_PATH",
|
|
9
|
+
"Generate a Glossarist register.yaml with hierarchical sections"
|
|
10
|
+
option :language_code, type: :string, default: "eng", aliases: "-l",
|
|
11
|
+
desc: "Language code for section names"
|
|
12
|
+
option :urn, type: :string, required: true, aliases: "-u",
|
|
13
|
+
desc: "URN prefix for the dataset"
|
|
14
|
+
option :id, type: :string, required: true,
|
|
15
|
+
desc: "Dataset identifier (e.g. iso10303-2-express)"
|
|
16
|
+
option :ref, type: :string, required: true,
|
|
17
|
+
desc: "Human-readable reference label"
|
|
18
|
+
option :owner, type: :string, default: Suma::RegisterManifestGenerator::DEFAULT_OWNER,
|
|
19
|
+
desc: "Owner of the dataset (e.g. 'ISO/TC 184/SC 4')"
|
|
20
|
+
|
|
21
|
+
def generate_register(schema_manifest_file, output_path)
|
|
22
|
+
RegisterManifestGenerator.new(
|
|
23
|
+
schema_manifest_file,
|
|
24
|
+
output_path,
|
|
25
|
+
urn: options[:urn],
|
|
26
|
+
id: options[:id],
|
|
27
|
+
ref: options[:ref],
|
|
28
|
+
language_code: options[:language_code],
|
|
29
|
+
owner: options[:owner],
|
|
30
|
+
).generate
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|