Source code for iiisight.language

"""The :class:`LanguageMap` value type for IIIF language maps.

IIIF represents human-readable strings (``label``, ``summary``, metadata
labels/values) as language maps: a mapping of BCP-47 language code to a list of
string values, with the special key ``"none"`` for values with no language.
:class:`LanguageMap` wraps that shape so callers can pull a display string
without hand-indexing ``{"en": ["..."]}``.
"""

from collections.abc import Iterable, Mapping


[docs] class LanguageMap: """An immutable IIIF language map (``lang -> list[str]``). Construct from a mapping of language code to a list of strings. The ``"none"`` key holds values with no associated language. """ __slots__ = ("_values",) def __init__(self, values: Mapping[str, Iterable[str]] | None = None): """Store a defensive copy of ``values`` as ``dict[str, list[str]]``.""" self._values: dict[str, list[str]] = { lang: list(strings) for lang, strings in (values or {}).items() }
[docs] def languages(self) -> list[str]: """Return the language codes present, in insertion order.""" return list(self._values)
[docs] def get(self, language: str) -> list[str]: """Return the values for ``language`` (empty list if absent).""" return list(self._values.get(language, []))
[docs] def text(self, language: str | None = None, separator: str = " ") -> str: """Return a single display string. Selection order: the requested ``language`` if given and present, else the no-language ``"none"`` values, else the first language present, else an empty string. Multiple values for the chosen language are joined with ``separator``. Args: language: Preferred language code, or ``None`` for the default order. separator: Joins multiple values for the chosen language. Returns: The chosen values joined into one string. """ if language is not None and language in self._values: chosen = self._values[language] elif "none" in self._values: chosen = self._values["none"] elif self._values: chosen = next(iter(self._values.values())) else: chosen = [] return separator.join(chosen)
def __bool__(self) -> bool: return bool(self._values) def __eq__(self, other: object) -> bool: if isinstance(other, LanguageMap): return self._values == other._values return NotImplemented def __str__(self) -> str: return self.text() def __repr__(self) -> str: return f"LanguageMap({self._values!r})"