diff options
author | Bruno Haible <bruno@clisp.org> | 2003-09-17 08:28:30 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:10:59 +0200 |
commit | c5bed3571961d5e7e42ca5d6b2e3f6b9136a8c20 (patch) | |
tree | dec072faa0b1413e4b767ab6fccc67299dc87892 /gettext-tools | |
parent | 2551fcdc2cfb12e622193a80c8ae9dd4333977e6 (diff) | |
download | external_gettext-c5bed3571961d5e7e42ca5d6b2e3f6b9136a8c20.zip external_gettext-c5bed3571961d5e7e42ca5d6b2e3f6b9136a8c20.tar.gz external_gettext-c5bed3571961d5e7e42ca5d6b2e3f6b9136a8c20.tar.bz2 |
Document how to internationalize shell scripts.
Diffstat (limited to 'gettext-tools')
-rw-r--r-- | gettext-tools/doc/ChangeLog | 13 | ||||
-rw-r--r-- | gettext-tools/doc/Makefile.am | 17 | ||||
-rw-r--r-- | gettext-tools/doc/gettext.texi | 262 |
3 files changed, 236 insertions, 56 deletions
diff --git a/gettext-tools/doc/ChangeLog b/gettext-tools/doc/ChangeLog index 7d41963..5058d68 100644 --- a/gettext-tools/doc/ChangeLog +++ b/gettext-tools/doc/ChangeLog @@ -1,5 +1,18 @@ 2003-09-13 Bruno Haible <bruno@clisp.org> + * gettext.texi: Update menus. + (sh): Update. + (Preparing Shell Scripts, gettext.sh, gettext Invocation, + ngettext Invocation, envsubst Invocation, eval_gettext Invocation, + eval_ngettext Invocation): New subsubsections. + * Makefile.am (TEXINCLUDES): New variable. + (gettext_TEXINFOS): Add the files from gettext-runtime/doc/. + (MAKEINFOFLAGS, TEXI2DVI): New variables, needed for TEXINCLUDES. + (TEXI2PDF): Add TEXINCLUDES. + (gettext.html, gettext_toc.html): Use TEXINCLUDES. + +2003-09-13 Bruno Haible <bruno@clisp.org> + * gettext.texi (sh-format): New subsection. 2003-09-09 Guido Flohr <guido@imperia.net> diff --git a/gettext-tools/doc/Makefile.am b/gettext-tools/doc/Makefile.am index 9147b90..cb55ffd 100644 --- a/gettext-tools/doc/Makefile.am +++ b/gettext-tools/doc/Makefile.am @@ -26,11 +26,13 @@ htmldir = $(docdir) AUTOMAKE_OPTIONS = 1.2 gnits EXTRA_DIST = MOSTLYCLEANFILES = +TEXINCLUDES = -I $(top_srcdir)/../gettext-runtime/doc SED = sed RM = rm -f MAKEINFO = env LANG= LANGUAGE= @MAKEINFO@ +MAKEINFOFLAGS = $(TEXINCLUDES) info_TEXINFOS = gettext.texi # List of texinfo sources @included by gettext.texi, excluding version.texi. @@ -38,7 +40,10 @@ gettext_TEXINFOS = \ xgettext.texi msginit.texi msgmerge.texi msgcat.texi msgconv.texi \ msggrep.texi msgfilter.texi msguniq.texi msgcomm.texi msgcmp.texi \ msgattrib.texi msgen.texi msgexec.texi msgfmt.texi msgunfmt.texi \ - gettextize.texi autopoint.texi iso-639.texi iso-3166.texi + gettextize.texi autopoint.texi iso-639.texi iso-3166.texi \ + $(top_srcdir)/../gettext-runtime/doc/rt-gettext.texi \ + $(top_srcdir)/../gettext-runtime/doc/rt-ngettext.texi \ + $(top_srcdir)/../gettext-runtime/doc/rt-envsubst.texi EXTRA_DIST += \ iso-639.sed iso-3166.sed ISO_639 ISO_3166 ISO_3166_de texi2html \ @@ -95,6 +100,8 @@ MAINTAINERCLEANFILES = gettext_*.html # Documentation in DVI format. +TEXI2DVI = texi2dvi $(TEXINCLUDES) + install-dvi: gettext.dvi $(mkinstalldirs) $(DESTDIR)$(dvidir) $(INSTALL_DATA) `if test -f gettext.dvi; then echo .; else echo $(srcdir); fi`/gettext.dvi $(DESTDIR)$(dvidir)/gettext.dvi @@ -141,7 +148,7 @@ uninstall-ps: # Documentation in Portable Document Format. -TEXI2PDF = @TEXI2PDF@ +TEXI2PDF = @TEXI2PDF@ $(TEXINCLUDES) SUFFIXES = .pdf pdf: gettext.pdf @@ -169,14 +176,14 @@ html-monolithic: gettext.html html-split: gettext_toc.html gettext.html: gettext.texi version.texi $(gettext_TEXINFOS) - $(TEXI2HTML) -expandinfo -number -monolithic `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` + $(TEXI2HTML) $(TEXINCLUDES) -expandinfo -number -monolithic `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` gettext_toc.html: gettext.texi version.texi $(gettext_TEXINFOS) case "@PERL@" in \ *"/missing perl") \ - $(TEXI2HTML) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` || exit 0 ;; \ + $(TEXI2HTML) $(TEXINCLUDES) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` || exit 0 ;; \ *) $(RM) gettext_*.html ; \ - $(TEXI2HTML) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` ;; \ + $(TEXI2HTML) $(TEXINCLUDES) -expandinfo -number -split_chapter `if test -f gettext.texi; then echo gettext.texi; else echo $(srcdir)/gettext.texi; fi` ;; \ esac install-html-monolithic: gettext.html diff --git a/gettext-tools/doc/gettext.texi b/gettext-tools/doc/gettext.texi index 164560d..207da11 100644 --- a/gettext-tools/doc/gettext.texi +++ b/gettext-tools/doc/gettext.texi @@ -364,6 +364,28 @@ Individual Programming Languages * Pike:: Pike * GCC-source:: GNU Compiler Collection sources +sh - Shell Script + +* Preparing Shell Scripts:: Preparing Shell Scripts for Internationalization +* gettext.sh:: Contents of @code{gettext.sh} +* gettext Invocation:: Invoking the @code{gettext} program +* ngettext Invocation:: Invoking the @code{ngettext} program +* envsubst Invocation:: Invoking the @code{envsubst} program +* eval_gettext Invocation:: Invoking the @code{eval_gettext} function +* eval_ngettext Invocation:: Invoking the @code{eval_ngettext} function + +Perl + +* General Problems:: General Problems Parsing Perl Code +* Default Keywords:: Which Keywords Will xgettext Look For? +* Special Keywords:: How to Extract Hash Keys +* Quote-like Expressions:: What are Strings And Quote-like Expressions? +* Interpolation I:: Invalid String Interpolation +* Interpolation II:: Valid String Interpolation +* Parentheses:: When To Use Parentheses +* Long Lines:: How To Grok with Long Lines +* Perl Pitfalls:: Bugs, Pitfalls, and Things That Do Not Work + Internationalizable Data * POT:: POT - Portable Object Template @@ -7438,7 +7460,7 @@ that language, and to combine the resulting files using @code{msgcat}. @c Java 1200 * @c PHP 1051 * @c Python 613 * -@c Unix Shell 357 +@c Unix Shell 357 * @c Tcl 266 * @c SQL 174 @c JavaScript 118 @@ -7574,12 +7596,13 @@ bash, gettext @code{"abc"}, @code{'abc'}, @code{abc} @item gettext shorthand -@code{"`gettext "abc"`"} +@code{"`gettext \"abc\"`"} @item gettext/ngettext functions @pindex gettext @pindex ngettext @code{gettext}, @code{ngettext} programs +@*@code{eval_gettext}, @code{eval_ngettext} shell functions @item textdomain @vindex TEXTDOMAIN@r{, environment variable} @@ -7593,75 +7616,212 @@ environment variable @code{TEXTDOMAINDIR} automatic @item Prerequisite ---- +@code{. gettext.sh} @item Use or emulate GNU gettext use @item Extractor ---- +@code{xgettext} @item Formatting with positions --- @item Portability ---- +fully portable @item po-mode marking --- @end table -@node bash, Python, sh, List of Programming Languages -@subsection bash - Bourne-Again Shell Script -@cindex bash +@menu +* Preparing Shell Scripts:: Preparing Shell Scripts for Internationalization +* gettext.sh:: Contents of @code{gettext.sh} +* gettext Invocation:: Invoking the @code{gettext} program +* ngettext Invocation:: Invoking the @code{ngettext} program +* envsubst Invocation:: Invoking the @code{envsubst} program +* eval_gettext Invocation:: Invoking the @code{eval_gettext} function +* eval_ngettext Invocation:: Invoking the @code{eval_ngettext} function +@end menu -@table @asis -@item RPMs -bash 2.0 or newer, gettext +@node Preparing Shell Scripts, gettext.sh, sh, sh +@subsubsection Preparing Shell Scripts for Internationalization +@cindex preparing shell scripts for translation -@item File extension -@code{sh} +Preparing a shell script for internationalization is conceptually similar +to the steps described in @ref{Sources}. The concrete steps for shell +scripts are as follows. -@item String syntax -@code{"abc"}, @code{'abc'}, @code{abc} +@enumerate +@item +Insert the line -@item gettext shorthand -@code{$"abc"} +@smallexample +. gettext.sh +@end smallexample -@item gettext/ngettext functions -@pindex gettext -@pindex ngettext -@code{gettext}, @code{ngettext} programs +near the top of the script. @code{gettext.sh} is a shell function library +that provides the functions +@code{eval_gettext} (see @ref{eval_gettext Invocation}) and +@code{eval_ngettext} (see @ref{eval_ngettext Invocation}). +You have to ensure that @code{gettext.sh} can be found in the @code{PATH}. -@item textdomain -@vindex TEXTDOMAIN@r{, environment variable} -environment variable @code{TEXTDOMAIN} +@item +Set and export the @code{TEXTDOMAIN} and @code{TEXTDOMAINDIR} environment +variables. Usually @code{TEXTDOMAIN} is the package or program name, and +@code{TEXTDOMAINDIR} is the absolute pathname corresponding to +@code{$prefix/share/locale}, where @code{$prefix} is the installation location. -@item bindtextdomain -@vindex TEXTDOMAINDIR@r{, environment variable} -environment variable @code{TEXTDOMAINDIR} +@smallexample +TEXTDOMAIN=@@PACKAGE@@ +export TEXTDOMAIN +TEXTDOMAINDIR=@@LOCALEDIR@@ +export TEXTDOMAINDIR +@end smallexample -@item setlocale -automatic +@item +Prepare the strings for translation, as described in @ref{Preparing Strings}. -@item Prerequisite ---- +@item +Simplify translatable strings so that they don't contain command substitution +(@code{"`...`"} or @code{"$(...)"}), variable access with defaulting (like +@code{$@{@var{variable}-@var{default}@}}), access to positional arguments +(like @code{$0}, @code{$1}, ...) or highly volatile shell variables (like +@code{$?}). This can always be done through simple local code restructuring. +For example, -@item Use or emulate GNU gettext -use +@smallexample +echo "Usage: $0 [OPTION] FILE..." +@end smallexample -@item Extractor -@code{bash --dump-po-strings} +becomes -@item Formatting with positions ---- +@smallexample +program_name=$0 +echo "Usage: $program_name [OPTION] FILE..." +@end smallexample -@item Portability ---- +Similarly, -@item po-mode marking ---- -@end table +@smallexample +echo "Remaining files: `ls | wc -l`" +@end smallexample + +becomes + +@smallexample +filecount="`ls | wc -l`" +echo "Remaining files: $filecount" +@end smallexample + +@item +For each translatable string, change the output command @samp{echo} or +@samp{$echo} to @samp{gettext} (if the string contains no references to +shell variables) or to @samp{eval_gettext} (if it refers to shell variables), +followed by a no-argument @samp{echo} command (to account for the terminating +newline). Similarly, for cases with plural handling, replace a conditional +@samp{echo} command with an invocation of @samp{ngettext} or +@samp{eval_ngettext}, followed by a no-argument @samp{echo} command. +@end enumerate + +@node gettext.sh, gettext Invocation, Preparing Shell Scripts, sh +@subsubsection Contents of @code{gettext.sh} + +@code{gettext.sh}, contained in the run-time package of GNU gettext, provides +the following: + +@itemize @bullet +@item $echo +The variable @code{echo} is set to a command that outputs its first argument +and a newline, without interpreting backslashes in the argument string. + +@item eval_gettext +See @ref{eval_gettext Invocation}. + +@item eval_ngettext +See @ref{eval_ngettext Invocation}. +@end itemize + +@node gettext Invocation, ngettext Invocation, gettext.sh, sh +@subsubsection Invoking the @code{gettext} program + +@include rt-gettext.texi + +@node ngettext Invocation, envsubst Invocation, gettext Invocation, sh +@subsubsection Invoking the @code{ngettext} program + +@include rt-ngettext.texi + +@node envsubst Invocation, eval_gettext Invocation, ngettext Invocation, sh +@subsubsection Invoking the @code{envsubst} program + +@include rt-envsubst.texi + +@node eval_gettext Invocation, eval_ngettext Invocation, envsubst Invocation, sh +@subsubsection Invoking the @code{eval_gettext} function + +@cindex @code{eval_gettext} function, usage +@example +eval_gettext @var{msgid} +@end example + +@cindex lookup message translation +This function outputs the native language translation of a textual message, +performing dollar-substitution on the result. Note that only shell variables +mentioned in @var{msgid} will be dollar-substituted in the result. + +@node eval_ngettext Invocation, , eval_gettext Invocation, sh +@subsubsection Invoking the @code{eval_ngettext} function + +@cindex @code{eval_ngettext} function, usage +@example +eval_ngettext @var{msgid} @var{msgid-plural} @var{count} +@end example + +@cindex lookup plural message translation +This function outputs the native language translation of a textual message +whose grammatical form depends on a number, performing dollar-substitution +on the result. Note that only shell variables mentioned in @var{msgid} or +@var{msgid-plural} will be dollar-substituted in the result. + +@node bash, Python, sh, List of Programming Languages +@subsection bash - Bourne-Again Shell Script +@cindex bash + +GNU @code{bash} 2.0 or newer has a special shorthand for translating a +string and substituting variable values in it: @code{$"msgid"}. But +the use of this construct is @strong{discouraged}, due to the security +holes it opens and due to its portability problems. + +The security holes of @code{$"..."} come from the fact that after looking up +the translation of the string, @code{bash} processes it like it processes +any double-quoted string: dollar and backquote processing, like @samp{eval} +does. + +@enumerate +@item +In a locale whose encoding is one of BIG5, BIG5-HKSCS, GBK, GB18030, SHIFT_JIS, +JOHAB, some double-byte characters have a second byte whose value is +@code{0x60}. For example, the byte sequence @code{\xe0\x60} is a single +character in these locales. Many versions of @code{bash} (all versions +up to bash-2.05, and newer versions on platforms without @code{mbsrtowcs()} +function) don't know about character boundaries and see a backquote character +where there is only a particular Chinese character. Thus it can start +executing part of the translation as a command list. This situation can occur +even without the translator being aware of it: if the translator provides +translations in the UTF-8 encoding, it is the @code{gettext()} function which +will, during its conversion from the translator's encoding to the user's +locale's encoding, produce the dangerous @code{\x60} bytes. + +@item +A translator could - voluntarily or inadvertantly - use backquotes +@code{"`...`"} or dollar-parentheses @code{"$(...)"} in her translations. +The enclosed strings would be executed as command lists by the shell. +@end enumerate + +The portability problem is that @code{bash} must be built with +internationalization support; this is normally not the case on systems +that don't have the @code{gettext()} function in libc. @node Python, Common Lisp, bash, List of Programming Languages @subsection Python @@ -8443,15 +8603,15 @@ the other backends but it also has some Perl specific limitations, the worst probably being its imperfectness. @menu -* General Problems:: General Problems Parsing Perl Code -* Default Keywords:: Which Keywords Will xgettext Look For? -* Special Keywords:: How to Extract Hash Keys -* Quote-like Expressions:: What are Strings And Quote-like Expressions? -* Interpolation I:: Invalid String Interpolation -* Interpolation II:: Valid String Interpolation -* Parentheses:: When To Use Parentheses -* Long Lines:: How To Grok with Long Lines -* Perl Pitfalls:: Bugs, Pitfalls, and Things That Do Not Work +* General Problems:: General Problems Parsing Perl Code +* Default Keywords:: Which Keywords Will xgettext Look For? +* Special Keywords:: How to Extract Hash Keys +* Quote-like Expressions:: What are Strings And Quote-like Expressions? +* Interpolation I:: Invalid String Interpolation +* Interpolation II:: Valid String Interpolation +* Parentheses:: When To Use Parentheses +* Long Lines:: How To Grok with Long Lines +* Perl Pitfalls:: Bugs, Pitfalls, and Things That Do Not Work @end menu @node General Problems, Default Keywords, , Perl |