diff --git a/build_tools/fish_xgettext.fish b/build_tools/fish_xgettext.fish index 2e50bbc72..25d5663c5 100755 --- a/build_tools/fish_xgettext.fish +++ b/build_tools/fish_xgettext.fish @@ -19,7 +19,7 @@ begin echo "" end - set -g workspace_root (status dirname)/.. + set -g workspace_root (path resolve (status dirname)/..) set -l rust_extraction_file if set -l --query _flag_use_existing_template @@ -31,6 +31,7 @@ begin or exit 1 end + echo '# fish-section-tier1-from-rust' # Get rid of duplicates and sort. msguniq --no-wrap --strict --sort-output $rust_extraction_file or exit 1 @@ -39,8 +40,9 @@ begin rm $rust_extraction_file end - function extract_fish_script_messages --argument-names regex - + function extract_fish_script_messages_impl + set -l regex $argv[1] + set -e argv[1] # Using xgettext causes more trouble than it helps. # This is due to handling of escaping in fish differing from formats xgettext understands # (e.g. POSIX shell strings). @@ -59,24 +61,74 @@ begin # 5. Double quotes are escaped, such that they are not interpreted as the start or end of # a msgid. # 6. We transform the string into the format expected in a PO file. - cat $share_dir/config.fish $share_dir/completions/*.fish $share_dir/functions/*.fish | + cat $argv | string replace --filter --regex $regex '$1' | string unescape | sort -u | sed -E -e 's_\\\\_\\\\\\\\_g' -e 's_"_\\\\"_g' -e 's_^(.*)$_msgid "\1"\nmsgstr ""\n_' end + function extract_fish_script_messages + set -l tier $argv[1] + set -e argv[1] + if not set -q argv[1] + return + end + # This regex handles explicit requests to translate a message. These are more important to translate + # than messages which should be implicitly translated. + set -l explicit_regex '.*\( *_ (([\'"]).+?(?&2 "$file:1 unexpected localization tier: $tier" + exit 1 + end + continue + end + set -l dirname (path basename (path dirname $file)) + set -l command_name (path basename --no-extension $file) + if test $dirname = functions && + string match -q -- 'fish_*' $command_name + set -a tier1 $file + continue + end + if test $dirname != completions + echo >&2 "$file:1 missing localization tier for function file" + exit 1 + end + if test -e $workspace_root/doc_src/cmds/$command_name.rst + set -a tier1 $file + else + set -a tier3 $file + end + end + + extract_fish_script_messages tier1 $tier1 + extract_fish_script_messages tier2 $tier2 + extract_fish_script_messages tier3 $tier3 end | # At this point, all extracted strings have been written to stdout, # starting with the ones taken from the Rust sources, diff --git a/build_tools/update_translations.fish b/build_tools/update_translations.fish index 4fd5ce187..5314673f2 100755 --- a/build_tools/update_translations.fish +++ b/build_tools/update_translations.fish @@ -99,15 +99,55 @@ if set -l --query _flag_dry_run cp -r $po_dir/* $tmpdir end +function merge_po_files --argument-names template_file po_file + msgmerge --no-wrap --update --no-fuzzy-matching --backup=none --quiet \ + $po_file $template_file + or cleanup_exit + set -l new_po_file (mktemp) # TODO Remove on failure. + and msgattrib --no-wrap --no-obsolete -o $new_po_file $po_file + or cleanup_exit + + begin + echo "# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment." + echo "# fish-note-sections: The first few sections are more important." + echo "# fish-note-sections: Ignore the tier3 sections unless you have a lot of time." + sed -i ' + /^# fish-note-sections:/d; + /^# fish-section-/d; + ' $new_po_file + + set -l next_line 1 + set -l section + awk <$template_file ' + /^# fish-section-\S*$/ { + section = $0 + } + section != "" && /^msgid ".+"$/ { + print section + print $0 + section = "" + } + ' | + while read -l section + read -l msgid_line + set -l line_number (grep -m1 -Fxn $msgid_line $new_po_file | string split :)[1] + sed -n "$next_line,$(math $line_number - 1)"p $new_po_file + echo $section + set next_line $line_number + # set section + end + sed -n "$next_line,\$"p $new_po_file + end >$po_file + rm $new_po_file +end + for po_file in $po_files if set --query tmpdir[1] set po_file $tmpdir/(basename $po_file) end if set -l --query po if test -e $po_file - msgmerge --no-wrap --update --no-fuzzy-matching --backup=none --quiet $po_file $template_file - and msgattrib --no-wrap --no-obsolete -o $po_file $po_file - or cleanup_exit + merge_po_files $template_file $po_file else cp $template_file $po_file end