diff options
author | Badlop <badlop@process-one.net> | 2008-08-17 16:35:58 +0000 |
---|---|---|
committer | Badlop <badlop@process-one.net> | 2008-08-17 16:35:58 +0000 |
commit | 61a639d5d99416cdb5743413230fb9ddc36ecf91 (patch) | |
tree | 48c8678173ee05be1dbbb7bee0668b6e41d4aa90 /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.erl | 121 |
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]). + |