Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added bin/jsonld for command-line manipulation of JSON-LD files and t…

…o perform RDF transformations.
  • Loading branch information...
commit ab38385f5723e561226d026eedc9f1ef000c8072 1 parent 2bd55c8
@gkellogg authored
Showing with 139 additions and 6 deletions.
  1. +5 −6 .gemspec
  2. +134 −0 bin/jsonld
View
11 .gemspec
@@ -13,16 +13,16 @@ Gem::Specification.new do |gem|
gem.rubyforge_project = 'json-ld'
gem.authors = ['Gregg Kellogg']
- gem.email = 'public-rdf-ruby@w3.org'
+ gem.email = 'public-linked-json@w3.org'
gem.platform = Gem::Platform::RUBY
gem.files = %w(AUTHORS README.markdown History.markdown UNLICENSE VERSION) + Dir.glob('lib/**/*.rb')
- #gem.bindir = %q(bin)
- #gem.executables = %w(json_ld)
- #gem.default_executable = gem.executables.first
+ gem.bindir = %q(bin)
+ gem.executables = %w(jsonld)
+ gem.default_executable = gem.executables.first
gem.require_paths = %w(lib)
gem.extensions = %w()
- gem.test_files = %w()
+ gem.test_files = Dir.glob('spec/**/*.rb') + Dir.glob('spec/test-files/*')
gem.has_rdoc = false
gem.required_ruby_version = '>= 1.8.1'
@@ -38,7 +38,6 @@ Gem::Specification.new do |gem|
gem.add_development_dependency 'rdf-turtle', '>= 0.1.1'
gem.add_development_dependency 'rdf-trig', '>= 0.1.1'
gem.add_development_dependency 'rdf-isomorphic', '>= 0.3.4'
- gem.add_development_dependency 'sparql', '>= 0.0.2'
gem.add_runtime_dependency 'backports'
gem.post_install_message = nil
end
View
134 bin/jsonld
@@ -0,0 +1,134 @@
+#!/usr/bin/env ruby
+require 'rubygems'
+$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib')))
+begin
+ require 'linkeddata'
+rescue LoadError
+end
+require 'json/ld'
+require 'getoptlong'
+require 'open-uri'
+
+def run(input, options)
+ reader_class = RDF::Reader.for(options[:input_format].to_sym)
+ raise "Reader not found for #{options[:input_format]}" unless reader_class
+
+ # Override default (or specified) output format when framing
+ options[:format] = :jsonld if options[:compact] || options[:frame]
+
+ # If input format is not JSON-LD, transform input to JSON-LD first
+ if options[:format] == :jsonld && options[:input_format] != :jsonld
+ r = reader_class.new(input, options[:parser_options])
+ g = RDF::Repository.new << r
+ input = JSON::LD::API.fromRDF(g)
+ end
+
+ prefixes = {}
+ start = Time.new
+ if options[:expand]
+ output = JSON::LD::API.expand(input, options[:context], nil, options)
+ secs = Time.new - start
+ options[:output].puts output.to_json(JSON::LD::JSON_STATE)
+ STDERR.puts "Expanded in #{secs} seconds." unless options[:quiet]
+ elsif options[:compact]
+ output = JSON::LD::API.compact(input, options[:context], nil, options)
+ secs = Time.new - start
+ options[:output].puts output.to_json(JSON::LD::JSON_STATE)
+ STDERR.puts "Compacted in #{secs} seconds." unless options[:quiet]
+ elsif options[:frame]
+ output = JSON::LD::API.frame(input, options[:frame], nil, options)
+ secs = Time.new - start
+ options[:output].puts output.to_json(JSON::LD::JSON_STATE)
+ STDERR.puts "Framed in #{secs} seconds." unless options[:quiet]
+ else
+ r = reader_class.new(input, options[:parser_options])
+ g = RDF::Repository.new << r
+ secs = Time.new - start
+ num = g.count
+ parser_options = options[:parser_options].merge(:prefixes => r.prefixes, :standard_prefixes => true)
+ options[:output].puts g.dump(options[:output_format], parser_options)
+ STDERR.puts "\nParsed #{num} statements in #{secs} seconds @ #{num/secs} statements/second." unless options[:quiet]
+ end
+rescue
+ fname = input.respond_to?(:path) ? input.path : "-stdin-"
+ STDERR.puts("Error in #{fname}")
+ raise
+end
+
+parser_options = {
+ :base => "",
+ :progress => false,
+ :validate => false,
+ :strict => false,
+}
+
+options = {
+ :parser_options => parser_options,
+ :output => STDOUT,
+ :output_format => :turtle,
+ :input_format => :jsonld,
+}
+input = nil
+
+OPT_ARGS = [
+ ["--dbg", GetoptLong::NO_ARGUMENT, "Turn on verbose debugging"],
+ ["--compact", GetoptLong::NO_ARGUMENT, "Compact document, using --context"],
+ ["--context", GetoptLong::REQUIRED_ARGUMENT,"Context to apply for expand, compact and converting from RDF"],
+ ["--evaluate","-e", GetoptLong::REQUIRED_ARGUMENT,"Evaluate argument as a JSON-LD document"],
+ ["--expand", GetoptLong::NO_ARGUMENT, "Expand document, using an optional --context"],
+ ["--format", GetoptLong::REQUIRED_ARGUMENT,"Specify output format when converting to RDF"],
+ ["--frame", GetoptLong::REQUIRED_ARGUMENT,"Frame document, using the file or URL as a frame specification"],
+ ["--input-format", GetoptLong::REQUIRED_ARGUMENT,"Format of the input document, when converting from RDF."],
+ ["--output", "-o", GetoptLong::REQUIRED_ARGUMENT,"Output to the specified file path"],
+ ["--parse-only", GetoptLong::NO_ARGUMENT, "Parse the document for well-formedness only"],
+ ["--quiet", GetoptLong::NO_ARGUMENT, "Supress most output other than progress indicators"],
+ ["--uri", GetoptLong::REQUIRED_ARGUMENT,"URI to be used as the document base"],
+ ["--verbose", GetoptLong::NO_ARGUMENT, "Detail on execution"],
+ ["--help", "-?", GetoptLong::NO_ARGUMENT, "This message"]
+]
+def usage
+ STDERR.puts %{Usage: #{$0} [options] file ...}
+ width = OPT_ARGS.map do |o|
+ l = o.first.length
+ l += o[1].length + 2 if o[1].is_a?(String)
+ l
+ end.max
+ OPT_ARGS.each do |o|
+ s = " %-*s " % [width, (o[1].is_a?(String) ? "#{o[0,2].join(', ')}" : o[0])]
+ s += o.last
+ STDERR.puts s
+ end
+ exit(1)
+end
+
+
+opts = GetoptLong.new(*OPT_ARGS.map {|o| o[0..-2]})
+
+opts.each do |opt, arg|
+ case opt
+ when '--dbg' then parser_options[:debug] = ::JSON::LD::debug = true
+ when '--compact' then options[:compact] = true
+ when '--context' then options[:context] = arg
+ when '--execute' then input = arg
+ when '--expand' then options[:expand] = true
+ when '--format' then options[:output_format] = arg.to_sym
+ when '--frame' then options[:frame] = arg
+ when '--input-format' then options[:input_format] = arg.to_sym
+ when '--output' then options[:output] = File.open(arg, "w")
+ when '--parse-only' then options[:parse_only] = true
+ when '--quiet' then options[:quiet] = true
+ when '--uri' then parser_options[:base] = arg
+ when '--verbose' then $verbose = true
+ when '--help' then usage
+ end
+end
+
+if ARGV.empty?
+ s = input ? input : $stdin.read
+ run(StringIO.new(s), options)
+else
+ ARGV.each do |file|
+ run(Kernel.open(file), options)
+ end
+end
+puts
Please sign in to comment.
Something went wrong with that request. Please try again.