Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique singular and plural messages #379

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions lib/gettext/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ defmodule Gettext.Compiler do
kind,
locale,
%Message.Plural{} = message,
_singular_fun,
singular_fun,
plural_fun,
file,
{plural_forms_fun, nplurals},
Expand Down Expand Up @@ -665,22 +665,54 @@ defmodule Gettext.Compiler do
line: unquote(Message.source_line_number(message, :msgid))
end

quote generated: true do
Kernel.unquote(kind)(
unquote(plural_fun)(
unquote(msgctxt),
unquote(msgid),
unquote(msgid_plural),
n,
bindings
)
) do
plural_form = unquote(plural_forms_fun)(n)
singular_fun_impl =
msgstr
|> Enum.find(&match?({0, _msgstr}, &1))
|> case do
{0, ""} ->
nil
maennchen marked this conversation as resolved.
Show resolved Hide resolved

{0, msgstr} ->
quote do
Kernel.unquote(kind)(
unquote(singular_fun)(unquote(msgctxt), unquote(msgid), bindings)
) do
require unquote(interpolation_module)

unquote(interpolation_module).compile_interpolate(
:translation,
unquote(msgstr),
bindings
)
end
end

nil ->
nil
end

plural_fun_impl =
quote generated: true do
Kernel.unquote(kind)(
unquote(plural_fun)(
unquote(msgctxt),
unquote(msgid),
unquote(msgid_plural),
n,
bindings
)
) do
plural_form = unquote(plural_forms_fun)(n)

var!(bindings) = Map.put(bindings, :count, n)
var!(bindings) = Map.put(bindings, :count, n)

case plural_form, do: unquote(clauses ++ error_clause)
case plural_form, do: unquote(clauses ++ error_clause)
end
end

quote do
unquote(singular_fun_impl)
unquote(plural_fun_impl)
maennchen marked this conversation as resolved.
Show resolved Hide resolved
end
end
end
Expand Down
38 changes: 7 additions & 31 deletions lib/gettext/extractor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,7 @@ defmodule Gettext.Extractor do
}
end

defp merge_message(
%Message.Singular{} = old,
%Message.Singular{comments: []} = new
) do
defp merge_message(old, new) do
ensure_empty_msgstr!(old)
ensure_empty_msgstr!(new)

Expand All @@ -353,36 +350,15 @@ defmodule Gettext.Extractor do
old.flags
end

%Message.Singular{
msgid: old.msgid,
msgstr: old.msgstr,
msgctxt: new.msgctxt,
old
|> Message.merge(new)
|> Map.merge(%{
flags: flags,
# The new in-memory message has no comments since it was extracted
# from the source code.
comments: old.comments,
# We don't care about the references of the old message since the new
# in-memory message has all the actual and current references.
references: new.references,
extracted_comments: new.extracted_comments
}
end

defp merge_message(%Message.Plural{} = old, %Message.Plural{comments: []} = new) do
ensure_empty_msgstr!(old)
ensure_empty_msgstr!(new)
maennchen marked this conversation as resolved.
Show resolved Hide resolved

# The logic here is the same as for %Message.Singular{}s.
%Message.Plural{
msgid: old.msgid,
msgctxt: new.msgctxt,
msgid_plural: old.msgid_plural,
msgstr: old.msgstr,
flags: old.flags,
comments: old.comments,
references: new.references,
extracted_comments: new.extracted_comments
}
})
end

defp ensure_empty_msgstr!(%Message.Singular{msgstr: msgstr} = message) do
Expand All @@ -392,8 +368,8 @@ defmodule Gettext.Extractor do
end
end

defp ensure_empty_msgstr!(%Message.Plural{msgstr: %{0 => str0, 1 => str1}} = message) do
if not blank?(str0) or not blank?(str1) do
defp ensure_empty_msgstr!(%Message.Plural{msgstr: msgstr} = message) do
if Enum.any?(Map.values(msgstr), &(not blank?(&1))) do
raise Error,
"plural message with msgid '#{IO.iodata_to_binary(message.msgid)}' has a non-empty msgstr"
end
Expand Down
28 changes: 5 additions & 23 deletions lib/gettext/merger.ex
Original file line number Diff line number Diff line change
Expand Up @@ -205,33 +205,15 @@ defmodule Gettext.Merger do
# flags: we should take the new flags and preserve the fuzzy flag
# references: new contains the updated and most recent references

defp merge_two_messages(
%Message.Singular{} = old,
%Message.Singular{} = new,
custom_flags_to_keep
) do
%Message.Singular{
msgctxt: new.msgctxt,
msgid: new.msgid,
msgstr: old.msgstr,
defp merge_two_messages(old, new, custom_flags_to_keep) do
old
|> Message.merge(new)
|> Map.merge(%{
comments: old.comments,
extracted_comments: new.extracted_comments,
flags: merge_flags(old, new, custom_flags_to_keep),
references: new.references
}
end

defp merge_two_messages(%Message.Plural{} = old, %Message.Plural{} = new, custom_flags_to_keep) do
%Message.Plural{
msgctxt: new.msgctxt,
msgid: new.msgid,
msgid_plural: new.msgid_plural,
msgstr: old.msgstr,
comments: old.comments,
extracted_comments: new.extracted_comments,
flags: merge_flags(old, new, custom_flags_to_keep),
references: new.references
}
})
end

defp merge_flags(old_message, new_message, custom_flags_to_keep) do
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ defmodule Gettext.Mixfile do

defp deps do
[
{:expo, "~> 0.4.0"},
{:expo, "~> 0.5.1"},

# Dev and test dependencies
{:ex_doc, "~> 0.19", only: :dev},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"},
"ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"},
"excoveralls": {:hex, :excoveralls, "0.17.0", "279f124dba347903bb654bc40745c493ae265d45040001b4899ea1edf88078c7", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "08b638d114387a888f9cb8d65f2a0021ec04c3e447b793efa7c1e734aba93004"},
"expo": {:hex, :expo, "0.4.0", "bbe4bf455e2eb2ebd2f1e7d83530ce50fb9990eb88fc47855c515bfdf1c6626f", [:mix], [], "hexpm", "a8ed1683ec8b7c7fa53fd7a41b2c6935f539168a6bb0616d7fd6b58a36f3abf2"},
"expo": {:hex, :expo, "0.5.0", "12035d6528e4fd6a9df5f71160ec114cce7f520f4c827fffe1f6760f1d8b4900", [:mix], [], "hexpm", "5a0231c3cf2fb221c313786cdc62aab91b99042c950d47bdb2e51b77d88df722"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
Expand Down
6 changes: 4 additions & 2 deletions test/gettext/extractor_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ defmodule Gettext.ExtractorTest do

ts2 = [
%Message.Singular{msgid: ["non-matching non-autogenerated"]},
%Message.Singular{
%Message.Plural{
msgid: ["matching autogenerated"],
msgid_plural: ["matching non-autogenerated 2"],
references: [{"foo.ex", 3}],
extracted_comments: ["#. Bar"],
flags: [["elixir-autogen"]]
Expand All @@ -152,8 +153,9 @@ defmodule Gettext.ExtractorTest do
) ==
%Messages{
messages: [
%Message.Singular{
%Message.Plural{
msgid: ["matching autogenerated"],
msgid_plural: ["matching non-autogenerated 2"],
references: [{"foo.ex", 3}],
flags: [["elixir-autogen"]],
extracted_comments: ["#. Bar"]
Expand Down
9 changes: 9 additions & 0 deletions test/gettext_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@ defmodule GettextTest do
)
end

test "plural messages can be used for singular message" do
import Translator, only: [lgettext: 5]

message =
lgettext("it", "errors", nil, "There was an error", %{})

assert message == {:ok, "C'è stato un errore"}
end

test "by default, non-found pluralized message behave like regular message" do
assert Translator.lngettext("it", "not a domain", nil, "foo", "foos", 1, %{}) ==
{:default, "foo"}
Expand Down
Loading