GettextOps.Entry (gettext_ops v0.1.1)

View Source

Helper functions for working with Expo.Message entries.

This module provides predicates and utilities for filtering and inspecting translation entries without needing to understand the Expo.Message structure directly.

Summary

Functions

Gets the domain from a message reference.

Gets the normalised msgctxt of a message, or nil when it has no context.

Gets the msgid as a string from a message.

Gets the msgstr as a string from a message.

Returns the gettext identity of a message as a {msgctxt, msgid} tuple.

Checks if the msgid matches a given pattern.

Checks if the msgstr matches a given pattern.

Checks if a message has an empty msgstr (is untranslated).

Creates a new message with updated msgid.

Creates a new message with updated msgstr.

Functions

get_domain(arg1)

@spec get_domain(Expo.Message.t()) :: String.t()

Gets the domain from a message reference.

Extracts the domain from the first reference path if available. Returns "default" if no references are found.

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hello"], references: [[{"lib/app_web/live/page_live.ex", 10}]]}
iex> GettextOps.Entry.get_domain(message)
"default"

get_msgctxt(arg1)

@spec get_msgctxt(Expo.Message.t()) :: String.t() | nil

Gets the normalised msgctxt of a message, or nil when it has no context.

Expo represents a missing context as nil and a present one as a list of string chunks. An explicit msgctxt "" is treated as no context, matching gettext (and Expo, which considers msgctxt "" and a bare msgid duplicates).

Examples

iex> message = %Expo.Message.Singular{msgid: ["Active"]}
iex> GettextOps.Entry.get_msgctxt(message)
nil

iex> message = %Expo.Message.Singular{msgid: ["Active"], msgctxt: ["token status"]}
iex> GettextOps.Entry.get_msgctxt(message)
"token status"

iex> message = %Expo.Message.Singular{msgid: ["Active"], msgctxt: [""]}
iex> GettextOps.Entry.get_msgctxt(message)
nil

get_msgid(arg1)

@spec get_msgid(Expo.Message.t()) :: String.t()

Gets the msgid as a string from a message.

Handles multi-line msgids by joining them together.

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hello"]}
iex> GettextOps.Entry.get_msgid(message)
"Hello"

iex> message = %Expo.Message.Singular{msgid: ["Hello\n", "World"]}
iex> GettextOps.Entry.get_msgid(message)
"Hello\nWorld"

get_msgstr(arg1)

@spec get_msgstr(Expo.Message.t()) :: String.t()

Gets the msgstr as a string from a message.

Handles multi-line msgstrs by joining them together. For plural forms, returns the first plural form (index 0).

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hello"], msgstr: ["Hej"]}
iex> GettextOps.Entry.get_msgstr(message)
"Hej"

iex> message = %Expo.Message.Plural{msgid: ["item"], msgid_plural: ["items"], msgstr: %{0 => ["One item"], 1 => ["Many items"]}}
iex> GettextOps.Entry.get_msgstr(message)
"One item"

key(message)

@spec key(Expo.Message.t()) :: {String.t() | nil, String.t()}

Returns the gettext identity of a message as a {msgctxt, msgid} tuple.

This — not the msgid alone — is what uniquely identifies an entry in a catalogue. Two entries sharing a msgid but carrying different msgctxt values are distinct entries, and keying them by msgid alone silently collapses one onto the other.

msgid_plural is deliberately not part of the key: gettext identifies a plural entry by its singular msgid, and Expo rejects a catalogue that holds both a singular and a plural entry for the same {msgctxt, msgid} pair.

Examples

iex> message = %Expo.Message.Singular{msgid: ["Active"]}
iex> GettextOps.Entry.key(message)
{nil, "Active"}

iex> message = %Expo.Message.Singular{msgid: ["Active"], msgctxt: ["token status"]}
iex> GettextOps.Entry.key(message)
{"token status", "Active"}

matches_msgid?(message, pattern)

@spec matches_msgid?(Expo.Message.t(), String.t() | Regex.t()) :: boolean()

Checks if the msgid matches a given pattern.

Pattern can be:

  • A string for exact match
  • A regex for pattern matching

Examples

iex> message = %Expo.Message.Singular{msgid: ["Welcome to Phoenix!"]}
iex> GettextOps.Entry.matches_msgid?(message, "Welcome")
false

iex> message = %Expo.Message.Singular{msgid: ["Welcome to Phoenix!"]}
iex> GettextOps.Entry.matches_msgid?(message, ~r/Phoenix/)
true

matches_msgstr?(message, pattern)

@spec matches_msgstr?(Expo.Message.t(), String.t() | Regex.t()) :: boolean()

Checks if the msgstr matches a given pattern.

Pattern can be:

  • A string for exact match
  • A regex for pattern matching

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hi"], msgstr: ["Välkommen till Phoenix!"]}
iex> GettextOps.Entry.matches_msgstr?(message, "Välkommen")
false

iex> message = %Expo.Message.Singular{msgid: ["Hi"], msgstr: ["Välkommen till Phoenix!"]}
iex> GettextOps.Entry.matches_msgstr?(message, ~r/Phoenix/)
true

untranslated?(arg1)

@spec untranslated?(Expo.Message.t()) :: boolean()

Checks if a message has an empty msgstr (is untranslated).

Returns true if the msgstr is empty or contains only empty strings.

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hello"], msgstr: [""]}
iex> GettextOps.Entry.untranslated?(message)
true

iex> message = %Expo.Message.Singular{msgid: ["Hello"], msgstr: ["Hej"]}
iex> GettextOps.Entry.untranslated?(message)
false

update_msgid(message, new_msgid)

@spec update_msgid(Expo.Message.t(), String.t()) :: Expo.Message.t()

Creates a new message with updated msgid.

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hello"], msgstr: ["Hej"]}
iex> updated = GettextOps.Entry.update_msgid(message, "Hi")
iex> updated.msgid
["Hi"]

update_msgstr(message, new_msgstr)

@spec update_msgstr(Expo.Message.t(), String.t()) :: Expo.Message.t()

Creates a new message with updated msgstr.

Examples

iex> message = %Expo.Message.Singular{msgid: ["Hello"], msgstr: [""]}
iex> updated = GettextOps.Entry.update_msgstr(message, "Hej")
iex> updated.msgstr
["Hej"]