aboutsummaryrefslogtreecommitdiff
path: root/contrib/extract_translations/extract_translations.erl
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2008-08-17 16:35:58 +0000
committerBadlop <badlop@process-one.net>2008-08-17 16:35:58 +0000
commit61a639d5d99416cdb5743413230fb9ddc36ecf91 (patch)
tree48c8678173ee05be1dbbb7bee0668b6e41d4aa90 /contrib/extract_translations/extract_translations.erl
parent* src/msgs/sv.msg: Fixed formatting typos (diff)
* contrib/extract_translations/extract_translations.erl: Use
Gettext PO for translators, export to ejabberd MSG (EJAB-468) * contrib/extract_translations/prepare-translation.sh: Likewise * doc/guide.tex: Likewise * doc/guide.html: Likewise * src/Makefile.in: New option 'make translations' * src/msgs/ejabberd.pot: Template translation file * src/msgs/*.po: Generated from old MSG files * src/msgs/*.msg: Automatic exported from PO files SVN Revision: 1527
Diffstat (limited to 'contrib/extract_translations/extract_translations.erl')
-rw-r--r--contrib/extract_translations/extract_translations.erl121
1 files changed, 110 insertions, 11 deletions
diff --git a/contrib/extract_translations/extract_translations.erl b/contrib/extract_translations/extract_translations.erl
index 5c727e785..1f38cd08e 100644
--- a/contrib/extract_translations/extract_translations.erl
+++ b/contrib/extract_translations/extract_translations.erl
@@ -20,9 +20,14 @@
start() ->
ets:new(translations, [named_table, public]),
+ ets:new(translations_obsolete, [named_table, public]),
ets:new(files, [named_table, public]),
ets:new(vars, [named_table, public]),
case init:get_plain_arguments() of
+ ["-srcmsg2po", Dir, File] ->
+ print_po_header(File),
+ Status = process(Dir, File, srcmsg2po),
+ halt(Status);
["-unused", Dir, File] ->
Status = process(Dir, File, unused),
halt(Status);
@@ -50,7 +55,11 @@ process(Dir, File, Used) ->
unused ->
ets:foldl(fun({Key, _}, _) ->
io:format("~p~n", [Key])
- end, ok, translations);
+ end, ok, translations);
+ srcmsg2po ->
+ ets:foldl(fun({Key, Trans}, _) ->
+ print_translation_obsolete(Key, Trans)
+ end, ok, translations_obsolete);
_ ->
ok
end,
@@ -74,46 +83,52 @@ parse_form(Dir, File, Form, Used) ->
{call,
_,
{remote, _, {atom, _, translate}, {atom, _, translate}},
- [_, {string, _, Str}]
+ [_, {string, Line, Str}]
} ->
- process_string(Dir, File, Str, Used);
+ process_string(Dir, File, Line, Str, Used);
{call,
_,
{remote, _, {atom, _, translate}, {atom, _, translate}},
[_, {var, _, Name}]
} ->
case ets:lookup(vars, Name) of
- [{_Name, Value}] ->
- process_string(Dir, File, Value, Used);
+ [{_Name, Value, Line}] ->
+ process_string(Dir, File, Line, Value, Used);
_ ->
ok
end;
{match,
_,
{var, _, Name},
- {string, _, Value}
+ {string, Line, Value}
} ->
- ets:insert(vars, {Name, Value});
+ ets:insert(vars, {Name, Value, Line});
L when is_list(L) ->
lists:foreach(
fun(F) ->
- parse_form(Dir, File, F, Used)
+ parse_form(Dir, File, F, Used)
end, L);
T when is_tuple(T) ->
lists:foreach(
fun(F) ->
- parse_form(Dir, File, F, Used)
+ parse_form(Dir, File, F, Used)
end, tuple_to_list(T));
_ ->
ok
end.
-process_string(_Dir, File, Str, Used) ->
+process_string(_Dir, _File, _Line, "", _Used) ->
+ ok;
+
+process_string(_Dir, File, Line, Str, Used) ->
case {ets:lookup(translations, Str), Used} of
{[{_Key, _Trans}], unused} ->
ets:delete(translations, Str);
{[{_Key, _Trans}], used} ->
ok;
+ {[{_Key, Trans}], srcmsg2po} ->
+ ets:delete(translations_obsolete, Str),
+ print_translation(File, Line, Str, Trans);
{_, used} ->
case ets:lookup(files, File) of
[{_}] ->
@@ -127,6 +142,15 @@ process_string(_Dir, File, Str, Used) ->
_ -> io:format("{~p, \"\"}.~n", [Str])
end,
ets:insert(translations, {Str, ""});
+ {_, srcmsg2po} ->
+ case ets:lookup(files, File) of
+ [{_}] ->
+ ok;
+ _ ->
+ ets:insert(files, {File})
+ end,
+ ets:insert(translations, {Str, ""}),
+ print_translation(File, Line, Str, "");
_ ->
ok
end.
@@ -140,7 +164,8 @@ load_file(File) ->
"" ->
ok;
_ ->
- ets:insert(translations, {Orig, Trans})
+ ets:insert(translations, {Orig, Trans}),
+ ets:insert(translations_obsolete, {Orig, Trans})
end
end, Terms);
Err ->
@@ -191,3 +216,77 @@ print_usage() ->
" extract_translations . ./msgs/ru.msg~n"
).
+
+%%%
+%%% Gettext
+%%%
+
+print_po_header(File) ->
+ MsgProps = get_msg_header_props(File),
+ {Language, [LastT | AddT]} = prepare_props(MsgProps),
+ application:load(ejabberd),
+ {ok, Version} = application:get_key(ejabberd, vsn),
+ print_po_header(Version, Language, LastT, AddT).
+
+get_msg_header_props(File) ->
+ {ok, F} = file:open(File, [read]),
+ Lines = get_msg_header_props(F, []),
+ file:close(F),
+ Lines.
+
+get_msg_header_props(F, Lines) ->
+ String = io:get_line(F, ""),
+ case io_lib:fread("% ", String) of
+ {ok, [], RemString} ->
+ case io_lib:fread("~s", RemString) of
+ {ok, [Key], Value} when Value /= "\n" ->
+ %% The first character in Value is a blankspace:
+ %% And the last characters are 'slash n'
+ ValueClean = string:substr(Value, 2, string:len(Value)-2),
+ get_msg_header_props(F, Lines ++ [{Key, ValueClean}]);
+ _ ->
+ get_msg_header_props(F, Lines)
+ end;
+ _ ->
+ Lines
+ end.
+
+prepare_props(MsgProps) ->
+ Language = proplists:get_value("Language:", MsgProps),
+ Authors = proplists:get_all_values("Author:", MsgProps),
+ {Language, Authors}.
+
+print_po_header(Version, Language, LastTranslator, AdditionalTranslatorsList) ->
+ AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList),
+ HeaderString =
+ "msgid \"\"\n"
+ "msgstr \"\"\n"
+ "\"Project-Id-Version: " ++ Version ++ "\\n\"\n"
+ ++ "\"X-Language: " ++ Language ++ "\\n\"\n"
+ "\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n"
+ ++ AdditionalTranslatorsString ++
+ "\"MIME-Version: 1.0\\n\"\n"
+ "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
+ "\"Content-Transfer-Encoding: 8bit\\n\"\n",
+ io:format("~s~n", [HeaderString]).
+
+build_additional_translators(List) ->
+ lists:foldl(
+ fun(T, Str) ->
+ Str ++ "\"X-Additional-Translator: " ++ T ++ "\\n\"\n"
+ end,
+ "",
+ List).
+
+print_translation(File, Line, Str, StrT) ->
+ {ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
+ {ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
+ io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
+
+print_translation_obsolete(Str, StrT) ->
+ File = "unknown.erl",
+ Line = 1,
+ {ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
+ {ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
+ io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
+