summaryrefslogtreecommitdiffstats
path: root/gettext-tools
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2003-09-17 08:28:30 +0000
committerBruno Haible <bruno@clisp.org>2009-06-23 12:10:59 +0200
commitc5bed3571961d5e7e42ca5d6b2e3f6b9136a8c20 (patch)
treedec072faa0b1413e4b767ab6fccc67299dc87892 /gettext-tools
parent2551fcdc2cfb12e622193a80c8ae9dd4333977e6 (diff)
downloadexternal_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/ChangeLog13
-rw-r--r--gettext-tools/doc/Makefile.am17
-rw-r--r--gettext-tools/doc/gettext.texi262
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