Skip to content

Commit

Permalink
Finish 0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Sep 7, 2022
2 parents d9705d0 + 49d440d commit b3932e7
Show file tree
Hide file tree
Showing 82 changed files with 1,374 additions and 532 deletions.
1 change: 1 addition & 0 deletions .yardopts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
--hide-void-return
--markup markdown
--readme README.md
--exclude lib/psych/amazing_print.rb
-
AUTHORS
VERSION
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.1
0.0.2
14 changes: 14 additions & 0 deletions examples/i18n.yamlld
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%YAML 1.2
%TAG !i18n! https://www.w3.org/ns/i18n%23
---
"@context":
"@vocab": http://example.com/
name: http://xmlns.com/foaf/0.1/name
homepage: http://xmlns.com/foaf/0.1/homepage
depiction: http://xmlns.com/foaf/0.1/depiction
name: Gregg Kellogg
homepage: https://greggkellogg.net/
depiction: http://www.gravatar.com/avatar/42f948adff3afaa52249d963117af7c8
lang: !i18n!en-US EN-US
dir: !i18n!_ltr "Left to Right"
langdir: !i18n!en-US_ltr "Left to Right US English"
26 changes: 26 additions & 0 deletions examples/scalars.yamlld
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
%YAML 1.2
%TAG !xsd! http://www.w3.org/2001/XMLSchema%23
---
"@context":
"@vocab": http://example.com/
name: http://xmlns.com/foaf/0.1/name
homepage: http://xmlns.com/foaf/0.1/homepage
depiction: http://xmlns.com/foaf/0.1/depiction
name: Gregg Kellogg
homepage: https://greggkellogg.net/
depiction: http://www.gravatar.com/avatar/42f948adff3afaa52249d963117af7c8
yint: 123
yfloat: 123.45
ystring: string
ynull: null
ybool: true
ydate: 2022-08-08
ytime: 12:00:00
ydateTime: 2022-08-08T12:00:00.000
integer: !xsd!integer 123
decimal: !xsd!decimal 123.456
double: !xsd!double 123.456e78
bool: !xsd!boolean true
date: !xsd!date "2022-08-08"
time: !xsd!time "12:00:00.000"
dateTime: !xsd!dateTime "2022-08-08T12:00:00.000"
9 changes: 9 additions & 0 deletions examples/xsd.yamlld
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
%YAML 1.2
%TAG ! http://www.w3.org/2001/XMLSchema%23
---
"@context":
"@vocab": http://xmlns.com/foaf/0.1/
name: !string Gregg Kellogg
homepage: https://greggkellogg.net/
depiction: http://www.gravatar.com/avatar/42f948adff3afaa52249d963117af7c8
date: !date "2022-08-08"
61 changes: 61 additions & 0 deletions lib/psych/amazing_print.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# frozen_string_literal: true

# Amazing Print extensions for Psych
#------------------------------------------------------------------------------
module AmazingPrint
module Psych
def self.included(base)
base.send :alias_method, :cast_without_psych, :cast
base.send :alias_method, :cast, :cast_with_psych
end

# Add Psych Node names to the dispatcher pipeline.
#------------------------------------------------------------------------------
def cast_with_psych(object, type)
cast = cast_without_psych(object, type)
if (defined?(::Psych::Nodes::Node) && object.is_a?(::Psych::Nodes::Node))
cast = :psych_node
end
cast
end

STYLES = %w(ANY BLOCK FLOW) #------------------------------------------------------------------------------
def awesome_psych_node(object)
contents = []
contents << colorize(object.class.name.split('::').last, :class)
contents << colorize("!<#{object.tag}>", :args) if object.tag
contents << colorize("&#{object.anchor}", :args) if object.respond_to?(:anchor) && object.anchor
contents << colorize("(implicit)", :args) if object.respond_to?(:implicit) && object.implicit
contents << colorize("(implicit end)", :args) if object.respond_to?(:implicit_end) && object.implicit_end
case object
when ::Psych::Nodes::Stream
contents << awesome_array(object.children)
when ::Psych::Nodes::Document
contents << colorize('%TAG(' + object.tag_directives.flatten.join(' ') + ')', :args) unless Array(object.tag_directives).empty?
contents << colorize("version #{object.version.join('.')}", :args) if object.version
contents << awesome_array(object.children)
when ::Psych::Nodes::Sequence
style = %w(ANY BLOCK FLOW)[object.style.to_i]
contents << awesome_array(object.children)
when ::Psych::Nodes::Mapping
style = %w(ANY BLOCK FLOW)[object.style.to_i]
contents << colorize(style, :args) if object.style
contents << awesome_hash(object.children.each_slice(2).to_h)
when ::Psych::Nodes::Scalar
style = %w(ANY PLAIN SINGLE_QUOTED DOUBLE_QUOTED LITERAL FOLDED)[object.style.to_i]
contents << colorize(style, :args) if object.style
contents << colorize("(plain)", :args) if object.plain
contents << colorize("(quoted)", :args) if object.quoted
contents << awesome_simple(object.value.inspect, :variable)
when ::Psych::Nodes::Alias
# No children
else
"Unknown node type: #{object.inspect}"
end

contents.join(' ')
end
end
end

AmazingPrint::Formatter.include AmazingPrint::Psych
1 change: 1 addition & 0 deletions lib/yaml_ld.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module YAML_LD

autoload :API, 'yaml_ld/api'
autoload :Reader, 'yaml_ld/reader'
autoload :Representation, 'yaml_ld/representation'
autoload :VERSION, 'yaml_ld/version'
autoload :Writer, 'yaml_ld/writer'

Expand Down
80 changes: 69 additions & 11 deletions lib/yaml_ld/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ module YAML_LD
# @see https://www.w3.org/TR/json-ld11-api/#the-application-programming-interface
# @author [Gregg Kellogg](http://greggkellogg.net/)
class API < ::JSON::LD::API

# The following constants are used to reduce object allocations
LINK_REL_CONTEXT = %w(rel http://www.w3.org/ns/yaml-ld#context).freeze
LINK_REL_ALTERNATE = %w(rel alternate).freeze
Expand All @@ -30,6 +29,35 @@ class API < ::JSON::LD::API
# A Serializer method used for generating the YAML serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to YAML externally via `#to_yaml`.
# See {YAML_LD::API.serializer}.
# @param [Hash{Symbol => Object}] options
# @option options [RDF::URI, String, #to_s] :base
# The Base IRI to use when expanding the document. This overrides the value of `input` if it is a _IRI_. If not specified and `input` is not an _IRI_, the base IRI defaults to the current document IRI if in a browser context, or the empty string if there is no document context. If not specified, and a base IRI is found from `input`, options[:base] will be modified with this value.
# @option options [Boolean] :compactArrays (true)
# If set to `true`, the JSON-LD processor replaces arrays with just one element with that element during compaction. If set to `false`, all arrays will remain arrays even if they have just one element.
# @option options [Boolean] :compactToRelative (true)
# Creates document relative IRIs when compacting, if `true`, otherwise leaves expanded.
# @option options [Proc] :documentLoader
# The callback of the loader to be used to retrieve remote documents and contexts. If specified, it must be used to retrieve remote documents and contexts; otherwise, if not specified, the processor's built-in loader must be used. See {documentLoader} for the method signature.
# @option options [String, #read, Hash, Array, JSON::LD::Context] :expandContext
# A context that is used to initialize the active context when expanding a document.
# @option options [Boolean] :extendedYAML (false)
# Use the expanded internal representation.
# @option options [Boolean] :extractAllScripts
# If set, when given an HTML input without a fragment identifier, extracts all `script` elements with type `application/ld+json` into an array during expansion.
# @option options [Boolean, String, RDF::URI] :flatten
# If set to a value that is not `false`, the JSON-LD processor must modify the output of the Compaction Algorithm or the Expansion Algorithm by coalescing all properties associated with each subject via the Flattening Algorithm. The value of `flatten must` be either an _IRI_ value representing the name of the graph to flatten, or `true`. If the value is `true`, then the first graph encountered in the input document is selected and flattened.
# @option options [String] :language
# When set, this has the effect of inserting a context definition with `@language` set to the associated value, creating a default language for interpreting string values.
# @option options [Boolean] :lowercaseLanguage
# By default, language tags are left as is. To normalize to lowercase, set this option to `true`.
# @option options [Boolean] :ordered (true)
# Order traversal of dictionary members by key when performing algorithms.
# @option options [Boolean] :rdfstar (false)
# support parsing JSON-LD-star statement resources.
# @option options [Boolean] :rename_bnodes (true)
# Rename bnodes as part of expansion, or keep them the same.
# @option options [Boolean] :unique_bnodes (false)
# Use unique bnode identifiers, defaults to using the identifier which the node was originally initialized with (if any).
# @option options [Boolean] :validate Validate input, if a string or readable object.
# @raise [JsonLdError]
# @yield YAML_LD, base_iri
# @yieldparam [Array<Hash>] yamlld
Expand All @@ -46,7 +74,10 @@ def self.expand(input,
**options,
&block)
JSON::LD::API.expand(input,
allowed_content_types: %r(application/(.+\+)?yaml),
documentLoader: documentLoader,
extendedRepresentation: options[:extendedYAML],
processingMode: 'json-ld-1.1',
serializer: serializer,
**options,
&block)
Expand All @@ -68,7 +99,7 @@ def self.expand(input,
# See {YAML_LD::API.serializer}.
# @param [Boolean] expanded (false) Input is already expanded
# @param [Hash{Symbol => Object}] options
# @option options (see #initialize)
# @option options (see expand)
# @yield YAML_LD
# @yieldparam [Array<Hash>] yamlld
# The expanded YAML-LD document
Expand All @@ -83,7 +114,10 @@ def self.compact(input, context, expanded: false,
**options,
&block)
JSON::LD::API.compact(input, context, expanded: expanded,
allowed_content_types: %r(application/(.+\+)?yaml),
documentLoader: documentLoader,
extendedRepresentation: options[:extendedYAML],
processingMode: 'json-ld-1.1',
serializer: serializer,
**options,
&block)
Expand All @@ -103,9 +137,11 @@ def self.compact(input, context, expanded: false,
# A Serializer method used for generating the YAML serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to YAML externally via `#to_yaml`.
# See {YAML_LD::API.serializer}.
# @param [Hash{Symbol => Object}] options
# @option options (see #initialize)
# @option options (see expand)
# @option options [Boolean] :createAnnotations
# Unfold embedded nodes which can be represented using `@annotation`.
# @option options [Boolean] :extendedYAML (false)
# Use the expanded internal representation.
# @yield YAML_LD
# @yieldparam [Array<Hash>] yamlld
# The expanded YAML-LD document
Expand All @@ -119,7 +155,10 @@ def self.flatten(input, context, expanded: false,
**options,
&block)
JSON::LD::API.flatten(input, context, expanded: expanded,
allowed_content_types: %r(application/(.+\+)?yaml),
documentLoader: documentLoader,
extendedRepresentation: options[:extendedYAML],
processingMode: 'json-ld-1.1',
serializer: serializer,
**options,
&block)
Expand All @@ -135,11 +174,13 @@ def self.flatten(input, context, expanded: false,
# @param [String, #read, Hash, Array] frame
# The frame to use when re-arranging the data.
# @param [Boolean] expanded (false) Input is already expanded
# @option options (see #initialize)
# @option options (see expand)
# @option options ['@always', '@link', '@once', '@never'] :embed ('@once')
# a flag specifying that objects should be directly embedded in the output, instead of being referred to by their IRI.
# @option options [Boolean] :explicit (false)
# a flag specifying that for properties to be included in the output, they must be explicitly declared in the framing context.
# @option options [Boolean] :extendedYAML (false)
# Use the expanded internal representation.
# @option options [Boolean] :requireAll (false)
# A flag specifying that all properties present in the input frame must either have a default value or be present in the JSON-LD input for the frame to match.
# @option options [Boolean] :omitDefault (false)
Expand All @@ -160,7 +201,10 @@ def self.frame(input, frame, expanded: false,
**options,
&block)
JSON::LD::API.frame(input, frame, expanded: expanded,
allowed_content_types: %r(application/(.+\+)?yaml),
documentLoader: documentLoader,
extendedRepresentation: options[:extendedYAML],
processingMode: 'json-ld-1.1',
serializer: serializer,
**options,
&block)
Expand All @@ -172,7 +216,9 @@ def self.frame(input, frame, expanded: false,
# @param [String, #read, Hash, Array] input
# The YAML-LD object to process when outputting statements.
# @param [Boolean] expanded (false) Input is already expanded
# @option options (see #initialize)
# @option options (see expand)
# @option options [Boolean] :extendedYAML (false)
# Use the expanded internal representation.
# @option options [Boolean] :produceGeneralizedRdf (false)
# If true, output will include statements having blank node predicates, otherwise they are dropped.
# @raise [JsonLdError]
Expand All @@ -184,7 +230,10 @@ def self.toRdf(input, expanded: false,
**options,
&block)
JSON::LD::API.toRdf(input, expanded: expanded,
allowed_content_types: %r(application/(.+\+)?yaml),
documentLoader: documentLoader,
extendedRepresentation: options[:extendedYAML],
processingMode: 'json-ld-1.1',
**options,
&block)
end
Expand All @@ -202,7 +251,9 @@ def self.toRdf(input, expanded: false,
# A Serializer method used for generating the YAML serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to YAML externally via `#to_yaml`.
# See {YAML_LD::API.serializer}.
# @param [Hash{Symbol => Object}] options
# @option options (see #initialize)
# @option options (see expand)
# @option options [Boolean] :extendedYAML (false)
# Use the expanded internal representation.
# @yield jsonld
# @yieldparam [Hash] jsonld
# The JSON-LD document in expanded form
Expand All @@ -215,10 +266,13 @@ def self.fromRdf(input, useRdfType: false, useNativeTypes: false,
**options,
&block)
JSON::LD::API.fromRdf(input,
useRdfType: useRdfType,
useNativeTypes: useNativeTypes,
allowed_content_types: %r(application/(.+\+)?yaml),
documentLoader: documentLoader,
extendedRepresentation: options[:extendedYAML],
processingMode: 'json-ld-1.1',
serializer: serializer,
useRdfType: useRdfType,
useNativeTypes: useNativeTypes,
**options,
&block)
end
Expand Down Expand Up @@ -257,7 +311,7 @@ def self.documentLoader(url, extractAllScripts: false, profile: nil, requestProf
content = case content_type
when nil, %r(application/(\w+\+)*yaml)
# Parse YAML
Psych.safe_load(url.read, aliases: true)
Representation.load(url.read, filename: url.to_s, **options)
else
url.read
end
Expand All @@ -267,7 +321,11 @@ def self.documentLoader(url, extractAllScripts: false, profile: nil, requestProf
contextUrl: context_url))
elsif url.to_s.match?(/\.yaml\w*$/) || content_type.to_s.match?(%r(application/(\w+\+)*yaml))
# Parse YAML
block.call(RemoteDocument.new(Psych.load_file(url.to_s, aliases: true),
content = Representation.load(RDF::Util::File.open_file(url.to_s).read,
filename: url.to_s,
**options)

block.call(RemoteDocument.new(content,
documentUrl: base_uri,
contentType: content_type,
contextUrl: context_url))
Expand All @@ -288,7 +346,7 @@ def self.documentLoader(url, extractAllScripts: false, profile: nil, requestProf
# options passed from the invoking context.
def self.serializer(object, *args, **options)
# de-alias any objects to avoid the use of aliases and anchors
"%YAML 1.2\n" + Psych.dump(object, **options)
"%YAML 1.2\n" + Representation.dump(object, **options)
end
end
end
Expand Down
25 changes: 25 additions & 0 deletions lib/yaml_ld/format.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# -*- encoding: utf-8 -*-
# frozen_string_literal: true
require 'json/ld/format'

module YAML_LD
##
# YAML-LD format specification.
Expand Down Expand Up @@ -28,6 +30,25 @@ class Format < RDF::Format
reader { YAML_LD::Reader }
writer { YAML_LD::Writer }

# Specify how to execute CLI commands for each supported format. These are added to the `LD_FORMATS` defined for `JSON::LD::Format`
# Derived formats (e.g., YAML-LD) define their own entrypoints.
LD_FORMATS = {
yamlld: {
expand: ->(input, **options) {
YAML_LD::API.expand(input, validate: false, **options)
},
compact: ->(input, **options) {
YAML_LD::API.compact(input, options[:context], **options)
},
flatten: ->(input, **options) {
YAML_LD::API.flatten(input, options[:context], **options)
},
frame: ->(input, **options) {
YAML_LD::API.frame(input, options[:frame], **options)
},
}
}

##
# Sample detection to see if it matches YAML-LD
#
Expand All @@ -54,3 +75,7 @@ def self.name
end
end
end


# Load into JSON::LD::Format::LD_FORMATS
::JSON::LD::Format.const_get(:LD_FORMATS).merge!(::YAML_LD::Format::LD_FORMATS)
4 changes: 3 additions & 1 deletion lib/yaml_ld/reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class Reader < JSON::LD::Reader
def initialize(input = $stdin,
documentLoader: YAML_LD::API.method(:documentLoader),
**options, &block)
input = StringIO.new(input) if input.is_a?(String)
input = StringIO.new(input).tap do |d|
d.define_singleton_method(:content_type) {'application/ld+yaml'}
end if input.is_a?(String)
super(input, documentLoader: documentLoader, **options, &block)
end

Expand Down
Loading

0 comments on commit b3932e7

Please sign in to comment.