# 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"
{containers,type_language,type_language_value}
# 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:
list?(value)->
# 2.6.1) If @index is a not key in value, then append @list to containers.
containers=
ifnotindex?(value),
do:containers++["@list"],else:containers
# 2.6.2) Initialize list to the array associated with the key @list in value.
list=value["@list"]
# 2.6.3) Initialize common type and common language to null. If list is empty, set common language to default language.
# TODO: Spec fixme: Setting common language to default language is effectively useless, since the only place it is used is the follow loop in 2.6.4, which is immediately left when the list is empty
# 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:
{item_type,item_language}=
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_type,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_language}
# 2.6.4.2.3) Otherwise, set item language to @null.
true->
{item_type,"@null"}
end
# 2.6.4.3) Otherwise, set item type to @id.
else
{"@id",item_language}
end
common_language=
conddo
# 2.6.4.4) If common language is null, set it to item language.
is_nil(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)->
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->
"@none"
true->
common_type
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.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.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.