# -*- encoding: utf-8 -*- # frozen_string_literal: true module JSON::LD ## # A JSON-LD parser in Ruby. # # @see https://www.w3.org/TR/json-ld11-api # @author [Gregg Kellogg](http://greggkellogg.net/) class Reader < RDF::Reader format Format ## # JSON-LD Reader options # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Reader#options-class_method def self.options super + [ RDF::CLI::Option.new( symbol: :expandContext, control: :url2, datatype: RDF::URI, on: ["--expand-context CONTEXT"], description: "Context to use when expanding.") {|arg| RDF::URI(arg)}, RDF::CLI::Option.new( symbol: :extractAllScripts, datatype: TrueClass, default: false, control: :checkbox, on: ["--[no-]extract-all-scripts"], description: "If set to true, when extracting JSON-LD script elements from HTML, unless a specific fragment identifier is targeted, extracts all encountered JSON-LD script elements using an array form, if necessary.") {|arg| RDF::URI(arg)}, RDF::CLI::Option.new( symbol: :lowercaseLanguage, datatype: TrueClass, control: :checkbox, on: ["--[no-]lowercase-language"], description: "By default, language tags are left as is. To normalize to lowercase, set this option to `true`."), RDF::CLI::Option.new( symbol: :processingMode, datatype: %w(json-ld-1.0 json-ld-1.1), control: :radio, on: ["--processingMode MODE", %w(json-ld-1.0 json-ld-1.1)], description: "Set Processing Mode (json-ld-1.0 or json-ld-1.1)"), RDF::CLI::Option.new( symbol: :rdfDirection, datatype: %w(i18n-datatype compound-literal), default: 'null', control: :select, on: ["--rdf-direction DIR", %w(i18n-datatype compound-literal)], description: "How to serialize literal direction (i18n-datatype compound-literal)") {|arg| RDF::URI(arg)}, ] end ## # Initializes the RDF/JSON reader instance. # # @param [IO, File, String] input # @param [Hash{Symbol => Object}] options # any additional options (see `RDF::Reader#initialize` and {JSON::LD::API.initialize}) # @yield [reader] `self` # @yieldparam [RDF::Reader] reader # @yieldreturn [void] ignored # @raise [RDF::ReaderError] if the JSON document cannot be loaded def initialize(input = $stdin, **options, &block) options[:base_uri] ||= options[:base] super do @options[:base] ||= base_uri.to_s if base_uri begin # Trim non-JSON stuff in script. @doc = if input.respond_to?(:read) input else StringIO.new(input.to_s.sub(%r(\A[^{\[]*)m, '').sub(%r([^}\]]*\Z)m, '')) end end if block_given? case block.arity when 0 then instance_eval(&block) else block.call(self) end end end end ## # @private # @see RDF::Reader#each_statement def each_statement(&block) JSON::LD::API.toRdf(@doc, **@options, &block) rescue ::JSON::ParserError, ::JSON::LD::JsonLdError => e log_fatal("Failed to parse input document: #{e.message}", exception: RDF::ReaderError) end ## # @private # @see RDF::Reader#each_triple def each_triple(&block) if block_given? JSON::LD::API.toRdf(@doc, **@options) do |statement| yield(*statement.to_triple) end end enum_for(:each_triple) end end end