CMUCL commit: src/docs/cmu-user (cmu-user.tex extensions.tex)
Raymond Toy
rtoy at common-lisp.net
Sat Apr 3 04:21:00 CEST 2010
Date: Friday, April 2, 2010 @ 22:21:00
Author: rtoy
Path: /project/cmucl/cvsroot/src/docs/cmu-user
Modified: cmu-user.tex extensions.tex
extensions.tex:
o Add some documentation for localization support
o Fix a few places where words were run together in the pdf output.
cmu-user.tex:
o Update date and version.
----------------+
cmu-user.tex | 2
extensions.tex | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 194 insertions(+), 4 deletions(-)
Index: src/docs/cmu-user/cmu-user.tex
diff -u src/docs/cmu-user/cmu-user.tex:1.41 src/docs/cmu-user/cmu-user.tex:1.42
--- src/docs/cmu-user/cmu-user.tex:1.41 Wed Sep 9 11:51:27 2009
+++ src/docs/cmu-user/cmu-user.tex Fri Apr 2 22:20:59 2010
@@ -47,7 +47,7 @@
\newcommand{\keywords}{lisp, Common Lisp, manual, compiler, programming
language implementation, programming environment}
-\date{Sep 2009 \\ Release 20a}
+\date{Apr 2009 \\ Snapshot 2010-04}
\begin{document}
Index: src/docs/cmu-user/extensions.tex
diff -u src/docs/cmu-user/extensions.tex:1.42 src/docs/cmu-user/extensions.tex:1.43
--- src/docs/cmu-user/extensions.tex:1.42 Wed Dec 30 11:39:46 2009
+++ src/docs/cmu-user/extensions.tex Fri Apr 2 22:20:59 2010
@@ -2470,7 +2470,7 @@
\code{(setf fdefinition)} will set the primary function in the
innermost fwrapper.
-\begin{defmac}{fwrappers:}{define-fwrapper}{name lambda-list \ampbody body}
+\begin{defmac}{fwrappers:}{define-fwrapper}{name lambda-list \ampbody{} body}
This macro is like \code{defun}, but defines a function named
\var{name} that can be used as an fwrapper definition.
@@ -2552,8 +2552,8 @@
undefined function.
\end{defun}
-\begin{defmac}{fwrappers:}{do-fwrappers}{(var fdefn \ampoptional
- result) \ampbody body}
+\begin{defmac}{fwrappers:}{do-fwrappers}{(var fdefn \ampoptional{}
+ result) \ampbody{} body}
Evaluate \var{body} with \var{var} bound to consecutive fwrappers of
\var{fdefn}. Return \var{result} at the end. Note that \var{fdefn}
must be an \code{fdefn} object. You can use
@@ -2763,3 +2763,193 @@
:case :common to :case :local. This merged name will be probed with
both a .lisp and .fasl extensions, calling \code{LOAD} if it exists.
\end{defun}
+
+
+\section{Localization}
+\label{sec:localization}
+
+\cmucl{} support localization where messages can be presented in the
+native language. This is done in the style of \code{gettext} which
+marks strings that are to be translated and provides the lookup to
+convert the string to the specified language.
+
+All messages from \cmucl{} can be translated but as of this writing,
+the only complete translation is a Pig Latin translation done by
+machine. There are a few messages translated to Korean.
+
+\subsection{Dictionary}
+\label{sec:localization-dictionary}
+
+
+\begin{defun}{intl:}{setlocale}{\ampoptional{} locale}
+ Sets the locale to the locale specified by \var{locale}. If
+ \var{locale} is not give or is \nil, the locale is determined by
+ look at the environment variables \code{LANGUAGE}, \code{LC\_ALL},
+ \code{LC\_MESSAGES}, or \code{LANG}. If none of these are set, the
+ locale is unchanged.
+
+ The default locale is ``C''.
+\end{defun}
+
+\begin{defun}{intl:}{textdomain}{domain}
+ Set the default domain to the domain specified by \var{domain}.
+ Typically, this only needs to be done at the top of each source
+ file. This is used to \code{gettext} and \code{ngettext} to set the
+ domain for the message string.
+\end{defun}
+
+\begin{defmac}{intl:}{gettext}{string}
+ Look up the specified string, \var{string}, in the current message
+ domain and return its translation.
+\end{defmac}
+
+\begin{defun}{intl:}{dgettext}{domain string}
+ Look up the specified string, \var{string}, in the message domain,
+ \var{domain}. The translation is returned.
+
+ When compiled, this also function also records the string so that an
+ appropriate message template file can be created. (See
+ \code{intl::dump-pot-files}.)
+\end{defun}
+
+\begin{defmac}{intl:}{ngettext}{singular plural n}
+ Look up the singular or plural form of a message in the default
+ domain. The singular form is \var{singular}; the plural is
+ \var{plural}. The number of items is specified by \var{n} in case
+ the correct translation depends on the actual number of items.
+\end{defmac}
+
+\begin{defun}{intl:}{dngettext}{domain singular plural n}
+ Look up the singular or plural form of a message in the specified
+ domain, \var{domain}. The singular form is \var{singular}; the
+ plural is \var{plural}. The number of items is specified by \var{n}
+ in case the correct translation depends on the actual number of
+ items.
+
+ When compiled, this also function also records the singular and
+ plural forms so that an appropriate message template file can be
+ created. (See \code{intl::dump-pot-files}.)
+\end{defun}
+
+\begin{defun}{intl::}{dump-pot-files}{\keys copyright
+ output-directory}
+ Dumps the translatable strings recorded by \code{dgettext} and
+ \code{dngettext}. The message template file (pot file) is written
+ to a file in the directory specified by \var{output-directory}, and
+ the name of the file is the domain of the string.
+
+ If \var{copyright} is specified, this is placed in the output file
+ as the copyright message.
+\end{defun}
+
+\begin{defvar}{intl:}{locale-directories}
+ This is a list of directory pathnames where the translations can be found.
+\end{defvar}
+
+Two reader macros are also provided: \code{\_''} and \code{\_N''}. The
+first is equivalent to wrapping \code{dgettext} around the string.
+The second returns the string, but also records the string. This is
+needed when we want to record a docstring for translation or any other
+string in a place where a macro or function call would be incorrect.
+
+Also, the standard comment reader is extended to allow translator
+comments to be saved and written to the messages template file so that
+the translator may not need to look at the original source to
+understand the string. Any comment line that begins with exactly
+\verb|"TRANSLATORS: "| is saved. This means each translator comment
+must be preceded by this string to be saved; the translator comment
+ends at the end of each line.
+
+
+\subsection{Example Usage}
+\label{sec:localization-usage}
+
+Here is a simple example of how to localize your code.
+
+\begin{example}
+
+(intl:textdomain "example")
+
+(defun foo (x y)
+ _N"Cool function foo of x and y"
+ (let ((result (bar x y)))
+ (format t _"bar of ~A and ~A = ~A~%" x y result)
+ ;; TRANSLATORS: Do the right thing here.
+ ;; TRANSLATORS: Whatever that might be.
+ (format t (intl:ngettext "There is one X"
+ "There are many Xs"
+ x))
+ result))
+\end{example}
+
+The call to \code{textdomain} sets the default domain for all
+translatable strings following the call.
+
+When this file is compiled, all of the translatable strings are
+recorded. This includes the docstring for \code{foo}, the string for
+the first \code{format}, and the string marked by the call to
+\code{intl:ngettext}.
+
+After all of the files have been compiled, we can dump the recorded
+strings. In this case,
+\begin{example}
+* (intl::dump-pot-files :output-directory "dir/")
+Dumping 3 messages for domain "example"
+NIL
+\end{example}
+will create a file named ``example.pot'' in the directory ``dir/''.
+The contents of this file are:
+\begin{example}
+#@ example
+
+# SOME DESCRIPTIVE TITLE
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION"
+"Report-Msgid-Bugs-To: "
+"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>"
+"Language-Team: LANGUAGE <LL at li.org>"
+"MIME-Version: 1.0"
+"Content-Type: text/plain; charset=UTF-8"
+"Content-Transfer-Encoding: 8bit"
+
+#: /tmp/foo.lisp
+msgid "Cool function foo of x and y"
+msgstr ""
+
+#. Whatever that might be.
+#: /tmp/foo.lisp
+msgid "bar of ~A and ~A = ~A~%"
+msgstr ""
+
+#: /tmp/foo.lisp
+msgid "There is one X"
+msgid_plural "There are many Xs"
+msgstr[0] ""
+
+\end{example}
+
+To finish the translation, a corresponding ``example.po'' file needs
+to be created with the appropriate translations for the given
+strings. This file must be placed in some directory that is included
+in \code{intl:*locale-directories*}.
+
+Suppose the translation is done for Korean. Then the user can set the
+environment variables appropriately or call \code{(intl:setlocale
+ "ko")}. Note that the external format for the standard streams
+needs to be set up appropriately too. It is up to the user to set
+this correctly. Once this is all done, the output from the function
+\code{foo} will now be in Korean instead of English as in the original
+source file.
+
+For further information, we refer the reader to documentation on
+\ifpdf
+\href{http://www.gnu.org/software/gettext/manual/gettext.html}{gettext}.
+\else
+gettext at
+\href{http://www.gnu.org/software/gettext/manual/gettext.html}{\texttt{http://www.gnu.org/software/gettext/manual/gettext.html}}.
+\fi
More information about the cmucl-commit
mailing list