Added HTML translator
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
defmodule Localizator.Commons do
|
||||
@html_regex ~r/<(br|basefont|hr|input|source|frame|param|area|meta|!--|col|link|option|base|img|wbr|!DOCTYPE).*?>|<(a|abbr|acronym|address|applet|article|aside|audio|b|bdi|bdo|big|blockquote|body|button|canvas|caption|center|cite|code|colgroup|command|datalist|dd|del|details|dfn|dialog|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frameset|head|header|hgroup|h1|h2|h3|h4|h5|h6|html|i|iframe|ins|kbd|keygen|label|legend|li|map|mark|menu|meter|nav|noframes|noscript|object|ol|optgroup|output|p|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video).*?<\/\2>/i
|
||||
|
||||
def is_html?(string) when is_binary(string) do
|
||||
String.match?(string, @html_regex)
|
||||
end
|
||||
|
||||
def struct_from_map(a_map, as: a_struct) do
|
||||
# Find the keys within the map
|
||||
keys =
|
||||
|
||||
@@ -19,4 +19,7 @@ defmodule Localizator.Translator.Base do
|
||||
@callback detect(text) :: {:ok, locale} | {:error, message}
|
||||
@callback translate(text, to) :: {:ok, text} | {:error, message}
|
||||
@callback translate(text, to, from) :: {:ok, text} | {:error, message}
|
||||
|
||||
@callback translate!(text, to) :: text | nil
|
||||
@callback translate!(text, to, from) :: text | nil
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
defmodule Localizator.Translator do
|
||||
alias Localizator.Commons
|
||||
alias Localizator.Direction
|
||||
|
||||
@typedoc """
|
||||
@@ -39,9 +40,63 @@ defmodule Localizator.Translator do
|
||||
@spec default() :: translator
|
||||
def default(), do: list() |> List.first()
|
||||
|
||||
@spec translate(source, direction, translator) :: {:ok, result} | {:error, message}
|
||||
@spec translate(source, direction, translator) :: result
|
||||
def translate(source, direction, translator \\ default()) do
|
||||
map = Direction.get(direction)
|
||||
translator.translate(source, map.to, map.from)
|
||||
translate(source, map.to, map.from, translator)
|
||||
end
|
||||
|
||||
@spec translate(String.t(), to, from_may_be_nil, translator) :: result
|
||||
def translate(string, to, from, translator) when is_binary(string) do
|
||||
case Commons.is_html?(string) do
|
||||
true -> translate_html(string, to, from, translator)
|
||||
false -> translate_plain(string, to, from, translator)
|
||||
end
|
||||
end
|
||||
|
||||
@spec translate(Map.t(), to, from_may_be_nil, translator) :: result
|
||||
def translate(map, to, from, translator) when is_map(map) do
|
||||
Enum.map(map, fn {key, value} ->
|
||||
{key, translate(value, to, from, translator)}
|
||||
end)
|
||||
|> Map.new()
|
||||
end
|
||||
|
||||
@spec translate(List.t(), to, from_may_be_nil, translator) :: result
|
||||
def translate(list, to, from, translator) when is_list(list) do
|
||||
Enum.map(list, fn element -> translate(element, to, from, translator) end)
|
||||
end
|
||||
|
||||
defp translate_plain(string, to, from, translator) do
|
||||
translator.translate!(string, to, from)
|
||||
end
|
||||
|
||||
defp translate_html(string, to, from, translator) do
|
||||
string
|
||||
|> Meeseeks.parse()
|
||||
|> Meeseeks.tree()
|
||||
|> translate_html_element(to, from, translator)
|
||||
|> Meeseeks.parse(:tuple_tree)
|
||||
|> Meeseeks.html()
|
||||
end
|
||||
|
||||
# Plain Text Content
|
||||
defp translate_html_element([element], to, from, translator) when is_binary(element) do
|
||||
[translator.translate!(element, to, from)]
|
||||
end
|
||||
|
||||
# Part of the Plain Text Content
|
||||
defp translate_html_element(element, to, from, translator) when is_binary(element) do
|
||||
translator.translate!(element, to, from)
|
||||
end
|
||||
|
||||
# List of html elements
|
||||
defp translate_html_element(elements, to, from, translator) when is_list(elements) do
|
||||
Enum.map(elements, &translate_html_element(&1, to, from, translator))
|
||||
end
|
||||
|
||||
# Html element
|
||||
defp translate_html_element({tag, attributes, content}, to, from, translator) do
|
||||
{tag, attributes, translate_html_element(content, to, from, translator)}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@ defmodule Localizator.Translator.Yandex do
|
||||
@type text :: String.t()
|
||||
@type locale :: String.t()
|
||||
@type from :: locale
|
||||
@type optional_from :: from | nil
|
||||
@type to :: locale
|
||||
@type message :: String.t()
|
||||
|
||||
@@ -17,7 +18,7 @@ defmodule Localizator.Translator.Yandex do
|
||||
end
|
||||
|
||||
@impl true
|
||||
@spec translate(text, to) :: {:ok, text} | {:error, message}
|
||||
@spec translate(text, to, optional_from) :: {:ok, text} | {:error, message}
|
||||
def translate(text, to, from \\ nil)
|
||||
|
||||
def translate(text, to, from) when is_bitstring(text) and is_bitstring(to) do
|
||||
@@ -37,4 +38,13 @@ defmodule Localizator.Translator.Yandex do
|
||||
{:error, message}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
@spec translate(text, to, optional_from) :: text | nil
|
||||
def translate!(text, to, from \\ nil) when is_bitstring(text) and is_bitstring(to) do
|
||||
case translate(text, to, from) do
|
||||
{:ok, result} -> result
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user