# 2.3) Initialize type/language to @language, and type/language value to @null. These two variables will keep track of the preferred type mapping or language mapping for a term, based on what is compatible with value.
type_language="@language"
type_language_value="@null"
# 2.2) Initialize containers to an empty array. This array will be used to keep track of an ordered list of preferred container mappings for a term, based on what is compatible with value.
# 2.4) If value is a JSON object that contains the key @index, then append the value @index to containers.
# 2.5) If reverse is true, set type/language to @type, type/language value to @reverse, and append @set to containers.
reverse->
containers=containers++["@set"]
type_language="@type"
type_language_value="@reverse"
# 2.6) Otherwise, if value is a list object, then set type/language and type/language value to the most specific values that work for all items in the list as follows:
# 2.6.4.1) Initialize item language to @none and item type to @none.
{item_type,item_language}={"@none","@none"}
# 2.6.4.2) If item contains the key @value:
ifMap.has_key?(item,"@value")do
conddo
# 2.6.4.2.1) If item contains the key @language, then set item language to its associated value.
Map.has_key?(item,"@language")->
item_language=item["@language"]
# 2.6.4.2.2) Otherwise, if item contains the key @type, set item type to its associated value.
Map.has_key?(item,"@type")->
item_type=item["@type"]
# 2.6.4.2.3) Otherwise, set item language to @null.
true->
item_language="@null"
end
# 2.6.4.3) Otherwise, set item type to @id.
else
item_type="@id"
end
conddo
# 2.6.4.4) If common language is null, set it to item language.
is_nil(common_language)->
common_language=item_language
# 2.6.4.5) Otherwise, if item language does not equal common language and item contains the key @value, then set common language to @none because list items have conflicting languages.
# 2.6.4.6) If common type is null, set it to item type.
is_nil(common_type)->
common_type=item_type
# 2.6.4.7) Otherwise, if item type does not equal common type, then set common type to @none because list items have conflicting types.
item_type!=common_type->
common_type="@none"
true->
end
# 2.6.4.8) If common language is @none and common type is @none, then stop processing items in the list because it has been detected that there is no common language or type amongst the items.
# 2.6.7) If common type is not @none then set type/language to @type and type/language value to common type.
ifcommon_type!="@none"do
type_language="@type"
type_language_value=common_type
# 2.6.8) Otherwise, set type/language value to common language.
else
type_language_value=common_language
end
end
# 2.7) Otherwise
true->
# 2.7.1) If value is a value object:
ifis_map(value)andMap.has_key?(value,"@value")do
# 2.7.1.1) If value contains the key @language and does not contain the key @index, then set type/language value to its associated value and append @language to containers.
# 2.7.1.2) Otherwise, if value contains the key @type, then set type/language value to its associated value and set type/language to @type.
ifMap.has_key?(value,"@type")do
type_language_value=value["@type"]
type_language="@type"
end
end
# 2.7.2) Otherwise, set type/language to @type and set type/language value to @id.
else
type_language="@type"
type_language_value="@id"
end
# 2.7.3) Append @set to containers.
containers=containers++["@set"]
end
# 2.8) Append @none to containers. This represents the non-existence of a container mapping, and it will be the last container mapping value to be checked as it is the most generic.
containers=containers++["@none"]
# 2.9) If type/language value is null, set it to @null. This is the key under which null values are stored in the inverse context entry.
# 2.10) Initialize preferred values to an empty array. This array will indicate, in order, the preferred values for a term's type mapping or language mapping.
preferred_values=[]
# 2.11) If type/language value is @reverse, append @reverse to preferred values.
# 2.12.1) If the result of using the IRI compaction algorithm, passing active context, inverse context, the value associated with the @id key in value for iri, true for vocab, and true for document relative has a term definition in the active context with an IRI mapping that equals the value associated with the @id key in value, then append @vocab, @id, and @none, in that order, to preferred values.
# TODO: Spec fixme? document_relative is not a specified parameter of compact_iri
# 3) At this point, there is no simple term that iri can be compacted to. If vocab is true and active context has a vocabulary mapping:
# 3.1) If iri begins with the vocabulary mapping's value but is longer, then initialize suffix to the substring of iri that does not match. If suffix does not have a term definition in active context, then return suffix.
# 4) The iri could not be compacted using the active context's vocabulary mapping. Try to create a compact IRI, starting by initializing compact IRI to null. This variable will be used to tore the created compact IRI, if any.
compact_iri=
# 5) For each key term and value term definition in the active context:
# 5.1) If the term contains a colon (:), then continue to the next term because terms with colons can't be used as prefixes.
String.contains?(term,":")->
compact_iri
# 5.2) If the term definition is null, its IRI mapping equals iri, or its IRI mapping is not a substring at the beginning of iri, the term cannot be used as a prefix because it is not a partial match with iri. Continue with the next term.
# 5.3) Initialize candidate by concatenating term, a colon (:), and the substring of iri that follows after the value of the term definition's IRI mapping.
# 5.4) If either compact IRI is null or candidate is shorter or the same length but lexicographically less than compact IRI and candidate does not have a term definition in active context or if the term definition has an IRI mapping that equals iri and value is null, set compact IRI to candidate.
# TODO: Spec fixme: The specified expression is pretty ambiguous without brackets ...
# TODO: Spec fixme: "if the term definition has an IRI mapping that equals iri" is already catched in 5.2, so will never happen here ...
# 4.1) If number members is 1 and the type mapping of active property is set to @id, return the result of using the IRI compaction algorithm, passing active context, inverse context, and the value of the @id member for iri.
# 4.2) Otherwise, if number members is 1 and the type mapping of active property is set to @vocab, return the result of using the IRI compaction algorithm, passing active context, inverse context, the value of the @id member for iri, and true for vocab.
# 5) Otherwise, if value has an @type member whose value matches the type mapping of active property, return the value associated with the @value member of value.
# 6) Otherwise, if value has an @language member whose value matches the language mapping of active property, return the value associated with the @value member of value.
(language=Map.get(value,"@language"))&&
# TODO: Spec fixme: doesn't specify to check default language as well
# 7) Otherwise, if number members equals 1 and either the value of the @value member is not a string, or the active context has no default language, or the language mapping of active property is set to null,, return the value associated with the @value member.
ifnumber_members==1and
(notis_binary(value_value=value["@value"])or
!active_context.default_languageor
# TODO: Spec fixme: doesn't specify to check default language as well