Skip to content

Commit a01667b

Browse files
committed
Consolidate CLI command processing and allow for other formats than :jsonld. This allows for YAML-LD to re-used the same commands.
1 parent 1e35c13 commit a01667b

File tree

1 file changed

+81
-115
lines changed

1 file changed

+81
-115
lines changed

lib/json/ld/format.rb

Lines changed: 81 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -45,82 +45,102 @@ def self.detect(sample)
4545
!sample.include?("http://www.w3.org/ns/csvw")
4646
end
4747

48+
# Specify how to execute CLI commands for each supported format.
49+
# Derived formats (e.g., YAML-LD) define their own entrypoints.
50+
LD_FORMATS = {
51+
jsonld: {
52+
expand: ->(input, **options) {
53+
JSON::LD::API.expand(input,
54+
serializer: JSON::LD::API.method(:serializer),
55+
**options)
56+
},
57+
compact: ->(input, **options) {
58+
JSON::LD::API.compact(input,
59+
options[:context],
60+
serializer: JSON::LD::API.method(:serializer),
61+
**options)
62+
},
63+
flatten: ->(input, **options) {
64+
JSON::LD::API.flatten(input,
65+
options[:context],
66+
serializer: JSON::LD::API.method(:serializer),
67+
**options)
68+
},
69+
frame: ->(input, **options) {
70+
JSON::LD::API.frame(input,
71+
options[:frame],
72+
serializer: JSON::LD::API.method(:serializer),
73+
**options)
74+
},
75+
}
76+
}
77+
78+
# Execute the body of a CLI command, generic for each different API method based on definitions on {LD_FORMATS}.
79+
#
80+
# Expands the input, or transforms from an RDF format based on the `:format` option, and then executes the appropriate command based on `:output_format` and does appropriate output serialization.
81+
# @private
82+
def self.cli_exec(command, files, output: $stdin, **options)
83+
output.set_encoding(Encoding::UTF_8) if output.respond_to?(:set_encoding) && RUBY_PLATFORM == "java"
84+
options[:base] ||= options[:base_uri]
85+
86+
# Parse using input format, serialize using output format
87+
in_fmt = LD_FORMATS[options.fetch(:format, :jsonld)]
88+
out_fmt = LD_FORMATS[options.fetch(:output_format, :jsonld)]
89+
90+
if in_fmt
91+
# Input is a JSON-LD based source (or derived)
92+
if files.empty?
93+
# If files are empty, either use options[:evaluate] or STDIN
94+
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
95+
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
96+
expanded = in_fmt[:expand].call(input, serializer: nil, **options)
97+
output.puts out_fmt[command].call(expanded, expanded: true, **options)
98+
else
99+
files.each do |file|
100+
expanded = in_fmt[:expand].call(file, serializer: nil, **options)
101+
output.puts out_fmt[command].call(expanded, expanded: true, **options)
102+
end
103+
end
104+
else
105+
# Turn RDF into JSON-LD first
106+
RDF::CLI.parse(files, **options) do |reader|
107+
JSON::LD::API.fromRdf(reader, serializer: nil, **options) do |expanded|
108+
output.puts out_fmt[command].call(expanded, expanded: true, **options)
109+
end
110+
end
111+
end
112+
end
113+
48114
##
49-
# Hash of CLI commands appropriate for this format
115+
# Hash of CLI commands appropriate for this format:
116+
#
117+
# * `expand` => {JSON::LD::API.expand}
118+
# * `compact` => {JSON::LD::API.compact}
119+
# * `flatten` => {JSON::LD::API.flatten}
120+
# * `frame` => {JSON::LD::API.frame}
121+
#
50122
# @return [Hash{Symbol => Hash}]
51123
def self.cli_commands
52124
{
53125
expand: {
54126
description: "Expand JSON-LD or parsed RDF",
55127
parse: false,
56128
help: "expand [--context <context-file>] files ...",
57-
filter: {output_format: :jsonld}, # Only shows output format set
129+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
58130
lambda: ->(files, **options) do
59-
out = options[:output] || $stdout
60-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
61131
options = options.merge(expandContext: options.delete(:context)) if options.key?(:context)
62-
options[:base] ||= options[:base_uri]
63-
if options[:format] == :jsonld
64-
if files.empty?
65-
# If files are empty, either use options[:evaluate] or STDIN
66-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
67-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
68-
JSON::LD::API.expand(input, validate: false, **options) do |expanded|
69-
out.puts expanded.to_json(JSON::LD::JSON_STATE)
70-
end
71-
else
72-
files.each do |file|
73-
JSON::LD::API.expand(file, validate: false, **options) do |expanded|
74-
out.puts expanded.to_json(JSON::LD::JSON_STATE)
75-
end
76-
end
77-
end
78-
else
79-
# Turn RDF into JSON-LD first
80-
RDF::CLI.parse(files, **options) do |reader|
81-
JSON::LD::API.fromRdf(reader) do |expanded|
82-
out.puts expanded.to_json(JSON::LD::JSON_STATE)
83-
end
84-
end
85-
end
132+
cli_exec(:expand, files, **options)
86133
end,
87134
option_use: {context: :removed}
88135
},
89136
compact: {
90137
description: "Compact JSON-LD or parsed RDF",
91138
parse: false,
92-
filter: {output_format: :jsonld}, # Only shows output format set
139+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
93140
help: "compact --context <context-file> files ...",
94141
lambda: ->(files, **options) do
95142
raise ArgumentError, "Compacting requires a context" unless options[:context]
96-
out = options[:output] || $stdout
97-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
98-
options[:base] ||= options[:base_uri]
99-
if options[:format] == :jsonld
100-
if files.empty?
101-
# If files are empty, either use options[:evaluate] or STDIN
102-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
103-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
104-
JSON::LD::API.compact(input, options[:context], **options) do |compacted|
105-
out.puts compacted.to_json(JSON::LD::JSON_STATE)
106-
end
107-
else
108-
files.each do |file|
109-
JSON::LD::API.compact(file, options[:context], **options) do |compacted|
110-
out.puts compacted.to_json(JSON::LD::JSON_STATE)
111-
end
112-
end
113-
end
114-
else
115-
# Turn RDF into JSON-LD first
116-
RDF::CLI.parse(files, **options) do |reader|
117-
JSON::LD::API.fromRdf(reader) do |expanded|
118-
JSON::LD::API.compact(expanded, options[:context], **options) do |compacted|
119-
out.puts compacted.to_json(JSON::LD::JSON_STATE)
120-
end
121-
end
122-
end
123-
end
143+
cli_exec(:compact, files, **options)
124144
end,
125145
options: [
126146
RDF::CLI::Option.new(
@@ -136,36 +156,9 @@ def self.cli_commands
136156
description: "Flatten JSON-LD or parsed RDF",
137157
parse: false,
138158
help: "flatten [--context <context-file>] files ...",
139-
filter: {output_format: :jsonld}, # Only shows output format set
159+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
140160
lambda: ->(files, **options) do
141-
out = options[:output] || $stdout
142-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
143-
options[:base] ||= options[:base_uri]
144-
if options[:format] == :jsonld
145-
if files.empty?
146-
# If files are empty, either use options[:evaluate] or STDIN
147-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
148-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
149-
JSON::LD::API.flatten(input, options[:context], **options) do |flattened|
150-
out.puts flattened.to_json(JSON::LD::JSON_STATE)
151-
end
152-
else
153-
files.each do |file|
154-
JSON::LD::API.flatten(file, options[:context], **options) do |flattened|
155-
out.puts flattened.to_json(JSON::LD::JSON_STATE)
156-
end
157-
end
158-
end
159-
else
160-
# Turn RDF into JSON-LD first
161-
RDF::CLI.parse(files, **options) do |reader|
162-
JSON::LD::API.fromRdf(reader) do |expanded|
163-
JSON::LD::API.flatten(expanded, options[:context], **options) do |flattened|
164-
out.puts flattened.to_json(JSON::LD::JSON_STATE)
165-
end
166-
end
167-
end
168-
end
161+
cli_exec(:compact, files, **options)
169162
end,
170163
options: [
171164
RDF::CLI::Option.new(
@@ -188,37 +181,10 @@ def self.cli_commands
188181
description: "Frame JSON-LD or parsed RDF",
189182
parse: false,
190183
help: "frame --frame <frame-file> files ...",
191-
filter: {output_format: :jsonld}, # Only shows output format set
184+
filter: {output_format: LD_FORMATS.keys}, # Only shows output format set
192185
lambda: ->(files, **options) do
193186
raise ArgumentError, "Framing requires a frame" unless options[:frame]
194-
out = options[:output] || $stdout
195-
out.set_encoding(Encoding::UTF_8) if RUBY_PLATFORM == "java"
196-
options[:base] ||= options[:base_uri]
197-
if options[:format] == :jsonld
198-
if files.empty?
199-
# If files are empty, either use options[:evaluate] or STDIN
200-
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
201-
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
202-
JSON::LD::API.frame(input, options[:frame], **options) do |framed|
203-
out.puts framed.to_json(JSON::LD::JSON_STATE)
204-
end
205-
else
206-
files.each do |file|
207-
JSON::LD::API.frame(file, options[:frame], **options) do |framed|
208-
out.puts framed.to_json(JSON::LD::JSON_STATE)
209-
end
210-
end
211-
end
212-
else
213-
# Turn RDF into JSON-LD first
214-
RDF::CLI.parse(files, **options) do |reader|
215-
JSON::LD::API.fromRdf(reader) do |expanded|
216-
JSON::LD::API.frame(expanded, options[:frame], **options) do |framed|
217-
out.puts framed.to_json(JSON::LD::JSON_STATE)
218-
end
219-
end
220-
end
221-
end
187+
cli_exec(:compact, files, **options)
222188
end,
223189
option_use: {context: :removed},
224190
options: [

0 commit comments

Comments
 (0)