#!/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