improve detection of msgs to be translated

This change does several things. First, it works around a quirk of the
`xgetttext` command that only recognizes description strings in even
numbered position on the command. Second, it allows descriptions
introduced by the `-d` short flag to be recognized.

More importantly, it normalizes the strings so that `xgettext` correctly
extracts them into the *.po file. Prior to this change many fish script
strings were ignored due to how they were written (e.g., single versus
double quotes).

Fixes #4073
This commit is contained in:
Kurtis Rader 2017-05-27 22:13:18 -07:00
parent 5e39efa45b
commit 3e29793d04
2 changed files with 51 additions and 6 deletions

View file

@ -516,13 +516,12 @@ doc.h: $(HDR_FILES)
-e "s,@prefix\@,$(prefix),g" \
-e "s,@fish_build_version\@,$(FISH_BUILD_VERSION),g" \
#
# Compile translation files to binary format
# Compile translation files to binary format.
#
%.gmo:
@echo " msgfmt $(em)$@$(sgr0)"
$v msgfmt -o $@ $*.po
$v msgfmt --use-fuzzy -o $@ $*.po
#
# Update existing po file or copy messages.pot
@ -538,10 +537,14 @@ doc.h: $(HDR_FILES)
#
# Create a template translation object
#
messages.pot: $(wildcard src/*.cpp src/*.h share/completions/*.fish share/functions/*.fish)
messages.pot: fish $(wildcard src/*.cpp src/*.h share/completions/*.fish share/functions/*.fish)
@echo " xgettext $(em)$@$(sgr0)"
xgettext -k_ -kN_ $(wildcard src/*.cpp src/*.h) -o messages.pot
$v xgettext -j -k_ -kN_ -k--description -LShell --from-code=UTF-8 $(wildcard share/completions/*.fish share/functions/*.fish) share/config.fish -o messages.pot
$v xgettext -k -k_ -kN_ -LC++ --no-wrap -o messages.pot src/*.cpp src/*.h
$v rm -rf /tmp/fish
$v ./fish build_tools/fish_xgettext.fish
$v xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot /tmp/fish/explicit/share/*.fish /tmp/fish/explicit/share/*/*.fish
$v xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot /tmp/fish/implicit/share/*.fish /tmp/fish/implicit/share/*/*.fish
$v rm -rf /tmp/fish
ifdef EXTRA_PCRE2
src/builtin_string.cpp: $(PCRE2_H)

42
build_tools/fish_xgettext.fish Executable file
View file

@ -0,0 +1,42 @@
#!/usr/bin/env fish
#
# This script was originally motivated to work around a quirk (or bug depending on your viewpoint)
# of the xgettext command. See https://lists.gnu.org/archive/html/bug-gettext/2014-11/msg00006.html.
# However, it turns out that even if that quirk did not exist we would still need something like
# this script to properly extract descriptions. That's because we need to normalize the strings to
# a format that xgettext will handle correctly. Also, `xgettext -LShell` doesn't correctly extract
# all the strings we want translated. So we extract and normalize all such strings into a format
# that `xgettext` can handle.
# This regex handles descriptions for `complete` and `function` statements. These messages are not
# particularly important to translate. Hence the "implicit" label.
set implicit_regex '(?:^| +)(?:complete|function) .*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
# This regex handles explicit requests to translate a message. These are more important to translate
# than messages which should be implicitly translated.
set explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
mkdir -p /tmp/fish/implicit/share/completions /tmp/fish/implicit/share/functions
mkdir -p /tmp/fish/explicit/share/completions /tmp/fish/explicit/share/functions
for f in share/config.fish share/completions/*.fish share/functions/*.fish
# Extract explicit attempts to translate a message. That is, those that are of the form
# `(_ "message")`.
string replace --filter --regex $explicit_regex 'echo $1' <$f | fish >/tmp/fish/explicit/$f.tmp ^/dev/null
while read description
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
end </tmp/fish/explicit/$f.tmp >/tmp/fish/explicit/$f
rm /tmp/fish/explicit/$f.tmp
# Handle `complete` / `function` description messages. The `| fish` is subtle. It basically
# avoids the need to use `source` with a command substituion that could affect the current
# shell.
string replace --filter --regex $implicit_regex 'echo $1' <$f | fish >/tmp/fish/implicit/$f.tmp ^/dev/null
while read description
# We don't use `string escape` as shown in the next comment because it produces output that
# is not parsed correctly by xgettext. Instead just escape double-quotes and quote the
# resulting string.
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
end </tmp/fish/implicit/$f.tmp >/tmp/fish/implicit/$f
rm /tmp/fish/implicit/$f.tmp
end