Skip to content

Commit ab38385

Browse files
committed
Added bin/jsonld for command-line manipulation of JSON-LD files and to perform RDF transformations.
1 parent 2bd55c8 commit ab38385

File tree

2 files changed

+139
-6
lines changed

2 files changed

+139
-6
lines changed

.gemspec

+5-6
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ Gem::Specification.new do |gem|
1313
gem.rubyforge_project = 'json-ld'
1414

1515
gem.authors = ['Gregg Kellogg']
16-
gem.email = 'public-rdf-ruby@w3.org'
16+
gem.email = 'public-linked-json@w3.org'
1717

1818
gem.platform = Gem::Platform::RUBY
1919
gem.files = %w(AUTHORS README.markdown History.markdown UNLICENSE VERSION) + Dir.glob('lib/**/*.rb')
20-
#gem.bindir = %q(bin)
21-
#gem.executables = %w(json_ld)
22-
#gem.default_executable = gem.executables.first
20+
gem.bindir = %q(bin)
21+
gem.executables = %w(jsonld)
22+
gem.default_executable = gem.executables.first
2323
gem.require_paths = %w(lib)
2424
gem.extensions = %w()
25-
gem.test_files = %w()
25+
gem.test_files = Dir.glob('spec/**/*.rb') + Dir.glob('spec/test-files/*')
2626
gem.has_rdoc = false
2727

2828
gem.required_ruby_version = '>= 1.8.1'
@@ -38,7 +38,6 @@ Gem::Specification.new do |gem|
3838
gem.add_development_dependency 'rdf-turtle', '>= 0.1.1'
3939
gem.add_development_dependency 'rdf-trig', '>= 0.1.1'
4040
gem.add_development_dependency 'rdf-isomorphic', '>= 0.3.4'
41-
gem.add_development_dependency 'sparql', '>= 0.0.2'
4241
gem.add_runtime_dependency 'backports'
4342
gem.post_install_message = nil
4443
end

bin/jsonld

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/usr/bin/env ruby
2+
require 'rubygems'
3+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib')))
4+
begin
5+
require 'linkeddata'
6+
rescue LoadError
7+
end
8+
require 'json/ld'
9+
require 'getoptlong'
10+
require 'open-uri'
11+
12+
def run(input, options)
13+
reader_class = RDF::Reader.for(options[:input_format].to_sym)
14+
raise "Reader not found for #{options[:input_format]}" unless reader_class
15+
16+
# Override default (or specified) output format when framing
17+
options[:format] = :jsonld if options[:compact] || options[:frame]
18+
19+
# If input format is not JSON-LD, transform input to JSON-LD first
20+
if options[:format] == :jsonld && options[:input_format] != :jsonld
21+
r = reader_class.new(input, options[:parser_options])
22+
g = RDF::Repository.new << r
23+
input = JSON::LD::API.fromRDF(g)
24+
end
25+
26+
prefixes = {}
27+
start = Time.new
28+
if options[:expand]
29+
output = JSON::LD::API.expand(input, options[:context], nil, options)
30+
secs = Time.new - start
31+
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
32+
STDERR.puts "Expanded in #{secs} seconds." unless options[:quiet]
33+
elsif options[:compact]
34+
output = JSON::LD::API.compact(input, options[:context], nil, options)
35+
secs = Time.new - start
36+
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
37+
STDERR.puts "Compacted in #{secs} seconds." unless options[:quiet]
38+
elsif options[:frame]
39+
output = JSON::LD::API.frame(input, options[:frame], nil, options)
40+
secs = Time.new - start
41+
options[:output].puts output.to_json(JSON::LD::JSON_STATE)
42+
STDERR.puts "Framed in #{secs} seconds." unless options[:quiet]
43+
else
44+
r = reader_class.new(input, options[:parser_options])
45+
g = RDF::Repository.new << r
46+
secs = Time.new - start
47+
num = g.count
48+
parser_options = options[:parser_options].merge(:prefixes => r.prefixes, :standard_prefixes => true)
49+
options[:output].puts g.dump(options[:output_format], parser_options)
50+
STDERR.puts "\nParsed #{num} statements in #{secs} seconds @ #{num/secs} statements/second." unless options[:quiet]
51+
end
52+
rescue
53+
fname = input.respond_to?(:path) ? input.path : "-stdin-"
54+
STDERR.puts("Error in #{fname}")
55+
raise
56+
end
57+
58+
parser_options = {
59+
:base => "",
60+
:progress => false,
61+
:validate => false,
62+
:strict => false,
63+
}
64+
65+
options = {
66+
:parser_options => parser_options,
67+
:output => STDOUT,
68+
:output_format => :turtle,
69+
:input_format => :jsonld,
70+
}
71+
input = nil
72+
73+
OPT_ARGS = [
74+
["--dbg", GetoptLong::NO_ARGUMENT, "Turn on verbose debugging"],
75+
["--compact", GetoptLong::NO_ARGUMENT, "Compact document, using --context"],
76+
["--context", GetoptLong::REQUIRED_ARGUMENT,"Context to apply for expand, compact and converting from RDF"],
77+
["--evaluate","-e", GetoptLong::REQUIRED_ARGUMENT,"Evaluate argument as a JSON-LD document"],
78+
["--expand", GetoptLong::NO_ARGUMENT, "Expand document, using an optional --context"],
79+
["--format", GetoptLong::REQUIRED_ARGUMENT,"Specify output format when converting to RDF"],
80+
["--frame", GetoptLong::REQUIRED_ARGUMENT,"Frame document, using the file or URL as a frame specification"],
81+
["--input-format", GetoptLong::REQUIRED_ARGUMENT,"Format of the input document, when converting from RDF."],
82+
["--output", "-o", GetoptLong::REQUIRED_ARGUMENT,"Output to the specified file path"],
83+
["--parse-only", GetoptLong::NO_ARGUMENT, "Parse the document for well-formedness only"],
84+
["--quiet", GetoptLong::NO_ARGUMENT, "Supress most output other than progress indicators"],
85+
["--uri", GetoptLong::REQUIRED_ARGUMENT,"URI to be used as the document base"],
86+
["--verbose", GetoptLong::NO_ARGUMENT, "Detail on execution"],
87+
["--help", "-?", GetoptLong::NO_ARGUMENT, "This message"]
88+
]
89+
def usage
90+
STDERR.puts %{Usage: #{$0} [options] file ...}
91+
width = OPT_ARGS.map do |o|
92+
l = o.first.length
93+
l += o[1].length + 2 if o[1].is_a?(String)
94+
l
95+
end.max
96+
OPT_ARGS.each do |o|
97+
s = " %-*s " % [width, (o[1].is_a?(String) ? "#{o[0,2].join(', ')}" : o[0])]
98+
s += o.last
99+
STDERR.puts s
100+
end
101+
exit(1)
102+
end
103+
104+
105+
opts = GetoptLong.new(*OPT_ARGS.map {|o| o[0..-2]})
106+
107+
opts.each do |opt, arg|
108+
case opt
109+
when '--dbg' then parser_options[:debug] = ::JSON::LD::debug = true
110+
when '--compact' then options[:compact] = true
111+
when '--context' then options[:context] = arg
112+
when '--execute' then input = arg
113+
when '--expand' then options[:expand] = true
114+
when '--format' then options[:output_format] = arg.to_sym
115+
when '--frame' then options[:frame] = arg
116+
when '--input-format' then options[:input_format] = arg.to_sym
117+
when '--output' then options[:output] = File.open(arg, "w")
118+
when '--parse-only' then options[:parse_only] = true
119+
when '--quiet' then options[:quiet] = true
120+
when '--uri' then parser_options[:base] = arg
121+
when '--verbose' then $verbose = true
122+
when '--help' then usage
123+
end
124+
end
125+
126+
if ARGV.empty?
127+
s = input ? input : $stdin.read
128+
run(StringIO.new(s), options)
129+
else
130+
ARGV.each do |file|
131+
run(Kernel.open(file), options)
132+
end
133+
end
134+
puts

0 commit comments

Comments
 (0)