summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@cygnus.com>2000-06-16 07:49:23 +0000
committerUlrich Drepper <drepper@cygnus.com>2000-06-16 07:49:23 +0000
commit60d2084de5dc3b65e6657f695f0f26df24b0f565 (patch)
tree224f21c30351570d6d7f06a385e829d5ab320f67 /doc
downloadexternal_gettext-60d2084de5dc3b65e6657f695f0f26df24b0f565.zip
external_gettext-60d2084de5dc3b65e6657f695f0f26df24b0f565.tar.gz
external_gettext-60d2084de5dc3b65e6657f695f0f26df24b0f565.tar.bz2
Initial revision
Diffstat (limited to 'doc')
-rw-r--r--doc/Admin/documentation1692
-rw-r--r--doc/Admin/solaris.msgfmt21
-rw-r--r--doc/ChangeLog426
-rw-r--r--doc/ISO_639180
-rw-r--r--doc/Makefile.am32
-rw-r--r--doc/Makefile.in370
-rw-r--r--doc/gettext.info126
-rw-r--r--doc/gettext.info-1999
-rw-r--r--doc/gettext.info-21127
-rw-r--r--doc/gettext.info-31072
-rw-r--r--doc/gettext.info-41110
-rw-r--r--doc/gettext.info-5852
-rw-r--r--doc/gettext.texi4820
-rw-r--r--doc/iso-apdx.sed19
-rw-r--r--doc/iso-apdx.texi278
-rw-r--r--doc/matrix.texi75
-rwxr-xr-xdoc/mdate-sh92
-rw-r--r--doc/nls.texi254
-rw-r--r--doc/texinfo.tex5302
-rw-r--r--doc/version.texi3
20 files changed, 18850 insertions, 0 deletions
diff --git a/doc/Admin/documentation b/doc/Admin/documentation
new file mode 100644
index 0000000..beb1d47
--- /dev/null
+++ b/doc/Admin/documentation
@@ -0,0 +1,1692 @@
+BABYL OPTIONS: -*- rmail -*-
+Version: 5
+Labels:
+Note: This is the header of an rmail file.
+Note: If you are seeing it in rmail,
+Note: it means the file has no messages in it.
+
+1, edited,,
+From: terrell@druhi.ATT.COM (TerrellE)
+Newsgroups: comp.sys.ibm.pc,sci.astro
+Subject: Internationalization of Software?
+Date: 30 Jun 89 19:05:23 GMT
+Reply-To: terrell@druhi.ATT.COM (TerrellE)
+Organization: AT&T, Denver, CO
+
+*** EOOH ***
+From: terrell@druhi.ATT.COM (TerrellE)
+Newsgroups: comp.sys.ibm.pc,sci.astro
+Subject: Internationalization of Software?
+Date: 30 Jun 89 19:05:23 GMT
+Reply-To: terrell@druhi.ATT.COM (TerrellE)
+
+I know that there are some modifications that I will have to perform to
+"internationalize" software products developed for use in the USA.
+These changes include the obvious (translate the program
+and documentation into the right language). However, some of the
+other changes are more subtle. I'm sure that I've overlooked some, but
+here's what I have so far:
+
+Necessary changes to "internationalize" a software product:
+
+1. Flexible date format:
+
+ dd/mm/yy
+ yy/dd/mm
+ yy/mm/dd
+ mm/dd/yy
+
+2. Handle foreign daylight savings time.
+
+3. Flexible radix (decimal) point (i.e. '.' or ','):
+
+ 3.14159
+ 3,14159
+
+4. Allow English or Metric units.
+
+5. Use "one thousand million" rather than "one billion".
+
+6. Flexible time format:
+
+ hh:mm
+ hh.mm
+ hh'mm
+
+7. Allow either ' ' or ',' for thousands delimiters:
+
+ 1,000,000
+ 1 000 000
+
+
+What else is necessary? Overseas users: what changes would you make
+to your "US Version" software to make it approprate for use in other
+countries?
+
+I'll post a summary of the results. Thanks in advance,
+
+
+
+Eric Terrell (att!druhi!terrell)
+
+1,,
+Xref: IRO.UMontreal.CA comp.std.c:13991 comp.software.international:607
+Path: IRO.UMontreal.CA!CC.UMontreal.CA!newsflash.concordia.ca!utcsri!utnut!cs.utexas.edu!howland.reston.ans.net!nctuccca.edu.tw!news.cc.nctu.edu.tw!mall!ywliu
+From: ywliu@beta.wsl.sinica.edu.tw ()
+Newsgroups: comp.std.c,comp.software.international
+Subject: Re: ANSI C Locale Character Sets
+Followup-To: comp.std.c,comp.software.international
+Date: 3 Oct 1994 06:39:25 GMT
+Organization: Computing Center, Academia Sinica
+Lines: 26
+Message-ID: <36o8ut$afu@mall.sinica.edu.tw>
+References: <Cx0Mpy.7Lo@actrix.gen.nz>
+NNTP-Posting-Host: ywliu%@beta.wsl.sinica.edu.tw
+X-Newsreader: TIN [version 1.2 PL0]
+
+*** EOOH ***
+From: ywliu@beta.wsl.sinica.edu.tw ()
+Newsgroups: comp.std.c,comp.software.international
+Subject: Re: ANSI C Locale Character Sets
+Followup-To: comp.std.c,comp.software.international
+Date: 3 Oct 1994 06:39:25 GMT
+Organization: Computing Center, Academia Sinica
+References: <Cx0Mpy.7Lo@actrix.gen.nz>
+NNTP-Posting-Host: ywliu%@beta.wsl.sinica.edu.tw
+X-Newsreader: TIN [version 1.2 PL0]
+
+Gary Houston (ghouston@actrix.gen.nz) wrote:
+: It seems to me there are a couple of details missing from the ANSI C
+: locale stuff:
+
+: 1/ How can a program find out which character set is being used?
+
+
+ You may use setlocale(LC_ALL,NULL) to get the language info.
+
+: 2/ How can a program determine whether text files use multibyte or
+: wide characters, or is it to be assumed that multibyte will
+: always be used?
+
+ As far as I am concerned, the wide character is used as the representation
+inside your program. That is, wide character is your internal data
+representatin form, as I/O operates on multi-byte characters. So, I always
+read/write mutl-bytes and convert to wide character , and vice versa.
+
+: Does anyone know of other standards/conventions/plans which fill
+: in this missing information?
+
+ You may check out P.J. Plauger's "Standard C" column on CUJ May 1993 - July
+1993. There is another one "Internationlization and Localization" in CUJ July
+ 1993 too. I am looking for more material.
+
+Yen-Wei Liu
+
+1, edited, answered,,
+Mail-from: From orac.iinet.com.au!pdcruze Thu Nov 24 17:38:19 1994
+Return-Path: <orac.iinet.com.au!pdcruze>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rAmnw-00009aC; Thu, 24 Nov 94 17:38 EST
+Received: from lagrande.iro.umontreal.ca by iros1.IRO.UMontreal.CA (8.6.9) with ESMTP
+ id LAA06293; Thu, 24 Nov 1994 11:57:58 -0500
+Received: from saguenay.IRO.UMontreal.CA (root@saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id LAA23939 for <pinard@lagrande.IRO.UMontreal.CA>; Thu, 24 Nov 1994 11:57:50 -0500
+Received: from uniwa.uwa.edu.au (root@uniwa.uwa.edu.au [130.95.128.1]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id LAA20957 for <pinard@IRO.UMontreal.CA>; Thu, 24 Nov 1994 11:57:46 -0500
+Received: from orac.iinet.com.au (orac.iinet.com.au [203.0.178.134]) by uniwa.uwa.edu.au (8.6.9/8.6.9) with ESMTP id AAA09394; Fri, 25 Nov 1994 00:57:29 +0800
+Received: from orac.iinet.com.au (pdcruze@localhost [127.0.0.1]) by orac.iinet.com.au (8.6.9/8.6.9) with ESMTP id AAA08605; Fri, 25 Nov 1994 00:57:11 +0800
+Message-Id: <199411241657.AAA08605@orac.iinet.com.au>
+To: pinard@IRO.UMontreal.CA
+cc: meyering@comco.com
+Subject: Re: Starting localization of GNU recode
+In-reply-to: Your message of "Thu, 24 Nov 1994 01:11:00 EST."
+ <m0rAXP2-00008sC@icule>
+Date: Fri, 25 Nov 1994 00:57:10 +0800
+From: "Patrick D'Cruze" <pdcruze@li.org>
+
+*** EOOH ***
+To: pinard@IRO.UMontreal.CA
+cc: meyering@comco.com
+Subject: Re: Starting localization of GNU recode
+In-reply-to: Your message of "Thu, 24 Nov 1994 01:11:00 EST."
+ <m0rAXP2-00008sC@icule>
+Date: Fri, 25 Nov 1994 00:57:10 +0800
+From: "Patrick D'Cruze" <pdcruze@li.org>
+
+> I met a few points of discussion while doing so:
+>
+> * I got to decide that, even if the program will eventually make
+> most of its output in the foreign languages, the input syntax,
+> option values, etc., are not to be localized.
+
+Yes. The purpose of message catalogs was to provide an easy to use method
+for displaying language independent messages. Hence little modifications
+need to be made to support this. However, no easy method exists for
+supporting language-independent inputs. So this will have to be left up to
+the developer to decide how they are going to implement this.
+
+> * it is not useful that I modify the lib/ routines if not done in the
+> true sources. How do you/I/they proceed for getting this job done?
+> I presume that lib/ routines will all use gettext for the time being.
+
+Probably Roland (or another volunteer) will internationalize glibc. Linux's
+libc has already been internationalised and a few message catalogs
+already exist - French, German, Polish. It probably would be useful
+modifying the routines in lib/ for those platforms that will be using
+the routines located in libc/.
+
+> I was expecting a problem which I did not met. All localizable
+> strings were luckily into executable positions, that is, affected
+> to variables or given as parameter to functions. But I will not
+> escape this problem in all my things, and will surely hit some
+> localizable strings in structured initializations. I'll see once
+> there, unless you thought out an all ready solution for this (?).
+
+I've come across this a few times within diffutils. Particularly struct
+definitions and the like. I'll send you a list of guidelines when looking
+for output messages. Will send this to you and Jim tommorrow.
+
+Regards,
+Patrick
+
+
+
+1, edited,,
+Mail-from: From pinard Mon Nov 28 12:15:47 1994
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rC9fz-00008uC; Mon, 28 Nov 94 12:15 EST
+Message-Id: <m0rC9fz-00008uC@icule>
+Date: Mon, 28 Nov 94 12:15 EST
+From: pinard (Francois Pinard)
+To: Richard M. Stallman <rms@prep.ai.mit.edu>
+CC: Jim Meyering <meyering@comco.com>
+Subject: GNU standards and localized message catalogs
+Mime-Version: 1.0
+Content-Type: text/plain; charset=US-ASCII
+
+*** EOOH ***
+Date: Mon, 28 Nov 94 12:15 EST
+From: pinard (Francois Pinard)
+To: Richard M. Stallman <rms@prep.ai.mit.edu>
+CC: Jim Meyering <meyering@comco.com>
+Subject: GNU standards and localized message catalogs
+Mime-Version: 1.0
+Content-Type: text/plain; charset=US-ASCII
+
+* We also need a uniform convention about where, in the installed
+hierarchy, to put translations of manuals in long term. The need is
+not immediate. One friend volunteered to translate the GNU recode
+manual in French. If this happens, I would like to know first *if*
+the distribution should install it by default, and where it should
+install it then. If not installed by default, what would be the
+uniform naming scheme for Makefile goals installing documents?
+
+1, edited,,
+Mail-from: From pinard Sat Dec 24 23:51:00 1994
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rLkv4-00009AC; Sat, 24 Dec 94 23:50 EST
+Message-Id: <m0rLkv4-00009AC@icule>
+Date: Sat, 24 Dec 94 23:50 EST
+From: pinard (Francois Pinard)
+To: rms@gnu.ai.mit.edu
+In-reply-to: <199412250445.XAA25324@mole.gnu.ai.mit.edu> (message from Richard Stallman on Sat, 24 Dec 1994 23:45:19 -0500)
+Subject: Re: GNU standards and localized message catalogs
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Sat, 24 Dec 94 23:50 EST
+From: pinard (Francois Pinard)
+To: rms@gnu.ai.mit.edu
+In-reply-to: <199412250445.XAA25324@mole.gnu.ai.mit.edu> (message from Richard Stallman on Sat, 24 Dec 1994 23:45:19 -0500)
+Subject: Re: GNU standards and localized message catalogs
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+ * We also need a uniform convention about where, in the installed
+ hierarchy, to put translations of manuals in long term.
+
+ I think they should go in the Info tree just like English manuals.
+
+Yes, of course. Suppose I have a French recode.info, and an
+English one. This kind of thing will not be immediate, but they
+will come. We need some convention to install both. We are not
+to give them different names, presumably. People will like to
+say, on an individual basis: ``if a French version of something is
+available, I'll prefer it over the standard English one''. So we
+need a convention to stock these, and a convention to select them.
+
+1,,
+Mail-from: From gnu.ai.mit.edu!rms Sun Dec 25 05:16:06 1994
+Return-Path: <gnu.ai.mit.edu!rms>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rLpze-00009IC; Sun, 25 Dec 94 05:16 EST
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id AAA12366 for <icule!pinard>; Sun, 25 Dec 1994 00:01:47 -0500
+Received: from saguenay.IRO.UMontreal.CA (root@saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id AAA10584 for <pinard@lagrande.IRO.UMontreal.CA>; Sun, 25 Dec 1994 00:01:46 -0500
+Received: from mole.gnu.ai.mit.edu (rms@mole.gnu.ai.mit.edu [128.52.46.33]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id AAA14869 for <pinard@iro.umontreal.ca>; Sun, 25 Dec 1994 00:01:37 -0500
+Received: by mole.gnu.ai.mit.edu (8.6.9/4.0)
+ id <AAA25411@mole.gnu.ai.mit.edu>; Sun, 25 Dec 1994 00:01:33 -0500
+Date: Sun, 25 Dec 1994 00:01:33 -0500
+Message-Id: <199412250501.AAA25411@mole.gnu.ai.mit.edu>
+From: Richard Stallman <rms@gnu.ai.mit.edu>
+To: pinard@iro.umontreal.ca
+In-reply-to: <m0rLkv4-00009AC@icule> (pinard@iro.umontreal.ca)
+Subject: Re: GNU standards and localized message catalogs
+
+*** EOOH ***
+Date: Sun, 25 Dec 1994 00:01:33 -0500
+From: Richard Stallman <rms@gnu.ai.mit.edu>
+To: pinard@iro.umontreal.ca
+In-reply-to: <m0rLkv4-00009AC@icule> (pinard@iro.umontreal.ca)
+Subject: Re: GNU standards and localized message catalogs
+
+ We need some convention to install both. We are not
+ to give them different names, presumably.
+
+I would give them different names. They would have
+separate menu items in the Info directory. That is the
+easiest way and it seems good enough, so I don't see a reason
+to spend time looking for any other way.
+
+
+1, edited,,
+Mail-from: From pinard Tue Jan 3 16:17:29 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rPGbe-00008xC; Tue, 3 Jan 95 16:17 EST
+Message-Id: <m0rPGbe-00008xC@icule>
+Date: Tue, 3 Jan 95 16:17 EST
+From: pinard (Francois Pinard)
+To: vern@ee.lbl.gov
+In-reply-to: <199501031914.LAA00333@daffy.ee.lbl.gov> (message from Vern Paxson on Tue, 03 Jan 95 11:14:17 PST)
+Subject: Re: Internationalization of Flex
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Tue, 3 Jan 95 16:17 EST
+From: pinard (Francois Pinard)
+To: vern@ee.lbl.gov
+In-reply-to: <199501031914.LAA00333@daffy.ee.lbl.gov> (message from Vern Paxson on Tue, 03 Jan 95 11:14:17 PST)
+Subject: Re: Internationalization of Flex
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+There are two categories of patches: a grouped set at initialization
+time, and all-over-the-place one which marks localizable strings.
+We can consider them separately (but I will most probably end up
+suggesting we give them the same treatment...).
+
+What would be easier would be that the original Flex sources already
+marks all strings which require localization. The way I do it in my
+things is merely replacing each "STRING" by _("STRING") *if* STRING
+should be translated. Flex could then be distributed with:
+
+ #define _(String) (String)
+
+effectively ignoring the marks. I may provide an initial patch
+to you for this. Later on, the maintenance would be relatively
+easy for you: if you add or modify a string, you will have to
+ask yourself if the new or altered string requires translation,
+and include it within _() if you think it should be translated.
+"%s: %d" is an example of string not requiring translation...
+
+The remaining work will be handled by group of volunteers from
+different countries. I took the responsibility of organizing how
+these things will be done. Once in a while, volunteers will provide
+you some COUNTRY.tt files which you might accept to distribute
+with Flex. (COUNTRY is a two letter code, like `de' for German.)
+If the COUNTRY.tt files ever lag with regard to Flex modifications,
+this would not break nationalized Flex: the current mechanics will
+merely return the original English string if a proper translation
+cannot be found. So you do not even have to feel tied to the
+translators for releasing new distributions for Flex. And nothing
+is subject to the GPL so far :-).
+
+The initialization is not very complex, and can be done within
+less than a dozen easy lines of code, hardly GPL'able. I think
+they could be included in standard Flex distribution, while being
+conditionalized out. The only harder modifications come from me,
+and touch Makefile.in, for including all the machinery to prepare
+and install locale message catalogs provided the underlying system
+has what is needed. In the way I am now distributing my things, this
+machinery automatically cut itself out when GNU locale is not usable.
+
+Remain only two modules, currently named libintl.h and libintl.c
+(this might change), which are covered by the GPL, which you
+do not want to distribute with Flex. The Flex README could
+suggest installers to grab them from any other GNU distribution.
+The configuration machinery might automatically check if they have
+been copied by the installer and, if not, forget about localization.
+
+This way, Flex will be easily and widely nationalized, the GPL
+principle will be safe, Flex will stay free of the GPL, and the
+burden on the installers, as well as both you and me, will be
+minimal in the long run.
+
+There is a difficulty I have not studied yet, and which comes from
+the fact that Flex generates C code (Bison has the same problem).
+Flex itself could be nationalized, and this is orthogonal to the fact
+Flex could generate nationalizable scanners. Both are desirable.
+
+
+1, edited,,
+Mail-from: From pinard Thu Jan 12 07:41:07 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rSOpt-00007LC; Thu, 12 Jan 95 07:41 EST
+Message-Id: <m0rSOpt-00007LC@icule>
+Date: Thu, 12 Jan 95 07:41 EST
+From: pinard (Francois Pinard)
+To: vern@ee.lbl.gov
+In-reply-to: <199501051930.LAA04658@daffy.ee.lbl.gov> (message from Vern Paxson on Thu, 05 Jan 95 11:30:54 PST)
+Subject: Re: Internationalization of Flex
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Thu, 12 Jan 95 07:41 EST
+From: pinard (Francois Pinard)
+To: vern@ee.lbl.gov
+In-reply-to: <199501051930.LAA04658@daffy.ee.lbl.gov> (message from Vern Paxson on Thu, 05 Jan 95 11:30:54 PST)
+Subject: Re: Internationalization of Flex
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+Besides, not long after having started this i18n effort for my
+own things, I realized that the i18n attribute should really be
+attached to strings themselves, and not to what we do with them.
+A blatant example is an error message produced by formatting.
+The format string needs i18n, while the result from sprintf may
+have so many different instances that it is unpractical to list
+them all in some error_string_out() routine. I also got other
+cases forcing me to concentrate on strings for i18n.
+
+There is a stylistic issue here. I use _("hello"), adding three
+characters to each localizable string, while you will most probably
+use _( "hello" ), adding five characters per localizable string.
+Yet, it has the advantage of being shorter than error_string_out,
+and be done at the right level.
+
+By merely defining _(String) to be (String), you just turn off
+localization in standard flex, with not a single nanosecond spoiled
+on it. But this will then allow me to produce a quite smaller and
+maintainable patch for i18n of flex.
+
+ This [error_string_out()] routine could then look up every string
+ passed it in a translation table that's compiled into flex
+ like the skel[] array. All that's needed is a public-domain
+ description of the format of the COUNTRY.tt translation files
+ and the rest should be easy.
+
+If I clearly understand your idea, you will compile in flex
+a French table, and obtain a French speaking binary. You will
+produce different binaries for Catalan, Dutch, etc. That is not
+practical on big sites having multinational users.
+
+Right now in my things, the setting of LANG in the environment
+decides the language to use, and there is a single binary to handle
+all things. Further, the evolving GNU locale will soon change its
+*.tt file format, and will try to use the current system underlying
+localization mechanics, if any good one is found at configure time.
+
+There is no need that you redo all this and throw new solutions to
+this whole set of problems. The most workable solution to me looks
+like standard flex distribution already have all _() included -- and
+that you accept routinely adding _() to new localizable strings when
+you are doing flex maintenance, and that a separately distributed
+patch attaches flex to GNU locale complexities, without having you
+discovering and solving them anew.
+
+ Let me know if this is workable (I'm willing to do the work).
+
+Let me take one hour this morning to offer you a patch for _() for
+2.5.0.6, hoping that you will accept it. That would be a start. Let
+me take care of the remaining organizational problems, synchronizing
+with other teams, etc. I already do this for other GNU packages
+and will eventually help with most of them (I've accepted that role).
+
+Once we will have had success with i18ned flex for some time, it
+would then become easier to convince you to go further for other
+aspects (like *producing* i18nable scanners :-).
+
+Let me hope that my pleading for the cause will touch your heart,
+somewhere :-). Keep happy!
+
+--
+François Pinard ``Happy GNU Year!'' pinard@iro.umontreal.ca
+A New Year's gift? Give us Programming Freedom! Write lpf@uunet.uu.net
+
+
+1, edited,,
+Mail-from: From pinard Thu Jan 12 16:44:56 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rSXKA-00007VC; Thu, 12 Jan 95 16:44 EST
+Message-Id: <m0rSXKA-00007VC@icule>
+Date: Thu, 12 Jan 95 16:44 EST
+From: pinard (Francois Pinard)
+To: vern@ee.lbl.gov
+In-reply-to: <199501121822.KAA21713@daffy.ee.lbl.gov> (message from Vern Paxson on Thu, 12 Jan 95 10:22:40 PST)
+Subject: Re: Internationalization of Flex
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Thu, 12 Jan 95 16:44 EST
+From: pinard (Francois Pinard)
+To: vern@ee.lbl.gov
+In-reply-to: <199501121822.KAA21713@daffy.ee.lbl.gov> (message from Vern Paxson on Thu, 12 Jan 95 10:22:40 PST)
+Subject: Re: Internationalization of Flex
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+ I'm not sure having to remember to use error_string_out() instead
+ of fprintf( stderr ... ) is any easier, though.
+
+Not only error strings are being made localizable by the patch I
+shipped this morning, but also statistics, version and help, and
+some debug output. These are not always error messages, and not
+always sent to stderr.
+
+Sometimes in flex, messages are constructed in pieces using %s to
+insert parts. Translating at the string level is the right approach
+in these situations. I'm not sure error_string_out() would have been
+satisfying (but I'm not going to argue, since I have your favor! :-)
+
+1, edited, answered,,
+Mail-from: From twinsun.com!eggert Tue Feb 14 05:16:50 1995
+Path: bloom-beacon.mit.edu!senator-bedfellow.mit.edu!faqserv
+From: mike@vlsivie.tuwien.ac.at
+Newsgroups: comp.unix.questions,comp.std.internat,comp.software.international,comp.lang.c,comp.windows.x,comp.std.c,comp.answers,news.answers
+Subject: Programming for Internationalization FAQ
+Supersedes: <internationalization/programming-faq_787570857@rtfm.mit.edu>
+Followup-To: comp.unix.questions,comp.std.internat,comp.software.international,comp.lang.c,comp.windows.x,comp.std.c
+Date: 15 Jan 1995 10:26:57 GMT
+Organization: TU Wien
+Lines: 564
+Approved: news-answers-request@MIT.EDU
+Expires: 28 Feb 1995 10:26:07 GMT
+Message-ID: <internationalization/programming-faq_790165567@rtfm.mit.edu>
+NNTP-Posting-Host: bloom-picayune.mit.edu
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+Summary: This FAQ discusses writing programs which can handle
+ different language conventions/character sets/etc.
+ Applicable to all character set encodings; with particular
+ emphasis on ISO-8859-1.
+X-Last-Updated: 1994/11/15
+Originator: faqserv@bloom-picayune.MIT.EDU
+Xref: bloom-beacon.mit.edu comp.unix.questions:38263 comp.std.internat:2069 comp.software.international:1289 comp.lang.c:65751 comp.windows.x:34580 comp.std.c:7917 comp.answers:9514 news.answers:33146
+
+*** EOOH ***
+From: mike@vlsivie.tuwien.ac.at
+Newsgroups: comp.unix.questions,comp.std.internat,comp.software.international,comp.lang.c,comp.windows.x,comp.std.c,comp.answers,news.answers
+Subject: Programming for Internationalization FAQ
+Supersedes: <internationalization/programming-faq_787570857@rtfm.mit.edu>
+Followup-To: comp.unix.questions,comp.std.internat,comp.software.international,comp.lang.c,comp.windows.x,comp.std.c
+Date: 15 Jan 1995 10:26:57 GMT
+Organization: TU Wien
+Approved: news-answers-request@MIT.EDU
+Expires: 28 Feb 1995 10:26:07 GMT
+NNTP-Posting-Host: bloom-picayune.mit.edu
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+Summary: This FAQ discusses writing programs which can handle
+ different language conventions/character sets/etc.
+ Applicable to all character set encodings; with particular
+ emphasis on ISO-8859-1.
+X-Last-Updated: 1994/11/15
+Originator: faqserv@bloom-picayune.MIT.EDU
+
+
+Archive-name: internationalization/programming-faq
+Posting-Frequency: monthly
+
+
+
+ Programming for Internationalization
+
+
+
+DISCLAIMER: THE AUTHOR MAKES NO WARRANTY OF ANY KIND WITH REGARD TO
+THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+Note: Most of this was tested on a Sun 10, running SunOS 4.1.* - other
+systems might differ slightly
+
+This FAQ discusses topics related to the use of ISO 8859-1 based 8 bit
+character sets. It discusses how to program applications which support
+the use European (Latin American) national character sets on
+UNIX-based systems and standard C environments.
+
+
+
+1. Which coding should I use for accented characters?
+Use the internationally standardized ISO-8859-1 character set to type
+accented characters. This character set contains all characters
+necessary to type (West) European languages. This encoding is also the
+preferred encoding on the Internet (where accepted - see below).
+
+This character set is also used by AmigaDOS, MS-Windows (Code Page
+1252 in Microsoft Speak. This is for Windows versions delivered in
+the US, Europe (except Eastern Europe) and Latin America. In Windows
+3.1 Microsoft added additional characters in the 0x80-9F range),
+VMS (DEC MCS is a draft version of the current ISO 8859-1 character
+set standard and differs in only two characters) and (most) UNIX
+implementations. MS-DOS uses a different character set and is not
+compatible with this character set.
+
+ISO 8859-X actually is a family of character set standards. Basically
+all of the information given here is also valid for these standards.
+These standards comprise 8859-X:
+8859-1 Europe, Latin America
+8859-2 Eastern Europe
+8859-3 SE Europe/miscellaneous (Esperanto, Maltese, etc.)
+8859-4 Scandinavia/Baltic (mostly covered by 8859-1 also)
+8859-5 Cyrillic
+8859-6 Arabic
+8859-7 Greek
+8859-8 Hebrew
+8859-9 Latin5, same as 8859-1 except for Turkish instead of Icelandic
+8859-10 Latin6, for Eskimo/Scandinavian languages
+
+Another nascent standard is UNICODE (ISO 10646). UNICODE is an
+extension of ISO 8859-1 (which itself is an extension of US-ASCII) to
+16 bit characters. Thus most of the world's languages (including
+Japanese, Korean, Chinese...) can be covered.
+
+Most of the information given here is independent of the character
+encoding used (e.g. DEC MCS, etc.), but can be applied to any
+character set, providing the programming environment has provisions
+for this standard.
+
+
+
+2. Getting your environment right
+To configure your environment such that you can enter, process and
+display 8 bit ISO characters, check out the ISO-8859-1 FAQ available
+via anonymous ftp from ftp.vlsivie.tuwien.ac.at in
+/pub/8bit/FAQ-ISO-8859-1.
+
+
+
+3. Setting your environment for ISO-C (ANSI-C) programs
+The ISO C Standard (ANSI C Standard 4.4) defines several functions for
+supporting localization. To set your international environment on
+program startup, you should make one or several calls to the setlocale
+functions. Calls to this function will predetermine the reaction of
+other localization functions according to your language/country
+environment.
+
+To configure a particular aspect of you environment, say the number
+representation, you would call
+--
+setlocale (LC_NUMERIC, "Germany");
+--
+
+This call would set all number representation functions defined in the
+localization set to return numbers in the format used in Germany. If
+the call was successful, setlocale will return the name of your
+locale. A NULL return value indicates failure. Note that the
+environments are predetermined outside your C program by the system
+you run on. (So the example given here is likely to fail on all but a
+few systems.) Check the setlocale manual page or your system
+documentation to find out about the environments available.
+
+There are several LOCALE types available for different localization
+aspects (currency sign, number representation, characters sets). The
+value they can take is highly system dependent. Also, it should be up
+to the use to define the local environment he needs.
+
+A C program inherits its locale environment variables when it starts up.
+This happens automatically. However, these variables do not
+automatically control the locale used by the library functions, because
+ISO/ANSI C says that all programs start by default in the standard C
+locale. To use the locales specified by the environment, The POSIX
+standard defines the following call:
+-----
+setlocale (LC_ALL, "");
+-----
+
+Of course, you can only set part of your environment, by calling, say:
+----
+setlocale (LC_CTYPE, "");
+----
+This only defines the character classification macros (defined in
+ctype.h).
+
+This is a list of local categories:
+
+ Effect of Specifying Environment Variable
+ category the Value Affected
+ __________________________________________________________
+
+ LC_ALL Sets or queries LANG
+ entire environment
+ LC_COLLATE Changes or queries LC_COLLATE
+ collation sequences
+ LC_CTYPE Changes or queries LC_CTYPE
+ character classifi-
+ cation
+ LC_NUMERIC Changes or queries LC_NUMERIC
+ number format infor-
+ mation
+ LC_TIME Changes or queries LC_TIME
+ time conversion
+ parameters
+ LC_MONETARY Changes or queries LC_MONETARY
+ monetary information
+
+
+
+
+4. Using the locale information for character classification
+If you write a program which supports international use, you should
+use the available standardized functions, as only these will be
+influenced by the setlocale call. Thus, if you want to convert a
+capital letter in c to a lower case letter in l, _don't_ write:
+
+l = c - 'A' + 'a';
+
+While this will work for characters in the US-ASCII character set, it
+will not work with many other character sets. The following,
+standard-conformant code will:
+
+#include <ctype.h>
+
+....
+
+l = tolower(c);
+
+Also note that the second code may actually be faster than even the
+full "C" locale functionality (for most implementations), as it
+replaces a complex expression ( (c<='Z' && c>='A')? c-'A'+a:c; )by a simple
+table lookup!
+
+Note that this ISO standard is independent of the character set
+encoding used!
+
+
+
+5. Language independent messages
+There are two competing standards for language independent messages:
+one by X/Open, and another one by POSIX. The X/Open standard seems to
+have found a larger following as it has been around for a longer time.
+
+5.1 X/Open language independent messages
+X/Open defines a method for providing language-independent messages.
+Error messages are kept in a catalog which is opened upon program
+start with a locale specification. Then the message number and a set
+specification are used to index the message catalog. A default fourth
+argument is specified which will be printed if a particular message
+cannot be found in the catalog.
+
+Here is the world-famous C program using the language-independent
+X/Open message standard:
+--------------------------------------------------------------------------
+#include <stdio.h>
+#include <nl_types.h>
+
+#define SET 1
+#define MSG_HELLO 1
+
+nl_catd catfd;
+
+int main (int argc, char **argv) {
+ /* Open the message catalog. We use the basename of the program
+ * as the catalog name. Of course, several programs can also
+ * share a common catalog.
+ */
+ catfd = catopen (basename (argv [0]), NL_CAT_LOCALE);
+ /* catgets returns message MSG_HELLO from set SET from the
+ * message catalog catfd. If catfd does not refer to a message
+ * catalog, or the requested message cannot be found, the
+ * catalog, or the requested message cannot be found, the
+ * fourth argument is returned.
+ */
+ printf (catgets (catfd, SET, MSG_HELLO, "hello, world\n"));
+ catclose (catfd);
+ return 0;
+}
+-------------------------------------------------------------------------
+
+For catopen, specify the constant NL_CAT_LOCALE to open the message
+catalog for the locale set for the LC_MESSAGES variable; using
+NL_CAT_LOCALE conforms to the XPG4 standard. You can specify 0 (zero)
+for compatibility with XPG3; when oflag is set to zero, the locale set
+for the LANG variable determines the message catalog locale.
+
+Several utilities exist for generating message catalogs and for
+upgrading programs which contain hard-wired strings:
+* gencat is used to generate message catalogs
+[All other programs are OS-specific:]
+* Ultrix and OSF support the extract program which will extract string
+ constants from the C source code, and has an option to replace these
+ strings with calls to catgets.
+* HP/UX has a similar utility called findmsg.
+* Under OSF, message catalogs may be listed with the dspcat utility.
+* HP/UX calls a similar utility dumpmsg.
+
+
+5.2 Sun/XView
+Sun implements a different set of functions functions to support i18n
+of messages (the source is available with the XView code):
+
+You can either use:
+-----------------------------------------------
+
+main()
+{
+ // get the message catalog named "helloprogram"
+ // for the hello world program
+ textdomain("helloprogram");
+
+ // get the translation for the "Hello, world\n" string
+ printf(gettext("Hello, world\n"));
+}
+-----------------------------------------------
+
+or you can roll all in one and write
+
+-----------------------------------------------
+main()
+{
+ // get the translation for the "Hello, world\n" string
+ // from the message catalog "helloprogram"
+ printf(dgettext("helloprogram","Hello, world\n"));
+}
+-----------------------------------------------
+
+The LC_MESSAGES locale category setting determines the locale of
+strings that gettext() returns. The message catalogs are generated
+with either the installtxt or gencat commands.
+
+No opening of files as in the old SYS V and X/Open routines, and no
+handling of message numbers that you must have in a database to
+administer.
+
+
+5.3 POSIX language independent messages
+Neither of the previous two mechanisms is in the POSIX standard.
+There was much disagreement in the POSIX.1 committee about using the
+gettext routines vs. catgets (XPG). In the end the committee couldn't
+agree on anything, so no messaging system was included as part of the
+standard. I believe the informative annex of the standard includes the
+XPG3 messaging interfaces, "...as an example of a messaging system
+that has been implemented..."
+
+They were very careful not to say anywhere that you should use one set
+of interfaces over the other.
+
+
+
+6. Other localization aspects in ISO/ANSI C (and POSIX environments)
+For a more thorough discussion of localization and
+internationalization (aka. i18n), check your system vendors
+documentation, and the C library manual which comes with the FSF's
+glibc library (Chapter 19, 'Locales and Internationalization').
+
+
+
+7. Internationalization under X11
+7.1 Output
+To output text encoded with ISO 8859-1 under X11, simply invoke the X
+display routines with 8 bit characters as you would use them with
+7-bit ASCII. You should however choose a font which contains bitmaps
+for these characters. You can use the xfd utility to display a font
+to verify that it contains a full set of characters.
+
+
+7.2 Input
+If you use a national keyboard (that is a keyboard, which has distinct
+keys for your countries special characters), inputting accents is
+straight forward and you'll get the corresponding characters by using
+the X11 input functions.
+
+Sometimes it may be necessary to input characters for which there are
+no keys on your keyboard (e.g. if you want to enter the German 'ß'
+from a French keyboard).
+
+X11R5 and X11R6 both have extensive support for i18n, but due to a
+variety of factors the R5 i18n was not well understood or widely
+used. Many people resorted to a work-around and might have been
+disappointed when R6 did not include this misfeature. It is important
+to recognize that the correct use of R5 and R6 i18n features will
+ensure maximum portability of your program.
+
+Footnote: Amongst other reasons, the X Consortium decision not to add
+support for input methods to the Xaw Athena widget contributes to this
+situation. Many users (and much of the PD software) live in an
+Xaw-only world, so they will not be able to benefit from this i18n
+effort.
+
+X11 R5 and R6 support input methods for entering non-ASCII, and
+displaying and configuring text, menus etc. for a wide variety of
+languages. This input method has to be installed by the application
+by calls to the Xlib library (or an Xt toolkit call).
+
+[Under X11R5, some X servers (notably the Xsun server) will let you
+enter ISO characters by supplying a built-in escape mechanism, if no
+keys for these characters are on your keyboard, and will pass along
+and display ISO 8859-1. This hack obviated the need to install an
+input method, but was less flexible.]
+
+
+If you are using a toolkit, it is quite simple to support localization
+of you X11 code:
+If you're using a toolkit -- Xt and a widget set like Motif or R6 Xaw --
+you need only add a single line of code to your source. Before any other
+calls to Xt, add a call to XtSetLanguageProc, e.g.:
+
+ int main (int argc, char** argv)
+ {
+ ...
+ XtSetLanguageProc (NULL, NULL, NULL);
+ top = XtAppInitialize ( ... );
+ ...
+ }
+
+The LANG and LC_xxx environment variables (see section 3) will then be
+used to determine the 'input method' for this X application. This
+input method is responsible for managing COMPOSE character sequences
+or any other input mechanism for this particular implementation. Also
+see section 9 of ftp://ftp.vlsivie.tuwien.ac.at/pub/8bit/FAQ-ISO-8859-1,
+the FAQ on ISO 8859-1 usage.
+
+
+7.3 Toolkits, Widgets, and I18N
+The preferred way of inputing national characters when a national
+keyboard is not available is one/several input methods. These input
+methods will then support various kinds of compose sequences to enter
+national characters.
+
+The environment variables LANG and/or LC_xxx select the language for
+the Input Method (IM), but if several input methods exist, the
+environment variable XMODIFIERS can be used to select a specific input
+method.
+
+Xlib supports IMs
+Xt supports IMs
+Xaw does not support IMs
+
+Thus, applications written with Xlib or Xt can support IMs (see
+section 7.2 on how to install input methods under Xt), but Xaw based
+applications will not.
+
+Motif 1.2 or greater automatically uses the R5/R6 input method APIs.
+Thus applications using Motif 1.2+ can be made to support IMs.
+Several Motif 1.[01] versions also had similar functionality added to
+them by the respective vendors, but these extensions are
+vendor-specific and not portable.
+
+FOOTNOTE: If you can have comments/corrections for this section and on
+ OpenLook, please let me know.
+
+
+7.4 I18N under X11R6, General Information
+Background information from the X11R6 announcement:
+Internationalization (also known as I18N, there being 18 letters between the
+i and n) of the X Window System, which was originally introduced in Release
+5, has been significantly improved in R6. The R6 I18N architecture follows
+that in R5, being based on the locale model used in ANSI C and POSIX, with
+most of the I18N capability provided by Xlib. R5 introduced a fundamental
+framework for internationalized input and output. It could enable basic
+localization for left-to-right, non-context sensitive, 8-bit or multi-byte
+codeset languages and cultural conventions. However, it did not deal with
+all possible languages and cultural conventions. R6 also does not cover all
+possible languages and cultural conventions, but R6 contains substantial new
+Xlib interfaces to support I18N enhancements, in order to enable additional
+language support and more practical localization.
+
+The additional support is mainly in the area of text display. In order to
+support multi-byte encodings, the concept of a FontSet was introduced in R5.
+In R6, Xlib enhances this concept to a more generalized notion of output
+methods and output contexts. Just as input methods and input contexts sup-
+port complex text input, output methods and output contexts support complex
+and more intelligent text display, dealing not only with multiple fonts but
+also with context dependencies. The result is a general framework to enable
+bi-directional text and context sensitive text display.
+
+The description of the X11R6 internationalization framework is
+available via anonymous ftp from ftp.x.org in
+/pub/R6untarred/xc/doc/specs/i18n.
+
+
+
+8. Supporting I18N Network Protocols
+8.1 MIME
+MIME is specified in RFC 1521 and RFC 1522 which are available from
+ftp.uu.net. There is also a MIME FAQ which is available via anonymous
+ftp from ftp.ics.uci.edu in /mh/contrib/multimedia/mime-faq.txt.gz.
+(This file is in compressed format. You will need the GNU gunzip
+program to decompress this file.)
+
+If you want to write applications which support the MIME protocol,
+there are several libraries/tools which can ease your task:
+
+
+8.1.1 metamail
+Source for supporting MIME (the `metamail' package) in various mail
+readers is available via anonymous ftp from thumper.bellcore.com in
+/pub/nsb. This distribution consists of several utilities, which can
+be called by MIME applications to handle MIME types.
+
+
+8.1.2 MIMElt
+A "lightweight" MIME library available via anon ftp from
+oslonett.no:Software/MsDos/Comm/Offline/mimeltXX.zip
+
+It is source code (ANSI C) packaged as a library to facilitate
+construction of a limited MIME facility (limited == handling only
+character-set aspects of MIME, not the multimedia-aspects). It
+includes hooks to recode character sets into whatever system you are
+running off (e.g. if you read mail on a MsDos platform using CP-850,
+MIMElite may be set up so that QUOTED-PRINTABLE ISO Latin 1 is recoded
+into CP-850 for reading and saving to file).
+
+It's main use is to provide programmers of so-called "off-line
+readers" (used by user's who access Internet mail through dial-up
+service providers) with the tools needed to include proper support for
+QUOTED-PRINTABLE encoding in their product.
+
+The archive also contain a couple of sample applications that
+demonstrates how the library may be used. UNMIME is a stand-alone
+utility to decode MIME-encoded messages (e.g. it works like UUDECODE
+for binary files with BASE64 encoding), SENDMIME is a simple utility
+to send MIME-encoded messages if your service provider doesn't have
+PINE or similar tools.
+
+The current version (2.1) is limited to character set issues. I am
+about to release version 2.2, which will support additional
+Content-Types (e.g. "application/octet-stream").
+
+
+
+9. Programming in Prolog
+SICStus Prolog accepts ISO characters as part of atoms, so you can
+even define goal names containing accented characters. I/O of 8 bit
+characters is (obviously) also supported.
+
+
+
+10. ISO 8859-1 on non-UNIX systems
+10.1 MS-DOS
+MS-DOS generally uses its own characters set. There are several code
+pages (one with the same symbols as ISO 8859-1, albeit at different
+character code positions, which can lead to problems with the transfer
+of data).
+
+If interoperability without data conversion is your goal, you can
+reconfigure your MS-DOS PC to use an ISO-8859-1 code page. Check out
+the anonymous ftp archive ftp.uni-erlangen.de, which contains data on
+how to do this (and other ISO-related stuff) in /pub/doc/ISO/charsets.
+The README file contains an index of the files you need.
+
+Most (all?) C compilers/libraries for MS-DOS have only minimal support
+for the ANSI/POSIX locale mechanism. The setlocale() and localeconv()
+calls (and stuff like strxfrm()) are generally hardwired.
+
+
+10.2 MS Windows
+MS-Windows (using code page 1252) normally uses the first 256
+characters of Unicode, which is (for all practical purposes)
+equivalent to ISO 8859-1. Thus, data representation and conversion
+for interoperability with other ISO 8859-1 compliant systems is not an
+issue.
+
+It seems that C libraries for MS Windows do not support the ANSI/POSIX
+locale mechanism. (If you have any experiences with that, please let
+me know.) There is a POSIX-like mechanism in some Microsoft platform
+services, but none in the compilers from any vendor.
+
+
+10.3 OS/2
+Text mode OS/2 programs generally suffer the same limitations as do
+MS-DOS programs, because the display hardware is the same.
+
+Presentation Manager OS/2 programs using code page 1004 will order
+the font glyphs in the same sequence as ISO 8859-1 (although of
+course whether the glyphs will actually look anything like those
+from ISO 8859-1 depends entirely from the font).
+
+The IBM CSet++ compiler supports full internationalization, with
+several predefined locales.
+
+The Borland C++ compiler supports only the "C" locale.
+
+The Watcom C++ compiler supports only the "C" locale.
+
+The Metaware High C++ compiler supports only the "C" locale. It
+does, however, also support UNICODE, providing UNICODE character
+types and UNICODE versions of the appropriate parts of the standard
+library (including I/O).
+
+
+
+10.4 Apple Macintosh
+MacIntoshes have their own non-standard character encodings;
+the first 128 characters are US-ASCII but the remaining characters are
+non-standard.
+
+I do not know whether C libraries (for which compilers?) for the
+MacIntosh support the ANSI/POSIX locale mechanism. If you have any
+experiences with that, please let me know.
+
+
+10.5 Amiga
+The AmigaOS uses ISO-8859-1. As of OS version 2.1, Amiga-specific
+means of localization are available.
+
+
+
+11. Home location of this document
+The most recent version of this document is available via anonymous
+ftp from ftp.vlsivie.tuwien.ac.at under the file name
+/pub/8bit/ISO-programming.
+
+-----------------
+
+Copyright İ 1994 Michael Gschwind (mike@vlsivie.tuwien.ac.at)
+
+This document may be copied for non-commercial purposes, provided this
+copyright notice appears. Publication in any other form requires the
+author's consent.
+
+Dieses Dokument darf unter Angabe dieser urheberrechtlichen
+Bestimmungen zum Zwecke der nicht-kommerziellen Nutzung beliebig
+vervielfältigt werden. Die Publikation in jeglicher anderer Form
+erfordert die Zustimmung des Autors.
+
+Michael Gschwind, Institut f. Technische Informatik, TU Wien
+snail: Treitlstrasse 3-182-2 || A-1040 Wien || Austria
+email: mike@vlsivie.tuwien.ac.at note: real time != real fast
+phone: +(43)(1)58801 8156 fax: +(43)(1)586 9697
+
+
+1, edited, resent,,
+Mail-from: From li.org!owner-li-international Fri Jan 20 08:56:04 1995
+Return-Path: <li.org!owner-li-international>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rVJon-00009Da; Fri, 20 Jan 95 08:56 EST
+Sender: li.org!owner-li-international
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id RAA25970 for <icule!pinard>; Mon, 16 Jan 1995 17:34:02 -0500
+Received: from saguenay.IRO.UMontreal.CA (root@saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id RAA14270 for <pinard@lagrande.IRO.UMontreal.CA>; Mon, 16 Jan 1995 17:33:53 -0500
+Received: from uniwa.uwa.edu.au (root@uniwa.uwa.edu.au [130.95.128.1]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id RAA07348 for <pinard@iro.umontreal.ca>; Mon, 16 Jan 1995 17:33:41 -0500
+Received: from orac.aust.li.org (orac.iinet.com.au [203.0.178.134]) by uniwa.uwa.edu.au (8.6.9/8.6.9) with ESMTP id GAA22040; Tue, 17 Jan 1995 06:29:21 +0800
+Received: (from majordom@localhost) by orac.aust.li.org (8.6.9/8.6.9) id FAA01118 for li-international-list; Tue, 17 Jan 1995 05:34:39 +0800
+Received: from alcor (alcor.twinsun.com [198.147.65.1]) by orac.aust.li.org (8.6.9/8.6.9) with ESMTP id FAA01112 for <li-international@li.org>; Tue, 17 Jan 1995 05:34:28 +0800
+Received: from twinsun.com (twinsun.twinsun.com [192.54.239.2]) by alcor (8.6.5/8.6.5) with SMTP id NAA04793 for <li-international@li.org>; Mon, 16 Jan 1995 13:06:52 -0800
+Received: from spot.twinsun.com by twinsun.com (4.1/SMI-4.1)
+ id AA06664; Mon, 16 Jan 95 13:33:30 PST
+Received: by spot.twinsun.com (4.1/SMI-4.1)
+ id AA04256; Mon, 16 Jan 95 13:33:30 PST
+Old-From: eggert@twinsun.com (Paul Eggert)
+Message-Id: <9501162133.AA04256@spot.twinsun.com>
+Date: 16 Jan 1995 13:33:28 -0800
+To: li-international@li.org
+Subject: ISO Normative Addendum 1 and its effect on the C library
+From: International List <li-international@li.org>
+Sender: owner-li-international@li.org
+Precedence: bulk
+Reply-To: LI-international@li.org
+
+*** EOOH ***
+From: eggert@twinsun.com (Paul Eggert)
+Date: 16 Jan 1995 13:33:28 -0800
+To: li-international@li.org
+Subject: ISO Normative Addendum 1 and its effect on the C library
+Reply-To: LI-international@li.org
+
+Normative Addendum 1 (NA1) to the ISO C standard was approved last year,
+and I recently ran across a nice summary written by Clive Feather.
+Please see <http://sf.www.lysator.liu.se/c/nal.html> for this;
+
+Most of the changes required by NA1 are to the C library's wide
+character and multibyte string support. I don't see these changes
+mentioned in the latest glibc snapshot. I asked Roland McGrath,
+glibc's developer, about this, and he replied:
+
+ Date: Mon, 16 Jan 95 15:53:26 -0500
+ From: Roland McGrath <roland@gnu.ai.mit.edu>
+
+ I think if you make the specifications available to the Linux community,
+ the new library functions will get written and contributed to glibc.
+ Try the mailing list li-international@li.org.
+
+So I'm sending this message to li-international. I can forward a copy
+of the NA1 summary to whoever needs it; just ask.
+
+Two of the NA1 changes (__STDC_VERSION__ and digraphs) require changes
+to GCC itself; I've volunteered to do this. One change (namely
+<iso646.h>) can be done either in GCC or in libc, though if GCC does
+digraphs it may make more sense for it to do <iso646.h> as well.
+But the other changes belong to the C library proper.
+
+
+
+1,,
+Mail-from: From twinsun.com!eggert Tue Feb 14 05:16:49 1995
+Return-Path: <twinsun.com!eggert>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0reKJK-00009mC; Tue, 14 Feb 95 05:16 EST
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id CAA00816 for <icule!pinard>; Tue, 14 Feb 1995 02:16:27 -0500
+Received: from saguenay.IRO.UMontreal.CA (root@saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id CAA02807 for <pinard@lagrande.IRO.UMontreal.CA>; Tue, 14 Feb 1995 02:16:20 -0500
+Received: from alcor.twinsun.com (alcor.twinsun.com [198.147.65.1]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id CAA29451 for <pinard@iro.umontreal.ca>; Tue, 14 Feb 1995 02:16:16 -0500
+Received: from twinsun.com (twinsun.twinsun.com [192.54.239.2]) by alcor.twinsun.com (8.6.5/8.6.5) with SMTP id WAA03362 for <pinard@iro.umontreal.ca>; Mon, 13 Feb 1995 22:44:50 -0800
+Received: from spot.twinsun.com by twinsun.com (4.1/SMI-4.1)
+ id AA08130; Mon, 13 Feb 95 23:15:06 PST
+Received: by spot.twinsun.com (4.1/SMI-4.1)
+ id AA05763; Mon, 13 Feb 95 23:15:05 PST
+From: eggert@twinsun.com (Paul Eggert)
+Message-Id: <9502140715.AA05763@spot.twinsun.com>
+Date: 13 Feb 1995 23:15:04 -0800
+To: pinard@iro.umontreal.ca
+In-Reply-To: <m0rdrDE-00009QC@icule> (pinard@iro.umontreal.ca)
+Subject: Re: glocale and Uniforum gettext simplicity
+
+*** EOOH ***
+From: eggert@twinsun.com (Paul Eggert)
+Date: 13 Feb 1995 23:15:04 -0800
+To: pinard@iro.umontreal.ca
+In-Reply-To: <m0rdrDE-00009QC@icule> (pinard@iro.umontreal.ca)
+Subject: Re: glocale and Uniforum gettext simplicity
+
+
+ Date: Sun, 12 Feb 95 22:12 EST
+ From: pinard@iro.umontreal.ca (Francois Pinard)
+
+ Hello, Paul.
+
+ For more on this topic please see the Programming
+ for Internationalization FAQ (Message-ID:
+ <internationalization/programming-faq_784901999@rtfm.mit.edu>)
+ which I can forward to you if you like.
+
+ Would you do this, please?
+
+Sure, the latest revision be in my next message. For future
+reference, the coordinates are
+<ftp://rtfm.mit.edu/pub/usenet-by-group/comp.answers/internationalization/programming-faq>.
+
+Alas, I haven't had time to work on this much lately -- beset with hardware
+problems at home and no time to fix them....
+
+
+1, edited,,
+Mail-from: From pinard Tue Mar 21 12:53:53 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0rr87q-00009TC; Tue, 21 Mar 95 12:53 EST
+Message-Id: <m0rr87q-00009TC@icule>
+Date: Tue, 21 Mar 95 12:53 EST
+From: pinard (François Pinard)
+To: meyering@comco.com
+CC: drepper@ipd.info.uni-karlsruhe.de
+In-reply-to: <199503211712.LAA25472@idefix.comco.com> (message from Jim Meyering on Tue, 21 Mar 1995 11:12:49 -0600)
+Subject: Re: international fileutils
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Tue, 21 Mar 95 12:53 EST
+From: pinard (François Pinard)
+To: meyering@comco.com
+CC: drepper@ipd.info.uni-karlsruhe.de
+In-reply-to: <199503211712.LAA25472@idefix.comco.com> (message from Jim Meyering on Tue, 21 Mar 1995 11:12:49 -0600)
+Subject: Re: international fileutils
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+There are three things to do for each package:
+
+* Adjust Autoconf and Makefiles
+* Mark all localizable strings in sources and doing other adjustments
+* Translating messages for French (and maybe, let's be fair, German :-).
+
+1, edited,,
+Mail-from: From pinard Sun Apr 23 13:26:30 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s35QR-00008FC; Sun, 23 Apr 95 13:26 EDT
+Message-Id: <m0s35QR-00008FC@icule>
+Date: Sun, 23 Apr 95 13:26 EDT
+From: pinard (François Pinard)
+To: Jim Meyering <meyering@comco.com>,
+ Ulrich Drepper <drepper@gnu.ai.mit.edu>,
+ Roland McGrath <roland@gnu.ai.mit.edu>,
+ Paul Eggert <eggert@twinsun.com>
+Subject: GNU locale and Ulrich's effort
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Sun, 23 Apr 95 13:26 EDT
+From: pinard (François Pinard)
+To: Jim Meyering <meyering@comco.com>,
+ Ulrich Drepper <drepper@gnu.ai.mit.edu>,
+ Roland McGrath <roland@gnu.ai.mit.edu>,
+ Paul Eggert <eggert@twinsun.com>
+Subject: GNU locale and Ulrich's effort
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+I'm trying to get started the overall effort for GNU localization,
+by offering translators GNU packages to translate, and the means
+to do so. I also do not want to spoil the energies being offered.
+Many pieces of the puzzle are in place already and, as usual, I
+contemplate them all trying to see what is missing, and working
+towards the complete picture.
+
+Surely to me, GNU locale (glocale, as a package) has to provide a
+fairly complete set of self-contained tools for helping package
+maintainers to internationalize their product, and also for
+localizers to translate message catalogs. Further, being itself
+internationalized, it should be a very carefully crafted example
+for maintainers, about how one might set his/her own package to be
+easily installed while localization is effective, and portably!
+
+
+
+1,,
+Mail-from: From pinard Mon May 1 22:16:31 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s67Vl-00008NC; Mon, 1 May 95 22:16 EDT
+Message-Id: <m0s67Vl-00008NC@icule>
+Date: Mon, 1 May 95 22:16 EDT
+From: pinard (=?ISO-8859-1?Q?Fran=E7ois_Pinard?=)
+To: gnu@prep.ai.mit.edu
+CC: rms@gnu.ai.mit.edu
+In-reply-to: <9505020044.AA12891@pizza> (gnu@ai.mit.edu)
+Subject: Re: [pinard@iro.umontreal.ca: Internationalizing GNU: the maintainer side]
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Mon, 1 May 95 22:16 EDT
+From: pinard (François Pinard)
+To: gnu@prep.ai.mit.edu
+CC: rms@gnu.ai.mit.edu
+In-reply-to: <9505020044.AA12891@pizza> (gnu@ai.mit.edu)
+Subject: Re: [pinard@iro.umontreal.ca: Internationalizing GNU: the maintainer side]
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+ It contains some statements that are harsh and, I believe,
+ not true. The practice of using gettext to mark strings is
+ *not* just "for the time being."
+
+ Fran\cois: Could you work with rms to update the GNU coding
+ standards to describe what GNUers needs to be do to make their
+ GNU programs use GNU Locale.
+
+I may try, but do not know exactly how to proceed. I also confess
+I've rewritten this paragraph twenty times, to merely censor myself.
+
+ We can then post that section of the GNU coding standards, so
+ all the GNUers know what to do.
+
+If GNU ever publishes utilities for Native Language Support, their
+own documentation should explain how to proceed, and maintainers
+should find in there the information they need about what to do.
+GNU standards might state the general principle, something like:
+``GNU programs and packages should be opened to Native Language
+Support (NLS) and, in particular, be able to write their messages
+translated into native languages, as selected at run time by
+environment variables''.
+
+--
+François Pinard ``Vivement GNU!'' <pinard@iro.umontreal.ca>
+Email lpf@uunet.uu.net for info about the League for Programming Freedom.
+
+
+1,,
+Mail-from: From IRO.UMontreal.CA!pinard Tue May 2 05:16:32 1995
+Return-Path: <IRO.UMontreal.CA!pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s6E4E-0000CaC; Tue, 2 May 95 05:16 EDT
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id AAA19507 for <icule!pinard>; Tue, 2 May 1995 00:02:38 -0400
+Received: (from pinard@localhost) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) id AAA00659 for icule!pinard; Tue, 2 May 1995 00:02:37 -0400
+Received: from saguenay.IRO.UMontreal.CA (saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id AAA00657 for <pinard@lagrande.IRO.UMontreal.CA>; Tue, 2 May 1995 00:02:34 -0400
+Received: from mole.gnu.ai.mit.edu (mole.gnu.ai.mit.edu [128.52.46.33]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id AAA08792 for <pinard@iro.umontreal.ca>; Tue, 2 May 1995 00:02:33 -0400
+Received: by mole.gnu.ai.mit.edu (8.6.12/8.6.12GNU) id AAA07143; Tue, 2 May 1995 00:02:31 -0400
+Date: Tue, 2 May 1995 00:02:31 -0400
+Message-Id: <199505020402.AAA07143@mole.gnu.ai.mit.edu>
+From: Richard Stallman <rms@gnu.ai.mit.edu>
+To: pinard@IRO.UMontreal.CA
+In-reply-to: <m0s67Vl-00008NC@icule> (pinard@iro.umontreal.ca)
+Subject: Re: [pinard@iro.umontreal.ca: Internationalizing GNU: the maintainer side]
+
+*** EOOH ***
+Date: Tue, 2 May 1995 00:02:31 -0400
+From: Richard Stallman <rms@gnu.ai.mit.edu>
+To: pinard@IRO.UMontreal.CA
+In-reply-to: <m0s67Vl-00008NC@icule> (pinard@iro.umontreal.ca)
+Subject: Re: [pinard@iro.umontreal.ca: Internationalizing GNU: the maintainer side]
+
+ ``GNU programs and packages should be opened to Native Language
+ Support (NLS) and, in particular, be able to write their messages
+ translated into native languages, as selected at run time by
+ environment variables''.
+
+I think that is too vague to be useful. I'd rather put in some
+variant of what you sent before. But I don't have time right now
+to fix it.
+
+
+1, answered, edited,,
+Mail-from: From IRO.UMontreal.CA!pinard Wed May 3 00:19:10 1995
+Return-Path: <IRO.UMontreal.CA!pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s6Vty-0000CSC; Wed, 3 May 95 00:19 EDT
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id XAA19717 for <icule!pinard>; Tue, 2 May 1995 23:51:54 -0400
+Received: (from pinard@localhost) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) id XAA20985 for icule!pinard; Tue, 2 May 1995 23:51:52 -0400
+Received: from saguenay.IRO.UMontreal.CA (saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id XAA20983 for <pinard@lagrande.IRO.UMontreal.CA>; Tue, 2 May 1995 23:51:49 -0400
+Received: from nz11.rz.uni-karlsruhe.de (nz11.rz.uni-karlsruhe.de [129.13.64.7]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id XAA12985 for <pinard@iro.umontreal.ca>; Tue, 2 May 1995 23:51:15 -0400
+Received: from ipd.info.uni-karlsruhe.de (actually i44ms.info.uni-karlsruhe.de)
+ by nz11.rz.uni-karlsruhe.de with SMTP (PP);
+ Wed, 3 May 1995 03:54:26 +0200
+Received: from i44pc2.info.uni-karlsruhe.de (i44pc2.info.uni-karlsruhe.de [129.13.171.31])
+ by ipd.info.uni-karlsruhe.de (8.6.4/8.6.4) with SMTP id DAA00768;
+ Wed, 3 May 1995 03:57:08 +0200
+Message-Id: <199505030157.DAA00768@ipd.info.uni-karlsruhe.de>
+To: "ois \"Pinard)\""@rz.uni-karlsruhe.de, meyering@comco.com (Jim Meyering),
+ eggert@twinsun.com (Paul Eggert),
+ roland@gnu.ai.mit.edu (Roland McGrath)
+Original-To: pinard@iro.umontreal.ca (François Pinard),
+ meyering@comco.com (Jim Meyering),
+ eggert@twinsun.com (Paul Eggert),
+ roland@gnu.ai.mit.edu (Roland McGrath)
+PP-Warning: Parse error in original version of preceding To line
+Subject: nlsutils-0.4.2
+Date: Wed, 03 May 1995 03:56:24 +0200
+From: Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
+
+*** EOOH ***
+To: "ois \"Pinard)\""@rz.uni-karlsruhe.de, meyering@comco.com (Jim Meyering),
+ eggert@twinsun.com (Paul Eggert),
+ roland@gnu.ai.mit.edu (Roland McGrath)
+Original-To: pinard@iro.umontreal.ca (François Pinard),
+ meyering@comco.com (Jim Meyering),
+ eggert@twinsun.com (Paul Eggert),
+ roland@gnu.ai.mit.edu (Roland McGrath)
+PP-Warning: Parse error in original version of preceding To line
+Subject: nlsutils-0.4.2
+Date: Wed, 03 May 1995 03:56:24 +0200
+From: Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
+
+I tried hard to limit all external things in the libgintl directory.
+You have to copy this, some variation of my code in aclocal.m4
+and acconfig.h. This should be all.
+
+1, answered,,
+Mail-from: From IRO.UMontreal.CA!pinard Thu May 4 08:22:15 1995
+Return-Path: <IRO.UMontreal.CA!pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s6zv4-0000CSC; Thu, 4 May 95 08:22 EDT
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id HAA19349 for <icule!pinard>; Thu, 4 May 1995 07:48:32 -0400
+Received: (from pinard@localhost) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) id HAA24822 for icule!pinard; Thu, 4 May 1995 07:47:28 -0400
+Received: from saguenay.IRO.UMontreal.CA (saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id HAA24816 for <pinard@lagrande.IRO.UMontreal.CA>; Thu, 4 May 1995 07:47:25 -0400
+Received: from nz11.rz.uni-karlsruhe.de (nz11.rz.uni-karlsruhe.de [129.13.64.7]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id HAA17159 for <pinard@iro.umontreal.ca>; Thu, 4 May 1995 07:48:25 -0400
+Received: from ipd.info.uni-karlsruhe.de (actually i44ms.info.uni-karlsruhe.de)
+ by nz11.rz.uni-karlsruhe.de with SMTP (PP);
+ Thu, 4 May 1995 13:45:17 +0200
+Received: from i44pc2.info.uni-karlsruhe.de (i44pc2.info.uni-karlsruhe.de [129.13.171.31])
+ by ipd.info.uni-karlsruhe.de (8.6.4/8.6.4) with SMTP id NAA06097
+ for <pinard@iro.umontreal.ca>; Thu, 4 May 1995 13:48:06 +0200
+Message-Id: <199505041148.NAA06097@ipd.info.uni-karlsruhe.de>
+To: pinard@IRO.UMontreal.CA
+Subject: Re: Path to message?
+In-Reply-To: Your message of "Thu, 4 May 95 00:45 EDT"
+References: <m0s6snG-00008NC@icule>
+X-Mailer: Mew beta version 0.89 on Emacs 19.28.1
+Mime-Version: 1.0
+Content-Type: Text/Plain; charset=iso-8859-1
+Date: Thu, 04 May 1995 13:47:46 +0200
+From: Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
+Content-Transfer-Encoding: 8bit
+X-Original-Encoding: quoted-printable
+
+*** EOOH ***
+To: pinard@IRO.UMontreal.CA
+Subject: Re: Path to message?
+In-Reply-To: Your message of "Thu, 4 May 95 00:45 EDT"
+References: <m0s6snG-00008NC@icule>
+Mime-Version: 1.0
+Content-Type: Text/Plain; charset=iso-8859-1
+Date: Thu, 04 May 1995 13:47:46 +0200
+From: Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
+Content-Transfer-Encoding: 8bit
+X-Original-Encoding: quoted-printable
+
+From: pinard@iro.umontreal.ca (François Pinard)
+Subject: Path to message?
+Date: Thu, 4 May 95 00:45 EDT
+
+> Ulrich, always me. I do not understand that xgettext --help writes:
+>
+> Suchpfad ist: /usr/local/share/nls/src
+>
+> while /usr/local/share/locale/de/LC_MESSAGES is indeed searched.
+> Could we solve this inconsistency?
+>
+
+Not quite. /usr/local/share/locale/de/LC_MESSAGES is the path where
+the .mo/.cat files will go. The search path (Suchpfad :) represents
+the path to additional directories where other .po files can be found.
+
+I thought to use this feature for standard .po files for, say, libiberty
+etc. Each package would have to translate it again and again but if
+we could install this somewhere and use the -x option to exclude this
+strings from the generation.
+
+Perhaps I should use a different description?
+
+-- Uli
+________---------------------------------------------------------------
+\ / Ulrich Drepper / Univ. at Karlsruhe, Germany / CS Dept. / IPD
+L\inux/ email: drepper@gnu.ai.mit.edu smail: Rubensstr. 5
+ \ / drepper@ipd.info.uni-karlsruhe.de 76149 Karlsruhe
+ \/1.2.7 ------------------------------------------- Germany --------
+
+
+1, forwarded, edited,,
+Mail-from: From pinard Thu May 4 15:27:13 1995
+Return-Path: <pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s76YH-00008NC; Thu, 4 May 95 15:27 EDT
+Message-Id: <m0s76YH-00008NC@icule>
+Date: Thu, 4 May 95 15:27 EDT
+From: pinard (=?ISO-8859-1?Q?Fran=E7ois_Pinard?=)
+To: ajc@di.uminho.pt
+In-reply-to: <9505041601.AA20254@shiva.di.uminho.pt> (ajc@di.uminho.pt)
+Subject: Re: tar is ready for pt
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+*** EOOH ***
+Date: Thu, 4 May 95 15:27 EDT
+From: pinard (François Pinard)
+To: ajc@di.uminho.pt
+In-reply-to: <9505041601.AA20254@shiva.di.uminho.pt> (ajc@di.uminho.pt)
+Subject: Re: tar is ready for pt
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+
+Even if it is not completely official yet in GNU, the format of
+translation file is being revised, and the extension is being
+changed from `.tt' to `.po'. This should bring the format closer
+to one of the few standards in existence for translation files.
+Hopefully, we think that translation files will be more easily
+manageable afterwards. We do not want to make a religious issue of
+this format selection, as each standard has proponents and opponents.
+Please help us by being receptive to the format GNU uses.
+
+Existing `.tt' translation files are being converted to `.po' files
+by maintainers. Translators should switch to using the `.po' format,
+as soon as possible. This is an easy job. The `.po' translation
+file format is quite affordable. Schematically, it looks like:
+
+ msgid STRING-TO-TRANSLATE
+ msgstr TRANSLATED-STRING
+
+ msgid STRING-TO-TRANSLATE
+ msgstr TRANSLATED-STRING
+
+ msgid STRING-TO-TRANSLATE
+ msgstr TRANSLATED-STRING
+ [...]
+
+`msgid' and `msgstr' are kind of keywords, written at the beginning
+of a line. Each STRING-TO-TRANSLATE or TRANSLATED-STRING respects
+the C syntax for a character string, including the surrounding
+quotes, escape sequences, and usual techniques for writing multi-line
+C strings.
+
+Outside strings, white lines and comments may be used freely.
+In the schema, white lines preceding the msgid lines are optional.
+Comments start at the beginning of a line with `#' and extend until
+the end of line. Comments written by translators should have the
+initial `#' immediately followed by some white space. If the `#'
+is not immediately followed by white space, this comment is most
+likely generated and managed by specialized GNU tools.
+
+There is a conventional, uniform way of presenting a `.po' file, but
+a description of this format is not yet available. It will be all
+easy to make suggested adjustements at a later time, so do not worry
+right now about precise conventions. Further, there are normalizing
+tools automating conformance to a great extent, to be published soon.
+
+ And another question: what happens when new versions of the
+ program are released, with new messages?
+
+Usually, most GNU packages are pretested before being released.
+All teams of translators are made aware of localizable prereleases.
+A special tool regenerates a `.po' file with obsolescent strings
+commented out, and new strings put in evidence.
+
+Further, for those of us using GNU Emacs, a special editing mode is
+being written for `.po' files, in which mode translators is able
+to navigate easily in the `.po' file, find untranslated entries,
+examine at will the context of these strings in the program sources,
+and also observe other translations already made in other languages,
+for the string being translated.
+
+Teams members should share their translations and resolve linguistic
+or terminological issues. When they reach something satisfying,
+the team should formally submit the translation to the package
+maintainer for the final release. The precise formalities are not
+organized yet, and there are many details to clear up. Some legal
+aspects also have to be addressed, this is under study right now.
+
+Special means should be used for transiting translation files
+over email. The simplest way is using GNU shar in default mode,
+or else, uuencoding the `.po' file prior to mailing.
+
+--
+François Pinard ``Vivement GNU!'' <pinard@iro.umontreal.ca>
+Email lpf@uunet.uu.net for info about the League for Programming Freedom.
+
+
+1, edited,,
+Mail-from: From IRO.UMontreal.CA!pinard Thu Apr 20 16:54:03 1995
+Return-Path: <IRO.UMontreal.CA!pinard>
+Received: by icule (Smail3.1.28.1 #1)
+ id m0s23Ea-0000CxC; Thu, 20 Apr 95 16:53 EDT
+Received: from lagrande.iro.umontreal.ca (lagrande.IRO.UMontreal.CA [132.204.32.32]) by iros1.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id KAA12085 for <icule!pinard>; Thu, 20 Apr 1995 10:13:02 -0400
+Received: (from pinard@localhost) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) id KAA08298 for icule!pinard; Thu, 20 Apr 1995 10:12:34 -0400
+Received: from saguenay.IRO.UMontreal.CA (saguenay32.IRO.UMontreal.CA [132.204.32.54]) by lagrande.iro.umontreal.ca (8.6.9/8.6.9) with ESMTP id KAA08254 for <pinard@lagrande.IRO.UMontreal.CA>; Thu, 20 Apr 1995 10:10:49 -0400
+Received: from nz11.rz.uni-karlsruhe.de (nz11.rz.uni-karlsruhe.de [129.13.64.7]) by saguenay.IRO.UMontreal.CA (8.6.9/8.6.9) with ESMTP id KAA20778 for <pinard@iro.umontreal.ca>; Thu, 20 Apr 1995 10:10:25 -0400
+Received: from ipd.info.uni-karlsruhe.de (actually i44ms.info.uni-karlsruhe.de)
+ by nz11.rz.uni-karlsruhe.de with SMTP (PP);
+ Thu, 20 Apr 1995 16:05:34 +0200
+Received: from i44pc2.info.uni-karlsruhe.de (i44pc2.info.uni-karlsruhe.de [129.13.171.31])
+ by ipd.info.uni-karlsruhe.de (8.6.4/8.6.4) with SMTP id QAA28513;
+ Thu, 20 Apr 1995 16:08:10 +0200
+Message-Id: <199504201408.QAA28513@ipd.info.uni-karlsruhe.de>
+To: pinard@IRO.UMontreal.CA (Francois Pinard),
+ meyering@comco.com (Jim Meyering),
+ roland@gnu.ai.mit.edu (Roland McGrath)
+Subject: more points to discuss
+X-Mailer: Mew beta version 0.89 on Emacs 19.28.1
+Mime-Version: 1.0
+Content-Type: Text/Plain; charset=iso-8859-1
+Date: Thu, 20 Apr 1995 16:08:55 +0200
+From: Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
+Content-Transfer-Encoding: 8bit
+X-Original-Encoding: quoted-printable
+
+*** EOOH ***
+To: pinard@IRO.UMontreal.CA (Francois Pinard),
+ meyering@comco.com (Jim Meyering),
+ roland@gnu.ai.mit.edu (Roland McGrath)
+Subject: more points to discuss
+Mime-Version: 1.0
+Content-Type: Text/Plain; charset=iso-8859-1
+Date: Thu, 20 Apr 1995 16:08:55 +0200
+From: Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
+Content-Transfer-Encoding: 8bit
+X-Original-Encoding: quoted-printable
+
+BTW my implementation will be able to process a lot of strange situation:
+- strings in preprocessor macros
+- something like gettext ("jkh" "jkhlk")
+or even
+- gettext ("jkkjh\
+sdfsdf")
+
+1, edited,,
+Received: from titan.comco.com (root@titan.comco.com [198.214.63.11]) by idefix.comco.com (8.6.9/8.6.9) with ESMTP id QAA16073 for <meyering@idefix.comco.com>; Sat, 19 Nov 1994 16:03:48 -0600
+Received: from alcor.twinsun.com (alcor.twinsun.com [198.147.65.1]) by titan.comco.com (8.6.9/8.6.9) with ESMTP id QAA03006 for <meyering@comco.com>; Sat, 19 Nov 1994 16:04:38 -0600
+Received: from twinsun.com (twinsun.twinsun.com [192.54.239.2]) by alcor.twinsun.com (8.6.5/8.6.5) with SMTP id NAA19013; Sat, 19 Nov 1994 13:55:18 -0800
+Received: from spot.twinsun.com by twinsun.com (4.1/SMI-4.1)
+ id AA29144; Sat, 19 Nov 94 14:01:01 PST
+Received: by spot.twinsun.com (4.1/SMI-4.1)
+ id AA02990; Sat, 19 Nov 94 14:01:00 PST
+From: eggert@twinsun.com (Paul Eggert)
+Message-Id: <9411192201.AA02990@spot.twinsun.com>
+Date: 19 Nov 1994 14:00:59 -0800
+To: rms@gnu.ai.mit.edu (Richard Stallman)
+Cc: meyering@comco.com, pdcruze@orac.iinet.com.au
+Subject: Re: glocale and diffutils
+Status: RO
+
+*** EOOH ***
+From: eggert@twinsun.com (Paul Eggert)
+Date: 19 Nov 1994 14:00:59 -0800
+To: rms@gnu.ai.mit.edu (Richard Stallman)
+Cc: meyering@comco.com, pdcruze@orac.iinet.com.au
+Subject: Re: glocale and diffutils
+
+The Uniforum proposal addresses this problem by partitioning message
+catalogs into ``textdomains''. Each textdomain can be maintained
+separately. Programs can share textdomains. Messages in different
+textdomains cannot clash. With diffutils, for example, I would expect
+one textdomain for diffutils programs and another for libc. The main
+module would use the default textdomain and invoke `gettext ("No
+newline at end of file")' just as diffutils-2.7.1 does; libc modules
+would use a system textdomain and would invoke something like
+`dgettext ("SYS_libc", "No such file or directory")'.
+
+
+ \ No newline at end of file
diff --git a/doc/Admin/solaris.msgfmt b/doc/Admin/solaris.msgfmt
new file mode 100644
index 0000000..fc46c2d
--- /dev/null
+++ b/doc/Admin/solaris.msgfmt
@@ -0,0 +1,21 @@
+talisker% /usr/bin/msgfmt -h
+usage: msgfmt [-v] [-o filename] [files ... ]
+
+
+talisker% /usr/bin/xgettext -h
+Usage: xgettext [-a [-x exclude-file]] [-jns][-c comment-tag]
+ [-d default-domain] [-m prefix] [-M suffix] [-p pathname] files ...
+ xgettext -h
+
+-a find ALL strings
+-c <comment-tag> get comments containing <flag>
+-d <default-domain> use <default-domain> for default domain
+-h Help
+-j update existing file with the current result
+-M <suffix> fill in msgstr with msgid<suffix>
+-m <prefix> fill in msgstr with <prefix>msgid
+-n line# file name and line number info in output
+-p <pathname> use <pathname> for output file directory
+-s generate sorted output files
+-x <exclude-file> exclude strings in file <exclude-file> from output
+- read stdin, use as a filter (input only)
diff --git a/doc/ChangeLog b/doc/ChangeLog
new file mode 100644
index 0000000..3ec5712
--- /dev/null
+++ b/doc/ChangeLog
@@ -0,0 +1,426 @@
+2000-05-06 Ulrich Drepper <drepper@redhat.com>
+
+ * nls.texi: Add section about "Using gettext in own code".
+
+1999-10-11 Ulrich Drepper <drepper@cygnus.com>
+
+ * gettext.texi: Fix use of @xref.
+
+1997-09-06 02:13 Ulrich Drepper <drepper@cygnus.com>
+
+ * gettext.texi: Fix names of autoconf macros now that they are in
+ automake.
+ File NLS is now named ABOUT-NLS.
+ Reported by Bruno Haible <haible@ilog.fr>.
+
+ * nls.texi: Better description of --with-included-gettext.
+
+1997-08-01 15:50 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Require version 1.2.
+
+1997-04-12 17:45 Ulrich Drepper <drepper@cygnus.com>
+
+ * mdate-sh: Update from libit version.
+
+ * mdate-sh: Handle ls output with file type in ls output is
+ starting with -.
+
+1997-04-05 18:14 Ulrich Drepper <drepper@cygnus.com>
+
+ * mdate-sh: Use ls command with -d so that we also can handle
+ directories. Patch by Bruno Haible.
+
+1997-03-11 16:24 Ulrich Drepper <drepper@cygnus.com>
+
+ * nls.texi: Don't mention removed translation teams anymore.
+
+Sat Dec 7 17:53:26 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * gettext.texi: We don't need the hack for getting the cedille
+ character anymore.
+
+Tue Dec 3 15:46:09 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.am (EXTRA_DIST): texinfo.tex is now automatically
+ distributed.
+
+Sun Aug 18 16:55:02 1996 Ulrich Drepper <drepper@myware.rz.uni-karlsruhe.de>
+
+ * nls.texi: Set STATUS to August.
+
+Mon Jun 17 02:29:15 1996 Ulrich Drepper <drepper@myware.rz.uni-karlsruhe.de>
+
+ * gettext.texi: More small fixes.
+
+Sat Jun 15 16:55:00 1996 Ulrich Drepper <drepper@myware.rz.uni-karlsruhe.de>
+
+ * nls.texi, gettext.texi: Some better words by François Pinard.
+
+Fri Jun 14 18:47:23 1996 Santiago Vila Doncel <sanvila@unex.es>
+
+ * gettext.texi: Correct a few typos.
+
+Tue Jun 11 19:31:16 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * gettext.texi: A few corrections by Thomas Esken.
+
+Tue Jun 11 15:29:56 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Add variable. Must be defined
+ in all subdirs.
+
+Tue Jun 4 03:43:17 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * gettext.texi:
+ Tons of changes. A first step for a real, uptodate manual.
+
+Sun Jun 2 21:21:18 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * iso-apdx.sed, Makefile.am, ISO_639: Initial revision.
+
+Sun May 26 18:21:25 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * nls.texi: Add Arabic.
+
+Fri May 24 18:24:56 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * nls.texi: Add Ukrainian.
+
+Tue May 21 14:25:02 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * nls.texi: Fix typo: outself -> ourself.
+
+ * nls.texi: Correct Indonesian.
+ Add Slovenian and Hungarian.
+
+Sun May 19 15:08:24 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * nls.texi: Update language list. Add Hebrew and Latin.
+
+Sat May 4 00:41:17 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * nls.texi: Rewording by François Pinard.
+
+ * nls.texi: Change explicitely' to `explicitly'. By François Pinard.
+
+Fri May 3 17:21:48 1996 Ulrich Drepper <drepper@cygnus.com>
+
+ * matrix.texi: 9605031921
+
+Wed Apr 10 22:04:29 1996 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: matrix.texi now contains table commands.
+
+ * matrix.texi: Update for 960410.
+
+Wed Apr 10 21:58:17 1996 François Pinard <pinard@iro.umontreal.ca>
+
+ * nls.texi: Add Korean to list of languages.
+
+Tue Apr 9 23:28:08 1996 François Pinard <pinard@iro.umontreal.ca>
+
+ * nls.texi: Some better words.
+
+Sat Apr 6 11:13:18 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Add matrix.texi. Reported by François
+ Pinard.
+
+Wed Apr 3 23:40:29 1996 François Pinard <pinard@iro.umontreal.ca>
+
+ * nls.texi: Correct typo: ones -> one.
+
+Tue Apr 2 18:53:01 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (all-gettext): New goal. Same as all.
+
+Tue Apr 2 16:13:11 1996 Ulrich Drepper <drepper@myware>
+
+ * nls.texi:
+ Document change in aclocal.m4. Describe --with-catgets option.
+
+Mon Mar 25 23:21:49 1996 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Append iso-apdx.sed, ISO_639,
+ iso-apdx.texi.
+ (gettext.info, gettext.dvi): Depend on iso-apdx.texi.
+ (iso-apdx.texi): New rules. Create file from ISO_639.
+
+Mon Mar 25 02:55:23 1996 François Pinard <pinard@iro.umontreal.ca>
+
+ * gettext.texi: Latest update of PO mode documentation.
+
+Sat Mar 23 14:07:57 1996 François Pinard <pinard@iro.umontreal.ca>
+
+ * gettext.texi: Added changes concerning PO mode changes.
+
+Sat Mar 23 13:46:49 1996 Frank Donahoe <fdonahoe@wilkes1.wilkes.edu>
+
+ * gettext.texi: Fixed many problems with the English language.
+
+Wed Mar 13 21:06:17 1996 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: Changed gnu-translation@prep to gnu-translation@gnu.
+ Suggested by Franc,ois Pinard.
+
+Fri Mar 1 23:46:28 1996 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: STATUS is 1996, not 1995.
+
+Thu Feb 15 03:45:30 1996 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Update documentation for
+ - `--force' option
+ - `-d -' option
+ - new intl/po subdir handling
+
+Mon Feb 12 01:33:49 1996 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: STATUS is January.
+
+ * nls.texi: Omitted pl at lower side.
+
+ * nls.texi: Add pl for gettext to matrix.
+
+Fri Dec 29 14:00:17 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: Incorporate some improvements by Franc,ois Pinard.
+
+Sun Dec 24 14:30:49 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: Small corrections.
+ Updte table for ko translation of gettext.
+
+Tue Dec 19 22:13:40 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (Makefile): Explicitly use $(SHELL) for running
+ shell scripts.
+
+Fri Dec 15 19:34:50 1995 Karl Eichwalder <ke@ke.central.de>
+
+ * gettext.texi: Correct list of needed macros form aclocal.m4.
+
+Mon Dec 4 16:19:29 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi (STATUS): Set to November.
+
+Mon Dec 4 16:14:18 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: Update matrix for official release.
+
+Sun Nov 26 01:22:07 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Fix some typos.
+
+Sat Nov 25 02:45:46 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (version.texi): Also depend on ../configure.in.
+
+Thu Nov 23 01:26:35 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi:
+ Change README.NLS to ABOUT-NLS. Reported by Franc,ois Pinard.
+
+Tue Nov 14 12:43:22 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: Mention Japanese translation for shar in table.
+
+Thu Nov 9 01:14:49 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi:
+ Document new option --directory and --files-from of xgettext program.
+
+Tue Nov 7 10:54:43 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi: CLISP now uses GNU gettext.
+
+Mon Nov 6 17:05:39 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in: Some more cleanups by Franc,ois Pinard.
+
+Mon Nov 6 00:36:37 1995 Ulrich Drepper <drepper@>
+
+ * nls.texi: Add comment about problems with systems which have GNU
+ gettext previously installed.
+
+Sun Nov 5 21:56:51 1995 Ulrich Drepper <drepper@myware>
+
+ * nls.texi:
+ Advise about always using GNU gettext moved to here from ../README.
+
+ * gettext.texi: Fix some typos reported by Franc,ois Pinard.
+ In descripton of _N change the name to N_.
+
+ * Makefile.in (gettext.info):
+ Remove old .info* files before generating new ones.
+ (stamp-vti): Remove old stamp before generating new one.
+
+Sun Nov 5 19:40:11 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (dist-gettext): Make synonym for dist.
+
+Sun Nov 5 17:59:31 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Add nls.texi.
+
+ * nls.texi: Initial revision.
+
+ * gettext.texi: Protect RFC and number by @w.
+
+Sun Nov 5 11:38:00 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (dist): Suppress error message when ln failed.
+ Remove Emacs local variable definition.
+ (dist): Get files from $(srcdir) explicitly.
+
+ * gettext.texi: Add some comments about gettext_noop and _N.
+ Describe defaults keywords for -k option of xgettext.
+
+Fri Nov 3 00:20:35 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Some small changes by Franc,ois.
+
+Sat Oct 28 23:26:28 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi:
+ Add warning about language changing and not using GNU gettext library.
+
+Sat Oct 28 17:15:07 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Run spell checker. :-) It was necessary.
+
+ * gettext.texi: Document usage of libintl in other programs.
+ Describe changing of language in programs.
+
+Sun Sep 17 23:16:16 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Remove references to ISO 639 in description of
+ locale variable settings.
+
+Wed Aug 23 20:49:57 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Applied Franc,ois' patch from 950821.
+
+Sat Aug 19 17:41:06 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in: Make only install-data depend on `all'.
+
+ * Makefile.in (install-src):
+ Make behave like install. I.e. really install the manual.
+
+Fri Aug 18 12:33:43 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Changes of 950817 by Franc,ois Pinard.
+
+Mon Aug 14 23:52:20 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-src): New no-op goal.
+
+Tue Aug 8 01:39:45 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi:
+ Add description of dcgettext() optimization for gcc-2.7.
+
+Fri Aug 4 15:47:10 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (dist): Remove `copying instead' message.
+
+Tue Aug 1 15:58:17 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Some typos fixed. Email address update for Eugene
+ H. Dorr. By Franc,ois Pinard.
+
+ * Makefile.in (stamp-vti):
+ Use $(SHELL) and make compilation offside $(srcdir) possible.
+
+Tue Aug 1 08:51:30 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (install-data): Use sed instead of expr to get basename.
+
+Sun Jul 30 22:17:14 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Minor corrections to menus and typos by Franc,ois.
+ Some more words about LIBS rule in src/Makefile.in.
+ PO mode file is now installed automatically.
+
+Wed Jul 26 01:00:11 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi:
+ Includes latest of Franc,ois' changes for the maintainer chapter.
+ Many little changes and addons.
+
+Mon Jul 24 00:51:38 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Typo changes by Franc,ois.
+ Added section about special cases in translatable strings.
+ Added section about changing Makefiles for Maintainers.
+ Various minor addons.
+
+Wed Jul 19 02:05:45 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi:
+ Fix typo: keywoards -> keywords. Reported by Franc,ois Pinard.
+
+ * gettext.texi:
+ Franc,ois added description of the last changes in Emacs PO mode
+ which allow marking translatable strings in C sources.
+
+Tue Jul 18 21:25:44 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): Now we have again gettext.info-[1-4].
+
+ * gettext.texi (Comparison):
+ Some points on comparing catgets vs. gettext are written.
+
+Mon Jul 17 01:03:49 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi: Typo fixed. Reported by Franc,ois Pinard.
+
+Sun Jul 16 13:25:05 1995 Ulrich Drepper <drepper@myware>
+
+ * gettext.texi:
+ Latest version for 0.7.4. Changes all by Franc,ois Pinard.
+
+Sun Jul 16 00:17:28 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES):
+ With the current makeinfo (1.63) there are only gettext.info-[123]
+ produced. Remove gettext.info-4. Reported by Erik Backus.
+
+Thu Jul 13 01:41:14 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (check): New no-op goal.
+
+ * gettext.texi: Version of 950712 by Franc,ois.
+
+Wed Jul 12 00:32:58 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): now we have gettext.info{,-[1-4]}
+
+ * gettext.texi: First version after rewrite by Franc,ois Pinard.
+
+Mon Jul 3 23:36:25 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in: Correct for new manual with NLS and po-mode chapter.
+ Do construct po-mode.{texi,dvi} use nls.texi.
+ Last correction on install goal was wrong.
+ Correct installation and unistallation rules.
+
+ * gettext.texi: Version with po-mode and NLS chapter.
+ Minor changes by Franc,ois.
+
+ * gettext.texi: Make NLS part an include file.
+
+Sun Jul 2 12:32:37 1995 Ulrich Drepper <drepper@myware>
+
+ * Makefile.in (DISTFILES): fix typo.
+
+ * gettext.texi: some more things written about using GNU gettext
+ in own projects.
+
+Sun Jul 2 01:47:02 1995 Ulrich Drepper <drepper@myware>
+
+ * First official release. This directory now contains a very
+ preliminary version of the gettext manual with a quite complete
+ chapter for todays Emacs PO mode by Franc,ois Pinard.
diff --git a/doc/ISO_639 b/doc/ISO_639
new file mode 100644
index 0000000..c90684f
--- /dev/null
+++ b/doc/ISO_639
@@ -0,0 +1,180 @@
+Technical contents of ISO 639:1988 (E/F)
+"Code for the representation of names of languages".
+
+Typed by Keld.Simonsen@dkuug.dk 1990-11-30
+Minor corrections, 1992-09-08 by Keld Simonsen
+Sundanese corrected, 1992-11-11 by Keld Simonsen
+Telugu corrected, 1995-08-24 by Keld Simonsen
+Hebrew, Indonesian, Yiddish corrected 1995-10-10 by Michael Everson
+Inuktitut, Uighur, Zhuang added 1995-10-10 by Michael Everson
+Sinhalese corrected, 1995-10-10 by Michael Everson
+Faeroese corrected to Faroese, 1995-11-18 by Keld Simonsen
+
+Two-letter lower-case symbols are used.
+The Registration Authority for ISO 639 is Infoterm, Osterreichisches
+Normungsinstitut (ON), Postfach 130, A-1021 Vienna, Austria.
+
+aa Afar
+ab Abkhazian
+af Afrikaans
+am Amharic
+ar Arabic
+as Assamese
+ay Aymara
+az Azerbaijani
+
+ba Bashkir
+be Byelorussian
+bg Bulgarian
+bh Bihari
+bi Bislama
+bn Bengali; Bangla
+bo Tibetan
+br Breton
+
+ca Catalan
+co Corsican
+cs Czech
+cy Welsh
+
+da Danish
+de German
+dz Bhutani
+
+el Greek
+en English
+eo Esperanto
+es Spanish
+et Estonian
+eu Basque
+
+fa Persian
+fi Finnish
+fj Fiji
+fo Faroese
+fr French
+fy Frisian
+
+ga Irish
+gd Scots Gaelic
+gl Galician
+gn Guarani
+gu Gujarati
+
+ha Hausa
+he Hebrew (formerly iw)
+hi Hindi
+hr Croatian
+hu Hungarian
+hy Armenian
+
+ia Interlingua
+id Indonesian (formerly in)
+ie Interlingue
+ik Inupiak
+is Icelandic
+it Italian
+iu Inuktitut
+
+ja Japanese
+jw Javanese
+
+ka Georgian
+kk Kazakh
+kl Greenlandic
+km Cambodian
+kn Kannada
+ko Korean
+ks Kashmiri
+ku Kurdish
+ky Kirghiz
+
+la Latin
+ln Lingala
+lo Laothian
+lt Lithuanian
+lv Latvian, Lettish
+
+mg Malagasy
+mi Maori
+mk Macedonian
+ml Malayalam
+mn Mongolian
+mo Moldavian
+mr Marathi
+ms Malay
+mt Maltese
+my Burmese
+
+na Nauru
+ne Nepali
+nl Dutch
+no Norwegian
+
+oc Occitan
+om (Afan) Oromo
+or Oriya
+
+pa Punjabi
+pl Polish
+ps Pashto, Pushto
+pt Portuguese
+
+qu Quechua
+
+rm Rhaeto-Romance
+rn Kirundi
+ro Romanian
+ru Russian
+rw Kinyarwanda
+
+sa Sanskrit
+sd Sindhi
+sg Sangro
+sh Serbo-Croatian
+si Sinhalese
+sk Slovak
+sl Slovenian
+sm Samoan
+sn Shona
+so Somali
+sq Albanian
+sr Serbian
+ss Siswati
+st Sesotho
+su Sundanese
+sv Swedish
+sw Swahili
+
+ta Tamil
+te Telugu
+tg Tajik
+th Thai
+ti Tigrinya
+tk Turkmen
+tl Tagalog
+tn Setswana
+to Tonga
+tr Turkish
+ts Tsonga
+tt Tatar
+tw Twi
+
+ug Uighur
+uk Ukrainian
+ur Urdu
+uz Uzbek
+
+vi Vietnamese
+vo Volapuk
+
+wo Wolof
+
+xh Xhosa
+
+yi Yiddish (formerly ji)
+yo Yoruba
+
+za Zhuang
+zh Chinese
+zu Zulu
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..661c978
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,32 @@
+## Makefile for the doc subdirectory of the GNU NLS Utilities
+## Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.2 gnits
+
+SED = sed
+
+info_TEXINFOS = gettext.texi
+gettext_TEXINFOS = iso-apdx.texi
+
+EXTRA_DIST = iso-apdx.sed ISO_639 nls.texi matrix.texi
+
+iso-apdx.texi: ISO_639 iso-apdx.sed
+ $(SED) -f $(srcdir)/iso-apdx.sed $(srcdir)/ISO_639 > iso-apdx.tmp
+ rm -f $(srcdir)/iso-apdx.texi
+ mv iso-apdx.tmp $(srcdir)/iso-apdx.texi
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..509f1fd
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,370 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+ACLOCAL_VERSION = @ACLOCAL_VERSION@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EMACS = @EMACS@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+YACC = @YACC@
+aclocaldir = @aclocaldir@
+l = @l@
+lispdir = @lispdir@
+
+AUTOMAKE_OPTIONS = 1.2 gnits
+
+SED = sed
+
+info_TEXINFOS = gettext.texi
+gettext_TEXINFOS = iso-apdx.texi
+
+EXTRA_DIST = iso-apdx.sed ISO_639 nls.texi matrix.texi
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+TEXI2DVI = texi2dvi
+INFO_DEPS = gettext.info
+DVIS = gettext.dvi
+TEXINFOS = gettext.texi
+DIST_COMMON = $(gettext_TEXINFOS) ChangeLog Makefile.am Makefile.in \
+mdate-sh stamp-vti texinfo.tex version.texi
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .dvi .info .ps .texi .texinfo .txi
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnits doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+$(srcdir)/version.texi: stamp-vti
+ @:
+
+$(srcdir)/stamp-vti: gettext.texi $(top_srcdir)/configure.in
+ @echo "@set UPDATED `$(SHELL) $(srcdir)/mdate-sh $(srcdir)/gettext.texi`" > vti.tmp
+ @echo "@set EDITION $(VERSION)" >> vti.tmp
+ @echo "@set VERSION $(VERSION)" >> vti.tmp
+ @cmp -s vti.tmp $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi"; \
+ cp vti.tmp $(srcdir)/version.texi)
+ -@rm -f vti.tmp
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp
+
+clean-vti:
+
+distclean-vti:
+
+maintainer-clean-vti:
+ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+
+gettext.info: gettext.texi version.texi $(gettext_TEXINFOS)
+gettext.dvi: gettext.texi version.texi $(gettext_TEXINFOS)
+
+
+DVIPS = dvips
+
+.texi.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texi.dvi:
+ TEXINPUTS=.:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.dvi:
+ TEXINPUTS=.:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi.info:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.txi.dvi:
+ TEXINPUTS=.:$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.txi:
+ @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ d=$(srcdir); \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
+ install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ test -z "$ii" \
+ || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
+ done
+ @$(NORMAL_UNINSTALL)
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ d=$(srcdir); \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -f gettext.aux gettext.cp gettext.cps gettext.dvi gettext.fn \
+ gettext.fns gettext.ky gettext.kys gettext.ps gettext.log \
+ gettext.pg gettext.toc gettext.tp gettext.tps gettext.vr \
+ gettext.vrs gettext.op gettext.tr gettext.cv gettext.cn
+
+clean-aminfo:
+
+distclean-aminfo:
+
+maintainer-clean-aminfo:
+ cd $(srcdir) && for i in $(INFO_DEPS); do \
+ rm -f $$i; \
+ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
+ rm -f $$i-[0-9]*; \
+ fi; \
+ done
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnits doc/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
+info-am: $(INFO_DEPS)
+info: info-am
+dvi-am: $(DVIS)
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am: install-info-am
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-info
+uninstall: uninstall-am
+all-am: Makefile $(INFO_DEPS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(infodir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-vti mostlyclean-aminfo mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-vti clean-aminfo clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-vti distclean-aminfo distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-vti maintainer-clean-aminfo \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-vti distclean-vti clean-vti maintainer-clean-vti \
+install-info-am uninstall-info mostlyclean-aminfo distclean-aminfo \
+clean-aminfo maintainer-clean-aminfo tags distdir info-am info dvi-am \
+dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+iso-apdx.texi: ISO_639 iso-apdx.sed
+ $(SED) -f $(srcdir)/iso-apdx.sed $(srcdir)/ISO_639 > iso-apdx.tmp
+ rm -f $(srcdir)/iso-apdx.texi
+ mv iso-apdx.tmp $(srcdir)/iso-apdx.texi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/gettext.info b/doc/gettext.info
new file mode 100644
index 0000000..51af348
--- /dev/null
+++ b/doc/gettext.info
@@ -0,0 +1,126 @@
+This is Info file gettext.info, produced by Makeinfo version 1.68 from
+the input file gettext.texi.
+
+INFO-DIR-SECTION GNU Gettext Utilities
+START-INFO-DIR-ENTRY
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+END-INFO-DIR-ENTRY
+
+ This file provides documentation for GNU `gettext' utilities. It
+also serves as a reference for the free Translation Project.
+
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+Indirect:
+gettext.info-1: 1431
+gettext.info-2: 48351
+gettext.info-3: 95765
+gettext.info-4: 145601
+gettext.info-5: 195230
+
+Tag Table:
+(Indirect)
+Node: Top1431
+Node: Introduction6625
+Node: Why8481
+Node: Concepts11727
+Node: Aspects15140
+Node: Files21196
+Node: Overview23464
+Node: Basics34088
+Node: Installation34918
+Node: PO Files36652
+Node: Main PO Commands43407
+Node: Entry Positioning48351
+Node: Normalizing53603
+Node: Sources58055
+Node: Triggering59326
+Node: Mark Keywords61682
+Node: Marking65232
+Node: c-format72873
+Node: Special cases76624
+Node: Initial79487
+Node: xgettext Invocation79809
+Node: C Sources Context83036
+Node: Compendium88015
+Node: Updating88718
+Node: msgmerge Invocation89358
+Node: Translated Entries89532
+Node: Fuzzy Entries90824
+Node: Untranslated Entries93926
+Node: Obsolete Entries95765
+Node: Modifying Translations98897
+Node: Modifying Comments106715
+Node: Subedit111022
+Node: Auxiliary114800
+Node: Binaries117870
+Node: msgfmt Invocation118134
+Node: MO Files120761
+Node: Users128173
+Node: Matrix129654
+Node: Installers130857
+Node: End Users132045
+Node: Programmers132674
+Node: catgets133848
+Node: Interface to catgets135253
+Node: Problems with catgets137254
+Node: gettext138152
+Node: Interface to gettext139393
+Node: Ambiguities141735
+Node: Locating Catalogs144292
+Node: Optimized gettext145601
+Node: Comparison149189
+Node: Using libintl.a154904
+Node: gettext grok155675
+Node: Temp Programmers158534
+Node: Temp Implementations158974
+Node: Temp catgets160340
+Node: Temp WSI162027
+Node: Temp Notes164015
+Node: Translators164504
+Node: Trans Intro 0164883
+Node: Trans Intro 1167532
+Node: Discussions169396
+Node: Organization172551
+Node: Central Coordination174532
+Node: National Teams175660
+Node: Sub-Cultures178172
+Node: Organizational Ideas179091
+Node: Mailing Lists180093
+Node: Information Flow181896
+Node: Maintainers184029
+Node: Flat and Non-Flat185789
+Node: Prerequisites187550
+Node: gettextize Invocation191658
+Node: Adjusting Files195230
+Node: po/POTFILES.in196453
+Node: configure.in197394
+Node: aclocal199521
+Node: acconfig200700
+Node: Makefile201314
+Node: src/Makefile203502
+Node: Conclusion205899
+Node: History206388
+Node: References209848
+Node: Country Codes211403
+
+End Tag Table
diff --git a/doc/gettext.info-1 b/doc/gettext.info-1
new file mode 100644
index 0000000..2718d25
--- /dev/null
+++ b/doc/gettext.info-1
@@ -0,0 +1,999 @@
+This is Info file gettext.info, produced by Makeinfo version 1.68 from
+the input file gettext.texi.
+
+INFO-DIR-SECTION GNU Gettext Utilities
+START-INFO-DIR-ENTRY
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+END-INFO-DIR-ENTRY
+
+ This file provides documentation for GNU `gettext' utilities. It
+also serves as a reference for the free Translation Project.
+
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: gettext.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir)
+
+GNU `gettext' utilities
+***********************
+
+* Menu:
+
+* Introduction:: Introduction
+* Basics:: PO Files and PO Mode Basics
+* Sources:: Preparing Program Sources
+* Initial:: Making the Initial PO File
+* Updating:: Updating Existing PO Files
+* Binaries:: Producing Binary MO Files
+* Users:: The User's View
+* Programmers:: The Programmer's View
+* Translators:: The Translator's View
+* Maintainers:: The Maintainer's View
+* Conclusion:: Concluding Remarks
+
+* Country Codes:: ISO 639 country codes
+
+ -- The Detailed Node Listing --
+
+Introduction
+
+* Why:: The Purpose of GNU `gettext'
+* Concepts:: I18n, L10n, and Such
+* Aspects:: Aspects in Native Language Support
+* Files:: Files Conveying Translations
+* Overview:: Overview of GNU `gettext'
+
+PO Files and PO Mode Basics
+
+* Installation:: Completing GNU `gettext' Installation
+* PO Files:: The Format of PO Files
+* Main PO Commands:: Main Commands
+* Entry Positioning:: Entry Positioning
+* Normalizing:: Normalizing Strings in Entries
+
+Preparing Program Sources
+
+* Triggering:: Triggering `gettext' Operations
+* Mark Keywords:: How Marks Appears in Sources
+* Marking:: Marking Translatable Strings
+* c-format:: Telling something about the following string
+* Special cases:: Special Cases of Translatable Strings
+
+Making the Initial PO File
+
+* xgettext Invocation:: Invoking the `xgettext' Program
+* C Sources Context:: C Sources Context
+* Compendium:: Using Translation Compendiums
+
+Updating Existing PO Files
+
+* msgmerge Invocation:: Invoking the `msgmerge' Program
+* Translated Entries:: Translated Entries
+* Fuzzy Entries:: Fuzzy Entries
+* Untranslated Entries:: Untranslated Entries
+* Obsolete Entries:: Obsolete Entries
+* Modifying Translations:: Modifying Translations
+* Modifying Comments:: Modifying Comments
+* Auxiliary:: Consulting Auxiliary PO Files
+
+Producing Binary MO Files
+
+* msgfmt Invocation:: Invoking the `msgfmt' Program
+* MO Files:: The Format of GNU MO Files
+
+The User's View
+
+* Matrix:: The Current `ABOUT-NLS' Matrix
+* Installers:: Magic for Installers
+* End Users:: Magic for End Users
+
+The Programmer's View
+
+* catgets:: About `catgets'
+* gettext:: About `gettext'
+* Comparison:: Comparing the two interfaces
+* Using libintl.a:: Using libintl.a in own programs
+* gettext grok:: Being a `gettext' grok
+* Temp Programmers:: Temporary Notes for the Programmers Chapter
+
+About `catgets'
+
+* Interface to catgets:: The interface
+* Problems with catgets:: Problems with the `catgets' interface?!
+
+About `gettext'
+
+* Interface to gettext:: The interface
+* Ambiguities:: Solving ambiguities
+* Locating Catalogs:: Locating message catalog files
+* Optimized gettext:: Optimization of the *gettext functions
+
+Temporary Notes for the Programmers Chapter
+
+* Temp Implementations:: Temporary - Two Possible Implementations
+* Temp catgets:: Temporary - About `catgets'
+* Temp WSI:: Temporary - Why a single implementation
+* Temp Notes:: Temporary - Notes
+
+The Translator's View
+
+* Trans Intro 0:: Introduction 0
+* Trans Intro 1:: Introduction 1
+* Discussions:: Discussions
+* Organization:: Organization
+* Information Flow:: Information Flow
+
+Organization
+
+* Central Coordination:: Central Coordination
+* National Teams:: National Teams
+* Mailing Lists:: Mailing Lists
+
+National Teams
+
+* Sub-Cultures:: Sub-Cultures
+* Organizational Ideas:: Organizational Ideas
+
+The Maintainer's View
+
+* Flat and Non-Flat:: Flat or Non-Flat Directory Structures
+* Prerequisites:: Prerequisite Works
+* gettextize Invocation:: Invoking the `gettextize' Program
+* Adjusting Files:: Files You Must Create or Alter
+
+Files You Must Create or Alter
+
+* po/POTFILES.in:: `POTFILES.in' in `po/'
+* configure.in:: `configure.in' at top level
+* aclocal:: `aclocal.m4' at top level
+* acconfig:: `acconfig.h' at top level
+* Makefile:: `Makefile.in' at top level
+* src/Makefile:: `Makefile.in' in `src/'
+
+Concluding Remarks
+
+* History:: History of GNU `gettext'
+* References:: Related Readings
+
+
+File: gettext.info, Node: Introduction, Next: Basics, Prev: Top, Up: Top
+
+Introduction
+************
+
+ This manual is still in *DRAFT* state. Some sections are still
+ empty, or almost. We keep merging material from other sources
+ (essentially e-mail folders) while the proper integration of this
+ material is delayed.
+
+ In this manual, we use *he* when speaking of the programmer or
+maintainer, *she* when speaking of the translator, and *they* when
+speaking of the installers or end users of the translated program.
+This is only a convenience for clarifying the documentation. It is
+*absolutely* not meant to imply that some roles are more appropriate to
+males or females. Besides, as you might guess, GNU `gettext' is meant
+to be useful for people using computers, whatever their sex, race,
+religion or nationality!
+
+ This chapter explains the goals sought in the creation of GNU
+`gettext' and the free Translation Project. Then, it explains a few
+broad concepts around Native Language Support, and positions message
+translation with regard to other aspects of national and cultural
+variance, as they apply to to programs. It also surveys those files
+used to convey the translations. It explains how the various tools
+interact in the initial generation of these files, and later, how the
+maintenance cycle should usually operate.
+
+ Please send suggestions and corrections to:
+
+ Internet address:
+ bug-gnu-utils@gnu.org
+
+Please include the manual's edition number and update date in your
+messages.
+
+* Menu:
+
+* Why:: The Purpose of GNU `gettext'
+* Concepts:: I18n, L10n, and Such
+* Aspects:: Aspects in Native Language Support
+* Files:: Files Conveying Translations
+* Overview:: Overview of GNU `gettext'
+
+
+File: gettext.info, Node: Why, Next: Concepts, Prev: Introduction, Up: Introduction
+
+The Purpose of GNU `gettext'
+============================
+
+ Usually, programs are written and documented in English, and use
+English at execution time to interact with users. This is true not
+only of GNU software, but also of a great deal of commercial and free
+software. Using a common language is quite handy for communication
+between developers, maintainers and users from all countries. On the
+other hand, most people are less comfortable with English than with
+their own native language, and would prefer to use their mother tongue
+for day to day's work, as far as possible. Many would simply *love* to
+see their computer screen showing a lot less of English, and far more
+of their own language.
+
+ However, to many people, this dream might appear so far fetched that
+they may believe it is not even worth spending time thinking about it.
+They have no confidence at all that the dream might ever become true.
+Yet some have not lost hope, and have organized themselves. The
+Translation Project is a formalization of this hope into a workable
+structure, which has a good chance to get all of us nearer the
+achievement of a truly multi-lingual set of programs.
+
+ GNU `gettext' is an important step for the Translation Project, as
+it is an asset on which we may build many other steps. This package
+offers to programmers, translators and even users, a well integrated
+set of tools and documentation. Specifically, the GNU `gettext'
+utilities are a set of tools that provides a framework within which
+other free packages may produce multi-lingual messages. These tools
+include a set of conventions about how programs should be written to
+support message catalogs, a directory and file naming organization for
+the message catalogs themselves, a runtime library supporting the
+retrieval of translated messages, and a few stand-alone programs to
+massage in various ways the sets of translatable strings, or already
+translated strings. A special mode for Emacs(1) also helps ease
+interested parties into preparing these sets, or bringing them up to
+date.
+
+ GNU `gettext' is designed to minimize the impact of
+internationalization on program sources, keeping this impact as small
+and hardly noticeable as possible. Internationalization has better
+chances of succeeding if it is very light weighted, or at least, appear
+to be so, when looking at program sources.
+
+ The Translation Project also uses the GNU `gettext' distribution as
+a vehicle for documenting its structure and methods. This goes beyond
+the strict technicalities of documenting the GNU `gettext' proper. By
+so doing, translators will find in a single place, as far as possible,
+all they need to know for properly doing their translating work. Also,
+this supplemental documentation might also help programmers, and even
+curious users, in understanding how GNU `gettext' is related to the
+remainder of the Translation Project, and consequently, have a glimpse
+at the *big picture*.
+
+ ---------- Footnotes ----------
+
+ (1) In this manual, all mentions of Emacs refers to either GNU Emacs
+or to XEmacs, which people sometimes call FSF Emacs and Lucid Emacs,
+respectively.
+
+
+File: gettext.info, Node: Concepts, Next: Aspects, Prev: Why, Up: Introduction
+
+I18n, L10n, and Such
+====================
+
+ Two long words appear all the time when we discuss support of native
+language in programs, and these words have a precise meaning, worth
+being explained here, once and for all in this document. The words are
+*internationalization* and *localization*. Many people, tired of
+writing these long words over and over again, took the habit of writing
+"i18n" and "l10n" instead, quoting the first and last letter of each
+word, and replacing the run of intermediate letters by a number merely
+telling how many such letters there are. But in this manual, in the
+sake of clarity, we will patiently write the names in full, each time...
+
+ By "internationalization", one refers to the operation by which a
+program, or a set of programs turned into a package, is made aware of
+and able to support multiple languages. This is a generalization
+process, by which the programs are untied from calling only English
+strings or other English specific habits, and connected to generic ways
+of doing the same, instead. Program developers may use various
+techniques to internationalize their programs. Some of these have been
+standardized. GNU `gettext' offers one of these standards. *Note
+Programmers::.
+
+ By "localization", one means the operation by which, in a set of
+programs already internationalized, one gives the program all needed
+information so that it can adapt itself to handle its input and output
+in a fashion which is correct for some native language and cultural
+habits. This is a particularisation process, by which generic methods
+already implemented in an internationalized program are used in
+specific ways. The programming environment puts several functions to
+the programmers disposal which allow this runtime configuration. The
+formal description of specific set of cultural habits for some country,
+together with all associated translations targeted to the same native
+language, is called the "locale" for this language or country. Users
+achieve localization of programs by setting proper values to special
+environment variables, prior to executing those programs, identifying
+which locale should be used.
+
+ In fact, locale message support is only one component of the cultural
+data that makes up a particular locale. There are a whole host of
+routines and functions provided to aid programmers in developing
+internationalized software and which allow them to access the data
+stored in a particular locale. When someone presently refers to a
+particular locale, they are obviously referring to the data stored
+within that particular locale. Similarly, if a programmer is referring
+to "accessing the locale routines", they are referring to the complete
+suite of routines that access all of the locale's information.
+
+ One uses the expression "Native Language Support", or merely NLS,
+for speaking of the overall activity or feature encompassing both
+internationalization and localization, allowing for multi-lingual
+interactions in a program. In a nutshell, one could say that
+internationalization is the operation by which further localizations
+are made possible.
+
+ Also, very roughly said, when it comes to multi-lingual messages,
+internationalization is usually taken care of by programmers, and
+localization is usually taken care of by translators.
+
+
+File: gettext.info, Node: Aspects, Next: Files, Prev: Concepts, Up: Introduction
+
+Aspects in Native Language Support
+==================================
+
+ For a totally multi-lingual distribution, there are many things to
+translate beyond output messages.
+
+ * As of today, GNU `gettext' offers a complete toolset for
+ translating messages output by C programs. Perl scripts and shell
+ scripts will also need to be translated. Even if there are today
+ some hooks by which this can be done, these hooks are not
+ integrated as well as they should be.
+
+ * Some programs, like `autoconf' or `bison', are able to produce
+ other programs (or scripts). Even if the generating programs
+ themselves are internationalized, the generated programs they
+ produce may need internationalization on their own, and this
+ indirect internationalization could be automated right from the
+ generating program. In fact, quite usually, generating and
+ generated programs could be internationalized independently, as
+ the effort needed is fairly orthogonal.
+
+ * A few programs include textual tables which might need translation
+ themselves, independently of the strings contained in the program
+ itself. For example, RFC 1345 gives an English description for
+ each character which the `recode' program is able to reconstruct
+ at execution. Since these descriptions are extracted from the RFC
+ by mechanical means, translating them properly would require a
+ prior translation of the RFC itself.
+
+ * Almost all programs accept options, which are often worded out so
+ to be descriptive for the English readers; one might want to
+ consider offering translated versions for program options as well.
+
+ * Many programs read, interpret, compile, or are somewhat driven by
+ input files which are texts containing keywords, identifiers, or
+ replies which are inherently translatable. For example, one may
+ want `gcc' to allow diacriticized characters in identifiers or use
+ translated keywords; `rm -i' might accept something else than `y'
+ or `n' for replies, etc. Even if the program will eventually make
+ most of its output in the foreign languages, one has to decide
+ whether the input syntax, option values, etc., are to be localized
+ or not.
+
+ * The manual accompanying a package, as well as all documentation
+ files in the distribution, could surely be translated, too.
+ Translating a manual, with the intent of later keeping up with
+ updates, is a major undertaking in itself, generally.
+
+ As we already stressed, translation is only one aspect of locales.
+Other internationalization aspects are not currently handled by GNU
+`gettext', but perhaps may be handled in future versions. There are
+many attributes that are needed to define a country's cultural
+conventions. These attributes include beside the country's native
+language, the formatting of the date and time, the representation of
+numbers, the symbols for currency, etc. These local "rules" are termed
+the country's locale. The locale represents the knowledge needed to
+support the country's native attributes.
+
+ There are a few major areas which may vary between countries and
+hence, define what a locale must describe. The following list helps
+putting multi-lingual messages into the proper context of other tasks
+related to locales, and also presents some other areas which GNU
+`gettext' might eventually tackle, maybe, one of these days.
+
+*Characters and Codesets*
+ The codeset most commonly used through out the USA and most English
+ speaking parts of the world is the ASCII codeset. However, there
+ are many characters needed by various locales that are not found
+ within this codeset. The 8-bit ISO 8859-1 code set has most of
+ the special characters needed to handle the major European
+ languages. However, in many cases, the ISO 8859-1 font is not
+ adequate. Hence each locale will need to specify which codeset
+ they need to use and will need to have the appropriate character
+ handling routines to cope with the codeset.
+
+*Currency*
+ The symbols used vary from country to country as does the position
+ used by the symbol. Software needs to be able to transparently
+ display currency figures in the native mode for each locale.
+
+*Dates*
+ The format of date varies between locales. For example, Christmas
+ day in 1994 is written as 12/25/94 in the USA and as 25/12/94 in
+ Australia. Other countries might use ISO 8061 dates, etc.
+
+ Time of the day may be noted as HH:MM, HH.MM, or otherwise. Some
+ locales require time to be specified in 24-hour mode rather than
+ as AM or PM. Further, the nature and yearly extent of the
+ Daylight Saving correction vary widely between countries.
+
+*Numbers*
+ Numbers can be represented differently in different locales. For
+ example, the following numbers are all written correctly for their
+ respective locales:
+
+ 12,345.67 English
+ 12.345,67 French
+ 1,2345.67 Asia
+
+ Some programs could go further and use different unit systems, like
+ English units or Metric units, or even take into account variants
+ about how numbers are spelled in full.
+
+*Messages*
+ The most obvious area is the language support within a locale.
+ This is where GNU `gettext' provides the means for developers and
+ users to easily change the language that the software uses to
+ communicate to the user.
+
+ In the near future we see no chance that components of locale
+outside of message handling will be made available for use in other
+packages. The reason for this is that most modern systems provide a
+more or less reasonable support for at least some of the missing
+components. Another point is that the GNU `libc' and Linux will get a
+new and complete implementation of the whole locale functionality which
+could be adopted by system lacking a reasonable locale support.
+
+
+File: gettext.info, Node: Files, Next: Overview, Prev: Aspects, Up: Introduction
+
+Files Conveying Translations
+============================
+
+ The letters PO in `.po' files means Portable Object, to distinguish
+it from `.mo' files, where MO stands for Machine Object. This
+paradigm, as well as the PO file format, is inspired by the NLS
+standard developed by Uniforum, and implemented by Sun in their Solaris
+system.
+
+ PO files are meant to be read and edited by humans, and associate
+each original, translatable string of a given package with its
+translation in a particular target language. A single PO file is
+dedicated to a single target language. If a package supports many
+languages, there is one such PO file per language supported, and each
+package has its own set of PO files. These PO files are best created by
+the `xgettext' program, and later updated or refreshed through the
+`msgmerge' program. Program `xgettext' extracts all marked messages
+from a set of C files and initializes a PO file with empty
+translations. Program `msgmerge' takes care of adjusting PO files
+between releases of the corresponding sources, commenting obsolete
+entries, initializing new ones, and updating all source line
+references. Files ending with `.pot' are kind of base translation
+files found in distributions, in PO file format, and `.pox' files are
+often temporary PO files.
+
+ MO files are meant to be read by programs, and are binary in nature.
+A few systems already offer tools for creating and handling MO files as
+part of the Native Language Support coming with the system, but the
+format of these MO files is often different from system to system, and
+non-portable. They do not necessary use `.mo' for file extensions, but
+since system libraries are also used for accessing these files, it
+works as long as the system is self-consistent about it. If GNU
+`gettext' is able to interface with the tools already provided with
+systems, it will consequently let these provided tools take care of
+generating the MO files. Or else, if such tools are not found or do
+not seem usable, GNU `gettext' will use its own ways and its own format
+for MO files. Files ending with `.gmo' are really MO files, when it is
+known that these files use the GNU format.
+
+
+File: gettext.info, Node: Overview, Prev: Files, Up: Introduction
+
+Overview of GNU `gettext'
+=========================
+
+ The following diagram summarizes the relation between the files
+handled by GNU `gettext' and the tools acting on these files. It is
+followed by a somewhat detailed explanations, which you should read
+while keeping an eye on the diagram. Having a clear understanding of
+these interrelations would surely help programmers, translators and
+maintainers.
+
+ Original C Sources ---> PO mode ---> Marked C Sources ---.
+ |
+ .---------<--- GNU gettext Library |
+ .--- make <---+ |
+ | `---------<--------------------+-----------'
+ | |
+ | .-----<--- PACKAGE.pot <--- xgettext <---' .---<--- PO Compendium
+ | | | ^
+ | | `---. |
+ | `---. +---> PO mode ---.
+ | +----> msgmerge ------> LANG.pox --->--------' |
+ | .---' |
+ | | |
+ | `-------------<---------------. |
+ | +--- LANG.po <--- New LANG.pox <----'
+ | .--- LANG.gmo <--- msgfmt <---'
+ | |
+ | `---> install ---> /.../LANG/PACKAGE.mo ---.
+ | +---> "Hello world!"
+ `-------> install ---> /.../bin/PROGRAM -------'
+
+ The indication `PO mode' appears in two places in this picture, and
+you may safely read it as merely meaning "hand editing", using any
+editor of your choice, really. However, for those of you being the
+lucky users of Emacs, PO mode has been specifically created for
+providing a cozy environment for editing or modifying PO files. While
+editing a PO file, PO mode allows for the easy browsing of auxiliary
+and compendium PO files, as well as for following references into the
+set of C program sources from which PO files have been derived. It has
+a few special features, among which are the interactive marking of
+program strings as translatable, and the validatation of PO files with
+easy repositioning to PO file lines showing errors.
+
+ As a programmer, the first step to bringing GNU `gettext' into your
+package is identifying, right in the C sources, those strings which are
+meant to be translatable, and those which are untranslatable. This
+tedious job can be done a little more comfortably using emacs PO mode,
+but you can use any means familiar to you for modifying your C sources.
+Beside this some other simple, standard changes are needed to properly
+initialize the translation library. *Note Sources::, for more
+information about all this.
+
+ For newly written software the strings of course can and should be
+marked while writing the it. The `gettext' approach makes this very
+easy. Simply put the following lines at the beginning of each file or
+in a central header file:
+
+ #define _(String) (String)
+ #define N_(String) (String)
+ #define textdomain(Domain)
+ #define bindtextdomain(Package, Directory)
+
+Doing this allows you to prepare the sources for internationalization.
+Later when you feel ready for the step to use the `gettext' library
+simply remove these definitions, include `libintl.h' and link against
+`libintl.a'. That is all you have to change.
+
+ Once the C sources have been modified, the `xgettext' program is
+used to find and extract all translatable strings, and create an
+initial PO file out of all these. This `PACKAGE.pot' file contains all
+original program strings. It has sets of pointers to exactly where in
+C sources each string is used. All translations are set to empty. The
+letter `t' in `.pot' marks this as a Template PO file, not yet oriented
+towards any particular language. *Note xgettext Invocation::, for more
+details about how one calls the `xgettext' program. If you are
+*really* lazy, you might be interested at working a lot more right
+away, and preparing the whole distribution setup (*note
+Maintainers::.). By doing so, you spare yourself typing the `xgettext'
+command, as `make' should now generate the proper things automatically
+for you!
+
+ The first time through, there is no `LANG.po' yet, so the `msgmerge'
+step may be skipped and replaced by a mere copy of `PACKAGE.pot' to
+`LANG.pox', where LANG represents the target language.
+
+ Then comes the initial translation of messages. Translation in
+itself is a whole matter, still exclusively meant for humans, and whose
+complexity far overwhelms the level of this manual. Nevertheless, a
+few hints are given in some other chapter of this manual (*note
+Translators::.). You will also find there indications about how to
+contact translating teams, or becoming part of them, for sharing your
+translating concerns with others who target the same native language.
+
+ While adding the translated messages into the `LANG.pox' PO file, if
+you do not have Emacs handy, you are on your own for ensuring that your
+efforts fully respect the PO file format, and quoting conventions
+(*note PO Files::.). This is surely not an impossible task, as this is
+the way many people have handled PO files already for Uniforum or
+Solaris. On the other hand, by using PO mode in Emacs, most details of
+PO file format are taken care of for you, but you have to acquire some
+familiarity with PO mode itself. Besides main PO mode commands (*note
+Main PO Commands::.), you should know how to move between entries
+(*note Entry Positioning::.), and how to handle untranslated entries
+(*note Untranslated Entries::.).
+
+ If some common translations have already been saved into a compendium
+PO file, translators may use PO mode for initializing untranslated
+entries from the compendium, and also save selected translations into
+the compendium, updating it (*note Compendium::.). Compendium files
+are meant to be exchanged between members of a given translation team.
+
+ Programs, or packages of programs, are dynamic in nature: users write
+bug reports and suggestion for improvements, maintainers react by
+modifying programs in various ways. The fact that a package has
+already been internationalized should not make maintainers shy of
+adding new strings, or modifying strings already translated. They just
+do their job the best they can. For the Translation Project to work
+smoothly, it is important that maintainers do not carry translation
+concerns on their already loaded shoulders, and that translators be
+kept as free as possible of programmatic concerns.
+
+ The only concern maintainers should have is carefully marking new
+strings as translatable, when they should be, and do not otherwise
+worry about them being translated, as this will come in proper time.
+Consequently, when programs and their strings are adjusted in various
+ways by maintainers, and for matters usually unrelated to translation,
+`xgettext' would construct `PACKAGE.pot' files which are evolving over
+time, so the translations carried by `LANG.po' are slowly fading out of
+date.
+
+ It is important for translators (and even maintainers) to understand
+that package translation is a continuous process in the lifetime of a
+package, and not something which is done once and for all at the start.
+After an initial burst of translation activity for a given package,
+interventions are needed once in a while, because here and there,
+translated entries become obsolete, and new untranslated entries
+appear, needing translation.
+
+ The `msgmerge' program has the purpose of refreshing an already
+existing `LANG.po' file, by comparing it with a newer `PACKAGE.pot'
+template file, extracted by `xgettext' out of recent C sources. The
+refreshing operation adjusts all references to C source locations for
+strings, since these strings move as programs are modified. Also,
+`msgmerge' comments out as obsolete, in `LANG.pox', those already
+translated entries which are no longer used in the program sources
+(*note Obsolete Entries::.). It finally discovers new strings and
+inserts them in the resulting PO file as untranslated entries (*note
+Untranslated Entries::.). *Note msgmerge Invocation::, for more
+information about what `msgmerge' really does.
+
+ Whatever route or means taken, the goal is to obtain an updated
+`LANG.pox' file offering translations for all strings. When this is
+properly achieved, this file `LANG.pox' may take the place of the
+previous official `LANG.po' file.
+
+ The temporal mobility, or fluidity of PO files, is an integral part
+of the translation game, and should be well understood, and accepted.
+People resisting it will have a hard time participating in the
+Translation Project, or will give a hard time to other participants! In
+particular, maintainers should relax and include all available official
+PO files in their distributions, even if these have not recently been
+updated, without banging or otherwise trying to exert pressure on the
+translator teams to get the job done. The pressure should rather come
+from the community of users speaking a particular language, and
+maintainers should consider themselves fairly relieved of any concern
+about the adequacy of translation files. On the other hand, translators
+should reasonably try updating the PO files they are responsible for,
+while the package is undergoing pretest, prior to an official
+distribution.
+
+ Once the PO file is complete and dependable, the `msgfmt' program is
+used for turning the PO file into a machine-oriented format, which may
+yield efficient retrieval of translations by the programs of the
+package, whenever needed at runtime (*note MO Files::.). *Note msgfmt
+Invocation::, for more information about all modalities of execution
+for the `msgfmt' program.
+
+ Finally, the modified and marked C sources are compiled and linked
+with the GNU `gettext' library, usually through the operation of
+`make', given a suitable `Makefile' exists for the project, and the
+resulting executable is installed somewhere users will find it. The MO
+files themselves should also be properly installed. Given the
+appropriate environment variables are set (*note End Users::.), the
+program should localize itself automatically, whenever it executes.
+
+ The remainder of this manual has the purpose of explaining in depth
+the various steps outlined above.
+
+
+File: gettext.info, Node: Basics, Next: Sources, Prev: Introduction, Up: Top
+
+PO Files and PO Mode Basics
+***************************
+
+ The GNU `gettext' toolset helps programmers and translators at
+producing, updating and using translation files, mainly those PO files
+which are textual, editable files. This chapter stresses the format of
+PO files, and contains a PO mode starter. PO mode description is
+spread throughout this manual instead of being concentrated in one
+place. Here we present only the basics of PO mode.
+
+* Menu:
+
+* Installation:: Completing GNU `gettext' Installation
+* PO Files:: The Format of PO Files
+* Main PO Commands:: Main Commands
+* Entry Positioning:: Entry Positioning
+* Normalizing:: Normalizing Strings in Entries
+
+
+File: gettext.info, Node: Installation, Next: PO Files, Prev: Basics, Up: Basics
+
+Completing GNU `gettext' Installation
+=====================================
+
+ Once you have received, unpacked, configured and compiled the GNU
+`gettext' distribution, the `make install' command puts in place the
+programs `xgettext', `msgfmt', `gettext', and `msgmerge', as well as
+their available message catalogs. To top off a comfortable
+installation, you might also want to make the PO mode available to your
+Emacs users.
+
+ During the installation of the PO mode, you might want modify your
+file `.emacs', once and for all, so it contains a few lines looking
+like:
+
+ (setq auto-mode-alist
+ (cons '("\\.po[tx]?\\'\\|\\.po\\." . po-mode) auto-mode-alist))
+ (autoload 'po-mode "po-mode")
+
+ Later, whenever you edit some `.po', `.pot' or `.pox' file, or any
+file having the string `.po.' within its name, Emacs loads
+`po-mode.elc' (or `po-mode.el') as needed, and automatically activates
+PO mode commands for the associated buffer. The string *PO* appears in
+the mode line for any buffer for which PO mode is active. Many PO
+files may be active at once in a single Emacs session.
+
+ If you are using Emacs version 20 or better, and have already
+installed the appropriate international fonts on your system, you may
+also manage for the these fonts to be automatically loaded and used for
+displaying the translations on your Emacs screen, whenever necessary.
+For this to happen, you might want to add the lines:
+
+ (autoload 'po-find-file-coding-system "po-mode")
+ (modify-coding-system-alist 'file "\\.po[tx]?\\'\\|\\.po\\."
+ 'po-find-file-coding-system)
+
+to your `.emacs' file.
+
+
+File: gettext.info, Node: PO Files, Next: Main PO Commands, Prev: Installation, Up: Basics
+
+The Format of PO Files
+======================
+
+ A PO file is made up of many entries, each entry holding the relation
+between an original untranslated string and its corresponding
+translation. All entries in a given PO file usually pertain to a
+single project, and all translations are expressed in a single target
+language. One PO file "entry" has the following schematic structure:
+
+ WHITE-SPACE
+ # TRANSLATOR-COMMENTS
+ #. AUTOMATIC-COMMENTS
+ #: REFERENCE...
+ #, FLAG...
+ msgid UNTRANSLATED-STRING
+ msgstr TRANSLATED-STRING
+
+ The general structure of a PO file should be well understood by the
+translator. When using PO mode, very little has to be known about the
+format details, as PO mode takes care of them for her.
+
+ Entries begin with some optional white space. Usually, when
+generated through GNU `gettext' tools, there is exactly one blank line
+between entries. Then comments follow, on lines all starting with the
+character `#'. There are two kinds of comments: those which have some
+white space immediately following the `#', which comments are created
+and maintained exclusively by the translator, and those which have some
+non-white character just after the `#', which comments are created and
+maintained automatically by GNU `gettext' tools. All comments, of
+either kind, are optional.
+
+ After white space and comments, entries show two strings, giving
+first the untranslated string as it appears in the original program
+sources, and then, the translation of this string. The original string
+is introduced by the keyword `msgid', and the translation, by `msgstr'.
+The two strings, untranslated and translated, are quoted in various
+ways in the PO file, using `"' delimiters and `\' escapes, but the
+translator does not really have to pay attention to the precise quoting
+format, as PO mode fully intend to take care of quoting for her.
+
+ The `msgid' strings, as well as automatic comments, are produced and
+managed by other GNU `gettext' tools, and PO mode does not provide
+means for the translator to alter these. The most she can do is merely
+deleting them, and only by deleting the whole entry. On the other
+hand, the `msgstr' string, as well as translator comments, are really
+meant for the translator, and PO mode gives her the full control she
+needs.
+
+ The comment lines beginning with `#,' are special because they are
+not completely ignored by the programs as comments generally are. The
+comma separated list of FLAGs is used by the `msgfmt' program to give
+the user some better disgnostic messages. Currently there are two
+forms of flags defined:
+
+`fuzzy'
+ This flag can be generated by the `msgmerge' program or it can be
+ inserted by the translator herself. It shows that the `msgstr'
+ string might not be a correct translation (anymore). Only the
+ translator can judge if the translation requires further
+ modification, or is acceptable as is. Once satisfied with the
+ translation, she then removes this `fuzzy' attribute. The
+ `msgmerge' programs inserts this when it combined the `msgid' and
+ `msgstr' entries after fuzzy search only. *Note Fuzzy Entries::.
+
+`c-format'
+`no-c-format'
+ These flags should not be added by a human. Instead only the
+ `xgettext' program adds them. In an automatized PO file processing
+ system as proposed here the user changes would be thrown away
+ again as soon as the `xgettext' program generates a new template
+ file.
+
+ In case the `c-format' flag is given for a string the `msgfmt'
+ does some more tests to check to validity of the translation.
+ *Note msgfmt Invocation::.
+
+ It happens that some lines, usually whitespace or comments, follow
+the very last entry of a PO file. Such lines are not part of any entry,
+and PO mode is unable to take action on those lines. By using the PO
+mode function `M-x po-normalize', the translator may get rid of those
+spurious lines. *Note Normalizing::.
+
+ The remainder of this section may be safely skipped by those using
+PO mode, yet it may be interesting for everybody to have a better idea
+of the precise format of a PO file. On the other hand, those not
+having Emacs handy should carefully continue reading on.
+
+ Each of UNTRANSLATED-STRING and TRANSLATED-STRING respects the C
+syntax for a character string, including the surrounding quotes and
+imbedded backslashed escape sequences. When the time comes to write
+multi-line strings, one should not use escaped newlines. Instead, a
+closing quote should follow the last character on the line to be
+continued, and an opening quote should resume the string at the
+beginning of the following PO file line. For example:
+
+ msgid ""
+ "Here is an example of how one might continue a very long string\n"
+ "for the common case the string represents multi-line output.\n"
+
+In this example, the empty string is used on the first line, to allow
+better alignment of the `H' from the word `Here' over the `f' from the
+word `for'. In this example, the `msgid' keyword is followed by three
+strings, which are meant to be concatenated. Concatenating the empty
+string does not change the resulting overall string, but it is a way
+for us to comply with the necessity of `msgid' to be followed by a
+string on the same line, while keeping the multi-line presentation
+left-justified, as we find this to be a cleaner disposition. The empty
+string could have been omitted, but only if the string starting with
+`Here' was promoted on the first line, right after `msgid'.(1) It was
+not really necessary either to switch between the two last quoted
+strings immediately after the newline `\n', the switch could have
+occurred after *any* other character, we just did it this way because
+it is neater.
+
+ One should carefully distinguish between end of lines marked as `\n'
+*inside* quotes, which are part of the represented string, and end of
+lines in the PO file itself, outside string quotes, which have no
+incidence on the represented string.
+
+ Outside strings, white lines and comments may be used freely.
+Comments start at the beginning of a line with `#' and extend until the
+end of the PO file line. Comments written by translators should have
+the initial `#' immediately followed by some white space. If the `#'
+is not immediately followed by white space, this comment is most likely
+generated and managed by specialized GNU tools, and might disappear or
+be replaced unexpectedly when the PO file is given to `msgmerge'.
+
+ ---------- Footnotes ----------
+
+ (1) This limitation is not imposed by GNU `gettext', but comes from
+the `msgfmt' implementation on Solaris.
+
+
+File: gettext.info, Node: Main PO Commands, Next: Entry Positioning, Prev: PO Files, Up: Basics
+
+Main PO mode Commands
+=====================
+
+ After setting up Emacs with something similar to the lines in *Note
+Installation::, PO mode is activated for a window when Emacs finds a PO
+file in that window. This puts the window read-only and establishes a
+po-mode-map, which is a genuine Emacs mode, in a way that is not derived
+from text mode in any way. Functions found on `po-mode-hook', if any,
+will be executed.
+
+ When PO mode is active in a window, the letters `PO' appear in the
+mode line for that window. The mode line also displays how many
+entries of each kind are held in the PO file. For example, the string
+`132t+3f+10u+2o' would tell the translator that the PO mode contains
+132 translated entries (*note Translated Entries::., 3 fuzzy entries
+(*note Fuzzy Entries::.), 10 untranslated entries (*note Untranslated
+Entries::.) and 2 obsolete entries (*note Obsolete Entries::.).
+Zero-coefficients items are not shown. So, in this example, if the
+fuzzy entries were unfuzzied, the untranslated entries were translated
+and the obsolete entries were deleted, the mode line would merely
+display `145t' for the counters.
+
+ The main PO commands are those which do not fit into the other
+categories of subsequent sections. These allow for quitting PO mode or
+for managing windows in special ways.
+
+`U'
+ Undo last modification to the PO file.
+
+`Q'
+ Quit processing and save the PO file.
+
+`q'
+ Quit processing, possibly after confirmation.
+
+`O'
+ Temporary leave the PO file window.
+
+`?'
+`h'
+ Show help about PO mode.
+
+`='
+ Give some PO file statistics.
+
+`V'
+ Batch validate the format of the whole PO file.
+
+ The command `U' (`po-undo') interfaces to the Emacs *undo* facility.
+*Note Undoing Changes: (emacs)Undo. Each time `U' is typed,
+modifications which the translator did to the PO file are undone a
+little more. For the purpose of undoing, each PO mode command is
+atomic. This is especially true for the `<RET>' command: the whole
+edition made by using a single use of this command is undone at once,
+even if the edition itself implied several actions. However, while in
+the editing window, one can undo the edition work quite parsimoniously.
+
+ The commands `Q' (`po-quit') and `q' (`po-confirm-and-quit') are
+used when the translator is done with the PO file. The former is a bit
+less verbose than the latter. If the file has been modified, it is
+saved to disk first. In both cases, and prior to all this, the
+commands check if some untranslated message remains in the PO file and,
+if yes, the translator is asked if she really wants to leave off
+working with this PO file. This is the preferred way of getting rid of
+an Emacs PO file buffer. Merely killing it through the usual command
+`C-x k' (`kill-buffer') is not the tidiest way to proceed.
+
+ The command `O' (`po-other-window') is another, softer way, to leave
+PO mode, temporarily. It just moves the cursor to some other Emacs
+window, and pops one if necessary. For example, if the translator just
+got PO mode to show some source context in some other, she might
+discover some apparent bug in the program source that needs correction.
+This command allows the translator to change sex, become a programmer,
+and have the cursor right into the window containing the program she
+(or rather *he*) wants to modify. By later getting the cursor back in
+the PO file window, or by asking Emacs to edit this file once again, PO
+mode is then recovered.
+
+ The command `h' (`po-help') displays a summary of all available PO
+mode commands. The translator should then type any character to resume
+normal PO mode operations. The command `?' has the same effect as `h'.
+
+ The command `=' (`po-statistics') computes the total number of
+entries in the PO file, the ordinal of the current entry (counted from
+1), the number of untranslated entries, the number of obsolete entries,
+and displays all these numbers.
+
+ The command `V' (`po-validate') launches `msgfmt' in verbose mode
+over the current PO file. This command first offers to save the
+current PO file on disk. The `msgfmt' tool, from GNU `gettext', has
+the purpose of creating a MO file out of a PO file, and PO mode uses
+the features of this program for checking the overall format of a PO
+file, as well as all individual entries.
+
+ The program `msgfmt' runs asynchronously with Emacs, so the
+translator regains control immediately while her PO file is being
+studied. Error output is collected in the Emacs `*compilation*' buffer,
+displayed in another window. The regular Emacs command `C-x`'
+(`next-error'), as well as other usual compile commands, allow the
+translator to reposition quickly to the offending parts of the PO file.
+Once the cursor is on the line in error, the translator may decide on
+any PO mode action which would help correcting the error.
+
diff --git a/doc/gettext.info-2 b/doc/gettext.info-2
new file mode 100644
index 0000000..20de9bc
--- /dev/null
+++ b/doc/gettext.info-2
@@ -0,0 +1,1127 @@
+This is Info file gettext.info, produced by Makeinfo version 1.68 from
+the input file gettext.texi.
+
+INFO-DIR-SECTION GNU Gettext Utilities
+START-INFO-DIR-ENTRY
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+END-INFO-DIR-ENTRY
+
+ This file provides documentation for GNU `gettext' utilities. It
+also serves as a reference for the free Translation Project.
+
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: gettext.info, Node: Entry Positioning, Next: Normalizing, Prev: Main PO Commands, Up: Basics
+
+Entry Positioning
+=================
+
+ The cursor in a PO file window is almost always part of an entry.
+The only exceptions are the special case when the cursor is after the
+last entry in the file, or when the PO file is empty. The entry where
+the cursor is found to be is said to be the current entry. Many PO
+mode commands operate on the current entry, so moving the cursor does
+more than allowing the translator to browse the PO file, this also
+selects on which entry commands operate.
+
+ Some PO mode commands alter the position of the cursor in a
+specialized way. A few of those special purpose positioning are
+described here, the others are described in following sections.
+
+`.'
+ Redisplay the current entry.
+
+`n'
+`n'
+ Select the entry after the current one.
+
+`p'
+`p'
+ Select the entry before the current one.
+
+`<'
+ Select the first entry in the PO file.
+
+`>'
+ Select the last entry in the PO file.
+
+`m'
+ Record the location of the current entry for later use.
+
+`l'
+ Return to a previously saved entry location.
+
+`x'
+ Exchange the current entry location with the previously saved one.
+
+ Any Emacs command able to reposition the cursor may be used to
+select the current entry in PO mode, including commands which move by
+characters, lines, paragraphs, screens or pages, and search commands.
+However, there is a kind of standard way to display the current entry
+in PO mode, which usual Emacs commands moving the cursor do not
+especially try to enforce. The command `.' (`po-current-entry') has
+the sole purpose of redisplaying the current entry properly, after the
+current entry has been changed by means external to PO mode, or the
+Emacs screen otherwise altered.
+
+ It is yet to be decided if PO mode helps the translator, or otherwise
+irritates her, by forcing a rigid window disposition while she is doing
+her work. We originally had quite precise ideas about how windows
+should behave, but on the other hand, anyone used to Emacs is often
+happy to keep full control. Maybe a fixed window disposition might be
+offered as a PO mode option that the translator might activate or
+deactivate at will, so it could be offered on an experimental basis.
+If nobody feels a real need for using it, or a compulsion for writing
+it, we should drop this whole idea. The incentive for doing it should
+come from translators rather than programmers, as opinions from an
+experienced translator are surely more worth to me than opinions from
+programmers *thinking* about how *others* should do translation.
+
+ The commands `n' (`po-next-entry') and `p' (`po-previous-entry')
+move the cursor the entry following, or preceding, the current one. If
+`n' is given while the cursor is on the last entry of the PO file, or
+if `p' is given while the cursor is on the first entry, no move is done.
+
+ The commands `<' (`po-first-entry') and `>' (`po-last-entry') move
+the cursor to the first entry, or last entry, of the PO file. When the
+cursor is located past the last entry in a PO file, most PO mode
+commands will return an error saying `After last entry'. Moreover, the
+commands `<' and `>' have the special property of being able to work
+even when the cursor is not into some PO file entry, and one may use
+them for nicely correcting this situation. But even these commands
+will fail on a truly empty PO file. There are development plans for
+the PO mode for it to interactively fill an empty PO file from sources.
+*Note Marking::.
+
+ The translator may decide, before working at the translation of a
+particular entry, that she needs to browse the remainder of the PO
+file, maybe for finding the terminology or phraseology used in related
+entries. She can of course use the standard Emacs idioms for saving
+the current cursor location in some register, and use that register for
+getting back, or else, use the location ring.
+
+ PO mode offers another approach, by which cursor locations may be
+saved onto a special stack. The command `m' (`po-push-location')
+merely adds the location of current entry to the stack, pushing the
+already saved locations under the new one. The command `r'
+(`po-pop-location') consumes the top stack element and reposition the
+cursor to the entry associated with that top element. This position is
+then lost, for the next `r' will move the cursor to the previously
+saved location, and so on until no locations remain on the stack.
+
+ If the translator wants the position to be kept on the location
+stack, maybe for taking a look at the entry associated with the top
+element, then go elsewhere with the intent of getting back later, she
+ought to use `m' immediately after `r'.
+
+ The command `x' (`po-exchange-location') simultaneously reposition
+the cursor to the entry associated with the top element of the stack of
+saved locations, and replace that top element with the location of the
+current entry before the move. Consequently, repeating the `x' command
+toggles alternatively between two entries. For achieving this, the
+translator will position the cursor on the first entry, use `m', then
+position to the second entry, and merely use `x' for making the switch.
+
+
+File: gettext.info, Node: Normalizing, Prev: Entry Positioning, Up: Basics
+
+Normalizing Strings in Entries
+==============================
+
+ There are many different ways for encoding a particular string into a
+PO file entry, because there are so many different ways to split and
+quote multi-line strings, and even, to represent special characters by
+backslahsed escaped sequences. Some features of PO mode rely on the
+ability for PO mode to scan an already existing PO file for a
+particular string encoded into the `msgid' field of some entry. Even
+if PO mode has internally all the built-in machinery for implementing
+this recognition easily, doing it fast is technically difficult. To
+facilitate a solution to this efficiency problem, we decided on a
+canonical representation for strings.
+
+ A conventional representation of strings in a PO file is currently
+under discussion, and PO mode experiments with a canonical
+representation. Having both `xgettext' and PO mode converging towards
+a uniform way of representing equivalent strings would be useful, as
+the internal normalization needed by PO mode could be automatically
+satisfied when using `xgettext' from GNU `gettext'. An explicit PO
+mode normalization should then be only necessary for PO files imported
+from elsewhere, or for when the convention itself evolves.
+
+ So, for achieving normalization of at least the strings of a given
+PO file needing a canonical representation, the following PO mode
+command is available:
+
+`M-x po-normalize'
+ Tidy the whole PO file by making entries more uniform.
+
+ The special command `M-x po-normalize', which has no associate keys,
+revises all entries, ensuring that strings of both original and
+translated entries use uniform internal quoting in the PO file. It
+also removes any crumb after the last entry. This command may be
+useful for PO files freshly imported from elsewhere, or if we ever
+improve on the canonical quoting format we use. This canonical format
+is not only meant for getting cleaner PO files, but also for greatly
+speeding up `msgid' string lookup for some other PO mode commands.
+
+ `M-x po-normalize' presently makes three passes over the entries.
+The first implements heuristics for converting PO files for GNU
+`gettext' 0.6 and earlier, in which `msgid' and `msgstr' fields were
+using K&R style C string syntax for multi-line strings. These
+heuristics may fail for comments not related to obsolete entries and
+ending with a backslash; they also depend on subsequent passes for
+finalizing the proper commenting of continued lines for obsolete
+entries. This first pass might disappear once all oldish PO files
+would have been adjusted. The second and third pass normalize all
+`msgid' and `msgstr' strings respectively. They also clean out those
+trailing backslashes used by XView's `msgfmt' for continued lines.
+
+ Having such an explicit normalizing command allows for importing PO
+files from other sources, but also eases the evolution of the current
+convention, evolution driven mostly by aesthetic concerns, as of now.
+It is easy to make suggested adjustments at a later time, as the
+normalizing command and eventually, other GNU `gettext' tools should
+greatly automate conformance. A description of the canonical string
+format is given below, for the particular benefit of those not having
+Emacs handy, and who would nevertheless want to handcraft their PO
+files in nice ways.
+
+ Right now, in PO mode, strings are single line or multi-line. A
+string goes multi-line if and only if it has *embedded* newlines, that
+is, if it matches `[^\n]\n+[^\n]'. So, we would have:
+
+ msgstr "\n\nHello, world!\n\n\n"
+
+ but, replacing the space by a newline, this becomes:
+
+ msgstr ""
+ "\n"
+ "\n"
+ "Hello,\n"
+ "world!\n"
+ "\n"
+ "\n"
+
+ We are deliberately using a caricatural example, here, to make the
+point clearer. Usually, multi-lines are not that bad looking. It is
+probable that we will implement the following suggestion. We might
+lump together all initial newlines into the empty string, and also all
+newlines introducing empty lines (that is, for N > 1, the N-1'th last
+newlines would go together on a separate string), so making the
+previous example appear:
+
+ msgstr "\n\n"
+ "Hello,\n"
+ "world!\n"
+ "\n\n"
+
+ There are a few yet undecided little points about string
+normalization, to be documented in this manual, once these questions
+settle.
+
+
+File: gettext.info, Node: Sources, Next: Initial, Prev: Basics, Up: Top
+
+Preparing Program Sources
+*************************
+
+ For the programmer, changes to the C source code fall into three
+categories. First, you have to make the localization functions known
+to all modules needing message translation. Second, you should
+properly trigger the operation of GNU `gettext' when the program
+initializes, usually from the `main' function. Last, you should
+identify and especially mark all constant strings in your program
+needing translation.
+
+ Presuming that your set of programs, or package, has been adjusted
+so all needed GNU `gettext' files are available, and your `Makefile'
+files are adjusted (*note Maintainers::.), each C module having
+translated C strings should contain the line:
+
+ #include <libintl.h>
+
+ The remaining changes to your C sources are discussed in the further
+sections of this chapter.
+
+* Menu:
+
+* Triggering:: Triggering `gettext' Operations
+* Mark Keywords:: How Marks Appears in Sources
+* Marking:: Marking Translatable Strings
+* c-format:: Telling something about the following string
+* Special cases:: Special Cases of Translatable Strings
+
+
+File: gettext.info, Node: Triggering, Next: Mark Keywords, Prev: Sources, Up: Sources
+
+Triggering `gettext' Operations
+===============================
+
+ The initialization of locale data should be done with more or less
+the same code in every program, as demonstrated below:
+
+ int
+ main (argc, argv)
+ int argc;
+ char argv;
+ {
+ ...
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+ ...
+ }
+
+ PACKAGE and LOCALEDIR should be provided either by `config.h' or by
+the Makefile. For now consult the `gettext' sources for more
+information.
+
+ The use of `LC_ALL' might not be appropriate for you. `LC_ALL'
+includes all locale categories and especially `LC_CTYPE'. This later
+category is responsible for determining character classes with the
+`isalnum' etc. functions from `ctype.h' which could especially for
+programs, which process some kind of input language, be wrong. For
+example this would mean that a source code using the c, (c-cedilla
+character) is runnable in France but not in the U.S.
+
+ Some systems also have problems with parsing number using the
+`scanf' functions if an other but the `LC_ALL' locale is used. The
+standards say that additional formats but the one known in the `"C"'
+locale might be recognized. But some systems seem to reject numbers in
+the `"C"' locale format. In some situation, it might also be a problem
+with the notation itself which makes it impossible to recognize whether
+the number is in the `"C"' locale or the local format. This can happen
+if thousands separator characters are used. Some locales define this
+character accordfing to the national conventions to `'.'' which is the
+same character used in the `"C"' locale to denote the decimal point.
+
+ So it is sometimes necessary to replace the `LC_ALL' line in the
+code above by a sequence of `setlocale' lines
+
+ {
+ ...
+ setlocale (LC_TIME, "");
+ setlocale (LC_MESSAGES, "");
+ ...
+ }
+
+or to switch for and back to the character class in question. On all
+POSIX conformant systems the locale categories `LC_CTYPE',
+`LC_COLLATE', `LC_MONETARY', `LC_NUMERIC', and `LC_TIME' are available.
+On some modern systems there is also a locale `LC_MESSAGES' which is
+called on some old, XPG2 compliant systems `LC_RESPONSES'.
+
+
+File: gettext.info, Node: Mark Keywords, Next: Marking, Prev: Triggering, Up: Sources
+
+How Marks Appears in Sources
+============================
+
+ All strings requiring translation should be marked in the C sources.
+Marking is done in such a way that each translatable string appears to
+be the sole argument of some function or preprocessor macro. There are
+only a few such possible functions or macros meant for translation, and
+their names are said to be marking keywords. The marking is attached
+to strings themselves, rather than to what we do with them. This
+approach has more uses. A blatant example is an error message produced
+by formatting. The format string needs translation, as well as some
+strings inserted through some `%s' specification in the format, while
+the result from `sprintf' may have so many different instances that it
+is impractical to list them all in some `error_string_out()' routine,
+say.
+
+ This marking operation has two goals. The first goal of marking is
+for triggering the retrieval of the translation, at run time. The
+keyword are possibly resolved into a routine able to dynamically return
+the proper translation, as far as possible or wanted, for the argument
+string. Most localizable strings are found in executable positions,
+that is, attached to variables or given as parameters to functions.
+But this is not universal usage, and some translatable strings appear
+in structured initializations. *Note Special cases::.
+
+ The second goal of the marking operation is to help `xgettext' at
+properly extracting all translatable strings when it scans a set of
+program sources and produces PO file templates.
+
+ The canonical keyword for marking translatable strings is `gettext',
+it gave its name to the whole GNU `gettext' package. For packages
+making only light use of the `gettext' keyword, macro or function, it
+is easily used *as is*. However, for packages using the `gettext'
+interface more heavily, it is usually more convenient to give the main
+keyword a shorter, less obtrusive name. Indeed, the keyword might
+appear on a lot of strings all over the package, and programmers
+usually do not want nor need their program sources to remind them
+forcefully, all the time, that they are internationalized. Further, a
+long keyword has the disadvantage of using more horizontal space,
+forcing more indentation work on sources for those trying to keep them
+within 79 or 80 columns.
+
+ Many packages use `_' (a simple underline) as a keyword, and write
+`_("Translatable string")' instead of `gettext ("Translatable
+string")'. Further, the coding rule, from GNU standards, wanting that
+there is a space between the keyword and the opening parenthesis is
+relaxed, in practice, for this particular usage. So, the textual
+overhead per translatable string is reduced to only three characters:
+the underline and the two parentheses. However, even if GNU `gettext'
+uses this convention internally, it does not offer it officially. The
+real, genuine keyword is truly `gettext' indeed. It is fairly easy for
+those wanting to use `_' instead of `gettext' to declare:
+
+ #include <libintl.h>
+ #define _(String) gettext (String)
+
+instead of merely using `#include <libintl.h>'.
+
+ Later on, the maintenance is relatively easy. If, as a programmer,
+you add or modify a string, you will have to ask yourself if the new or
+altered string requires translation, and include it within `_()' if you
+think it should be translated. `"%s: %d"' is an example of string
+*not* requiring translation!
+
+
+File: gettext.info, Node: Marking, Next: c-format, Prev: Mark Keywords, Up: Sources
+
+Marking Translatable Strings
+============================
+
+ In PO mode, one set of features is meant more for the programmer than
+for the translator, and allows him to interactively mark which strings,
+in a set of program sources, are translatable, and which are not. Even
+if it is a fairly easy job for a programmer to find and mark such
+strings by other means, using any editor of his choice, PO mode makes
+this work more comfortable. Further, this gives translators who feel a
+little like programmers, or programmers who feel a little like
+translators, a tool letting them work at marking translatable strings
+in the program sources, while simultaneously producing a set of
+translation in some language, for the package being internationalized.
+
+ The set of program sources, targetted by the PO mode commands
+describe here, should have an Emacs tags table constructed for your
+project, prior to using these PO file commands. This is easy to do.
+In any shell window, change the directory to the root of your project,
+then execute a command resembling:
+
+ etags src/*.[hc] lib/*.[hc]
+
+presuming here you want to process all `.h' and `.c' files from the
+`src/' and `lib/' directories. This command will explore all said
+files and create a `TAGS' file in your root directory, somewhat
+summarizing the contents using a special file format Emacs can
+understand.
+
+ For packages following the GNU coding standards, there is a make
+goal `tags' or `TAGS' which construct the tag files in all directories
+and for all files containing source code.
+
+ Once your `TAGS' file is ready, the following commands assist the
+programmer at marking translatable strings in his set of sources. But
+these commands are necessarily driven from within a PO file window, and
+it is likely that you do not even have such a PO file yet. This is not
+a problem at all, as you may safely open a new, empty PO file, mainly
+for using these commands. This empty PO file will slowly fill in while
+you mark strings as translatable in your program sources.
+
+`,'
+ Search through program sources for a string which looks like a
+ candidate for translation.
+
+`M-,'
+ Mark the last string found with `_()'.
+
+`M-.'
+ Mark the last string found with a keyword taken from a set of
+ possible keywords. This command with a prefix allows some
+ management of these keywords.
+
+ The `,' (`po-tags-search') command search for the next occurrence of
+a string which looks like a possible candidate for translation, and
+displays the program source in another Emacs window, positioned in such
+a way that the string is near the top of this other window. If the
+string is too big to fit whole in this window, it is positioned so only
+its end is shown. In any case, the cursor is left in the PO file
+window. If the shown string would be better presented differently in
+different native languages, you may mark it using `M-,' or `M-.'.
+Otherwise, you might rather ignore it and skip to the next string by
+merely repeating the `,' command.
+
+ A string is a good candidate for translation if it contains a
+sequence of three or more letters. A string containing at most two
+letters in a row will be considered as a candidate if it has more
+letters than non-letters. The command disregards strings containing no
+letters, or isolated letters only. It also disregards strings within
+comments, or strings already marked with some keyword PO mode knows
+(see below).
+
+ If you have never told Emacs about some `TAGS' file to use, the
+command will request that you specify one from the minibuffer, the
+first time you use the command. You may later change your `TAGS' file
+by using the regular Emacs command `M-x visit-tags-table', which will
+ask you to name the precise `TAGS' file you want to use. *Note Tag
+Tables: (emacs)Tags.
+
+ Each time you use the `,' command, the search resumes from where it
+was left by the previous search, and goes through all program sources,
+obeying the `TAGS' file, until all sources have been processed.
+However, by giving a prefix argument to the command (`C-u ,'), you may
+request that the search be restarted all over again from the first
+program source; but in this case, strings that you recently marked as
+translatable will be automatically skipped.
+
+ Using this `,' command does not prevent using of other regular Emacs
+tags commands. For example, regular `tags-search' or
+`tags-query-replace' commands may be used without disrupting the
+independent `,' search sequence. However, as implemented, the
+*initial* `,' command (or the `,' command is used with a prefix) might
+also reinitialize the regular Emacs tags searching to the first tags
+file, this reinitialization might be considered spurious.
+
+ The `M-,' (`po-mark-translatable') command will mark the recently
+found string with the `_' keyword. The `M-.'
+(`po-select-mark-and-mark') command will request that you type one
+keyword from the minibuffer and use that keyword for marking the
+string. Both commands will automatically create a new PO file
+untranslated entry for the string being marked, and make it the current
+entry (making it easy for you to immediately proceed to its
+translation, if you feel like doing it right away). It is possible
+that the modifications made to the program source by `M-,' or `M-.'
+render some source line longer than 80 columns, forcing you to break
+and re-indent this line differently. You may use the `O' command from
+PO mode, or any other window changing command from Emacs, to break out
+into the program source window, and do any needed adjustments. You
+will have to use some regular Emacs command to return the cursor to the
+PO file window, if you want command `,' for the next string, say.
+
+ The `M-.' command has a few built-in speedups, so you do not have to
+explicitly type all keywords all the time. The first such speedup is
+that you are presented with a *preferred* keyword, which you may accept
+by merely typing `<RET>' at the prompt. The second speedup is that you
+may type any non-ambiguous prefix of the keyword you really mean, and
+the command will complete it automatically for you. This also means
+that PO mode has to *know* all your possible keywords, and that it will
+not accept mistyped keywords.
+
+ If you reply `?' to the keyword request, the command gives a list of
+all known keywords, from which you may choose. When the command is
+prefixed by an argument (`C-u M-.'), it inhibits updating any program
+source or PO file buffer, and does some simple keyword management
+instead. In this case, the command asks for a keyword, written in
+full, which becomes a new allowed keyword for later `M-.' commands.
+Moreover, this new keyword automatically becomes the *preferred*
+keyword for later commands. By typing an already known keyword in
+response to `C-u M-.', one merely changes the *preferred* keyword and
+does nothing more.
+
+ All keywords known for `M-.' are recognized by the `,' command when
+scanning for strings, and strings already marked by any of those known
+keywords are automatically skipped. If many PO files are opened
+simultaneously, each one has its own independent set of known keywords.
+There is no provision in PO mode, currently, for deleting a known
+keyword, you have to quit the file (maybe using `q') and reopen it
+afresh. When a PO file is newly brought up in an Emacs window, only
+`gettext' and `_' are known as keywords, and `gettext' is preferred for
+the `M-.' command. In fact, this is not useful to prefer `_', as this
+one is already built in the `M-,' command.
+
+
+File: gettext.info, Node: c-format, Next: Special cases, Prev: Marking, Up: Sources
+
+Special Comments preceding Keywords
+===================================
+
+ In C programs strings are often used within calls of functions from
+the `printf' family. The special thing about these format strings is
+that they can contain format specifiers introduced with `%'. Assume we
+have the code
+
+ printf (gettext ("String `%s' has %d characters\n"), s, strlen (s));
+
+A possible German translation for the above string might be:
+
+ "%d Zeichen lang ist die Zeichenkette `%s'"
+
+ A C programmer, even if he cannot speak German, will recognize that
+there is something wrong here. The order of the two format specifiers
+is changed but of course the arguments in the `printf' don't have.
+This will most probably lead to problems because now the length of the
+string is regarded as the address.
+
+ To prevent errors at runtime caused by translations the `msgfmt'
+tool can check statically whether the arguments in the original and the
+translation string match in type and number. If this is not the case a
+warning will be given and the error cannot causes problems at runtime.
+
+If the word order in the above German translation would be correct one
+would have to write
+
+ "%2$d Zeichen lang ist die Zeichenkette `%1$s'"
+
+The routines in `msgfmt' know about this special notation.
+
+ Because not all strings in a program must be format strings it is not
+useful for `msgfmt' to test all the strings in the `.po' file. This
+might cause problems because the string might contain what looks like a
+format specifier, but the string is not used in `printf'.
+
+ Therefore the `xgettext' adds a special tag to those messages it
+thinks might be a format string. There is no absolute rule for this,
+only a heuristic. In the `.po' file the entry is marked using the
+`c-format' flag in the `#,' comment line (*note PO Files::.).
+
+ The careful reader now might say that this again can cause problems.
+The heuristic might guess it wrong. This is true and therefore
+`xgettext' knows about special kind of comment which lets the
+programmer take over the decision. If in the same line or the
+immediately preceding line of the `gettext' keyword the `xgettext'
+program find a comment containing the words `xgettext:c-format' it will
+mark the string in any case with the `c-format' flag. This kind of
+comment should be used when `xgettext' does not recognize the string as
+a format string but is really is one and it should be tested. Please
+note that when the comment is in the same line of the `gettext'
+keyword, it must be before the string to be translated.
+
+ This situation happens quite often. The `printf' function is often
+called with strings which do not contain a format specifier. Of course
+one would normally use `fputs' but it does happen. In this case
+`xgettext' does not recognize this as a format string but what happens
+if the translation introduces a valid format specifier? The `printf'
+function will try to access one of the parameter but none exists
+because the original code does not refer to any parameter.
+
+ `xgettext' of course could make a wrong decision the other way
+round. A string marked as a format string is not really a format
+string. In this case the `msgfmt' might give too many warnings and
+would prevent translating the `.po' file. The method to prevent this
+wrong decision is similar to the one used above, only the comment to
+use must contain the string `xgettext:no-c-format'.
+
+ If a string is marked with `c-format' and this is not correct the
+user can find out who is responsible for the decision. See *Note
+xgettext Invocation:: to see how the `--debug' option can be used for
+solving this problem.
+
+
+File: gettext.info, Node: Special cases, Prev: c-format, Up: Sources
+
+Special Cases of Translatable Strings
+=====================================
+
+ The attentive reader might now point out that it is not always
+possible to mark translatable string with `gettext' or something like
+this. Consider the following case:
+
+ {
+ static const char *messages[] = {
+ "some very meaningful message",
+ "and another one"
+ };
+ const char *string;
+ ...
+ string
+ = index > 1 ? "a default message" : messages[index];
+
+ fputs (string);
+ ...
+ }
+
+ While it is no problem to mark the string `"a default message"' it
+is not possible to mark the string initializers for `messages'. What
+is to be done? We have to fulfill two tasks. First we have to mark the
+strings so that the `xgettext' program (*note xgettext Invocation::.)
+can find them, and second we have to translate the string at runtime
+before printing them.
+
+ The first task can be fulfilled by creating a new keyword, which
+names a no-op. For the second we have to mark all access points to a
+string from the array. So one solution can look like this:
+
+ #define gettext_noop(String) (String)
+
+ {
+ static const char *messages[] = {
+ gettext_noop ("some very meaningful message"),
+ gettext_noop ("and another one")
+ };
+ const char *string;
+ ...
+ string
+ = index > 1 ? gettext ("a default message") : gettext (messages[index]);
+
+ fputs (string);
+ ...
+ }
+
+ Please convince yourself that the string which is written by `fputs'
+is translated in any case. How to get `xgettext' know the additional
+keyword `gettext_noop' is explained in *Note xgettext Invocation::.
+
+ The above is of course not the only solution. You could also come
+along with the following one:
+
+ #define gettext_noop(String) (String)
+
+ {
+ static const char *messages[] = {
+ gettext_noop ("some very meaningful message",
+ gettext_noop ("and another one")
+ };
+ const char *string;
+ ...
+ string
+ = index > 1 ? gettext_noop ("a default message") : messages[index];
+
+ fputs (gettext (string));
+ ...
+ }
+
+ But this has some drawbacks. First the programmer has to take care
+that he uses `gettext_noop' for the string `"a default message"'. A
+use of `gettext' could have in rare cases unpredictable results. The
+second reason is found in the internals of the GNU `gettext' Library
+which will make this solution less efficient.
+
+ One advantage is that you need not make control flow analysis to make
+sure the output is really translated in any case. But this analysis is
+generally not very difficult. If it should be in any situation you can
+use this second method in this situation.
+
+
+File: gettext.info, Node: Initial, Next: Updating, Prev: Sources, Up: Top
+
+Making the Initial PO File
+**************************
+
+* Menu:
+
+* xgettext Invocation:: Invoking the `xgettext' Program
+* C Sources Context:: C Sources Context
+* Compendium:: Using Translation Compendiums
+
+
+File: gettext.info, Node: xgettext Invocation, Next: C Sources Context, Prev: Initial, Up: Initial
+
+Invoking the `xgettext' Program
+===============================
+
+ xgettext [OPTION] INPUTFILE ...
+
+`-a'
+`--extract-all'
+ Extract all strings.
+
+`-c [TAG]'
+`--add-comments[=TAG]'
+ Place comment block with TAG (or those preceding keyword lines) in
+ output file.
+
+`-C'
+`--c++'
+ Recognize C++ style comments.
+
+`--debug'
+ Use the flags `c-format' and `possible-c-format' to show who was
+ responsible for marking a message as a format string. The later
+ form is used if the `xgettext' program decided, the format form is
+ used if the programmer prescribed it.
+
+ By default only the `c-format' form is used. The translator should
+ not have to care about these details.
+
+`-d NAME'
+`--default-domain=NAME'
+ Use `NAME.po' for output (instead of `messages.po').
+
+ The special domain name `-' or `/dev/stdout' means to write the
+ output to `stdout'.
+
+`-D DIRECTORY'
+`--directory=DIRECTORY'
+ Change to DIRECTORY before beginning to search and scan source
+ files. The resulting `.po' file will be written relative to the
+ original directory, though.
+
+`-f FILE'
+`--files-from=FILE'
+ Read the names of the input files from FILE instead of getting
+ them from the command line.
+
+`--force'
+ Always write output file even if no message is defined.
+
+`-h'
+`--help'
+ Display this help and exit.
+
+`-I LIST'
+`--input-path=LIST'
+ List of directories searched for input files.
+
+`-j'
+`--join-existing'
+ Join messages with existing file.
+
+`-k WORD'
+`--keyword[=WORD]'
+ Additonal keyword to be looked for (without WORD means not to use
+ default keywords).
+
+ The default keywords, which are always looked for if not explicitly
+ disabled, are `gettext', `dgettext', `dcgettext' and
+ `gettext_noop'.
+
+`-m [STRING]'
+`--msgstr-prefix[=STRING]'
+ Use STRING or "" as prefix for msgstr entries.
+
+`-M [STRING]'
+`--msgstr-suffix[=STRING]'
+ Use STRING or "" as suffix for msgstr entries.
+
+`--no-location'
+ Do not write `#: FILENAME:LINE' lines.
+
+`-n'
+`--add-location'
+ Generate `#: FILENAME:LINE' lines (default).
+
+`--omit-header'
+ Don't write header with `msgid ""' entry.
+
+ This is useful for testing purposes because it eliminates a source
+ of variance for generated `.gmo' files. We can ship some of these
+ files in the GNU `gettext' package, and the result of regenerating
+ them through `msgfmt' should yield the same values.
+
+`-p DIR'
+`--output-dir=DIR'
+ Output files will be placed in directory DIR.
+
+`-s'
+`--sort-output'
+ Generate sorted output and remove duplicates.
+
+`--strict'
+ Write out strict Uniforum conforming PO file.
+
+`-v'
+`--version'
+ Output version information and exit.
+
+`-x FILE'
+`--exclude-file=FILE'
+ Entries from FILE are not extracted.
+
+ Search path for supplementary PO files is:
+`/usr/local/share/nls/src/'.
+
+ If INPUTFILE is `-', standard input is read.
+
+ This implementation of `xgettext' is able to process a few awkward
+cases, like strings in preprocessor macros, ANSI concatenation of
+adjacent strings, and escaped end of lines for continued strings.
+
+
+File: gettext.info, Node: C Sources Context, Next: Compendium, Prev: xgettext Invocation, Up: Initial
+
+C Sources Context
+=================
+
+ PO mode is particularily powerful when used with PO files created
+through GNU `gettext' utilities, as those utilities insert special
+comments in the PO files they generate. Some of these special comments
+relate the PO file entry to exactly where the untranslated string
+appears in the program sources.
+
+ When the translator gets to an untranslated entry, she is fairly
+often faced with an original string which is not as informative as it
+normally should be, being succinct, cryptic, or otherwise ambiguous.
+Before chosing how to translate the string, she needs to understand
+better what the string really means and how tight the translation has
+to be. Most of times, when problems arise, the only way left to make
+her judgment is looking at the true program sources from where this
+string originated, searching for surrounding comments the programmer
+might have put in there, and looking around for helping clues of *any*
+kind.
+
+ Surely, when looking at program sources, the translator will receive
+more help if she is a fluent programmer. However, even if she is not
+versed in programming and feels a little lost in C code, the translator
+should not be shy at taking a look, once in a while. It is most
+probable that she will still be able to find some of the hints she
+needs. She will learn quickly to not feel uncomfortable in program
+code, paying more attention to programmer's comments, variable and
+function names (if he dared chosing them well), and overall
+organization, than to programmation itself.
+
+ The following commands are meant to help the translator at getting
+program source context for a PO file entry.
+
+`s'
+ Resume the display of a program source context, or cycle through
+ them.
+
+`M-s'
+ Display of a program source context selected by menu.
+
+`S'
+ Add a directory to the search path for source files.
+
+`M-S'
+ Delete a directory from the search path for source files.
+
+ The commands `s' (`po-cycle-reference') and `M-s'
+(`po-select-source-reference') both open another window displaying some
+source program file, and already positioned in such a way that it shows
+an actual use of the string to be translated. By doing so, the command
+gives source program context for the string. But if the entry has no
+source context references, or if all references are unresolved along
+the search path for program sources, then the command diagnoses this as
+an error.
+
+ Even if `s' (or `M-s') opens a new window, the cursor stays in the
+PO file window. If the translator really wants to get into the program
+source window, she ought to do it explicitly, maybe by using command
+`O'.
+
+ When `s' is typed for the first time, or for a PO file entry which
+is different of the last one used for getting source context, then the
+command reacts by giving the first context available for this entry, if
+any. If some context has already been recently displayed for the
+current PO file entry, and the translator wandered off to do other
+things, typing `s' again will merely resume, in another window, the
+context last displayed. In particular, if the translator moved the
+cursor away from the context in the source file, the command will bring
+the cursor back to the context. By using `s' many times in a row, with
+no other commands intervening, PO mode will cycle to the next available
+contexts for this particular entry, getting back to the first context
+once the last has been shown.
+
+ The command `M-s' behaves differently. Instead of cycling through
+references, it lets the translator choose of particular reference among
+many, and displays that reference. It is best used with completion, if
+the translator types `<TAB>' immediately after `M-s', in response to
+the question, she will be offered a menu of all possible references, as
+a reminder of which are the acceptable answers. This command is useful
+only where there are really many contexts available for a single string
+to translate.
+
+ Program source files are usually found relative to where the PO file
+stands. As a special provision, when this fails, the file is also
+looked for, but relative to the directory immediately above it. Those
+two cases take proper care of most PO files. However, it might happen
+that a PO file has been moved, or is edited in a different place than
+its normal location. When this happens, the translator should tell PO
+mode in which directory normally sits the genuine PO file. Many such
+directories may be specified, and all together, they constitute what is
+called the "search path" for program sources. The command `S'
+(`po-consider-source-path') is used to interactively enter a new
+directory at the front of the search path, and the command `M-S'
+(`po-ignore-source-path') is used to select, with completion, one of
+the directories she does not want anymore on the search path.
+
+
+File: gettext.info, Node: Compendium, Prev: C Sources Context, Up: Initial
+
+Using Translation Compendiums
+=============================
+
+ Compendiums are yet to be implemented.
+
+ An incoming PO mode feature will let the translator maintain a
+compendium of already achieved translations. A "compendium" is a
+special PO file containing a set of translations recurring in many
+different packages. The translator will be given commands for adding
+entries to her compendium, and later initializing untranslated entries,
+or updating already translated entries, from translations kept in the
+compendium. For this to work, however, the compendium would have to be
+normalized. *Note Normalizing::.
+
+
+File: gettext.info, Node: Updating, Next: Binaries, Prev: Initial, Up: Top
+
+Updating Existing PO Files
+**************************
+
+* Menu:
+
+* msgmerge Invocation:: Invoking the `msgmerge' Program
+* Translated Entries:: Translated Entries
+* Fuzzy Entries:: Fuzzy Entries
+* Untranslated Entries:: Untranslated Entries
+* Obsolete Entries:: Obsolete Entries
+* Modifying Translations:: Modifying Translations
+* Modifying Comments:: Modifying Comments
+* Subedit:: Mode for Editing Translations
+* Auxiliary:: Consulting Auxiliary PO Files
+
+
+File: gettext.info, Node: msgmerge Invocation, Next: Translated Entries, Prev: Updating, Up: Updating
+
+Invoking the `msgmerge' Program
+===============================
+
+
+File: gettext.info, Node: Translated Entries, Next: Fuzzy Entries, Prev: msgmerge Invocation, Up: Updating
+
+Translated Entries
+==================
+
+ Each PO file entry for which the `msgstr' field has been filled with
+a translation, and which is not marked as fuzzy (*note Fuzzy
+Entries::.), is a said to be a "translated" entry. Only translated
+entries will later be compiled by GNU `msgfmt' and become usable in
+programs. Other entry types will be excluded; translation will not
+occur for them.
+
+ Some commands are more specifically related to translated entry
+processing.
+
+`t'
+ Find the next translated entry.
+
+`M-t'
+ Find the previous translated entry.
+
+ The commands `t' (`po-next-translated-entry') and `M-t'
+(`po-previous-transted-entry') move forwards or backwards, chasing for
+an translated entry. If none is found, the search is extended and
+wraps around in the PO file buffer.
+
+ Translated entries usually result from the translator having edited
+in a translation for them, *Note Modifying Translations::. However, if
+the variable `po-auto-fuzzy-on-edit' is not `nil', the entry having
+received a new translation first becomes a fuzzy entry, which ought to
+be later unfuzzied before becoming an official, genuine translated
+entry. *Note Fuzzy Entries::.
+
+
+File: gettext.info, Node: Fuzzy Entries, Next: Untranslated Entries, Prev: Translated Entries, Up: Updating
+
+Fuzzy Entries
+=============
+
+ Each PO file entry may have a set of "attributes", which are
+qualities given an name and explicitely associated with the entry
+translation, using a special system comment. One of these attributes
+has the name `fuzzy', and entries having this attribute are said to
+have a fuzzy translation. They are called fuzzy entries, for short.
+
+ Fuzzy entries, even if they account for translated entries for most
+other purposes, usually call for revision by the translator. Those may
+be produced by applying the program `msgmerge' to update an older
+translated PO files according to a new PO template file, when this tool
+hypothesises that some new `msgid' has been modified only slightly out
+of an older one, and chooses to pair what it thinks to be the old
+translation for the new modified entry. The slight alteration in the
+original string (the `msgid' string) should often be reflected in the
+translated string, and this requires the intervention of the
+translator. For this reason, `msgmerge' might mark some entries as
+being fuzzy.
+
+ Also, the translator may decide herself to mark an entry as fuzzy
+for her own convenience, when she wants to remember that the entry has
+to be later revisited. So, some commands are more specifically related
+to fuzzy entry processing.
+
+`f'
+ Find the next fuzzy entry.
+
+`M-f'
+ Find the previous fuzzy entry.
+
+`<TAB>'
+ Remove the fuzzy attribute of the current entry.
+
+ The commands `f' (`po-next-fuzzy') and `M-f' (`po-previous-fuzzy')
+move forwards or backwards, chasing for a fuzzy entry. If none is
+found, the search is extended and wraps around in the PO file buffer.
+
+ The command `<TAB>' (`po-unfuzzy') removes the fuzzy attribute
+associated with an entry, usually leaving it translated. Further, if
+the variable `po-auto-select-on-unfuzzy' has not the `nil' value, the
+`<TAB>' command will automatically chase for another interesting entry
+to work on. The initial value of `po-auto-select-on-unfuzzy' is `nil'.
+
+ The initial value of `po-auto-fuzzy-on-edit' is `nil'. However, if
+the variable `po-auto-fuzzy-on-edit' is set to `t', any entry edited
+through the `<RET>' command is marked fuzzy, as a way to ensure some
+kind of double check, later. In this case, the usual paradigm is that
+an entry becomes fuzzy (if not already) whenever the translator
+modifies it. If she is satisfied with the translation, she then uses
+`<TAB>' to pick another entry to work on, clearing the fuzzy attribute
+on the same blow. If she is not satisfied yet, she merely uses `<SPC>'
+to chase another entry, leaving the entry fuzzy.
+
+ The translator may also use the `<DEL>' command
+(`po-fade-out-entry') over any translated entry to mark it as being
+fuzzy, when she wants to easily leave a trace she wants to later return
+working at this entry.
+
+ Also, when time comes to quit working on a PO file buffer with the
+`q' command, the translator is asked for confirmation, if fuzzy string
+still exists.
+
+
+File: gettext.info, Node: Untranslated Entries, Next: Obsolete Entries, Prev: Fuzzy Entries, Up: Updating
+
+Untranslated Entries
+====================
+
+ When `xgettext' originally creates a PO file, unless told otherwise,
+it initializes the `msgid' field with the untranslated string, and
+leaves the `msgstr' string to be empty. Such entries, having an empty
+translation, are said to be "untranslated" entries. Later, when the
+programmer slightly modifies some string right in the program, this
+change is later reflected in the PO file by the appearance of a new
+untranslated entry for the modified string.
+
+ The usual commands moving from entry to entry consider untranslated
+entries on the same level as active entries. Untranslated entries are
+easily recognizable by the fact they end with `msgstr ""'.
+
+ The work of the translator might be (quite naively) seen as the
+process of seeking after an untranslated entry, editing a translation
+for it, and repeating these actions until no untranslated entries
+remain. Some commands are more specifically related to untranslated
+entry processing.
+
+`u'
+ Find the next untranslated entry.
+
+`M-u'
+ Find the previous untranslated entry.
+
+`k'
+ Turn the current entry into an untranslated one.
+
+ The commands `u' (`po-next-untranslated-entry') and `M-u'
+(`po-previous-untransted-entry') move forwards or backwards, chasing
+for an untranslated entry. If none is found, the search is extended
+and wraps around in the PO file buffer.
+
+ An entry can be turned back into an untranslated entry by merely
+emptying its translation, using the command `k' (`po-kill-msgstr').
+*Note Modifying Translations::.
+
+ Also, when time comes to quit working on a PO file buffer with the
+`q' command, the translator is asked for confirmation, if some
+untranslated string still exists.
+
diff --git a/doc/gettext.info-3 b/doc/gettext.info-3
new file mode 100644
index 0000000..cd5db2b
--- /dev/null
+++ b/doc/gettext.info-3
@@ -0,0 +1,1072 @@
+This is Info file gettext.info, produced by Makeinfo version 1.68 from
+the input file gettext.texi.
+
+INFO-DIR-SECTION GNU Gettext Utilities
+START-INFO-DIR-ENTRY
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+END-INFO-DIR-ENTRY
+
+ This file provides documentation for GNU `gettext' utilities. It
+also serves as a reference for the free Translation Project.
+
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: gettext.info, Node: Obsolete Entries, Next: Modifying Translations, Prev: Untranslated Entries, Up: Updating
+
+Obsolete Entries
+================
+
+ By "obsolete" PO file entries, we mean those entries which are
+commented out, usually by `msgmerge' when it found that the translation
+is not needed anymore by the package being localized.
+
+ The usual commands moving from entry to entry consider obsolete
+entries on the same level as active entries. Obsolete entries are
+easily recognizable by the fact that all their lines start with `#',
+even those lines containing `msgid' or `msgstr'.
+
+ Commands exist for emptying the translation or reinitializing it to
+the original untranslated string. Commands interfacing with the kill
+ring may force some previously saved text into the translation. The
+user may interactively edit the translation. All these commands may
+apply to obsolete entries, carefully leaving the entry obsolete after
+the fact.
+
+ Moreover, some commands are more specifically related to obsolete
+entry processing.
+
+`o'
+ Find the next obsolete entry.
+
+`M-o'
+ Find the previous obsolete entry.
+
+`<DEL>'
+ Make an active entry obsolete, or zap out an obsolete entry.
+
+ The commands `o' (`po-next-obsolete-entry') and `M-o'
+(`po-previous-obsolete-entry') move forwards or backwards, chasing for
+an obsolete entry. If none is found, the search is extended and wraps
+around in the PO file buffer.
+
+ PO mode does not provide ways for un-commenting an obsolete entry
+and making it active, because this would reintroduce an original
+untranslated string which does not correspond to any marked string in
+the program sources. This goes with the philosophy of never
+introducing useless `msgid' values.
+
+ However, it is possible to comment out an active entry, so making it
+obsolete. GNU `gettext' utilities will later react to the
+disappearance of a translation by using the untranslated string. The
+command `<DEL>' (`po-fade-out-entry') pushes the current entry a little
+further towards annihilation. If the entry is active (it is a
+translated entry), then it is first made fuzzy. If it is already fuzzy,
+then the entry is merely commented out, with confirmation. If the entry
+is already obsolete, then it is completely deleted from the PO file.
+It is easy to recycle the translation so deleted into some other PO file
+entry, usually one which is untranslated. *Note Modifying
+Translations::.
+
+ Here is a quite interesting problem to solve for later development of
+PO mode, for those nights you are not sleepy. The idea would be that
+PO mode might become bright enough, one of these days, to make good
+guesses at retrieving the most probable candidate, among all obsolete
+entries, for initializing the translation of a newly appeared string.
+I think it might be a quite hard problem to do this algorithmically, as
+we have to develop good and efficient measures of string similarity.
+Right now, PO mode completely lets the decision to the translator, when
+the time comes to find the adequate obsolete translation, it merely
+tries to provide handy tools for helping her to do so.
+
+
+File: gettext.info, Node: Modifying Translations, Next: Modifying Comments, Prev: Obsolete Entries, Up: Updating
+
+Modifying Translations
+======================
+
+ PO mode prevents direct edition of the PO file, by the usual means
+Emacs give for altering a buffer's contents. By doing so, it pretends
+helping the translator to avoid little clerical errors about the
+overall file format, or the proper quoting of strings, as those errors
+would be easily made. Other kinds of errors are still possible, but
+some may be caught and diagnosed by the batch validation process, which
+the translator may always trigger by the `V' command. For all other
+errors, the translator has to rely on her own judgment, and also on the
+linguistic reports submitted to her by the users of the translated
+package, having the same mother tongue.
+
+ When the time comes to create a translation, correct an error
+diagnosed mechanically or reported by a user, the translators have to
+resort to using the following commands for modifying the translations.
+
+`<RET>'
+ Interactively edit the translation.
+
+`<LFD>'
+ Reinitialize the translation with the original, untranslated
+ string.
+
+`k'
+ Save the translation on the kill ring, and delete it.
+
+`w'
+ Save the translation on the kill ring, without deleting it.
+
+`y'
+ Replace the translation, taking the new from the kill ring.
+
+ The command `<RET>' (`po-edit-msgstr') opens a new Emacs window
+meant to edit in a new translation, or to modify an already existing
+translation. The new window contains a copy of the translation taken
+from the current PO file entry, all ready for edition, expunged of all
+quoting marks, fully modifiable and with the complete extent of Emacs
+modifying commands. When the translator is done with her
+modifications, she may use `C-c C-c' to close the subedit window with
+the automatically requoted results, or `C-c C-k' to abort her
+modifications. *Note Subedit::, for more information.
+
+ The command `<LFD>' (`po-msgid-to-msgstr') initializes, or
+reinitializes the translation with the original string. This command is
+normally used when the translator wants to redo a fresh translation of
+the original string, disregarding any previous work.
+
+ It is possible to arrange so, whenever editing an untranslated
+entry, the `<LFD>' command be automatically executed. If you set
+`po-auto-edit-with-msgid' to `t', the translation gets initialised with
+the original string, in case none exist already. The default value for
+`po-auto-edit-with-msgid' is `nil'.
+
+ In fact, whether it is best to start a translation with an empty
+string, or rather with a copy of the original string, is a matter of
+taste or habit. Sometimes, the source language and the target language
+are so different that is simply best to start writing on an empty page.
+At other times, the source and target languages are so close that it
+would be a waste to retype a number of words already being written in
+the original string. A translator may also like having the original
+string right under her eyes, as she will progressively overwrite the
+original text with the translation, even if this requires some extra
+editing work to get rid of the original.
+
+ The command `k' (`po-kill-msgstr') merely empties the translation
+string, so turning the entry into an untranslated one. But while doing
+so, its previous contents is put apart in a special place, known as the
+kill ring. The command `w' (`po-kill-ring-save-msgstr') has also the
+effect of taking a copy of the translation onto the kill ring, but it
+otherwise leaves the entry alone, and does *not* remove the translation
+from the entry. Both commands use exactly the Emacs kill ring, which
+is shared between buffers, and which is well known already to Emacs
+lovers.
+
+ The translator may use `k' or `w' many times in the course of her
+work, as the kill ring may hold several saved translations. From the
+kill ring, strings may later be reinserted in various Emacs buffers.
+In particular, the kill ring may be used for moving translation strings
+between different entries of a single PO file buffer, or if the
+translator is handling many such buffers at once, even between PO files.
+
+ To facilitate exchanges with buffers which are not in PO mode, the
+translation string put on the kill ring by the `k' command is fully
+unquoted before being saved: external quotes are removed, multi-lines
+strings are concatenated, and backslashed escaped sequences are turned
+into their corresponding characters. In the special case of obsolete
+entries, the translation is also uncommented prior to saving.
+
+ The command `y' (`po-yank-msgstr') completely replaces the
+translation of the current entry by a string taken from the kill ring.
+Following Emacs terminology, we then say that the replacement string is
+"yanked" into the PO file buffer. *Note Yanking: (emacs)Yanking. The
+first time `y' is used, the translation receives the value of the most
+recent addition to the kill ring. If `y' is typed once again,
+immediately, without intervening keystrokes, the translation just
+inserted is taken away and replaced by the second most recent addition
+to the kill ring. By repeating `y' many times in a row, the translator
+may travel along the kill ring for saved strings, until she finds the
+string she really wanted.
+
+ When a string is yanked into a PO file entry, it is fully and
+automatically requoted for complying with the format PO files should
+have. Further, if the entry is obsolete, PO mode then appropriately
+push the inserted string inside comments. Once again, translators
+should not burden themselves with quoting considerations besides, of
+course, the necessity of the translated string itself respective to the
+program using it.
+
+ Note that `k' or `w' are not the only commands pushing strings on
+the kill ring, as almost any PO mode command replacing translation
+strings (or the translator comments) automatically save the old string
+on the kill ring. The main exceptions to this general rule are the
+yanking commands themselves.
+
+ To better illustrate the operation of killing and yanking, let's use
+an actual example, taken from a common situation. When the programmer
+slightly modifies some string right in the program, his change is later
+reflected in the PO file by the appearance of a new untranslated entry
+for the modified string, and the fact that the entry translating the
+original or unmodified string becomes obsolete. In many cases, the
+translator might spare herself some work by retrieving the unmodified
+translation from the obsolete entry, then initializing the untranslated
+entry `msgstr' field with this retrieved translation. Once this done,
+the obsolete entry is not wanted anymore, and may be safely deleted.
+
+ When the translator finds an untranslated entry and suspects that a
+slight variant of the translation exists, she immediately uses `m' to
+mark the current entry location, then starts chasing obsolete entries
+with `o', hoping to find some translation corresponding to the
+unmodified string. Once found, she uses the `<DEL>' command for
+deleting the obsolete entry, knowing that `<DEL>' also *kills* the
+translation, that is, pushes the translation on the kill ring. Then,
+`r' returns to the initial untranslated entry, `y' then *yanks* the
+saved translation right into the `msgstr' field. The translator is
+then free to use `<RET>' for fine tuning the translation contents, and
+maybe to later use `u', then `m' again, for going on with the next
+untranslated string.
+
+ When some sequence of keys has to be typed over and over again, the
+translator may find it useful to become better acquainted with the Emacs
+capability of learning these sequences and playing them back under
+request. *Note Keyboard Macros: (emacs)Keyboard Macros.
+
+
+File: gettext.info, Node: Modifying Comments, Next: Subedit, Prev: Modifying Translations, Up: Updating
+
+Modifying Comments
+==================
+
+ Any translation work done seriously will raise many linguistic
+difficulties, for which decisions have to be made, and the choices
+further documented. These documents may be saved within the PO file in
+form of translator comments, which the translator is free to create,
+delete, or modify at will. These comments may be useful to herself
+when she returns to this PO file after a while.
+
+ Comments not having whitespace after the initial `#', for example,
+those beginning with `#.' or `#:', are *not* translator comments, they
+are exclusively created by other `gettext' tools. So, the commands
+below will never alter such system added comments, they are not meant
+for the translator to modify. *Note PO Files::.
+
+ The following commands are somewhat similar to those modifying
+translations, so the general indications given for those apply here.
+*Note Modifying Translations::.
+
+`#'
+ Interactively edit the translator comments.
+
+`K'
+ Save the translator comments on the kill ring, and delete it.
+
+`W'
+ Save the translator comments on the kill ring, without deleting it.
+
+`Y'
+ Replace the translator comments, taking the new from the kill ring.
+
+ These commands parallel PO mode commands for modifying the
+translation strings, and behave much the same way as they do, except
+that they handle this part of PO file comments meant for translator
+usage, rather than the translation strings. So, if the descriptions
+given below are slightly succinct, it is because the full details have
+already been given. *Note Modifying Translations::.
+
+ The command `#' (`po-edit-comment') opens a new Emacs window
+containing a copy of the translator comments on the current PO file
+entry. If there are no such comments, PO mode understands that the
+translator wants to add a comment to the entry, and she is presented
+with an empty screen. Comment marks (`#') and the space following them
+are automatically removed before edition, and reinstated after. For
+translator comments pertaining to obsolete entries, the uncommenting
+and recommenting operations are done twice. Once in the editing
+window, the keys `C-c C-c' allow the translator to tell she is finished
+with editing the comment. *Note Subedit::, for further details.
+
+ Functions found on `po-subedit-mode-hook', if any, are executed after
+the string has been inserted in the edit buffer.
+
+ The command `K' (`po-kill-comment') get rid of all translator
+comments, while saving those comments on the kill ring. The command
+`W' (`po-kill-ring-save-comment') takes a copy of the translator
+comments on the kill ring, but leaves them undisturbed in the current
+entry. The command `Y' (`po-yank-comment') completely replaces the
+translator comments by a string taken at the front of the kill ring.
+When this command is immediately repeated, the comments just inserted
+are withdrawn, and replaced by other strings taken along the kill ring.
+
+ On the kill ring, all strings have the same nature. There is no
+distinction between *translation* strings and *translator comments*
+strings. So, for example, let's presume the translator has just
+finished editing a translation, and wants to create a new translator
+comment to document why the previous translation was not good, just to
+remember what was the problem. Foreseeing that she will do that in her
+documentation, the translator may want to quote the previous
+translation in her translator comments. To do so, she may initialize
+the translator comments with the previous translation, still at the
+head of the kill ring. Because editing already pushed the previous
+translation on the kill ring, she merely has to type `M-w' prior to
+`#', and the previous translation will be right there, all ready for
+being introduced by some explanatory text.
+
+ On the other hand, presume there are some translator comments already
+and that the translator wants to add to those comments, instead of
+wholly replacing them. Then, she should edit the comment right away
+with `#'. Once inside the editing window, she can use the regular
+Emacs commands `C-y' (`yank') and `M-y' (`yank-pop') to get the
+previous translation where she likes.
+
+
+File: gettext.info, Node: Subedit, Next: Auxiliary, Prev: Modifying Comments, Up: Updating
+
+Details of Sub Edition
+======================
+
+ The PO subedit minor mode has a few peculiarities worth being
+described in fuller detail. It installs a few commands over the usual
+editing set of Emacs, which are described below.
+
+`C-c C-c'
+ Complete edition.
+
+`C-c C-k'
+ Abort edition.
+
+`C-c C-a'
+ Consult auxiliary PO files.
+
+ The windows contents represents a translation for a given message,
+or a translator comment. The translator may modify this window to her
+heart's content. Once this done, the command `C-c C-c'
+(`po-subedit-exit') may be used to return the edited translation into
+the PO file, replacing the original translation, even if it moved out of
+sight or if buffers were switched.
+
+ If the translator becomes unsatisfied with her translation or
+comment, to the extent she prefers keeping what was existent prior to
+the `<RET>' or `#' command, she may use the command `C-c C-k'
+(`po-subedit-abort') to merely get rid of edition, while preserving the
+original translation or comment. Another way would be for her to exit
+normally with `C-c C-c', then type `U' once for undoing the whole
+effect of last edition.
+
+ The command `C-c C-a' allows for glancing through translations
+already achieved in other languages, directly while editing the current
+translation. This may be quite convenient when the translator is fluent
+at many languages, but of course, only makes sense when such completed
+auxiliary PO files are already available to her (*note Auxiliary::.).
+
+ Functions found on `po-subedit-mode-hook', if any, are executed after
+the string has been inserted in the edit buffer.
+
+ While editing her translation, the translator should pay attention
+to not inserting unwanted `<RET>' (carriage returns) characters at the
+end of the translated string if those are not meant to be there, or to
+removing such characters when they are required. Since these
+characters are not visible in the editing buffer, they are easily
+introduced by mistake. To help her, `<RET>' automatically puts the
+character `<' at the end of the string being edited, but this `<' is
+not really part of the string. On exiting the editing window with
+`C-c C-c', PO mode automatically removes such `<' and all whitespace
+added after it. If the translator adds characters after the
+terminating `<', it looses its delimiting property and integrally
+becomes part of the string. If she removes the delimiting `<', then
+the edited string is taken *as is*, with all trailing newlines, even if
+invisible. Also, if the translated string ought to end itself with a
+genuine `<', then the delimiting `<' may not be removed; so the string
+should appear, in the editing window, as ending with two `<' in a row.
+
+ When a translation (or a comment) is being edited, the translator
+may move the cursor back into the PO file buffer and freely move to
+other entries, browsing at will. If, with an edition pending, the
+translator wanders in the PO file buffer, she may decide to start
+modifying another entry. Each entry being edited has its own subedit
+buffer. It is possible to simultaneously edit the translation *and*
+the comment of a single entry, or to edit entries in different PO
+files, all at once. Typing `<RET>' on a field already being edited
+merely resume that particular edit. Yet, the translator should better
+be comfortable at handling many Emacs windows!
+
+ Pending subedits may be completed or aborted in any order, regardless
+of how or when they were started. When many subedits are pending and
+the translator asks for quitting the PO file (with the `q' command),
+subedits are automatically resumed one at a time, so she may decide for
+each of them.
+
+
+File: gettext.info, Node: Auxiliary, Prev: Subedit, Up: Updating
+
+Consulting Auxiliary PO Files
+=============================
+
+ PO mode is able to help the knowledgeable translator, being fluent in
+many languages, at taking advantage of translations already achieved in
+other languages she just happens to know. It provides these other
+language translations as additional context for her own work. Moreover,
+it has features to ease the production of translations for many
+languages at once, for translators preferring to work in this way.
+
+ An "auxiliary" PO file is an existing PO file meant for the same
+package the translator is working on, but targeted to a different mother
+tongue language. Commands exist for declaring and handling auxiliary
+PO files, and also for showing contexts for the entry under work.
+
+ Here are the auxiliary file commands available in PO mode.
+
+`a'
+ Seek auxiliary files for another translation for the same entry.
+
+`M-a'
+ Switch to a particular auxiliary file.
+
+`A'
+ Declare this PO file as an auxiliary file.
+
+`M-A'
+ Remove this PO file from the list of auxiliary files.
+
+ Command `A' (`po-consider-as-auxiliary') adds the current PO file to
+the list of auxiliary files, while command `M-A'
+(`po-ignore-as-auxiliary' just removes it.
+
+ The command `a' (`po-cycle-auxiliary') seeks all auxiliary PO files,
+round-robin, searching for a translated entry in some other language
+having an `msgid' field identical as the one for the current entry.
+The found PO file, if any, takes the place of the current PO file in
+the display (its window gets on top). Before doing so, the current PO
+file is also made into an auxiliary file, if not already. So, `a' in
+this newly displayed PO file will seek another PO file, and so on, so
+repeating `a' will eventually yield back the original PO file.
+
+ The command `M-a' (`po-select-auxiliary') asks the translator for
+her choice of a particular auxiliary file, with completion, and then
+switches to that selected PO file. The command also checks if the
+selected file has an `msgid' field identical as the one for the current
+entry, and if yes, this entry becomes current. Otherwise, the cursor
+of the selected file is left undisturbed.
+
+ For all this to work fully, auxiliary PO files will have to be
+normalized, in that way that `msgid' fields should be written *exactly*
+the same way. It is possible to write `msgid' fields in various ways
+for representing the same string, different writing would break the
+proper behaviour of the auxiliary file commands of PO mode. This is not
+expected to be much a problem in practice, as most existing PO files
+have their `msgid' entries written by the same GNU `gettext' tools.
+
+ However, PO files initially created by PO mode itself, while marking
+strings in source files, are normalised differently. So are PO files
+resulting of the the `M-x normalize' command. Until these
+discrepancies between PO mode and other GNU `gettext' tools get fully
+resolved, the translator should stay aware of normalisation issues.
+
+
+File: gettext.info, Node: Binaries, Next: Users, Prev: Updating, Up: Top
+
+Producing Binary MO Files
+*************************
+
+* Menu:
+
+* msgfmt Invocation:: Invoking the `msgfmt' Program
+* MO Files:: The Format of GNU MO Files
+
+
+File: gettext.info, Node: msgfmt Invocation, Next: MO Files, Prev: Binaries, Up: Binaries
+
+Invoking the `msgfmt' Program
+=============================
+
+ Usage: msgfmt [OPTION] FILENAME.po ...
+
+`-a NUMBER'
+`--alignment=NUMBER'
+ Align strings to NUMBER bytes (default: 1).
+
+`-h'
+`--help'
+ Display this help and exit.
+
+`--no-hash'
+ Binary file will not include the hash table.
+
+`-o FILE'
+`--output-file=FILE'
+ Specify output file name as FILE.
+
+`--strict'
+ Direct the program to work strictly following the Uniforum/Sun
+ implementation. Currently this only affects the naming of the
+ output file. If this option is not given the name of the output
+ file is the same as the domain name. If the strict Uniforum mode
+ is enable the suffix `.mo' is added to the file name if it is not
+ already present.
+
+ We find this behaviour of Sun's implementation rather silly and so
+ by default this mode is *not* selected.
+
+`-v'
+`--verbose'
+ Detect and diagnose input file anomalies which might represent
+ translation errors. The `msgid' and `msgstr' strings are studied
+ and compared. It is considered abnormal that one string starts or
+ ends with a newline while the other does not.
+
+ Also, if the string represents a format sring used in a
+ `printf'-like function both strings should have the same number of
+ `%' format specifiers, with matching types. If the flag
+ `c-format' or `possible-c-format' appears in the special comment
+ <#,> for this entry a check is performed. For example, the check
+ will diagnose using `%.*s' against `%s', or `%d' against `%s', or
+ `%d' against `%x'. It can even handle positional parameters.
+
+ Normally the `xgettext' program automatically decides whether a
+ string is a format string or not. This algorithm is not perfect,
+ though. It might regard a string as a format string though it is
+ not used in a `printf'-like function and so `msgfmt' might report
+ errors where there are none. Or the other way round: a string is
+ not regarded as a format string but it is used in a `printf'-like
+ function.
+
+ So solve this problem the programmer can dictate the decision to
+ the `xgettext' program (*note c-format::.). The translator should
+ not consider removing the flag from the <#,> line. This "fix"
+ would be reversed again as soon as `msgmerge' is called the next
+ time.
+
+`-V'
+`--version'
+ Output version information and exit.
+
+ If input file is `-', standard input is read. If output file is
+`-', output is written to standard output.
+
+
+File: gettext.info, Node: MO Files, Prev: msgfmt Invocation, Up: Binaries
+
+The Format of GNU MO Files
+==========================
+
+ The format of the generated MO files is best described by a picture,
+which appears below.
+
+ The first two words serve the identification of the file. The magic
+number will always signal GNU MO files. The number is stored in the
+byte order of the generating machine, so the magic number really is two
+numbers: `0x950412de' and `0xde120495'. The second word describes the
+current revision of the file format. For now the revision is 0. This
+might change in future versions, and ensures that the readers of MO
+files can distinguish new formats from old ones, so that both can be
+handled correctly. The version is kept separate from the magic number,
+instead of using different magic numbers for different formats, mainly
+because `/etc/magic' is not updated often. It might be better to have
+magic separated from internal format version identification.
+
+ Follow a number of pointers to later tables in the file, allowing
+for the extension of the prefix part of MO files without having to
+recompile programs reading them. This might become useful for later
+inserting a few flag bits, indication about the charset used, new
+tables, or other things.
+
+ Then, at offset O and offset T in the picture, two tables of string
+descriptors can be found. In both tables, each string descriptor uses
+two 32 bits integers, one for the string length, another for the offset
+of the string in the MO file, counting in bytes from the start of the
+file. The first table contains descriptors for the original strings,
+and is sorted so the original strings are in increasing lexicographical
+order. The second table contains descriptors for the translated
+strings, and is parallel to the first table: to find the corresponding
+translation one has to access the array slot in the second array with
+the same index.
+
+ Having the original strings sorted enables the use of simple binary
+search, for when the MO file does not contain an hashing table, or for
+when it is not practical to use the hashing table provided in the MO
+file. This also has another advantage, as the empty string in a PO
+file GNU `gettext' is usually *translated* into some system information
+attached to that particular MO file, and the empty string necessarily
+becomes the first in both the original and translated tables, making
+the system information very easy to find.
+
+ The size S of the hash table can be zero. In this case, the hash
+table itself is not contained in the MO file. Some people might prefer
+this because a precomputed hashing table takes disk space, and does not
+win *that* much speed. The hash table contains indices to the sorted
+array of strings in the MO file. Conflict resolution is done by double
+hashing. The precise hashing algorithm used is fairly dependent of GNU
+`gettext' code, and is not documented here.
+
+ As for the strings themselves, they follow the hash file, and each
+is terminated with a <NUL>, and this <NUL> is not counted in the length
+which appears in the string descriptor. The `msgfmt' program has an
+option selecting the alignment for MO file strings. With this option,
+each string is separately aligned so it starts at an offset which is a
+multiple of the alignment value. On some RISC machines, a correct
+alignment will speed things up.
+
+ Nothing prevents a MO file from having embedded <NUL>s in strings.
+However, the program interface currently used already presumes that
+strings are <NUL> terminated, so embedded <NUL>s are somewhat useless.
+But MO file format is general enough so other interfaces would be later
+possible, if for example, we ever want to implement wide characters
+right in MO files, where <NUL> bytes may accidently appear.
+
+ This particular issue has been strongly debated in the GNU `gettext'
+development forum, and it is expectable that MO file format will evolve
+or change over time. It is even possible that many formats may later
+be supported concurrently. But surely, we have to start somewhere, and
+the MO file format described here is a good start. Nothing is cast in
+concrete, and the format may later evolve fairly easily, so we should
+feel comfortable with the current approach.
+
+ byte
+ +------------------------------------------+
+ 0 | magic number = 0x950412de |
+ | |
+ 4 | file format revision = 0 |
+ | |
+ 8 | number of strings | == N
+ | |
+ 12 | offset of table with original strings | == O
+ | |
+ 16 | offset of table with translation strings | == T
+ | |
+ 20 | size of hashing table | == S
+ | |
+ 24 | offset of hashing table | == H
+ | |
+ . .
+ . (possibly more entries later) .
+ . .
+ | |
+ O | length & offset 0th string ----------------.
+ O + 8 | length & offset 1st string ------------------.
+ ... ... | |
+ O + ((N-1)*8)| length & offset (N-1)th string | | |
+ | | | |
+ T | length & offset 0th translation ---------------.
+ T + 8 | length & offset 1st translation -----------------.
+ ... ... | | | |
+ T + ((N-1)*8)| length & offset (N-1)th translation | | | | |
+ | | | | | |
+ H | start hash table | | | | |
+ ... ... | | | |
+ H + S * 4 | end hash table | | | | |
+ | | | | | |
+ | NUL terminated 0th string <----------------' | | |
+ | | | | |
+ | NUL terminated 1st string <------------------' | |
+ | | | |
+ ... ... | |
+ | | | |
+ | NUL terminated 0th translation <---------------' |
+ | | |
+ | NUL terminated 1st translation <-----------------'
+ | |
+ ... ...
+ | |
+ +------------------------------------------+
+
+
+File: gettext.info, Node: Users, Next: Programmers, Prev: Binaries, Up: Top
+
+The User's View
+***************
+
+ When GNU `gettext' will truly have reached is goal, average users
+should feel some kind of astonished pleasure, seeing the effect of that
+strange kind of magic that just makes their own native language appear
+everywhere on their screens. As for naive users, they would ideally
+have no special pleasure about it, merely taking their own language for
+*granted*, and becoming rather unhappy otherwise.
+
+ So, let's try to describe here how we would like the magic to
+operate, as we want the users' view to be the simplest, among all ways
+one could look at GNU `gettext'. All other software engineers:
+programmers, translators, maintainers, should work together in such a
+way that the magic becomes possible. This is a long and progressive
+undertaking, and information is available about the progress of the
+Translation Project.
+
+ When a package is distributed, there are two kind of users:
+"installers" who fetch the distribution, unpack it, configure it,
+compile it and install it for themselves or others to use; and "end
+users" that call programs of the package, once these have been
+installed at their site. GNU `gettext' is offering magic for both
+installers and end users.
+
+* Menu:
+
+* Matrix:: The Current `ABOUT-NLS' Matrix
+* Installers:: Magic for Installers
+* End Users:: Magic for End Users
+
+
+File: gettext.info, Node: Matrix, Next: Installers, Prev: Users, Up: Users
+
+The Current `ABOUT-NLS' Matrix
+==============================
+
+ Languages are not equally supported in all packages using GNU
+`gettext'. To know if some package uses GNU `gettext', one may check
+the distribution for the `ABOUT-NLS' information file, for some `LL.po'
+files, often kept together into some `po/' directory, or for an `intl/'
+directory. Internationalized packages have usually many `LL.po' files,
+where LL represents the language. *Note End Users:: for a complete
+description of the format for LL.
+
+ More generally, a matrix is available for showing the current state
+of the Translation Project, listing which packages are prepared for
+multi-lingual messages, and which languages is supported by each.
+Because this information changes often, this matrix is not kept within
+this GNU `gettext' manual. This information is often found in file
+`ABOUT-NLS' from various distributions, but is also as old as the
+distribution itself. A recent copy of this `ABOUT-NLS' file,
+containing up-to-date information, should generally be found on the
+Translation Project sites, and also on most GNU archive sites.
+
+
+File: gettext.info, Node: Installers, Next: End Users, Prev: Matrix, Up: Users
+
+Magic for Installers
+====================
+
+ By default, packages fully using GNU `gettext', internally, are
+installed in such a way that they to allow translation of messages. At
+*configuration* time, those packages should automatically detect
+whether the underlying host system provides usable `catgets' or
+`gettext' functions. If neither is present, the GNU `gettext' library
+should be automatically prepared and used. Installers may use special
+options at configuration time for changing this behavior. The command
+`./configure --with-included-gettext' bypasses system `catgets' or
+`gettext' to use GNU `gettext' instead, while `./configure
+--disable-nls' produces program totally unable to translate messages.
+
+ Internationalized packages have usually many `LL.po' files. Unless
+translations are disabled, all those available are installed together
+with the package. However, the environment variable `LINGUAS' may be
+set, prior to configuration, to limit the installed set. `LINGUAS'
+should then contain a space separated list of two-letter codes, stating
+which languages are allowed.
+
+
+File: gettext.info, Node: End Users, Prev: Installers, Up: Users
+
+Magic for End Users
+===================
+
+ We consider here those packages using GNU `gettext' internally, and
+for which the installers did not disable translation at *configure*
+time. Then, users only have to set the `LANG' environment variable to
+the appropriate `LL' prior to using the programs in the package. *Note
+Matrix::. For example, let's presume a German site. At the shell
+prompt, users merely have to execute `setenv LANG de' (in `csh') or
+`export LANG; LANG=de' (in `sh'). They could even do this from their
+`.login' or `.profile' file.
+
+
+File: gettext.info, Node: Programmers, Next: Translators, Prev: Users, Up: Top
+
+The Programmer's View
+*********************
+
+ One aim of the current message catalog implementation provided by
+GNU `gettext' was to use the systems message catalog handling, if the
+installer wishes to do so. So we perhaps should first take a look at
+the solutions we know about. The people in the POSIX committee does not
+manage to agree on one of the semi-official standards which we'll
+describe below. In fact they couldn't agree on anything, so nothing
+decide only to include an example of an interface. The major Unix
+vendors are split in the usage of the two most important
+specifications: X/Opens catgets vs. Uniforums gettext interface. We'll
+describe them both and later explain our solution of this dilemma.
+
+* Menu:
+
+* catgets:: About `catgets'
+* gettext:: About `gettext'
+* Comparison:: Comparing the two interfaces
+* Using libintl.a:: Using libintl.a in own programs
+* gettext grok:: Being a `gettext' grok
+* Temp Programmers:: Temporary Notes for the Programmers Chapter
+
+
+File: gettext.info, Node: catgets, Next: gettext, Prev: Programmers, Up: Programmers
+
+About `catgets'
+===============
+
+ The `catgets' implementation is defined in the X/Open Portability
+Guide, Volume 3, XSI Supplementary Definitions, Chapter 5. But the
+process of creating this standard seemed to be too slow for some of the
+Unix vendors so they created their implementations on preliminary
+versions of the standard. Of course this leads again to problems while
+writing platform independent programs: even the usage of `catgets' does
+not guarantee a unique interface.
+
+ Another, personal comment on this that only a bunch of committee
+members could have made this interface. They never really tried to
+program using this interface. It is a fast, memory-saving
+implementation, an user can happily live with it. But programmers hate
+it (at least me and some others do...)
+
+ But we must not forget one point: after all the trouble with
+transfering the rights on Unix(tm) they at last came to X/Open, the
+very same who published this specifications. This leads me to making
+the prediction that this interface will be in future Unix standards
+(e.g. Spec1170) and therefore part of all Unix implementation
+(implementations, which are *allowed* to wear this name).
+
+* Menu:
+
+* Interface to catgets:: The interface
+* Problems with catgets:: Problems with the `catgets' interface?!
+
+
+File: gettext.info, Node: Interface to catgets, Next: Problems with catgets, Prev: catgets, Up: catgets
+
+The Interface
+-------------
+
+ The interface to the `catgets' implementation consists of three
+functions which correspond to those used in file access: `catopen' to
+open the catalog for using, `catgets' for accessing the message tables,
+and `catclose' for closing after work is done. Prototypes for the
+functions and the needed definitions are in the `<nl_types.h>' header
+file.
+
+ `catopen' is used like in this:
+
+ nl_catd catd = catopen ("catalog_name", 0);
+
+ The function takes as the argument the name of the catalog. This
+usual refers to the name of the program or the package. The second
+parameter is not further specified in the standard. I don't even know
+whether it is implemented consistently among various systems. So the
+common advice is to use `0' as the value. The return value is a handle
+to the message catalog, equivalent to handles to file returned by
+`open'.
+
+ This handle is of course used in the `catgets' function which can be
+used like this:
+
+ char *translation = catgets (catd, set_no, msg_id, "original string");
+
+ The first parameter is this catalog descriptor. The second parameter
+specifies the set of messages in this catalog, in which the message
+described by `msg_id' is obtained. `catgets' therefore uses a
+three-stage addressing:
+
+ catalog name => set number => message ID => translation
+
+ The fourth argument is not used to address the translation. It is
+given as a default value in case when one of the addressing stages
+fail. One important thing to remember is that although the return type
+of catgets is `char *' the resulting string *must not* be changed. It
+should better `const char *', but the standard is published in 1988,
+one year before ANSI C.
+
+The last of these function functions is used and behaves as expected:
+
+ catclose (catd);
+
+ After this no `catgets' call using the descriptor is legal anymore.
+
+
+File: gettext.info, Node: Problems with catgets, Prev: Interface to catgets, Up: catgets
+
+Problems with the `catgets' Interface?!
+---------------------------------------
+
+ Now that this descriptions seemed to be really easy where are the
+problem we speak of. In fact the interface could be used in a
+reasonable way, but constructing the message catalogs is a pain. The
+reason for this lies in the third argument of `catgets': the unique
+message ID. This has to be a numeric value for all messages in a single
+set. Perhaps you could imagine the problems keeping such list while
+changing the source code. Add a new message here, remove one there. Of
+course there have been developed a lot of tools helping to organize this
+chaos but one as the other fails in one aspect or the other. We don't
+want to say that the other approach has no problems but they are far
+more easily to manage.
+
+
+File: gettext.info, Node: gettext, Next: Comparison, Prev: catgets, Up: Programmers
+
+About `gettext'
+===============
+
+ The definition of the `gettext' interface comes from a Uniforum
+proposal and it is followed by at least one major Unix vendor (Sun) in
+its last developments. It is not specified in any official standard,
+though.
+
+ The main points about this solution is that it does not follow the
+method of normal file handling (open-use-close) and that it does not
+burden the programmer so many task, especially the unique key handling.
+Of course here is also a unique key needed, but this key is the message
+itself (how long or short it is). See *Note Comparison:: for a more
+detailed comparison of the two methods.
+
+ The following section contains a rather detailed description of the
+interface. We make it that detailed because this is the interface we
+chose for the GNU `gettext' Library. Programmers interested in using
+this library will be interested in this description.
+
+* Menu:
+
+* Interface to gettext:: The interface
+* Ambiguities:: Solving ambiguities
+* Locating Catalogs:: Locating message catalog files
+* Optimized gettext:: Optimization of the *gettext functions
+
+
+File: gettext.info, Node: Interface to gettext, Next: Ambiguities, Prev: gettext, Up: gettext
+
+The Interface
+-------------
+
+ The minimal functionality an interface must have is a) to select a
+domain the strings are coming from (a single domain for all programs is
+not reasonable because its construction and maintenance is difficult,
+perhaps impossible) and b) to access a string in a selected domain.
+
+ This is principally the description of the `gettext' interface. It
+has an global domain which unqualified usages reference. Of course this
+domain is selectable by the user.
+
+ char *textdomain (const char *domain_name);
+
+ This provides the possibility to change or query the current status
+of the current global domain of the `LC_MESSAGE' category. The
+argument is a null-terminated string, whose characters must be legal in
+the use in filenames. If the DOMAIN_NAME argument is `NULL', the
+function return the current value. If no value has been set before,
+the name of the default domain is returned: *messages*. Please note
+that although the return value of `textdomain' is of type `char *' no
+changing is allowed. It is also important to know that no checks of
+the availability are made. If the name is not available you will see
+this by the fact that no translations are provided.
+
+To use a domain set by `textdomain' the function
+
+ char *gettext (const char *msgid);
+
+ is to be used. This is the simplest reasonable form one can imagine.
+The translation of the string MSGID is returned if it is available in
+the current domain. If not available the argument itself is returned.
+If the argument is `NULL' the result is undefined.
+
+ One things which should come into mind is that no explicit
+dependency to the used domain is given. The current value of the
+domain for the `LC_MESSAGES' locale is used. If this changes between
+two executions of the same `gettext' call in the program, both calls
+reference a different message catalog.
+
+ For the easiest case, which is normally used in internationalized
+packages, once at the beginning of execution a call to `textdomain' is
+issued, setting the domain to a unique name, normally the package name.
+In the following code all strings which have to be translated are
+filtered through the gettext function. That's all, the package speaks
+your language.
+
+
+File: gettext.info, Node: Ambiguities, Next: Locating Catalogs, Prev: Interface to gettext, Up: gettext
+
+Solving Ambiguities
+-------------------
+
+ While this single name domain work good for most applications there
+might be the need to get translations from more than one domain. Of
+course one could switch between different domains with calls to
+`textdomain', but this is really not convenient nor is it fast. A
+possible situation could be one case discussing while this writing: all
+error messages of functions in the set of common used functions should
+go into a separate domain `error'. By this mean we would only need to
+translate them once.
+
+For this reasons there are two more functions to retrieve strings:
+
+ char *dgettext (const char *domain_name, const char *msgid);
+ char *dcgettext (const char *domain_name, const char *msgid,
+ int category);
+
+ Both take an additional argument at the first place, which
+corresponds to the argument of `textdomain'. The third argument of
+`dcgettext' allows to use another locale but `LC_MESSAGES'. But I
+really don't know where this can be useful. If the DOMAIN_NAME is
+`NULL' or CATEGORY has an value beside the known ones, the result is
+undefined. It should also be noted that this function is not part of
+the second known implementation of this function family, the one found
+in Solaris.
+
+ A second ambiguity can arise by the fact, that perhaps more than one
+domain has the same name. This can be solved by specifying where the
+needed message catalog files can be found.
+
+ char *bindtextdomain (const char *domain_name,
+ const char *dir_name);
+
+ Calling this function binds the given domain to a file in the
+specified directory (how this file is determined follows below).
+Especially a file in the systems default place is not favored against
+the specified file anymore (as it would be by solely using
+`textdomain'). A `NULL' pointer for the DIR_NAME parameter returns the
+binding associated with DOMAIN_NAME. If DOMAIN_NAME itself is `NULL'
+nothing happens and a `NULL' pointer is returned. Here again as for
+all the other functions is true that none of the return value must be
+changed!
+
+ It is important to remember that relative path names for the
+DIR_NAME parameter can be trouble. Since the path is always computed
+relative to the current directory different results will be achieved
+when the program executes a `chdir' command. Relative paths should
+always be avoided to avoid dependencies and unreliabilities.
+
+
+File: gettext.info, Node: Locating Catalogs, Next: Optimized gettext, Prev: Ambiguities, Up: gettext
+
+Locating Message Catalog Files
+------------------------------
+
+ Because many different languages for many different packages have to
+be stored we need some way to add these information to file message
+catalog files. The way usually used in Unix environments is have this
+encoding in the file name. This is also done here. The directory name
+given in `bindtextdomain's second argument (or the default directory),
+followed by the value and name of the locale and the domain name are
+concatenated:
+
+ DIR_NAME/LOCALE/LC_CATEGORY/DOMAIN_NAME.mo
+
+ The default value for DIR_NAME is system specific. For the GNU
+library, and for packages adhering to its conventions, it's:
+ /usr/local/share/locale
+
+LOCALE is the value of the locale whose name is this `LC_CATEGORY'.
+For `gettext' and `dgettext' this locale is always `LC_MESSAGES'.
+`dcgettext' specifies the locale by the third argument.(1) (2)
+
+ ---------- Footnotes ----------
+
+ (1) Some system, eg Ultrix, don't have `LC_MESSAGES'. Here we use a
+more or less arbitrary value for it.
+
+ (2) When the system does not support `setlocale' its behavior in
+setting the locale values is simulated by looking at the environment
+variables.
+
diff --git a/doc/gettext.info-4 b/doc/gettext.info-4
new file mode 100644
index 0000000..21f46dd
--- /dev/null
+++ b/doc/gettext.info-4
@@ -0,0 +1,1110 @@
+This is Info file gettext.info, produced by Makeinfo version 1.68 from
+the input file gettext.texi.
+
+INFO-DIR-SECTION GNU Gettext Utilities
+START-INFO-DIR-ENTRY
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+END-INFO-DIR-ENTRY
+
+ This file provides documentation for GNU `gettext' utilities. It
+also serves as a reference for the free Translation Project.
+
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: gettext.info, Node: Optimized gettext, Prev: Locating Catalogs, Up: gettext
+
+Optimization of the *gettext functions
+--------------------------------------
+
+ At this point of the discussion we should talk about an advantage of
+the GNU `gettext' implementation. Some readers might have pointed out
+that an internationalized program might have a poor performance if some
+string has to be translated in an inner loop. While this is unavoidable
+when the string varies from one run of the loop to the other it is
+simply a waste of time when the string is always the same. Take the
+following example:
+
+ {
+ while (...)
+ {
+ puts (gettext ("Hello world"));
+ }
+ }
+
+When the locale selection does not change between two runs the resulting
+string is always the same. One way to use this is:
+
+ {
+ str = gettext ("Hello world");
+ while (...)
+ {
+ puts (str);
+ }
+ }
+
+But this solution is not usable in all situation (e.g. when the locale
+selection changes) nor is it good readable.
+
+ The GNU C compiler, version 2.7 and above, provide another solution
+for this. To describe this we show here some lines of the
+`intl/libgettext.h' file. For an explanation of the expression command
+block see *Note Statements and Declarations in Expressions:
+(gcc)Statement Exprs.
+
+ # if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+ extern int _nl_msg_cat_cntr;
+ # define dcgettext(domainname, msgid, category) \
+ (__extension__ \
+ ({ \
+ char *result; \
+ if (__builtin_constant_p (msgid)) \
+ { \
+ static char *__translation__; \
+ static int __catalog_counter__; \
+ if (! __translation__ \
+ || __catalog_counter__ != _nl_msg_cat_cntr) \
+ { \
+ __translation__ = \
+ dcgettext__ ((domainname), (msgid), (category)); \
+ __catalog_counter__ = _nl_msg_cat_cntr; \
+ } \
+ result = __translation__; \
+ } \
+ else \
+ result = dcgettext__ ((domainname), (msgid), (category)); \
+ result; \
+ }))
+ # endif
+
+ The interesting thing here is the `__builtin_constant_p' predicate.
+This is evaluated at compile time and so optimization can take place
+immediately. Here two cases are distinguished: the argument to
+`gettext' is not a constant value in which case simply the function
+`dcgettext__' is called, the real implementation of the `dcgettext'
+function.
+
+ If the string argument *is* constant we can reuse the once gained
+translation when the locale selection has not changed. This is exactly
+what is done here. The `_nl_msg_cat_cntr' variable is defined in the
+`loadmsgcat.c' which is available in `libintl.a' and is changed
+whenever a new message catalog is loaded.
+
+
+File: gettext.info, Node: Comparison, Next: Using libintl.a, Prev: gettext, Up: Programmers
+
+Comparing the Two Interfaces
+============================
+
+ The following discussion is perhaps a little bit colored. As said
+above we implemented GNU `gettext' following the Uniforum proposal and
+this surely has its reasons. But it should show how we came to this
+decision.
+
+ First we take a look at the developing process. When we write an
+application using NLS provided by `gettext' we proceed as always. Only
+when we come to a string which might be seen by the users and thus has
+to be translated we use `gettext("...")' instead of `"..."'. At the
+beginning of each source file (or in a central header file) we define
+
+ #define gettext(String) (String)
+
+ Even this definition can be avoided when the system supports the
+`gettext' function in its C library. When we compile this code the
+result is the same as if no NLS code is used. When you take a look at
+the GNU `gettext' code you will see that we use `_("...")' instead of
+`gettext("...")'. This reduces the number of additional characters per
+translatable string to *3* (in words: three).
+
+ When now a production version of the program is needed we simply
+replace the definition
+
+ #define _(String) (String)
+
+by
+
+ #include <libintl.h>
+ #define _(String) gettext (String)
+
+Additionally we run the program `xgettext' on all source code file
+which contain translatable strings and that's it: we have a running
+program which does not depend on translations to be available, but which
+can use any that becomes available.
+
+ The same procedure can be done for the `gettext_noop' invocations
+(*note Special cases::.). First you can define `gettext_noop' to a
+no-op macro and later use the definition from `libintl.h'. Because
+this name is not used in Suns implementation of `libintl.h', you should
+consider the following code for your project:
+
+ #ifdef gettext_noop
+ # define N_(String) gettext_noop (String)
+ #else
+ # define N_(String) (String)
+ #endif
+
+ `N_' is a short form similar to `_'. The `Makefile' in the `po/'
+directory of GNU `gettext' knows by default both of the mentioned short
+forms so you are invited to follow this proposal for your own ease.
+
+ Now to `catgets'. The main problem is the work for the programmer.
+Every time he comes to a translatable string he has to define a number
+(or a symbolic constant) which has also be defined in the message
+catalog file. He also has to take care for duplicate entries,
+duplicate message IDs etc. If he wants to have the same quality in the
+message catalog as the GNU `gettext' program provides he also has to
+put the descriptive comments for the strings and the location in all
+source code files in the message catalog. This is nearly a Mission:
+Impossible.
+
+ But there are also some points people might call advantages speaking
+for `catgets'. If you have a single word in a string and this string
+is used in different contexts it is likely that in one or the other
+language the word has different translations. Example:
+
+ printf ("%s: %d", gettext ("number"), number_of_errors)
+
+ printf ("you should see %d %s", number_count,
+ number_count == 1 ? gettext ("number") : gettext ("numbers"))
+
+ Here we have to translate two times the string `"number"'. Even if
+you do not speak a language beside English it might be possible to
+recognize that the two words have a different meaning. In German the
+first appearance has to be translated to `"Anzahl"' and the second to
+`"Zahl"'.
+
+ Now you can say that this example is really esoteric. And you are
+right! This is exactly how we felt about this problem and decide that
+it does not weight that much. The solution for the above problem could
+be very easy:
+
+ printf ("%s %d", gettext ("number:"), number_of_errors)
+
+ printf (number_count == 1 ? gettext ("you should see %d number")
+ : gettext ("you should see %d numbers"),
+ number_count)
+
+ We believe that we can solve all conflicts with this method. If it
+is difficult one can also consider changing one of the conflicting
+string a little bit. But it is not impossible to overcome.
+
+ Translator note: It is perhaps appropriate here to tell those English
+speaking programmers that the plural form of a noun cannot be formed by
+appending a single `s'. Most other languages use different methods.
+Even the above form is not general enough to cope with all languages.
+Rafal Maszkowski <rzm@mat.uni.torun.pl> reports:
+
+ In Polish we use e.g. plik (file) this way:
+ 1 plik
+ 2,3,4 pliki
+ 5-21 pliko'w
+ 22-24 pliki
+ 25-31 pliko'w
+ and so on (o' means 8859-2 oacute which should be rather okreska,
+ similar to aogonek).
+
+ A workable approach might be to consider methods like the one used
+for `LC_TIME' in the POSIX.2 standard. The value of the `alt_digits'
+field can be up to 100 strings which represent the numbers 1 to 100.
+Using this in a situation of an internationalized program means that an
+array of translatable strings should be indexed by the number which
+should represent. A small example:
+
+ void
+ print_month_info (int month)
+ {
+ const char *month_pos[12] =
+ { N_("first"), N_("second"), N_("third"), N_("fourth"),
+ N_("fifth"), N_("sixth"), N_("seventh"), N_("eighth"),
+ N_("ninth"), N_("tenth"), N_("eleventh"), N_("twelfth") };
+ printf (_("%s is the %s month\n"), nl_langinfo (MON_1 + month),
+ _(month_pos[month]));
+ }
+
+It should be obvious that this method is only reasonable for small
+ranges of numbers.
+
+
+File: gettext.info, Node: Using libintl.a, Next: gettext grok, Prev: Comparison, Up: Programmers
+
+Using libintl.a in own programs
+===============================
+
+ Starting with version 0.9.4 the library `libintl.h' should be
+self-contained. I.e., you can use it in your own programs without
+providing additional functions. The `Makefile' will put the header and
+the library in directories selected using the `$(prefix)'.
+
+ One exception of the above is found on HP-UX systems. Here the C
+library does not contain the `alloca' function (and the HP compiler does
+not generate it inlined). But it is not intended to rewrite the whole
+library just because of this dumb system. Instead include the `alloca'
+function in all package you use the `libintl.a' in.
+
+
+File: gettext.info, Node: gettext grok, Next: Temp Programmers, Prev: Using libintl.a, Up: Programmers
+
+Being a `gettext' grok
+======================
+
+ To fully exploit the functionality of the GNU `gettext' library it
+is surely helpful to read the source code. But for those who don't want
+to spend that much time in reading the (sometimes complicated) code here
+is a list comments:
+
+ * Changing the language at runtime
+
+ For interactive programs it might be useful to offer a selection
+ of the used language at runtime. To understand how to do this one
+ need to know how the used language is determined while executing
+ the `gettext' function. The method which is presented here only
+ works correctly with the GNU implementation of the `gettext'
+ functions. It is not possible with underlying `catgets' functions
+ or `gettext' functions from the systems C library. The exception
+ is of course the GNU C Library which uses the GNU `gettext'
+ Library for message handling.
+
+ In the function `dcgettext' at every call the current setting of
+ the highest priority environment variable is determined and used.
+ Highest priority means here the following list with decreasing
+ priority:
+
+ 1. `LANGUAGE'
+
+ 2. `LC_ALL'
+
+ 3. `LC_xxx', according to selected locale
+
+ 4. `LANG'
+
+ Afterwards the path is constructed using the found value and the
+ translation file is loaded if available.
+
+ What is now when the value for, say, `LANGUAGE' changes. According
+ to the process explained above the new value of this variable is
+ found as soon as the `dcgettext' function is called. But this
+ also means the (perhaps) different message catalog file is loaded.
+ In other words: the used language is changed.
+
+ But there is one little hook. The code for gcc-2.7.0 and up
+ provides some optimization. This optimization normally prevents
+ the calling of the `dcgettext' function as long as no new catalog
+ is loaded. But if `dcgettext' is not called the program also
+ cannot find the `LANGUAGE' variable be changed (*note Optimized
+ gettext::.). A solution for this is very easy. Include the
+ following code in the language switching function.
+
+ /* Change language. */
+ setenv ("LANGUAGE", "fr", 1);
+
+ /* Make change known. */
+ {
+ extern int _nl_msg_cat_cntr;
+ ++_nl_msg_cat_cntr;
+ }
+
+ The variable `_nl_msg_cat_cntr' is defined in `loadmsgcat.c'. The
+ programmer will find himself in need for a construct like this only
+ when developing programs which do run longer and provide the user
+ to select the language at runtime. Non-interactive programs (like
+ all these little Unix tools) should never need this.
+
+
+File: gettext.info, Node: Temp Programmers, Prev: gettext grok, Up: Programmers
+
+Temporary Notes for the Programmers Chapter
+===========================================
+
+* Menu:
+
+* Temp Implementations:: Temporary - Two Possible Implementations
+* Temp catgets:: Temporary - About `catgets'
+* Temp WSI:: Temporary - Why a single implementation
+* Temp Notes:: Temporary - Notes
+
+
+File: gettext.info, Node: Temp Implementations, Next: Temp catgets, Prev: Temp Programmers, Up: Temp Programmers
+
+Temporary - Two Possible Implementations
+----------------------------------------
+
+ There are two competing methods for language independent messages:
+the X/Open `catgets' method, and the Uniforum `gettext' method. The
+`catgets' method indexes messages by integers; the `gettext' method
+indexes them by their English translations. The `catgets' method has
+been around longer and is supported by more vendors. The `gettext'
+method is supported by Sun, and it has been heard that the COSE
+multi-vendor initiative is supporting it. Neither method is a POSIX
+standard; the POSIX.1 committee had a lot of disagreement in this area.
+
+ Neither one is in the POSIX standard. There was much disagreement
+in the POSIX.1 committee about using the `gettext' routines vs.
+`catgets' (XPG). In the end the committee couldn't agree on anything,
+so no messaging system was included as part of the standard. I believe
+the informative annex of the standard includes the XPG3 messaging
+interfaces, "...as an example of a messaging system that has been
+implemented..."
+
+ They were very careful not to say anywhere that you should use one
+set of interfaces over the other. For more on this topic please see
+the Programming for Internationalization FAQ.
+
+
+File: gettext.info, Node: Temp catgets, Next: Temp WSI, Prev: Temp Implementations, Up: Temp Programmers
+
+Temporary - About `catgets'
+---------------------------
+
+ There have been a few discussions of late on the use of `catgets' as
+a base. I think it important to present both sides of the argument and
+hence am opting to play devil's advocate for a little bit.
+
+ I'll not deny the fact that `catgets' could have been designed a lot
+better. It currently has quite a number of limitations and these have
+already been pointed out.
+
+ However there is a great deal to be said for consistency and
+standardization. A common recurring problem when writing Unix software
+is the myriad portability problems across Unix platforms. It seems as
+if every Unix vendor had a look at the operating system and found parts
+they could improve upon. Undoubtedly, these modifications are probably
+innovative and solve real problems. However, software developers have
+a hard time keeping up with all these changes across so many platforms.
+
+ And this has prompted the Unix vendors to begin to standardize their
+systems. Hence the impetus for Spec1170. Every major Unix vendor has
+committed to supporting this standard and every Unix software developer
+waits with glee the day they can write software to this standard and
+simply recompile (without having to use autoconf) across different
+platforms.
+
+ As I understand it, Spec1170 is roughly based upon version 4 of the
+X/Open Portability Guidelines (XPG4). Because `catgets' and friends
+are defined in XPG4, I'm led to believe that `catgets' is a part of
+Spec1170 and hence will become a standardized component of all Unix
+systems.
+
+
+File: gettext.info, Node: Temp WSI, Next: Temp Notes, Prev: Temp catgets, Up: Temp Programmers
+
+Temporary - Why a single implementation
+---------------------------------------
+
+ Now it seems kind of wasteful to me to have two different systems
+installed for accessing message catalogs. If we do want to remedy
+`catgets' deficiencies why don't we try to expand `catgets' (in a
+compatible manner) rather than implement an entirely new system.
+Otherwise, we'll end up with two message catalog access systems
+installed with an operating system - one set of routines for packages
+using GNU `gettext' for their internationalization, and another set of
+routines (catgets) for all other software. Bloated?
+
+ Supposing another catalog access system is implemented. Which do we
+recommend? At least for Linux, we need to attract as many software
+developers as possible. Hence we need to make it as easy for them to
+port their software as possible. Which means supporting `catgets'. We
+will be implementing the `glocale' code within our `libc', but does
+this mean we also have to incorporate another message catalog access
+scheme within our `libc' as well? And what about people who are going
+to be using the `glocale' + non-`catgets' routines. When they port
+their software to other platforms, they're now going to have to include
+the front-end (`glocale') code plus the back-end code (the non-`catgets'
+access routines) with their software instead of just including the
+`glocale' code with their software.
+
+ Message catalog support is however only the tip of the iceberg.
+What about the data for the other locale categories. They also have a
+number of deficiencies. Are we going to abandon them as well and
+develop another duplicate set of routines (should `glocale' expand
+beyond message catalog support)?
+
+ Like many parts of Unix that can be improved upon, we're stuck with
+balancing compatibility with the past with useful improvements and
+innovations for the future.
+
+
+File: gettext.info, Node: Temp Notes, Prev: Temp WSI, Up: Temp Programmers
+
+Temporary - Notes
+-----------------
+
+ X/Open agreed very late on the standard form so that many
+implementations differ from the final form. Both of my system (old
+Linux catgets and Ultrix-4) have a strange variation.
+
+ OK. After incorporating the last changes I have to spend some time
+on making the GNU/Linux `libc' `gettext' functions. So in future
+Solaris is not the only system having `gettext'.
+
+
+File: gettext.info, Node: Translators, Next: Maintainers, Prev: Programmers, Up: Top
+
+The Translator's View
+*********************
+
+* Menu:
+
+* Trans Intro 0:: Introduction 0
+* Trans Intro 1:: Introduction 1
+* Discussions:: Discussions
+* Organization:: Organization
+* Information Flow:: Information Flow
+
+
+File: gettext.info, Node: Trans Intro 0, Next: Trans Intro 1, Prev: Translators, Up: Translators
+
+Introduction 0
+==============
+
+ Free software is going international! The Translation Project is a
+way to get maintainers, translators and users all together, so free
+software will gradually become able to speak many native languages.
+
+ The GNU `gettext' tool set contains *everything* maintainers need
+for internationalizing their packages for messages. It also contains
+quite useful tools for helping translators at localizing messages to
+their native language, once a package has already been
+internationalized.
+
+ To achieve the Translation Project, we need many interested people
+who like their own language and write it well, and who are also able to
+synergize with other translators speaking the same language. If you'd
+like to volunteer to *work* at translating messages, please send mail
+to your translating team.
+
+ Each team has its own mailing list, courtesy of Linux International.
+You may reach your translating team at the address `LL@li.org',
+replacing LL by the two-letter ISO 639 code for your language.
+Language codes are *not* the same as country codes given in ISO 3166.
+The following translating teams exist:
+
+ Chinese `zh', Czech `cs', Danish `da', Dutch `nl', Esperanto `eo',
+ Finnish `fi', French `fr', Irish `ga', German `de', Greek `el',
+ Italian `it', Japanese `ja', Indonesian `in', Norwegian `no',
+ Polish `pl', Portuguese `pt', Russian `ru', Spanish `es', Swedish
+ `sv' and Turkish `tr'.
+
+For example, you may reach the Chinese translating team by writing to
+`zh@li.org'. When you become a member of the translating team for your
+own language, you may subscribe to its list. For example, Swedish
+people can send a message to `sv-request@li.org', having this message
+body:
+
+ subscribe
+
+ Keep in mind that team members should be interested in *working* at
+translations, or at solving translational difficulties, rather than
+merely lurking around. If your team does not exist yet and you want to
+start one, please write to `translation@iro.umontreal.ca'; you will
+then reach the coordinator for all translator teams.
+
+ A handful of GNU packages have already been adapted and provided
+with message translations for several languages. Translation teams
+have begun to organize, using these packages as a starting point. But
+there are many more packages and many languages for which we have no
+volunteer translators. If you would like to volunteer to work at
+translating messages, please send mail to
+`translation@iro.umontreal.ca' indicating what language(s) you can work
+on.
+
+
+File: gettext.info, Node: Trans Intro 1, Next: Discussions, Prev: Trans Intro 0, Up: Translators
+
+Introduction 1
+==============
+
+ This is now official, GNU is going international! Here is the
+announcement submitted for the January 1995 GNU Bulletin:
+
+ A handful of GNU packages have already been adapted and provided
+ with message translations for several languages. Translation
+ teams have begun to organize, using these packages as a starting
+ point. But there are many more packages and many languages for
+ which we have no volunteer translators. If you'd like to
+ volunteer to work at translating messages, please send mail to
+ `translation@iro.umontreal.ca' indicating what language(s) you can
+ work on.
+
+ This document should answer many questions for those who are curious
+about the process or would like to contribute. Please at least skim
+over it, hoping to cut down a little of the high volume of e-mail
+generated by this collective effort towards internationalization of
+free software.
+
+ Most free programming which is widely shared is done in English, and
+currently, English is used as the main communicating language between
+national communities collaborating to free software. This very document
+is written in English. This will not change in the foreseeable future.
+
+ However, there is a strong appetite from national communities for
+having more software able to write using national language and habits,
+and there is an on-going effort to modify free software in such a way
+that it becomes able to do so. The experiments driven so far raised an
+enthusiastic response from pretesters, so we believe that
+internationalization of free software is dedicated to succeed.
+
+ For suggestion clarifications, additions or corrections to this
+document, please e-mail to `translation@iro.umontreal.ca'.
+
+
+File: gettext.info, Node: Discussions, Next: Organization, Prev: Trans Intro 1, Up: Translators
+
+Discussions
+===========
+
+ Facing this internationalization effort, a few users expressed their
+concerns. Some of these doubts are presented and discussed, here.
+
+ * Smaller groups
+
+ Some languages are not spoken by a very large number of people, so
+ people speaking them sometimes consider that there may not be all
+ that much demand such versions of free software packages.
+ Moreover, many people being *into computers*, in some countries,
+ generally seem to prefer English versions of their software.
+
+ On the other end, people might enjoy their own language a lot, and
+ be very motivated at providing to themselves the pleasure of
+ having their beloved free software speaking their mother tongue.
+ They do themselves a personal favor, and do not pay that much
+ attention to the number of people beneficiating of their work.
+
+ * Misinterpretation
+
+ Other users are shy to push forward their own language, seeing in
+ this some kind of misplaced propaganda. Someone thought there
+ must be some users of the language over the networks pestering
+ other people with it.
+
+ But any spoken language is worth localization, because there are
+ people behind the language for whom the language is important and
+ dear to their hearts.
+
+ * Odd translations
+
+ The biggest problem is to find the right translations so that
+ everybody can understand the messages. Translations are usually a
+ little odd. Some people get used to English, to the extent they
+ may find translations into their own language "rather pushy,
+ obnoxious and sometimes even hilarious." As a French speaking
+ man, I have the experience of those instruction manuals for goods,
+ so poorly translated in French in Korea or Taiwan...
+
+ The fact is that we sometimes have to create a kind of national
+ computer culture, and this is not easy without the collaboration of
+ many people liking their mother tongue. This is why translations
+ are better achieved by people knowing and loving their own
+ language, and ready to work together at improving the results they
+ obtain.
+
+ * Dependencies over the GPL
+
+ Some people wonder if using GNU `gettext' necessarily brings their
+ package under the protective wing of the GNU General Public
+ License, when they do not want to make their program free, or want
+ other kinds of freedom. The simplest answer is yes.
+
+ The mere marking of localizable strings in a package, or
+ conditional inclusion of a few lines for initialization, is not
+ really including GPL'ed code. However, the localization routines
+ themselves are under the GPL and would bring the remainder of the
+ package under the GPL if they were distributed with it. So, I
+ presume that, for those for which this is a problem, it could be
+ circumvented by letting to the end installers the burden of
+ assembling a package prepared for localization, but not providing
+ the localization routines themselves.
+
+
+File: gettext.info, Node: Organization, Next: Information Flow, Prev: Discussions, Up: Translators
+
+Organization
+============
+
+ On a larger scale, the true solution would be to organize some kind
+of fairly precise set up in which volunteers could participate. I gave
+some thought to this idea lately, and realize there will be some touchy
+points. I thought of writing to Richard Stallman to launch such a
+project, but feel it might be good to shake out the ideas between
+ourselves first. Most probably that Linux International has some
+experience in the field already, or would like to orchestrate the
+volunteer work, maybe. Food for thought, in any case!
+
+ I guess we have to setup something early, somehow, that will help
+many possible contributors of the same language to interlock and avoid
+work duplication, and further be put in contact for solving together
+problems particular to their tongue (in most languages, there are many
+difficulties peculiar to translating technical English). My Swedish
+contributor acknowledged these difficulties, and I'm well aware of them
+for French.
+
+ This is surely not a technical issue, but we should manage so the
+effort of locale contributors be maximally useful, despite the national
+team layer interface between contributors and maintainers.
+
+ The Translation Project needs some setup for coordinating language
+coordinators. Localizing evolving programs will surely become a
+permanent and continuous activity in the free software community, once
+well started. The setup should be minimally completed and tested
+before GNU `gettext' becomes an official reality. The e-mail address
+`translation@iro.umontreal.ca' has been setup for receiving offers from
+volunteers and general e-mail on these topics. This address reaches
+the Translation Project coordinator.
+
+* Menu:
+
+* Central Coordination:: Central Coordination
+* National Teams:: National Teams
+* Mailing Lists:: Mailing Lists
+
+
+File: gettext.info, Node: Central Coordination, Next: National Teams, Prev: Organization, Up: Organization
+
+Central Coordination
+--------------------
+
+ I also think GNU will need sooner than it thinks, that someone setup
+a way to organize and coordinate these groups. Some kind of group of
+groups. My opinion is that it would be good that GNU delegates this
+task to a small group of collaborating volunteers, shortly. Perhaps in
+`gnu.announce' a list of this national committee's can be published.
+
+ My role as coordinator would simply be to refer to Ulrich any German
+speaking volunteer interested to localization of free software
+packages, and maybe helping national groups to initially organize,
+while maintaining national registries for until national groups are
+ready to take over. In fact, the coordinator should ease volunteers to
+get in contact with one another for creating national teams, which
+should then select one coordinator per language, or country
+(regionalized language). If well done, the coordination should be
+useful without being an overwhelming task, the time to put delegations
+in place.
+
+
+File: gettext.info, Node: National Teams, Next: Mailing Lists, Prev: Central Coordination, Up: Organization
+
+National Teams
+--------------
+
+ I suggest we look for volunteer coordinators/editors for individual
+languages. These people will scan contributions of translation files
+for various programs, for their own languages, and will ensure high and
+uniform standards of diction.
+
+ From my current experience with other people in these days, those who
+provide localizations are very enthusiastic about the process, and are
+more interested in the localization process than in the program they
+localize, and want to do many programs, not just one. This seems to
+confirm that having a coordinator/editor for each language is a good
+idea.
+
+ We need to choose someone who is good at writing clear and concise
+prose in the language in question. That is hard--we can't check it
+ourselves. So we need to ask a few people to judge each others'
+writing and select the one who is best.
+
+ I announce my prerelease to a few dozen people, and you would not
+believe all the discussions it generated already. I shudder to think
+what will happen when this will be launched, for true, officially,
+world wide. Who am I to arbitrate between two Czekolsovak users
+contradicting each other, for example?
+
+ I assume that your German is not much better than my French so that
+I would not be able to judge about these formulations. What I would
+suggest is that for each language there is a group for people who
+maintain the PO files and judge about changes. I suspect there will be
+cultural differences between how such groups of people will behave.
+Some will have relaxed ways, reach consensus easily, and have anyone of
+the group relate to the maintainers, while others will fight to death,
+organize heavy administrations up to national standards, and use strict
+channels.
+
+ The German team is putting out a good example. Right now, they are
+maybe half a dozen people revising translations of each other and
+discussing the linguistic issues. I do not even have all the names.
+Ulrich Drepper is taking care of coordinating the German team. He
+subscribed to all my pretest lists, so I do not even have to warn him
+specifically of incoming releases.
+
+ I'm sure, that is a good idea to get teams for each language working
+on translations. That will make the translations better and more
+consistent.
+
+* Menu:
+
+* Sub-Cultures:: Sub-Cultures
+* Organizational Ideas:: Organizational Ideas
+
+
+File: gettext.info, Node: Sub-Cultures, Next: Organizational Ideas, Prev: National Teams, Up: National Teams
+
+Sub-Cultures
+............
+
+ Taking French for example, there are a few sub-cultures around
+computers which developed diverging vocabularies. Picking volunteers
+here and there without addressing this problem in an organized way,
+soon in the project, might produce a distasteful mix of
+internationalized programs, and possibly trigger endless quarrels among
+those who really care.
+
+ Keeping some kind of unity in the way French localization of
+internationalized programs is achieved is a difficult (and delicate)
+job. Knowing the latin character of French people (:-), if we take this
+the wrong way, we could end up nowhere, or spoil a lot of energies.
+Maybe we should begin to address this problem seriously *before* GNU
+`gettext' become officially published. And I suspect that this means
+soon!
+
+
+File: gettext.info, Node: Organizational Ideas, Prev: Sub-Cultures, Up: National Teams
+
+Organizational Ideas
+....................
+
+ I expect the next big changes after the official release. Please
+note that I use the German translation of the short GPL message. We
+need to set a few good examples before the localization goes out for
+true in the free software community. Here are a few points to discuss:
+
+ * Each group should have one FTP server (at least one master).
+
+ * The files on the server should reflect the latest version (of
+ course!) and it should also contain a RCS directory with the
+ corresponding archives (I don't have this now).
+
+ * There should also be a ChangeLog file (this is more useful than the
+ RCS archive but can be generated automatically from the later by
+ Emacs).
+
+ * A "core group" should judge about questionable changes (for now
+ this group consists solely by me but I ask some others
+ occasionally; this also seems to work).
+
+
+File: gettext.info, Node: Mailing Lists, Prev: National Teams, Up: Organization
+
+Mailing Lists
+-------------
+
+ If we get any inquiries about GNU `gettext', send them on to:
+
+ `translation@iro.umontreal.ca'
+
+ The `*-pretest' lists are quite useful to me, maybe the idea could
+be generalized to many GNU, and non-GNU packages. But each maintainer
+his/her way!
+
+ Franc,ois, we have a mechanism in place here at `gnu.ai.mit.edu' to
+track teams, support mailing lists for them and log members. We have a
+slight preference that you use it. If this is OK with you, I can get
+you clued in.
+
+ Things are changing! A few years ago, when Daniel Fekete and I
+asked for a mailing list for GNU localization, nested at the FSF, we
+were politely invited to organize it anywhere else, and so did we. For
+communicating with my pretesters, I later made a handful of mailing
+lists located at iro.umontreal.ca and administrated by `majordomo'.
+These lists have been *very* dependable so far...
+
+ I suspect that the German team will organize itself a mailing list
+located in Germany, and so forth for other countries. But before they
+organize for true, it could surely be useful to offer mailing lists
+located at the FSF to each national team. So yes, please explain me
+how I should proceed to create and handle them.
+
+ We should create temporary mailing lists, one per country, to help
+people organize. Temporary, because once regrouped and structured, it
+would be fair the volunteers from country bring back *their* list in
+there and manage it as they want. My feeling is that, in the long run,
+each team should run its own list, from within their country. There
+also should be some central list to which all teams could subscribe as
+they see fit, as long as each team is represented in it.
+
+
+File: gettext.info, Node: Information Flow, Prev: Organization, Up: Translators
+
+Information Flow
+================
+
+ There will surely be some discussion about this messages after the
+packages are finally released. If people now send you some proposals
+for better messages, how do you proceed? Jim, please note that right
+now, as I put forward nearly a dozen of localizable programs, I receive
+both the translations and the coordination concerns about them.
+
+ If I put one of my things to pretest, Ulrich receives the
+announcement and passes it on to the German team, who make last minute
+revisions. Then he submits the translation files to me *as the
+maintainer*. For free packages I do not maintain, I would not even
+hear about it. This scheme could be made to work for the whole
+Translation Project, I think. For security reasons, maybe Ulrich
+(national coordinators, in fact) should update central registry kept at
+the Translation Project (Jim, me, or Len's recruits) once in a while.
+
+ In December/January, I was aggressively ready to internationalize
+all of GNU, giving myself the duty of one small GNU package per week or
+so, taking many weeks or months for bigger packages. But it does not
+work this way. I first did all the things I'm responsible for. I've
+nothing against some missionary work on other maintainers, but I'm also
+loosing a lot of energy over it--same debates over again.
+
+ And when the first localized packages are released we'll get a lot of
+responses about ugly translations :-). Surely, and we need to have
+beforehand a fairly good idea about how to handle the information flow
+between the national teams and the package maintainers.
+
+ Please start saving somewhere a quick history of each PO file. I
+know for sure that the file format will change, allowing for comments.
+It would be nice that each file has a kind of log, and references for
+those who want to submit comments or gripes, or otherwise contribute.
+I sent a proposal for a fast and flexible format, but it is not
+receiving acceptance yet by the GNU deciders. I'll tell you when I
+have more information about this.
+
+
+File: gettext.info, Node: Maintainers, Next: Conclusion, Prev: Translators, Up: Top
+
+The Maintainer's View
+*********************
+
+ The maintainer of a package has many responsibilities. One of them
+is ensuring that the package will install easily on many platforms, and
+that the magic we described earlier (*note Users::.) will work for
+installers and end users.
+
+ Of course, there are many possible ways by which GNU `gettext' might
+be integrated in a distribution, and this chapter does not cover them
+in all generality. Instead, it details one possible approach which is
+especially adequate for many free software distributions following GNU
+standards, or even better, Gnits standards, because GNU `gettext' is
+purposely for helping the internationalization of the whole GNU
+project, and as many other good free packages as possible. So, the
+maintainer's view presented here presumes that the package already has
+a `configure.in' file and uses GNU Autoconf.
+
+ Nevertheless, GNU `gettext' may surely be useful for free packages
+not following GNU standards and conventions, but the maintainers of such
+packages might have to show imagination and initiative in organizing
+their distributions so `gettext' work for them in all situations.
+There are surely many, out there.
+
+ Even if `gettext' methods are now stabilizing, slight adjustments
+might be needed between successive `gettext' versions, so you should
+ideally revise this chapter in subsequent releases, looking for changes.
+
+* Menu:
+
+* Flat and Non-Flat:: Flat or Non-Flat Directory Structures
+* Prerequisites:: Prerequisite Works
+* gettextize Invocation:: Invoking the `gettextize' Program
+* Adjusting Files:: Files You Must Create or Alter
+
+
+File: gettext.info, Node: Flat and Non-Flat, Next: Prerequisites, Prev: Maintainers, Up: Maintainers
+
+Flat or Non-Flat Directory Structures
+=====================================
+
+ Some free software packages are distributed as `tar' files which
+unpack in a single directory, these are said to be "flat" distributions.
+Other free software packages have a one level hierarchy of
+subdirectories, using for example a subdirectory named `doc/' for the
+Texinfo manual and man pages, another called `lib/' for holding
+functions meant to replace or complement C libraries, and a
+subdirectory `src/' for holding the proper sources for the package.
+These other distributions are said to be "non-flat".
+
+ For now, we cannot say much about flat distributions. A flat
+directory structure has the disadvantage of increasing the difficulty
+of updating to a new version of GNU `gettext'. Also, if you have many
+PO files, this could somewhat pollute your single directory. In the
+GNU `gettext' distribution, the `misc/' directory contains a shell
+script named `combine-sh'. That script may be used for combining all
+the C files of the `intl/' directory into a pair of C files (one `.c'
+and one `.h'). Those two generated files would fit more easily in a
+flat directory structure, and you will then have to add these two files
+to your project.
+
+ Maybe because GNU `gettext' itself has a non-flat structure, we have
+more experience with this approach, and this is what will be described
+in the remaining of this chapter. Some maintainers might use this as
+an opportunity to unflatten their package structure. Only later, once
+gained more experience adapting GNU `gettext' to flat distributions, we
+might add some notes about how to proceed in flat situations.
+
+
+File: gettext.info, Node: Prerequisites, Next: gettextize Invocation, Prev: Flat and Non-Flat, Up: Maintainers
+
+Prerequisite Works
+==================
+
+ There are some works which are required for using GNU `gettext' in
+one of your package. These works have some kind of generality that
+escape the point by point descriptions used in the remainder of this
+chapter. So, we describe them here.
+
+ * Before attempting to use you should install some other packages
+ first. Ensure that recent versions of GNU `m4', GNU Autoconf and
+ GNU `gettext' are already installed at your site, and if not,
+ proceed to do this first. If you got to install these things,
+ beware that GNU `m4' must be fully installed before GNU Autoconf
+ is even *configured*.
+
+ To further ease the task of a package maintainer the `automake'
+ package was designed and implemented. GNU `gettext' now uses this
+ tool and the `Makefile's in the `intl/' and `po/' therefore know
+ about all the goals necessary for using `automake' and `libintl'
+ in one project.
+
+ Those four packages are only needed to you, as a maintainer; the
+ installers of your own package and end users do not really need
+ any of GNU `m4', GNU Autoconf, GNU `gettext', or GNU `automake'
+ for successfully installing and running your package, with messages
+ properly translated. But this is not completely true if you
+ provide internationalized shell scripts within your own package:
+ GNU `gettext' shall then be installed at the user site if the end
+ users want to see the translation of shell script messages.
+
+ * Your package should use Autoconf and have a `configure.in' file.
+ If it does not, you have to learn how. The Autoconf documentation
+ is quite well written, it is a good idea that you print it and get
+ familiar with it.
+
+ * Your C sources should have already been modified according to
+ instructions given earlier in this manual. *Note Sources::.
+
+ * Your `po/' directory should receive all PO files submitted to you
+ by the translator teams, each having `LL.po' as a name. This is
+ not usually easy to get translation work done before your package
+ gets internationalized and available! Since the cycle has to
+ start somewhere, the easiest for the maintainer is to start with
+ absolutely no PO files, and wait until various translator teams
+ get interested in your package, and submit PO files.
+
+ It is worth adding here a few words about how the maintainer should
+ideally behave with PO files submissions. As a maintainer, your role is
+to authentify the origin of the submission as being the representative
+of the appropriate translating teams of the Translation Project (forward
+the submission to `translation@iro.umontreal.ca' in case of doubt), to
+ensure that the PO file format is not severely broken and does not
+prevent successful installation, and for the rest, to merely to put
+these PO files in `po/' for distribution.
+
+ As a maintainer, you do not have to take on your shoulders the
+responsibility of checking if the translations are adequate or
+complete, and should avoid diving into linguistic matters. Translation
+teams drive themselves and are fully responsible of their linguistic
+choices for the Translation Project. Keep in mind that translator
+teams are *not* driven by maintainers. You can help by carefully
+redirecting all communications and reports from users about linguistic
+matters to the appropriate translation team, or explain users how to
+reach or join their team. The simplest might be to send them the
+`ABOUT-NLS' file.
+
+ Maintainers should *never ever* apply PO file bug reports
+themselves, short-cutting translation teams. If some translator has
+difficulty to get some of her points through her team, it should not be
+an issue for her to directly negotiate translations with maintainers.
+Teams ought to settle their problems themselves, if any. If you, as a
+maintainer, ever think there is a real problem with a team, please
+never try to *solve* a team's problem on your own.
+
+
+File: gettext.info, Node: gettextize Invocation, Next: Adjusting Files, Prev: Prerequisites, Up: Maintainers
+
+Invoking the `gettextize' Program
+=================================
+
+ Some files are consistently and identically needed in every package
+internationalized through GNU `gettext'. As a matter of convenience,
+the `gettextize' program puts all these files right in your package.
+This program has the following synopsis:
+
+ gettextize [ OPTION... ] [ DIRECTORY ]
+
+and accepts the following options:
+
+`-c'
+`--copy'
+ Copy the needed files instead of making symbolic links. Using
+ links would allow the package to always use the latest `gettext'
+ code available on the system, but it might disturb some mechanism
+ the maintainer is used to apply to the sources. Because running
+ `gettextize' is easy there shouldn't be problems with using copies.
+
+`-f'
+`--force'
+ Force replacement of files which already exist.
+
+`-h'
+`--help'
+ Display this help and exit.
+
+`--version'
+ Output version information and exit.
+
+ If DIRECTORY is given, this is the top level directory of a package
+to prepare for using GNU `gettext'. If not given, it is assumed that
+the current directory is the top level directory of such a package.
+
+ The program `gettextize' provides the following files. However, no
+existing file will be replaced unless the option `--force' (`-f') is
+specified.
+
+ 1. The `ABOUT-NLS' file is copied in the main directory of your
+ package, the one being at the top level. This file gives the main
+ indications about how to install and use the Native Language
+ Support features of your program. You might elect to use a more
+ recent copy of this `ABOUT-NLS' file than the one provided through
+ `gettextize', if you have one handy. You may also fetch a more
+ recent copy of file `ABOUT-NLS' from Translation Project sites,
+ and from most GNU archive sites.
+
+ 2. A `po/' directory is created for eventually holding all
+ translation files, but initially only containing the file
+ `po/Makefile.in.in' from the GNU `gettext' distribution. (beware
+ the double `.in' in the file name). If the `po/' directory already
+ exists, it will be preserved along with the files it contains, and
+ only `Makefile.in.in' will be overwritten.
+
+ 3. A `intl/' directory is created and filled with most of the files
+ originally in the `intl/' directory of the GNU `gettext'
+ distribution. Also, if option `--force' (`-f') is given, the
+ `intl/' directory is emptied first.
+
+
+ If your site support symbolic links, `gettextize' will not actually
+copy the files into your package, but establish symbolic links instead.
+This avoids duplicating the disk space needed in all packages. Merely
+using the `-h' option while creating the `tar' archive of your
+distribution will resolve each link by an actual copy in the
+distribution archive. So, to insist, you really should use `-h' option
+with `tar' within your `dist' goal of your main `Makefile.in'.
+
+ It is interesting to understand that most new files for supporting
+GNU `gettext' facilities in one package go in `intl/' and `po/'
+subdirectories. One distinction between these two directories is that
+`intl/' is meant to be completely identical in all packages using GNU
+`gettext', while all newly created files, which have to be different,
+go into `po/'. There is a common `Makefile.in.in' in `po/', because
+the `po/' directory needs its own `Makefile', and it has been designed
+so it can be identical in all packages.
+
diff --git a/doc/gettext.info-5 b/doc/gettext.info-5
new file mode 100644
index 0000000..0279fa5
--- /dev/null
+++ b/doc/gettext.info-5
@@ -0,0 +1,852 @@
+This is Info file gettext.info, produced by Makeinfo version 1.68 from
+the input file gettext.texi.
+
+INFO-DIR-SECTION GNU Gettext Utilities
+START-INFO-DIR-ENTRY
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+END-INFO-DIR-ENTRY
+
+ This file provides documentation for GNU `gettext' utilities. It
+also serves as a reference for the free Translation Project.
+
+ Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: gettext.info, Node: Adjusting Files, Prev: gettextize Invocation, Up: Maintainers
+
+Files You Must Create or Alter
+==============================
+
+ Besides files which are automatically added through `gettextize',
+there are many files needing revision for properly interacting with GNU
+`gettext'. If you are closely following GNU standards for Makefile
+engineering and auto-configuration, the adaptations should be easier to
+achieve. Here is a point by point description of the changes needed in
+each.
+
+ So, here comes a list of files, each one followed by a description of
+all alterations it needs. Many examples are taken out from the GNU
+`gettext' 0.10.36 distribution itself. You may indeed refer to the
+source code of the GNU `gettext' package, as it is intended to be a
+good example and master implementation for using its own functionality.
+
+* Menu:
+
+* po/POTFILES.in:: `POTFILES.in' in `po/'
+* configure.in:: `configure.in' at top level
+* aclocal:: `aclocal.m4' at top level
+* acconfig:: `acconfig.h' at top level
+* Makefile:: `Makefile.in' at top level
+* src/Makefile:: `Makefile.in' in `src/'
+
+
+File: gettext.info, Node: po/POTFILES.in, Next: configure.in, Prev: Adjusting Files, Up: Adjusting Files
+
+`POTFILES.in' in `po/'
+----------------------
+
+ The `po/' directory should receive a file named `POTFILES.in'. This
+file tells which files, among all program sources, have marked strings
+needing translation. Here is an example of such a file:
+
+ # List of source files containing translatable strings.
+ # Copyright (C) 1995 Free Software Foundation, Inc.
+
+ # Common library files
+ lib/error.c
+ lib/getopt.c
+ lib/xmalloc.c
+
+ # Package source files
+ src/gettextp.c
+ src/msgfmt.c
+ src/xgettext.c
+
+Dashed comments and white lines are ignored. All other lines list
+those source files containing strings marked for translation (*note
+Mark Keywords::.), in a notation relative to the top level of your
+whole distribution, rather than the location of the `POTFILES.in' file
+itself.
+
+
+File: gettext.info, Node: configure.in, Next: aclocal, Prev: po/POTFILES.in, Up: Adjusting Files
+
+`configure.in' at top level
+---------------------------
+
+ 1. Declare the package and version.
+
+ This is done by a set of lines like these:
+
+ PACKAGE=gettext
+ VERSION=0.10.36
+ AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+ AC_SUBST(PACKAGE)
+ AC_SUBST(VERSION)
+
+ Of course, you replace `gettext' with the name of your package,
+ and `0.10.36' by its version numbers, exactly as they should
+ appear in the packaged `tar' file name of your distribution
+ (`gettext-0.10.36.tar.gz', here).
+
+ 2. Declare the available translations.
+
+ This is done by defining `ALL_LINGUAS' to the white separated,
+ quoted list of available languages, in a single line, like this:
+
+ ALL_LINGUAS="de fr"
+
+ This example means that German and French PO files are available,
+ so that these languages are currently supported by your package.
+ If you want to further restrict, at installation time, the set of
+ installed languages, this should not be done by modifying
+ `ALL_LINGUAS' in `configure.in', but rather by using the `LINGUAS'
+ environment variable (*note Installers::.).
+
+ 3. Check for internationalization support.
+
+ Here is the main `m4' macro for triggering internationalization
+ support. Just add this line to `configure.in':
+
+ AM_GNU_GETTEXT
+
+ This call is purposely simple, even if it generates a lot of
+ configure time checking and actions.
+
+ 4. Have output files created.
+
+ The `AC_OUTPUT' directive, at the end of your `configure.in' file,
+ needs to be modified in two ways:
+
+ AC_OUTPUT([EXISTING CONFIGURATION FILES intl/Makefile po/Makefile.in],
+ EXISTING ADDITIONAL ACTIONS])
+
+ The modification to the first argument to `AC_OUTPUT' asks for
+ substitution in the `intl/' and `po/' directories. Note the `.in'
+ suffix used for `po/' only. This is because the distributed file
+ is really `po/Makefile.in.in'.
+
+
+
+File: gettext.info, Node: aclocal, Next: acconfig, Prev: configure.in, Up: Adjusting Files
+
+`aclocal.m4' at top level
+-------------------------
+
+ If you do not have an `aclocal.m4' file in your distribution, the
+simplest is taking a copy of `aclocal.m4' from GNU `gettext'. But to
+be precise, you only need macros `AM_LC_MESSAGES', `AM_WITH_NLS' and
+`AM_GNU_GETTEXT', and `AM_PATH_PROG_WITH_TEST', which is called by
+`AM_WITH_NLS', so you may use an editor and remove macros you do not
+need.
+
+ If you already have an `aclocal.m4' file, then you will have to
+merge the said macros into your `aclocal.m4'. Note that if you are
+upgrading from a previous release of GNU `gettext', you should most
+probably *replace* the said macros, as they usually change a little
+from one release of GNU `gettext' to the next. Their contents may vary
+as we get more experience with strange systems out there.
+
+ These macros check for the internationalization support functions
+and related informations. Hopefully, once stabilized, these macros
+might be integrated in the standard Autoconf set, because this piece of
+`m4' code will be the same for all projects using GNU `gettext'.
+
+
+File: gettext.info, Node: acconfig, Next: Makefile, Prev: aclocal, Up: Adjusting Files
+
+`acconfig.h' at top level
+-------------------------
+
+ If you do not have an `acconfig.h' file in your distribution, the
+simplest is use take a copy of `acconfig.h' from GNU `gettext'. But to
+be precise, you only need the lines and comments for `ENABLE_NLS',
+`HAVE_CATGETS', `HAVE_GETTEXT' and `HAVE_LC_MESSAGES', `HAVE_STPCPY',
+`PACKAGE' and `VERSION', so you may use an editor and remove everything
+else. If you already have an `acconfig.h' file, then you should merge
+the said definitions into your `acconfig.h'.
+
+
+File: gettext.info, Node: Makefile, Next: src/Makefile, Prev: acconfig, Up: Adjusting Files
+
+`Makefile.in' at top level
+--------------------------
+
+ Here are a few modifications you need to make to your main, top-level
+`Makefile.in' file.
+
+ 1. Add the following lines near the beginning of your `Makefile.in',
+ so the `dist:' goal will work properly (as explained further down):
+
+ PACKAGE = @PACKAGE@
+ VERSION = @VERSION@
+
+ 2. Add file `ABOUT-NLS' to the `DISTFILES' definition, so the file
+ gets distributed.
+
+ 3. Wherever you process subdirectories in your `Makefile.in', be sure
+ you also process dir subdirectories `intl' and `po'. Special
+ rules in the `Makefiles' take care for the case where no
+ internationalization is wanted.
+
+ If you are using Makefiles, either generated by automake, or
+ hand-written so they carefully follow the GNU coding standards,
+ the effected goals for which the new subdirectories must be
+ handled include `installdirs', `install', `uninstall', `clean',
+ `distclean'.
+
+ Here is an example of a canonical order of processing. In this
+ example, we also define `SUBDIRS' in `Makefile.in' for it to be
+ further used in the `dist:' goal.
+
+ SUBDIRS = doc lib @INTLSUB@ src @POSUB@
+
+ that you will have to adapt to your own package.
+
+ 4. A delicate point is the `dist:' goal, as both `intl/Makefile' and
+ `po/Makefile' will later assume that the proper directory has been
+ set up from the main `Makefile'. Here is an example at what the
+ `dist:' goal might look like:
+
+ distdir = $(PACKAGE)-$(VERSION)
+ dist: Makefile
+ rm -fr $(distdir)
+ mkdir $(distdir)
+ chmod 777 $(distdir)
+ for file in $(DISTFILES); do \
+ ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
+ done
+ for subdir in $(SUBDIRS); do \
+ mkdir $(distdir)/$$subdir || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $@) || exit 1; \
+ done
+ tar chozf $(distdir).tar.gz $(distdir)
+ rm -fr $(distdir)
+
+
+
+File: gettext.info, Node: src/Makefile, Prev: Makefile, Up: Adjusting Files
+
+`Makefile.in' in `src/'
+-----------------------
+
+ Some of the modifications made in the main `Makefile.in' will also
+be needed in the `Makefile.in' from your package sources, which we
+assume here to be in the `src/' subdirectory. Here are all the
+modifications needed in `src/Makefile.in':
+
+ 1. In view of the `dist:' goal, you should have these lines near the
+ beginning of `src/Makefile.in':
+
+ PACKAGE = @PACKAGE@
+ VERSION = @VERSION@
+
+ 2. If not done already, you should guarantee that `top_srcdir' gets
+ defined. This will serve for `cpp' include files. Just add the
+ line:
+
+ top_srcdir = @top_srcdir@
+
+ 3. You might also want to define `subdir' as `src', later allowing
+ for almost uniform `dist:' goals in all your `Makefile.in'. At
+ list, the `dist:' goal below assume that you used:
+
+ subdir = src
+
+ 4. You should ensure that the final linking will use `@INTLLIBS@' as
+ a library. An easy way to achieve this is to manage that it gets
+ into `LIBS', like this:
+
+ LIBS = @INTLLIBS@ @LIBS@
+
+ In most packages internationalized with GNU `gettext', one will
+ find a directory `lib/' in which a library containing some helper
+ functions will be build. (You need at least the few functions
+ which the GNU `gettext' Library itself needs.) However some of
+ the functions in the `lib/' also give messages to the user which
+ of course should be translated, too. Taking care of this it is
+ not enough to place the support library (say `libsupport.a') just
+ between the `@INTLLIBS@' and `@LIBS@' in the above example.
+ Instead one has to write this:
+
+ LIBS = ../lib/libsupport.a @INTLLIBS@ ../lib/libsupport.a @LIBS@
+
+ 5. You should also ensure that directory `intl/' will be searched for
+ C preprocessor include files in all circumstances. So, you have to
+ manage so both `-I../intl' and `-I$(top_srcdir)/intl' will be
+ given to the C compiler.
+
+ 6. Your `dist:' goal has to conform with others. Here is a
+ reasonable definition for it:
+
+ distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+ dist: Makefile $(DISTFILES)
+ for file in $(DISTFILES); do \
+ ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
+ done
+
+
+
+File: gettext.info, Node: Conclusion, Next: Country Codes, Prev: Maintainers, Up: Top
+
+Concluding Remarks
+******************
+
+ We would like to conclude this GNU `gettext' manual by presenting an
+history of the Translation Project so far. We finally give a few
+pointers for those who want to do further research or readings about
+Native Language Support matters.
+
+* Menu:
+
+* History:: History of GNU `gettext'
+* References:: Related Readings
+
+
+File: gettext.info, Node: History, Next: References, Prev: Conclusion, Up: Conclusion
+
+History of GNU `gettext'
+========================
+
+ Internationalization concerns and algorithms have been informally
+and casually discussed for years in GNU, sometimes around GNU `libc',
+maybe around the incoming `Hurd', or otherwise (nobody clearly
+remembers). And even then, when the work started for real, this was
+somewhat independently of these previous discussions.
+
+ This all began in July 1994, when Patrick D'Cruze had the idea and
+initiative of internationalizing version 3.9.2 of GNU `fileutils'. He
+then asked Jim Meyering, the maintainer, how to get those changes
+folded into an official release. That first draft was full of
+`#ifdef's and somewhat disconcerting, and Jim wanted to find nicer
+ways. Patrick and Jim shared some tries and experimentations in this
+area. Then, feeling that this might eventually have a deeper impact on
+GNU, Jim wanted to know what standards were, and contacted Richard
+Stallman, who very quickly and verbally described an overall design for
+what was meant to become `glocale', at that time.
+
+ Jim implemented `glocale' and got a lot of exhausting feedback from
+Patrick and Richard, of course, but also from Mitchum DSouza (who wrote
+a `catgets'-like package), Roland McGrath, maybe David MacKenzie,
+Franc,ois Pinard, and Paul Eggert, all pushing and pulling in various
+directions, not always compatible, to the extent that after a couple of
+test releases, `glocale' was torn apart.
+
+ While Jim took some distance and time and became dad for a second
+time, Roland wanted to get GNU `libc' internationalized, and got Ulrich
+Drepper involved in that project. Instead of starting from `glocale',
+Ulrich rewrote something from scratch, but more conformant to the set
+of guidelines who emerged out of the `glocale' effort. Then, Ulrich
+got people from the previous forum to involve themselves into this new
+project, and the switch from `glocale' to what was first named
+`msgutils', renamed `nlsutils', and later `gettext', became officially
+accepted by Richard in May 1995 or so.
+
+ Let's summarize by saying that Ulrich Drepper wrote GNU `gettext' in
+April 1995. The first official release of the package, including PO
+mode, occurred in July 1995, and was numbered 0.7. Other people
+contributed to the effort by providing a discussion forum around
+Ulrich, writing little pieces of code, or testing. These are quoted in
+the `THANKS' file which comes with the GNU `gettext' distribution.
+
+ While this was being done, Franc,ois adapted half a dozen of GNU
+packages to `glocale' first, then later to `gettext', putting them in
+pretest, so providing along the way an effective user environment for
+fine tuning the evolving tools. He also took the responsibility of
+organizing and coordinating the Translation Project. After nearly a
+year of informal exchanges between people from many countries,
+translator teams started to exist in May 1995, through the creation and
+support by Patrick D'Cruze of twenty unmoderated mailing lists for that
+many native languages, and two moderated lists: one for reaching all
+teams at once, the other for reaching all willing maintainers of
+internationalized free software packages.
+
+ Franc,ois also wrote PO mode in June 1995 with the collaboration of
+Greg McGary, as a kind of contribution to Ulrich's package. He also
+gave a hand with the GNU `gettext' Texinfo manual.
+
+
+File: gettext.info, Node: References, Prev: History, Up: Conclusion
+
+Related Readings
+================
+
+ Eugene H. Dorr (`dorre@well.com') maintains an interesting
+bibliography on internationalization matters, called
+`Internationalization Reference List', which is available as:
+ ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/i18n-books.txt
+
+ Michael Gschwind (`mike@vlsivie.tuwien.ac.at') maintains a
+Frequently Asked Questions (FAQ) list, entitled `Programming for
+Internationalisation'. This FAQ discusses writing programs which can
+handle different language conventions, character sets, etc.; and is
+applicable to all character set encodings, with particular emphasis on
+ISO 8859-1. It is regularly published in Usenet groups
+`comp.unix.questions', `comp.std.internat',
+`comp.software.international', `comp.lang.c', `comp.windows.x',
+`comp.std.c', `comp.answers' and `news.answers'. The home location of
+this document is:
+ ftp://ftp.vlsivie.tuwien.ac.at/pub/8bit/ISO-programming
+
+ Patrick D'Cruze (`pdcruze@li.org') wrote a tutorial about NLS
+matters, and Jochen Hein (`Hein@student.tu-clausthal.de') took over the
+responsibility of maintaining it. It may be found as:
+ ftp://sunsite.unc.edu/pub/Linux/utils/nls/catalogs/Incoming/...
+ ...locale-tutorial-0.8.txt.gz
+
+This site is mirrored in:
+ ftp://ftp.ibp.fr/pub/linux/sunsite/
+
+ A French version of the same tutorial should be findable at:
+ ftp://ftp.ibp.fr/pub/linux/french/docs/
+
+together with French translations of many Linux-related documents.
+
+
+File: gettext.info, Node: Country Codes, Prev: Conclusion, Up: Top
+
+Country Codes
+*************
+
+ The ISO 639 standard defines two character codes for many countries.
+All abreviations for countries or languages used in the Translation
+Project should come from this standard.
+
+`aa'
+ Afar.
+
+`ab'
+ Abkhazian.
+
+`af'
+ Afrikaans.
+
+`am'
+ Amharic.
+
+`ar'
+ Arabic.
+
+`as'
+ Assamese.
+
+`ay'
+ Aymara.
+
+`az'
+ Azerbaijani.
+
+`ba'
+ Bashkir.
+
+`be'
+ Byelorussian.
+
+`bg'
+ Bulgarian.
+
+`bh'
+ Bihari.
+
+`bi'
+ Bislama.
+
+`bn'
+ Bengali; Bangla.
+
+`bo'
+ Tibetan.
+
+`br'
+ Breton.
+
+`ca'
+ Catalan.
+
+`co'
+ Corsican.
+
+`cs'
+ Czech.
+
+`cy'
+ Welsh.
+
+`da'
+ Danish.
+
+`de'
+ German.
+
+`dz'
+ Bhutani.
+
+`el'
+ Greek.
+
+`en'
+ English.
+
+`eo'
+ Esperanto.
+
+`es'
+ Spanish.
+
+`et'
+ Estonian.
+
+`eu'
+ Basque.
+
+`fa'
+ Persian.
+
+`fi'
+ Finnish.
+
+`fj'
+ Fiji.
+
+`fo'
+ Faroese.
+
+`fr'
+ French.
+
+`fy'
+ Frisian.
+
+`ga'
+ Irish.
+
+`gd'
+ Scots Gaelic.
+
+`gl'
+ Galician.
+
+`gn'
+ Guarani.
+
+`gu'
+ Gujarati.
+
+`ha'
+ Hausa.
+
+`he'
+ Hebrew (formerly iw).
+
+`hi'
+ Hindi.
+
+`hr'
+ Croatian.
+
+`hu'
+ Hungarian.
+
+`hy'
+ Armenian.
+
+`ia'
+ Interlingua.
+
+`id'
+ Indonesian (formerly in).
+
+`ie'
+ Interlingue.
+
+`ik'
+ Inupiak.
+
+`is'
+ Icelandic.
+
+`it'
+ Italian.
+
+`iu'
+ Inuktitut.
+
+`ja'
+ Japanese.
+
+`jw'
+ Javanese.
+
+`ka'
+ Georgian.
+
+`kk'
+ Kazakh.
+
+`kl'
+ Greenlandic.
+
+`km'
+ Cambodian.
+
+`kn'
+ Kannada.
+
+`ko'
+ Korean.
+
+`ks'
+ Kashmiri.
+
+`ku'
+ Kurdish.
+
+`ky'
+ Kirghiz.
+
+`la'
+ Latin.
+
+`ln'
+ Lingala.
+
+`lo'
+ Laothian.
+
+`lt'
+ Lithuanian.
+
+`lv'
+ Latvian, Lettish.
+
+`mg'
+ Malagasy.
+
+`mi'
+ Maori.
+
+`mk'
+ Macedonian.
+
+`ml'
+ Malayalam.
+
+`mn'
+ Mongolian.
+
+`mo'
+ Moldavian.
+
+`mr'
+ Marathi.
+
+`ms'
+ Malay.
+
+`mt'
+ Maltese.
+
+`my'
+ Burmese.
+
+`na'
+ Nauru.
+
+`ne'
+ Nepali.
+
+`nl'
+ Dutch.
+
+`no'
+ Norwegian.
+
+`oc'
+ Occitan.
+
+`om'
+ (Afan) Oromo.
+
+`or'
+ Oriya.
+
+`pa'
+ Punjabi.
+
+`pl'
+ Polish.
+
+`ps'
+ Pashto, Pushto.
+
+`pt'
+ Portuguese.
+
+`qu'
+ Quechua.
+
+`rm'
+ Rhaeto-Romance.
+
+`rn'
+ Kirundi.
+
+`ro'
+ Romanian.
+
+`ru'
+ Russian.
+
+`rw'
+ Kinyarwanda.
+
+`sa'
+ Sanskrit.
+
+`sd'
+ Sindhi.
+
+`sg'
+ Sangro.
+
+`sh'
+ Serbo-Croatian.
+
+`si'
+ Sinhalese.
+
+`sk'
+ Slovak.
+
+`sl'
+ Slovenian.
+
+`sm'
+ Samoan.
+
+`sn'
+ Shona.
+
+`so'
+ Somali.
+
+`sq'
+ Albanian.
+
+`sr'
+ Serbian.
+
+`ss'
+ Siswati.
+
+`st'
+ Sesotho.
+
+`su'
+ Sundanese.
+
+`sv'
+ Swedish.
+
+`sw'
+ Swahili.
+
+`ta'
+ Tamil.
+
+`te'
+ Telugu.
+
+`tg'
+ Tajik.
+
+`th'
+ Thai.
+
+`ti'
+ Tigrinya.
+
+`tk'
+ Turkmen.
+
+`tl'
+ Tagalog.
+
+`tn'
+ Setswana.
+
+`to'
+ Tonga.
+
+`tr'
+ Turkish.
+
+`ts'
+ Tsonga.
+
+`tt'
+ Tatar.
+
+`tw'
+ Twi.
+
+`ug'
+ Uighur.
+
+`uk'
+ Ukrainian.
+
+`ur'
+ Urdu.
+
+`uz'
+ Uzbek.
+
+`vi'
+ Vietnamese.
+
+`vo'
+ Volapuk.
+
+`wo'
+ Wolof.
+
+`xh'
+ Xhosa.
+
+`yi'
+ Yiddish (formerly ji).
+
+`yo'
+ Yoruba.
+
+`za'
+ Zhuang.
+
+`zh'
+ Chinese.
+
+`zu'
+ Zulu.
+
+
diff --git a/doc/gettext.texi b/doc/gettext.texi
new file mode 100644
index 0000000..343ffb4
--- /dev/null
+++ b/doc/gettext.texi
@@ -0,0 +1,4820 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gettext.info
+@settitle GNU @code{gettext} utilities
+@finalout
+@c %**end of header
+
+@include version.texi
+
+@dircategory GNU Gettext Utilities
+@direntry
+* Gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msgmerge: (gettext)msgmerge Invocation. Update two PO files into one.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+@end direntry
+
+@ifinfo
+This file provides documentation for GNU @code{gettext} utilities.
+It also serves as a reference for the free Translation Project.
+
+Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@titlepage
+@title GNU gettext tools, version @value{VERSION}
+@subtitle Native Language Support Library and Tools
+@subtitle Edition @value{EDITION}, @value{UPDATED}
+@author Ulrich Drepper
+@author Jim Meyering
+@author Fran@,{c}ois Pinard
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end titlepage
+
+@ifinfo
+@node Top, Introduction, (dir), (dir)
+@top GNU @code{gettext} utilities
+
+@menu
+* Introduction:: Introduction
+* Basics:: PO Files and PO Mode Basics
+* Sources:: Preparing Program Sources
+* Initial:: Making the Initial PO File
+* Updating:: Updating Existing PO Files
+* Binaries:: Producing Binary MO Files
+* Users:: The User's View
+* Programmers:: The Programmer's View
+* Translators:: The Translator's View
+* Maintainers:: The Maintainer's View
+* Conclusion:: Concluding Remarks
+
+* Country Codes:: ISO 639 country codes
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Introduction
+
+* Why:: The Purpose of GNU @code{gettext}
+* Concepts:: I18n, L10n, and Such
+* Aspects:: Aspects in Native Language Support
+* Files:: Files Conveying Translations
+* Overview:: Overview of GNU @code{gettext}
+
+PO Files and PO Mode Basics
+
+* Installation:: Completing GNU @code{gettext} Installation
+* PO Files:: The Format of PO Files
+* Main PO Commands:: Main Commands
+* Entry Positioning:: Entry Positioning
+* Normalizing:: Normalizing Strings in Entries
+
+Preparing Program Sources
+
+* Triggering:: Triggering @code{gettext} Operations
+* Mark Keywords:: How Marks Appears in Sources
+* Marking:: Marking Translatable Strings
+* c-format:: Telling something about the following string
+* Special cases:: Special Cases of Translatable Strings
+
+Making the Initial PO File
+
+* xgettext Invocation:: Invoking the @code{xgettext} Program
+* C Sources Context:: C Sources Context
+* Compendium:: Using Translation Compendiums
+
+Updating Existing PO Files
+
+* msgmerge Invocation:: Invoking the @code{msgmerge} Program
+* Translated Entries:: Translated Entries
+* Fuzzy Entries:: Fuzzy Entries
+* Untranslated Entries:: Untranslated Entries
+* Obsolete Entries:: Obsolete Entries
+* Modifying Translations:: Modifying Translations
+* Modifying Comments:: Modifying Comments
+* Auxiliary:: Consulting Auxiliary PO Files
+
+Producing Binary MO Files
+
+* msgfmt Invocation:: Invoking the @code{msgfmt} Program
+* MO Files:: The Format of GNU MO Files
+
+The User's View
+
+* Matrix:: The Current @file{ABOUT-NLS} Matrix
+* Installers:: Magic for Installers
+* End Users:: Magic for End Users
+
+The Programmer's View
+
+* catgets:: About @code{catgets}
+* gettext:: About @code{gettext}
+* Comparison:: Comparing the two interfaces
+* Using libintl.a:: Using libintl.a in own programs
+* gettext grok:: Being a @code{gettext} grok
+* Temp Programmers:: Temporary Notes for the Programmers Chapter
+
+About @code{catgets}
+
+* Interface to catgets:: The interface
+* Problems with catgets:: Problems with the @code{catgets} interface?!
+
+About @code{gettext}
+
+* Interface to gettext:: The interface
+* Ambiguities:: Solving ambiguities
+* Locating Catalogs:: Locating message catalog files
+* Optimized gettext:: Optimization of the *gettext functions
+
+Temporary Notes for the Programmers Chapter
+
+* Temp Implementations:: Temporary - Two Possible Implementations
+* Temp catgets:: Temporary - About @code{catgets}
+* Temp WSI:: Temporary - Why a single implementation
+* Temp Notes:: Temporary - Notes
+
+The Translator's View
+
+* Trans Intro 0:: Introduction 0
+* Trans Intro 1:: Introduction 1
+* Discussions:: Discussions
+* Organization:: Organization
+* Information Flow:: Information Flow
+
+Organization
+
+* Central Coordination:: Central Coordination
+* National Teams:: National Teams
+* Mailing Lists:: Mailing Lists
+
+National Teams
+
+* Sub-Cultures:: Sub-Cultures
+* Organizational Ideas:: Organizational Ideas
+
+The Maintainer's View
+
+* Flat and Non-Flat:: Flat or Non-Flat Directory Structures
+* Prerequisites:: Prerequisite Works
+* gettextize Invocation:: Invoking the @code{gettextize} Program
+* Adjusting Files:: Files You Must Create or Alter
+
+Files You Must Create or Alter
+
+* po/POTFILES.in:: @file{POTFILES.in} in @file{po/}
+* configure.in:: @file{configure.in} at top level
+* aclocal:: @file{aclocal.m4} at top level
+* acconfig:: @file{acconfig.h} at top level
+* Makefile:: @file{Makefile.in} at top level
+* src/Makefile:: @file{Makefile.in} in @file{src/}
+
+Concluding Remarks
+
+* History:: History of GNU @code{gettext}
+* References:: Related Readings
+
+@end detailmenu
+@end menu
+
+@end ifinfo
+
+@node Introduction, Basics, Top, Top
+@chapter Introduction
+
+@quotation
+This manual is still in @emph{DRAFT} state. Some sections are still
+empty, or almost. We keep merging material from other sources
+(essentially e-mail folders) while the proper integration of this
+material is delayed.
+@end quotation
+
+In this manual, we use @emph{he} when speaking of the programmer or
+maintainer, @emph{she} when speaking of the translator, and @emph{they}
+when speaking of the installers or end users of the translated program.
+This is only a convenience for clarifying the documentation. It is
+@emph{absolutely} not meant to imply that some roles are more appropriate
+to males or females. Besides, as you might guess, GNU @code{gettext}
+is meant to be useful for people using computers, whatever their sex,
+race, religion or nationality!
+
+This chapter explains the goals sought in the creation
+of GNU @code{gettext} and the free Translation Project.
+Then, it explains a few broad concepts around
+Native Language Support, and positions message translation with regard
+to other aspects of national and cultural variance, as they apply to
+to programs. It also surveys those files used to convey the
+translations. It explains how the various tools interact in the
+initial generation of these files, and later, how the maintenance
+cycle should usually operate.
+
+Please send suggestions and corrections to:
+
+@example
+@group
+@r{Internet address:}
+ bug-gnu-utils@@gnu.org
+@end group
+@end example
+
+@noindent
+Please include the manual's edition number and update date in your messages.
+
+@menu
+* Why:: The Purpose of GNU @code{gettext}
+* Concepts:: I18n, L10n, and Such
+* Aspects:: Aspects in Native Language Support
+* Files:: Files Conveying Translations
+* Overview:: Overview of GNU @code{gettext}
+@end menu
+
+@node Why, Concepts, Introduction, Introduction
+@section The Purpose of GNU @code{gettext}
+
+Usually, programs are written and documented in English, and use
+English at execution time to interact with users. This is true
+not only of GNU software, but also of a great deal of commercial
+and free software. Using a common language is quite handy for
+communication between developers, maintainers and users from all
+countries. On the other hand, most people are less comfortable with
+English than with their own native language, and would prefer to
+use their mother tongue for day to day's work, as far as possible.
+Many would simply @emph{love} to see their computer screen showing
+a lot less of English, and far more of their own language.
+
+However, to many people, this dream might appear so far fetched that
+they may believe it is not even worth spending time thinking about
+it. They have no confidence at all that the dream might ever
+become true. Yet some have not lost hope, and have organized themselves.
+The Translation Project is a formalization of this hope into a
+workable structure, which has a good chance to get all of us nearer
+the achievement of a truly multi-lingual set of programs.
+
+GNU @code{gettext} is an important step for the Translation Project,
+as it is an asset on which we may build many other steps. This package
+offers to programmers, translators and even users, a well integrated
+set of tools and documentation. Specifically, the GNU @code{gettext}
+utilities are a set of tools that provides a framework within which
+other free packages may produce multi-lingual messages. These tools
+include a set of conventions about how programs should be written to
+support message catalogs, a directory and file naming organization for the
+message catalogs themselves, a runtime library supporting the retrieval of
+translated messages, and a few stand-alone programs to massage in various
+ways the sets of translatable strings, or already translated strings.
+A special mode for Emacs@footnote{In this manual, all mentions of Emacs
+refers to either GNU Emacs or to XEmacs, which people sometimes call FSF
+Emacs and Lucid Emacs, respectively.} also helps ease interested parties
+into preparing these sets, or bringing them up to date.
+
+GNU @code{gettext} is designed to minimize the impact of
+internationalization on program sources, keeping this impact as small
+and hardly noticeable as possible. Internationalization has better
+chances of succeeding if it is very light weighted, or at least,
+appear to be so, when looking at program sources.
+
+The Translation Project also uses the GNU @code{gettext}
+distribution as a vehicle for documenting its structure and methods.
+This goes beyond the strict technicalities of documenting the GNU @code{gettext}
+proper. By so doing, translators will find in a single place, as
+far as possible, all they need to know for properly doing their
+translating work. Also, this supplemental documentation might also
+help programmers, and even curious users, in understanding how GNU
+@code{gettext} is related to the remainder of the Translation
+Project, and consequently, have a glimpse at the @emph{big picture}.
+
+@node Concepts, Aspects, Why, Introduction
+@section I18n, L10n, and Such
+
+Two long words appear all the time when we discuss support of native
+language in programs, and these words have a precise meaning, worth
+being explained here, once and for all in this document. The words are
+@emph{internationalization} and @emph{localization}. Many people,
+tired of writing these long words over and over again, took the
+habit of writing @dfn{i18n} and @dfn{l10n} instead, quoting the first
+and last letter of each word, and replacing the run of intermediate
+letters by a number merely telling how many such letters there are.
+But in this manual, in the sake of clarity, we will patiently write
+the names in full, each time@dots{}
+
+By @dfn{internationalization}, one refers to the operation by which a
+program, or a set of programs turned into a package, is made aware of and
+able to support multiple languages. This is a generalization process,
+by which the programs are untied from calling only English strings or
+other English specific habits, and connected to generic ways of doing
+the same, instead. Program developers may use various techniques to
+internationalize their programs. Some of these have been standardized.
+GNU @code{gettext} offers one of these standards. @xref{Programmers}.
+
+By @dfn{localization}, one means the operation by which, in a set
+of programs already internationalized, one gives the program all
+needed information so that it can adapt itself to handle its input
+and output in a fashion which is correct for some native language and
+cultural habits. This is a particularisation process, by which generic
+methods already implemented in an internationalized program are used
+in specific ways. The programming environment puts several functions
+to the programmers disposal which allow this runtime configuration.
+The formal description of specific set of cultural habits for some
+country, together with all associated translations targeted to the
+same native language, is called the @dfn{locale} for this language
+or country. Users achieve localization of programs by setting proper
+values to special environment variables, prior to executing those
+programs, identifying which locale should be used.
+
+In fact, locale message support is only one component of the cultural
+data that makes up a particular locale. There are a whole host of
+routines and functions provided to aid programmers in developing
+internationalized software and which allow them to access the data
+stored in a particular locale. When someone presently refers to a
+particular locale, they are obviously referring to the data stored
+within that particular locale. Similarly, if a programmer is referring
+to ``accessing the locale routines'', they are referring to the
+complete suite of routines that access all of the locale's information.
+
+One uses the expression @dfn{Native Language Support}, or merely NLS,
+for speaking of the overall activity or feature encompassing both
+internationalization and localization, allowing for multi-lingual
+interactions in a program. In a nutshell, one could say that
+internationalization is the operation by which further localizations
+are made possible.
+
+Also, very roughly said, when it comes to multi-lingual messages,
+internationalization is usually taken care of by programmers, and
+localization is usually taken care of by translators.
+
+@node Aspects, Files, Concepts, Introduction
+@section Aspects in Native Language Support
+
+For a totally multi-lingual distribution, there are many things to
+translate beyond output messages.
+
+@itemize @bullet
+@item
+As of today, GNU @code{gettext} offers a complete toolset for
+translating messages output by C programs. Perl scripts and shell
+scripts will also need to be translated. Even if there are today some hooks
+by which this can be done, these hooks are not integrated as well as they
+should be.
+
+@item
+Some programs, like @code{autoconf} or @code{bison}, are able
+to produce other programs (or scripts). Even if the generating
+programs themselves are internationalized, the generated programs they
+produce may need internationalization on their own, and this indirect
+internationalization could be automated right from the generating
+program. In fact, quite usually, generating and generated programs
+could be internationalized independently, as the effort needed is
+fairly orthogonal.
+
+@item
+A few programs include textual tables which might need translation
+themselves, independently of the strings contained in the program
+itself. For example, @w{RFC 1345} gives an English description for each
+character which the @code{recode} program is able to reconstruct at execution.
+Since these descriptions are extracted from the RFC by mechanical means,
+translating them properly would require a prior translation of the RFC
+itself.
+
+@item
+Almost all programs accept options, which are often worded out so to
+be descriptive for the English readers; one might want to consider
+offering translated versions for program options as well.
+
+@item
+Many programs read, interpret, compile, or are somewhat driven by
+input files which are texts containing keywords, identifiers, or
+replies which are inherently translatable. For example, one may want
+@code{gcc} to allow diacriticized characters in identifiers or use
+translated keywords; @samp{rm -i} might accept something else than
+@samp{y} or @samp{n} for replies, etc. Even if the program will
+eventually make most of its output in the foreign languages, one has
+to decide whether the input syntax, option values, etc., are to be
+localized or not.
+
+@item
+The manual accompanying a package, as well as all documentation files
+in the distribution, could surely be translated, too. Translating a
+manual, with the intent of later keeping up with updates, is a major
+undertaking in itself, generally.
+
+@end itemize
+
+As we already stressed, translation is only one aspect of locales.
+Other internationalization aspects are not currently handled by GNU
+@code{gettext}, but perhaps may be handled in future versions. There
+are many attributes that are needed to define a country's cultural
+conventions. These attributes include beside the country's native
+language, the formatting of the date and time, the representation of
+numbers, the symbols for currency, etc. These local @dfn{rules} are
+termed the country's locale. The locale represents the knowledge
+needed to support the country's native attributes.
+
+There are a few major areas which may vary between countries and
+hence, define what a locale must describe. The following list helps
+putting multi-lingual messages into the proper context of other tasks
+related to locales, and also presents some other areas which GNU
+@code{gettext} might eventually tackle, maybe, one of these days.
+
+@table @emph
+
+@item Characters and Codesets
+
+The codeset most commonly used through out the USA and most English
+speaking parts of the world is the ASCII codeset. However, there are
+many characters needed by various locales that are not found within
+this codeset. The 8-bit @w{ISO 8859-1} code set has most of the special
+characters needed to handle the major European languages. However, in
+many cases, the @w{ISO 8859-1} font is not adequate. Hence each locale
+will need to specify which codeset they need to use and will need
+to have the appropriate character handling routines to cope with
+the codeset.
+
+@item Currency
+
+The symbols used vary from country to country as does the position
+used by the symbol. Software needs to be able to transparently
+display currency figures in the native mode for each locale.
+
+@item Dates
+
+The format of date varies between locales. For example, Christmas day
+in 1994 is written as 12/25/94 in the USA and as 25/12/94 in Australia.
+Other countries might use @w{ISO 8061} dates, etc.
+
+Time of the day may be noted as @var{hh}:@var{mm}, @var{hh}.@var{mm},
+or otherwise. Some locales require time to be specified in 24-hour
+mode rather than as AM or PM. Further, the nature and yearly extent
+of the Daylight Saving correction vary widely between countries.
+
+@item Numbers
+
+Numbers can be represented differently in different locales.
+For example, the following numbers are all written correctly for
+their respective locales:
+
+@example
+12,345.67 English
+12.345,67 French
+1,2345.67 Asia
+@end example
+
+Some programs could go further and use different unit systems, like
+English units or Metric units, or even take into account variants
+about how numbers are spelled in full.
+
+@item Messages
+
+The most obvious area is the language support within a locale. This is
+where GNU @code{gettext} provides the means for developers and users to
+easily change the language that the software uses to communicate to
+the user.
+
+@end table
+
+In the near future we see no chance that components of locale outside of
+message handling will be made available for use in other
+packages. The reason for this is that most modern systems provide
+a more or less reasonable support for at least some of the missing
+components. Another point is that the GNU @code{libc} and Linux will get
+a new and complete implementation of the whole locale functionality
+which could be adopted by system lacking a reasonable locale support.
+
+@node Files, Overview, Aspects, Introduction
+@section Files Conveying Translations
+
+The letters PO in @file{.po} files means Portable Object, to
+distinguish it from @file{.mo} files, where MO stands for Machine
+Object. This paradigm, as well as the PO file format, is inspired
+by the NLS standard developed by Uniforum, and implemented by Sun
+in their Solaris system.
+
+PO files are meant to be read and edited by humans, and associate each
+original, translatable string of a given package with its translation
+in a particular target language. A single PO file is dedicated to
+a single target language. If a package supports many languages,
+there is one such PO file per language supported, and each package
+has its own set of PO files. These PO files are best created by
+the @code{xgettext} program, and later updated or refreshed through
+the @code{msgmerge} program. Program @code{xgettext} extracts all
+marked messages from a set of C files and initializes a PO file with
+empty translations. Program @code{msgmerge} takes care of adjusting
+PO files between releases of the corresponding sources, commenting
+obsolete entries, initializing new ones, and updating all source
+line references. Files ending with @file{.pot} are kind of base
+translation files found in distributions, in PO file format, and
+@file{.pox} files are often temporary PO files.
+
+MO files are meant to be read by programs, and are binary in nature.
+A few systems already offer tools for creating and handling MO files
+as part of the Native Language Support coming with the system, but the
+format of these MO files is often different from system to system,
+and non-portable. They do not necessary use @file{.mo} for file
+extensions, but since system libraries are also used for accessing
+these files, it works as long as the system is self-consistent about
+it. If GNU @code{gettext} is able to interface with the tools already
+provided with systems, it will consequently let these provided tools
+take care of generating the MO files. Or else, if such tools are not
+found or do not seem usable, GNU @code{gettext} will use its own ways
+and its own format for MO files. Files ending with @file{.gmo} are
+really MO files, when it is known that these files use the GNU format.
+
+@node Overview, , Files, Introduction
+@section Overview of GNU @code{gettext}
+
+The following diagram summarizes the relation between the files
+handled by GNU @code{gettext} and the tools acting on these files.
+It is followed by a somewhat detailed explanations, which you should
+read while keeping an eye on the diagram. Having a clear understanding
+of these interrelations would surely help programmers, translators
+and maintainers.
+
+@example
+@group
+Original C Sources ---> PO mode ---> Marked C Sources ---.
+ |
+ .---------<--- GNU gettext Library |
+.--- make <---+ |
+| `---------<--------------------+-----------'
+| |
+| .-----<--- PACKAGE.pot <--- xgettext <---' .---<--- PO Compendium
+| | | ^
+| | `---. |
+| `---. +---> PO mode ---.
+| +----> msgmerge ------> LANG.pox --->--------' |
+| .---' |
+| | |
+| `-------------<---------------. |
+| +--- LANG.po <--- New LANG.pox <----'
+| .--- LANG.gmo <--- msgfmt <---'
+| |
+| `---> install ---> /.../LANG/PACKAGE.mo ---.
+| +---> "Hello world!"
+`-------> install ---> /.../bin/PROGRAM -------'
+@end group
+@end example
+
+The indication @samp{PO mode} appears in two places in this picture,
+and you may safely read it as merely meaning ``hand editing'', using
+any editor of your choice, really. However, for those of you being
+the lucky users of Emacs, PO mode has been specifically created
+for providing a cozy environment for editing or modifying PO files.
+While editing a PO file, PO mode allows for the easy browsing of
+auxiliary and compendium PO files, as well as for following references into
+the set of C program sources from which PO files have been derived.
+It has a few special features, among which are the interactive marking
+of program strings as translatable, and the validatation of PO files
+with easy repositioning to PO file lines showing errors.
+
+As a programmer, the first step to bringing GNU @code{gettext}
+into your package is identifying, right in the C sources, those strings
+which are meant to be translatable, and those which are untranslatable.
+This tedious job can be done a little more comfortably using emacs PO
+mode, but you can use any means familiar to you for modifying your
+C sources. Beside this some other simple, standard changes are needed to
+properly initialize the translation library. @xref{Sources}, for
+more information about all this.
+
+For newly written software the strings of course can and should be
+marked while writing the it. The @code{gettext} approach makes this
+very easy. Simply put the following lines at the beginning of each file
+or in a central header file:
+
+@example
+@group
+#define _(String) (String)
+#define N_(String) (String)
+#define textdomain(Domain)
+#define bindtextdomain(Package, Directory)
+@end group
+@end example
+
+@noindent
+Doing this allows you to prepare the sources for internationalization.
+Later when you feel ready for the step to use the @code{gettext} library
+simply remove these definitions, include @file{libintl.h} and link
+against @file{libintl.a}. That is all you have to change.
+
+Once the C sources have been modified, the @code{xgettext} program
+is used to find and extract all translatable strings, and create an
+initial PO file out of all these. This @file{@var{package}.pot} file
+contains all original program strings. It has sets of pointers to
+exactly where in C sources each string is used. All translations
+are set to empty. The letter @kbd{t} in @file{.pot} marks this as
+a Template PO file, not yet oriented towards any particular language.
+@xref{xgettext Invocation}, for more details about how one calls the
+@code{xgettext} program. If you are @emph{really} lazy, you might
+be interested at working a lot more right away, and preparing the
+whole distribution setup (@pxref{Maintainers}). By doing so, you
+spare yourself typing the @code{xgettext} command, as @code{make}
+should now generate the proper things automatically for you!
+
+The first time through, there is no @file{@var{lang}.po} yet, so the
+@code{msgmerge} step may be skipped and replaced by a mere copy of
+@file{@var{package}.pot} to @file{@var{lang}.pox}, where @var{lang}
+represents the target language.
+
+Then comes the initial translation of messages. Translation in
+itself is a whole matter, still exclusively meant for humans,
+and whose complexity far overwhelms the level of this manual.
+Nevertheless, a few hints are given in some other chapter of this
+manual (@pxref{Translators}). You will also find there indications
+about how to contact translating teams, or becoming part of them,
+for sharing your translating concerns with others who target the same
+native language.
+
+While adding the translated messages into the @file{@var{lang}.pox}
+PO file, if you do not have Emacs handy, you are on your own
+for ensuring that your efforts fully respect the PO file format, and quoting
+conventions (@pxref{PO Files}). This is surely not an impossible task,
+as this is the way many people have handled PO files already for Uniforum or
+Solaris. On the other hand, by using PO mode in Emacs, most details
+of PO file format are taken care of for you, but you have to acquire
+some familiarity with PO mode itself. Besides main PO mode commands
+(@pxref{Main PO Commands}), you should know how to move between entries
+(@pxref{Entry Positioning}), and how to handle untranslated entries
+(@pxref{Untranslated Entries}).
+
+If some common translations have already been saved into a compendium
+PO file, translators may use PO mode for initializing untranslated
+entries from the compendium, and also save selected translations into
+the compendium, updating it (@pxref{Compendium}). Compendium files
+are meant to be exchanged between members of a given translation team.
+
+Programs, or packages of programs, are dynamic in nature: users write
+bug reports and suggestion for improvements, maintainers react by
+modifying programs in various ways. The fact that a package has
+already been internationalized should not make maintainers shy
+of adding new strings, or modifying strings already translated.
+They just do their job the best they can. For the Translation
+Project to work smoothly, it is important that maintainers do not
+carry translation concerns on their already loaded shoulders, and that
+translators be kept as free as possible of programmatic concerns.
+
+The only concern maintainers should have is carefully marking new
+strings as translatable, when they should be, and do not otherwise
+worry about them being translated, as this will come in proper time.
+Consequently, when programs and their strings are adjusted in various
+ways by maintainers, and for matters usually unrelated to translation,
+@code{xgettext} would construct @file{@var{package}.pot} files which are
+evolving over time, so the translations carried by @file{@var{lang}.po}
+are slowly fading out of date.
+
+It is important for translators (and even maintainers) to understand
+that package translation is a continuous process in the lifetime of a
+package, and not something which is done once and for all at the start.
+After an initial burst of translation activity for a given package,
+interventions are needed once in a while, because here and there,
+translated entries become obsolete, and new untranslated entries
+appear, needing translation.
+
+The @code{msgmerge} program has the purpose of refreshing an already
+existing @file{@var{lang}.po} file, by comparing it with a newer
+@file{@var{package}.pot} template file, extracted by @code{xgettext}
+out of recent C sources. The refreshing operation adjusts all
+references to C source locations for strings, since these strings
+move as programs are modified. Also, @code{msgmerge} comments out as
+obsolete, in @file{@var{lang}.pox}, those already translated entries
+which are no longer used in the program sources (@pxref{Obsolete
+Entries}). It finally discovers new strings and inserts them in
+the resulting PO file as untranslated entries (@pxref{Untranslated
+Entries}). @xref{msgmerge Invocation}, for more information about what
+@code{msgmerge} really does.
+
+Whatever route or means taken, the goal is to obtain an updated
+@file{@var{lang}.pox} file offering translations for all strings.
+When this is properly achieved, this file @file{@var{lang}.pox} may
+take the place of the previous official @file{@var{lang}.po} file.
+
+The temporal mobility, or fluidity of PO files, is an integral part of
+the translation game, and should be well understood, and accepted.
+People resisting it will have a hard time participating in the
+Translation Project, or will give a hard time to other participants! In
+particular, maintainers should relax and include all available official
+PO files in their distributions, even if these have not recently been
+updated, without banging or otherwise trying to exert pressure on the
+translator teams to get the job done. The pressure should rather come
+from the community of users speaking a particular language, and
+maintainers should consider themselves fairly relieved of any concern
+about the adequacy of translation files. On the other hand, translators
+should reasonably try updating the PO files they are responsible for,
+while the package is undergoing pretest, prior to an official
+distribution.
+
+Once the PO file is complete and dependable, the @code{msgfmt} program
+is used for turning the PO file into a machine-oriented format, which
+may yield efficient retrieval of translations by the programs of the
+package, whenever needed at runtime (@pxref{MO Files}). @xref{msgfmt
+Invocation}, for more information about all modalities of execution
+for the @code{msgfmt} program.
+
+Finally, the modified and marked C sources are compiled and linked
+with the GNU @code{gettext} library, usually through the operation of
+@code{make}, given a suitable @file{Makefile} exists for the project,
+and the resulting executable is installed somewhere users will find it.
+The MO files themselves should also be properly installed. Given the
+appropriate environment variables are set (@pxref{End Users}), the
+program should localize itself automatically, whenever it executes.
+
+The remainder of this manual has the purpose of explaining in depth the various
+steps outlined above.
+
+@node Basics, Sources, Introduction, Top
+@chapter PO Files and PO Mode Basics
+
+The GNU @code{gettext} toolset helps programmers and translators
+at producing, updating and using translation files, mainly those
+PO files which are textual, editable files. This chapter stresses
+the format of PO files, and contains a PO mode starter. PO mode
+description is spread throughout this manual instead of being concentrated
+in one place. Here we present only the basics of PO mode.
+
+@menu
+* Installation:: Completing GNU @code{gettext} Installation
+* PO Files:: The Format of PO Files
+* Main PO Commands:: Main Commands
+* Entry Positioning:: Entry Positioning
+* Normalizing:: Normalizing Strings in Entries
+@end menu
+
+@node Installation, PO Files, Basics, Basics
+@section Completing GNU @code{gettext} Installation
+
+Once you have received, unpacked, configured and compiled the GNU
+@code{gettext} distribution, the @samp{make install} command puts in
+place the programs @code{xgettext}, @code{msgfmt}, @code{gettext}, and
+@code{msgmerge}, as well as their available message catalogs. To
+top off a comfortable installation, you might also want to make the
+PO mode available to your Emacs users.
+
+During the installation of the PO mode, you might want modify your
+file @file{.emacs}, once and for all, so it contains a few lines looking
+like:
+
+@example
+(setq auto-mode-alist
+ (cons '("\\.po[tx]?\\'\\|\\.po\\." . po-mode) auto-mode-alist))
+(autoload 'po-mode "po-mode")
+@end example
+
+Later, whenever you edit some @file{.po}, @file{.pot} or @file{.pox}
+file, or any file having the string @samp{.po.} within its name,
+Emacs loads @file{po-mode.elc} (or @file{po-mode.el}) as needed, and
+automatically activates PO mode commands for the associated buffer.
+The string @emph{PO} appears in the mode line for any buffer for
+which PO mode is active. Many PO files may be active at once in a
+single Emacs session.
+
+If you are using Emacs version 20 or better, and have already installed
+the appropriate international fonts on your system, you may also manage
+for the these fonts to be automatically loaded and used for displaying
+the translations on your Emacs screen, whenever necessary. For this to
+happen, you might want to add the lines:
+
+@example
+(autoload 'po-find-file-coding-system "po-mode")
+(modify-coding-system-alist 'file "\\.po[tx]?\\'\\|\\.po\\."
+ 'po-find-file-coding-system)
+@end example
+
+@noindent
+to your @file{.emacs} file.
+
+@node PO Files, Main PO Commands, Installation, Basics
+@section The Format of PO Files
+
+A PO file is made up of many entries, each entry holding the relation
+between an original untranslated string and its corresponding
+translation. All entries in a given PO file usually pertain
+to a single project, and all translations are expressed in a single
+target language. One PO file @dfn{entry} has the following schematic
+structure:
+
+@example
+@var{white-space}
+# @var{translator-comments}
+#. @var{automatic-comments}
+#: @var{reference}@dots{}
+#, @var{flag}@dots{}
+msgid @var{untranslated-string}
+msgstr @var{translated-string}
+@end example
+
+The general structure of a PO file should be well understood by
+the translator. When using PO mode, very little has to be known
+about the format details, as PO mode takes care of them for her.
+
+Entries begin with some optional white space. Usually, when generated
+through GNU @code{gettext} tools, there is exactly one blank line
+between entries. Then comments follow, on lines all starting with the
+character @kbd{#}. There are two kinds of comments: those which have
+some white space immediately following the @kbd{#}, which comments are
+created and maintained exclusively by the translator, and those which
+have some non-white character just after the @kbd{#}, which comments
+are created and maintained automatically by GNU @code{gettext} tools.
+All comments, of either kind, are optional.
+
+After white space and comments, entries show two strings, giving
+first the untranslated string as it appears in the original program
+sources, and then, the translation of this string. The original
+string is introduced by the keyword @code{msgid}, and the translation,
+by @code{msgstr}. The two strings, untranslated and translated,
+are quoted in various ways in the PO file, using @kbd{"}
+delimiters and @kbd{\} escapes, but the translator does not really
+have to pay attention to the precise quoting format, as PO mode fully
+intend to take care of quoting for her.
+
+The @code{msgid} strings, as well as automatic comments, are produced
+and managed by other GNU @code{gettext} tools, and PO mode does not
+provide means for the translator to alter these. The most she can
+do is merely deleting them, and only by deleting the whole entry.
+On the other hand, the @code{msgstr} string, as well as translator
+comments, are really meant for the translator, and PO mode gives her
+the full control she needs.
+
+The comment lines beginning with @kbd{#,} are special because they are
+not completely ignored by the programs as comments generally are. The
+comma separated list of @var{flag}s is used by the @code{msgfmt}
+program to give the user some better disgnostic messages. Currently
+there are two forms of flags defined:
+
+@table @kbd
+@item fuzzy
+This flag can be generated by the @code{msgmerge} program or it can be
+inserted by the translator herself. It shows that the @code{msgstr}
+string might not be a correct translation (anymore). Only the translator
+can judge if the translation requires further modification, or is
+acceptable as is. Once satisfied with the translation, she then removes
+this @kbd{fuzzy} attribute. The @code{msgmerge} programs inserts this
+when it combined the @code{msgid} and @code{msgstr} entries after fuzzy
+search only. @xref{Fuzzy Entries}.
+
+@item c-format
+@itemx no-c-format
+These flags should not be added by a human. Instead only the
+@code{xgettext} program adds them. In an automatized PO file processing
+system as proposed here the user changes would be thrown away again as
+soon as the @code{xgettext} program generates a new template file.
+
+In case the @kbd{c-format} flag is given for a string the @code{msgfmt}
+does some more tests to check to validity of the translation.
+@xref{msgfmt Invocation}.
+
+@end table
+
+It happens that some lines, usually whitespace or comments, follow the
+very last entry of a PO file. Such lines are not part of any entry,
+and PO mode is unable to take action on those lines. By using the
+PO mode function @w{@kbd{M-x po-normalize}}, the translator may get
+rid of those spurious lines. @xref{Normalizing}.
+
+The remainder of this section may be safely skipped by those using
+PO mode, yet it may be interesting for everybody to have a better
+idea of the precise format of a PO file. On the other hand, those
+not having Emacs handy should carefully continue reading on.
+
+Each of @var{untranslated-string} and @var{translated-string} respects
+the C syntax for a character string, including the surrounding quotes
+and imbedded backslashed escape sequences. When the time comes
+to write multi-line strings, one should not use escaped newlines.
+Instead, a closing quote should follow the last character on the
+line to be continued, and an opening quote should resume the string
+at the beginning of the following PO file line. For example:
+
+@example
+msgid ""
+"Here is an example of how one might continue a very long string\n"
+"for the common case the string represents multi-line output.\n"
+@end example
+
+@noindent
+In this example, the empty string is used on the first line, to
+allow better alignment of the @kbd{H} from the word @samp{Here}
+over the @kbd{f} from the word @samp{for}. In this example, the
+@code{msgid} keyword is followed by three strings, which are meant
+to be concatenated. Concatenating the empty string does not change
+the resulting overall string, but it is a way for us to comply with
+the necessity of @code{msgid} to be followed by a string on the same
+line, while keeping the multi-line presentation left-justified, as
+we find this to be a cleaner disposition. The empty string could have
+been omitted, but only if the string starting with @samp{Here} was
+promoted on the first line, right after @code{msgid}.@footnote{This
+limitation is not imposed by GNU @code{gettext}, but comes from the
+@code{msgfmt} implementation on Solaris.} It was not really necessary
+either to switch between the two last quoted strings immediately after
+the newline @samp{\n}, the switch could have occurred after @emph{any}
+other character, we just did it this way because it is neater.
+
+One should carefully distinguish between end of lines marked as
+@samp{\n} @emph{inside} quotes, which are part of the represented
+string, and end of lines in the PO file itself, outside string quotes,
+which have no incidence on the represented string.
+
+Outside strings, white lines and comments may be used freely.
+Comments start at the beginning of a line with @samp{#} and extend
+until the end of the PO file line. Comments written by translators
+should have the initial @samp{#} immediately followed by some white
+space. If the @samp{#} is not immediately followed by white space,
+this comment is most likely generated and managed by specialized GNU
+tools, and might disappear or be replaced unexpectedly when the PO
+file is given to @code{msgmerge}.
+
+@node Main PO Commands, Entry Positioning, PO Files, Basics
+@section Main PO mode Commands
+
+After setting up Emacs with something similar to the lines in
+@ref{Installation}, PO mode is activated for a window when Emacs finds a
+PO file in that window. This puts the window read-only and establishes a
+po-mode-map, which is a genuine Emacs mode, in a way that is not derived
+from text mode in any way. Functions found on @code{po-mode-hook},
+if any, will be executed.
+
+When PO mode is active in a window, the letters @samp{PO} appear
+in the mode line for that window. The mode line also displays how
+many entries of each kind are held in the PO file. For example,
+the string @samp{132t+3f+10u+2o} would tell the translator that the
+PO mode contains 132 translated entries (@pxref{Translated Entries},
+3 fuzzy entries (@pxref{Fuzzy Entries}), 10 untranslated entries
+(@pxref{Untranslated Entries}) and 2 obsolete entries (@pxref{Obsolete
+Entries}). Zero-coefficients items are not shown. So, in this example, if
+the fuzzy entries were unfuzzied, the untranslated entries were translated
+and the obsolete entries were deleted, the mode line would merely display
+@samp{145t} for the counters.
+
+The main PO commands are those which do not fit into the other categories of
+subsequent sections. These allow for quitting PO mode or for managing windows
+in special ways.
+
+@table @kbd
+@item U
+Undo last modification to the PO file.
+
+@item Q
+Quit processing and save the PO file.
+
+@item q
+Quit processing, possibly after confirmation.
+
+@item O
+Temporary leave the PO file window.
+
+@item ?
+@itemx h
+Show help about PO mode.
+
+@item =
+Give some PO file statistics.
+
+@item V
+Batch validate the format of the whole PO file.
+
+@end table
+
+The command @kbd{U} (@code{po-undo}) interfaces to the Emacs
+@emph{undo} facility. @xref{Undo, , Undoing Changes, emacs, The Emacs
+Editor}. Each time @kbd{U} is typed, modifications which the translator
+did to the PO file are undone a little more. For the purpose of
+undoing, each PO mode command is atomic. This is especially true for
+the @kbd{@key{RET}} command: the whole edition made by using a single
+use of this command is undone at once, even if the edition itself
+implied several actions. However, while in the editing window, one
+can undo the edition work quite parsimoniously.
+
+The commands @kbd{Q} (@code{po-quit}) and @kbd{q}
+(@code{po-confirm-and-quit}) are used when the translator is done with the
+PO file. The former is a bit less verbose than the latter. If the file
+has been modified, it is saved to disk first. In both cases, and prior to
+all this, the commands check if some untranslated message remains in the
+PO file and, if yes, the translator is asked if she really wants to leave
+off working with this PO file. This is the preferred way of getting rid
+of an Emacs PO file buffer. Merely killing it through the usual command
+@w{@kbd{C-x k}} (@code{kill-buffer}) is not the tidiest way to proceed.
+
+The command @kbd{O} (@code{po-other-window}) is another, softer way,
+to leave PO mode, temporarily. It just moves the cursor to some other
+Emacs window, and pops one if necessary. For example, if the translator
+just got PO mode to show some source context in some other, she might
+discover some apparent bug in the program source that needs correction.
+This command allows the translator to change sex, become a programmer,
+and have the cursor right into the window containing the program she
+(or rather @emph{he}) wants to modify. By later getting the cursor back
+in the PO file window, or by asking Emacs to edit this file once again,
+PO mode is then recovered.
+
+The command @kbd{h} (@code{po-help}) displays a summary of all available PO
+mode commands. The translator should then type any character to resume
+normal PO mode operations. The command @kbd{?} has the same effect
+as @kbd{h}.
+
+The command @kbd{=} (@code{po-statistics}) computes the total number of
+entries in the PO file, the ordinal of the current entry (counted from
+1), the number of untranslated entries, the number of obsolete entries,
+and displays all these numbers.
+
+The command @kbd{V} (@code{po-validate}) launches @code{msgfmt} in verbose
+mode over the current PO file. This command first offers to save the
+current PO file on disk. The @code{msgfmt} tool, from GNU @code{gettext},
+has the purpose of creating a MO file out of a PO file, and PO mode uses
+the features of this program for checking the overall format of a PO file,
+as well as all individual entries.
+
+The program @code{msgfmt} runs asynchronously with Emacs, so the
+translator regains control immediately while her PO file is being studied.
+Error output is collected in the Emacs @samp{*compilation*} buffer,
+displayed in another window. The regular Emacs command @kbd{C-x`}
+(@code{next-error}), as well as other usual compile commands, allow the
+translator to reposition quickly to the offending parts of the PO file.
+Once the cursor is on the line in error, the translator may decide on
+any PO mode action which would help correcting the error.
+
+@node Entry Positioning, Normalizing, Main PO Commands, Basics
+@section Entry Positioning
+
+The cursor in a PO file window is almost always part of
+an entry. The only exceptions are the special case when the cursor
+is after the last entry in the file, or when the PO file is
+empty. The entry where the cursor is found to be is said to be the
+current entry. Many PO mode commands operate on the current entry,
+so moving the cursor does more than allowing the translator to browse
+the PO file, this also selects on which entry commands operate.
+
+Some PO mode commands alter the position of the cursor in a specialized
+way. A few of those special purpose positioning are described here,
+the others are described in following sections.
+
+@table @kbd
+
+@item .
+Redisplay the current entry.
+
+@item n
+@itemx n
+Select the entry after the current one.
+
+@item p
+@itemx p
+Select the entry before the current one.
+
+@item <
+Select the first entry in the PO file.
+
+@item >
+Select the last entry in the PO file.
+
+@item m
+Record the location of the current entry for later use.
+
+@item l
+Return to a previously saved entry location.
+
+@item x
+Exchange the current entry location with the previously saved one.
+
+@end table
+
+Any Emacs command able to reposition the cursor may be used
+to select the current entry in PO mode, including commands which
+move by characters, lines, paragraphs, screens or pages, and search
+commands. However, there is a kind of standard way to display the
+current entry in PO mode, which usual Emacs commands moving
+the cursor do not especially try to enforce. The command @kbd{.}
+(@code{po-current-entry}) has the sole purpose of redisplaying the
+current entry properly, after the current entry has been changed by
+means external to PO mode, or the Emacs screen otherwise altered.
+
+It is yet to be decided if PO mode helps the translator, or otherwise
+irritates her, by forcing a rigid window disposition while she
+is doing her work. We originally had quite precise ideas about
+how windows should behave, but on the other hand, anyone used to
+Emacs is often happy to keep full control. Maybe a fixed window
+disposition might be offered as a PO mode option that the translator
+might activate or deactivate at will, so it could be offered on an
+experimental basis. If nobody feels a real need for using it, or
+a compulsion for writing it, we should drop this whole idea.
+The incentive for doing it should come from translators rather than
+programmers, as opinions from an experienced translator are surely
+more worth to me than opinions from programmers @emph{thinking} about
+how @emph{others} should do translation.
+
+The commands @kbd{n} (@code{po-next-entry}) and @kbd{p}
+(@code{po-previous-entry}) move the cursor the entry following,
+or preceding, the current one. If @kbd{n} is given while the
+cursor is on the last entry of the PO file, or if @kbd{p}
+is given while the cursor is on the first entry, no move is done.
+
+The commands @kbd{<} (@code{po-first-entry}) and @kbd{>}
+(@code{po-last-entry}) move the cursor to the first entry, or last
+entry, of the PO file. When the cursor is located past the last
+entry in a PO file, most PO mode commands will return an error saying
+@samp{After last entry}. Moreover, the commands @kbd{<} and @kbd{>}
+have the special property of being able to work even when the cursor
+is not into some PO file entry, and one may use them for nicely
+correcting this situation. But even these commands will fail on a
+truly empty PO file. There are development plans for the PO mode for it
+to interactively fill an empty PO file from sources. @xref{Marking}.
+
+The translator may decide, before working at the translation of
+a particular entry, that she needs to browse the remainder of the
+PO file, maybe for finding the terminology or phraseology used
+in related entries. She can of course use the standard Emacs idioms
+for saving the current cursor location in some register, and use that
+register for getting back, or else, use the location ring.
+
+PO mode offers another approach, by which cursor locations may be saved
+onto a special stack. The command @kbd{m} (@code{po-push-location})
+merely adds the location of current entry to the stack, pushing
+the already saved locations under the new one. The command
+@kbd{r} (@code{po-pop-location}) consumes the top stack element and
+reposition the cursor to the entry associated with that top element.
+This position is then lost, for the next @kbd{r} will move the cursor
+to the previously saved location, and so on until no locations remain
+on the stack.
+
+If the translator wants the position to be kept on the location stack,
+maybe for taking a look at the entry associated with the top
+element, then go elsewhere with the intent of getting back later, she
+ought to use @kbd{m} immediately after @kbd{r}.
+
+The command @kbd{x} (@code{po-exchange-location}) simultaneously
+reposition the cursor to the entry associated with the top element of
+the stack of saved locations, and replace that top element with the
+location of the current entry before the move. Consequently, repeating
+the @kbd{x} command toggles alternatively between two entries.
+For achieving this, the translator will position the cursor on the
+first entry, use @kbd{m}, then position to the second entry, and
+merely use @kbd{x} for making the switch.
+
+@node Normalizing, , Entry Positioning, Basics
+@section Normalizing Strings in Entries
+
+There are many different ways for encoding a particular string into a
+PO file entry, because there are so many different ways to split and
+quote multi-line strings, and even, to represent special characters
+by backslahsed escaped sequences. Some features of PO mode rely on
+the ability for PO mode to scan an already existing PO file for a
+particular string encoded into the @code{msgid} field of some entry.
+Even if PO mode has internally all the built-in machinery for
+implementing this recognition easily, doing it fast is technically
+difficult. To facilitate a solution to this efficiency problem,
+we decided on a canonical representation for strings.
+
+A conventional representation of strings in a PO file is currently
+under discussion, and PO mode experiments with a canonical representation.
+Having both @code{xgettext} and PO mode converging towards a uniform
+way of representing equivalent strings would be useful, as the internal
+normalization needed by PO mode could be automatically satisfied
+when using @code{xgettext} from GNU @code{gettext}. An explicit
+PO mode normalization should then be only necessary for PO files
+imported from elsewhere, or for when the convention itself evolves.
+
+So, for achieving normalization of at least the strings of a given
+PO file needing a canonical representation, the following PO mode
+command is available:
+
+@table @kbd
+@item M-x po-normalize
+Tidy the whole PO file by making entries more uniform.
+
+@end table
+
+The special command @kbd{M-x po-normalize}, which has no associate
+keys, revises all entries, ensuring that strings of both original
+and translated entries use uniform internal quoting in the PO file.
+It also removes any crumb after the last entry. This command may be
+useful for PO files freshly imported from elsewhere, or if we ever
+improve on the canonical quoting format we use. This canonical format
+is not only meant for getting cleaner PO files, but also for greatly
+speeding up @code{msgid} string lookup for some other PO mode commands.
+
+@kbd{M-x po-normalize} presently makes three passes over the entries.
+The first implements heuristics for converting PO files for GNU
+@code{gettext} 0.6 and earlier, in which @code{msgid} and @code{msgstr}
+fields were using K&R style C string syntax for multi-line strings.
+These heuristics may fail for comments not related to obsolete
+entries and ending with a backslash; they also depend on subsequent
+passes for finalizing the proper commenting of continued lines for
+obsolete entries. This first pass might disappear once all oldish PO
+files would have been adjusted. The second and third pass normalize
+all @code{msgid} and @code{msgstr} strings respectively. They also
+clean out those trailing backslashes used by XView's @code{msgfmt}
+for continued lines.
+
+Having such an explicit normalizing command allows for importing PO
+files from other sources, but also eases the evolution of the current
+convention, evolution driven mostly by aesthetic concerns, as of now.
+It is easy to make suggested adjustments at a later time, as the
+normalizing command and eventually, other GNU @code{gettext} tools
+should greatly automate conformance. A description of the canonical
+string format is given below, for the particular benefit of those not
+having Emacs handy, and who would nevertheless want to handcraft
+their PO files in nice ways.
+
+Right now, in PO mode, strings are single line or multi-line. A string
+goes multi-line if and only if it has @emph{embedded} newlines, that
+is, if it matches @samp{[^\n]\n+[^\n]}. So, we would have:
+
+@example
+msgstr "\n\nHello, world!\n\n\n"
+@end example
+
+but, replacing the space by a newline, this becomes:
+
+@example
+msgstr ""
+"\n"
+"\n"
+"Hello,\n"
+"world!\n"
+"\n"
+"\n"
+@end example
+
+We are deliberately using a caricatural example, here, to make the
+point clearer. Usually, multi-lines are not that bad looking.
+It is probable that we will implement the following suggestion.
+We might lump together all initial newlines into the empty string,
+and also all newlines introducing empty lines (that is, for @w{@var{n}
+> 1}, the @var{n}-1'th last newlines would go together on a separate
+string), so making the previous example appear:
+
+@example
+msgstr "\n\n"
+"Hello,\n"
+"world!\n"
+"\n\n"
+@end example
+
+There are a few yet undecided little points about string normalization,
+to be documented in this manual, once these questions settle.
+
+@node Sources, Initial, Basics, Top
+@chapter Preparing Program Sources
+
+@c FIXME: Rewrite (the whole chapter).
+
+For the programmer, changes to the C source code fall into three
+categories. First, you have to make the localization functions
+known to all modules needing message translation. Second, you should
+properly trigger the operation of GNU @code{gettext} when the program
+initializes, usually from the @code{main} function. Last, you should
+identify and especially mark all constant strings in your program
+needing translation.
+
+Presuming that your set of programs, or package, has been adjusted
+so all needed GNU @code{gettext} files are available, and your
+@file{Makefile} files are adjusted (@pxref{Maintainers}), each C module
+having translated C strings should contain the line:
+
+@example
+#include <libintl.h>
+@end example
+
+The remaining changes to your C sources are discussed in the further
+sections of this chapter.
+
+@menu
+* Triggering:: Triggering @code{gettext} Operations
+* Mark Keywords:: How Marks Appears in Sources
+* Marking:: Marking Translatable Strings
+* c-format:: Telling something about the following string
+* Special cases:: Special Cases of Translatable Strings
+@end menu
+
+@node Triggering, Mark Keywords, Sources, Sources
+@section Triggering @code{gettext} Operations
+
+The initialization of locale data should be done with more or less
+the same code in every program, as demonstrated below:
+
+@example
+@group
+int
+main (argc, argv)
+ int argc;
+ char argv;
+@{
+ @dots{}
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+ @dots{}
+@}
+@end group
+@end example
+
+@var{PACKAGE} and @var{LOCALEDIR} should be provided either by
+@file{config.h} or by the Makefile. For now consult the @code{gettext}
+sources for more information.
+
+The use of @code{LC_ALL} might not be appropriate for you.
+@code{LC_ALL} includes all locale categories and especially
+@code{LC_CTYPE}. This later category is responsible for determining
+character classes with the @code{isalnum} etc. functions from
+@file{ctype.h} which could especially for programs, which process some
+kind of input language, be wrong. For example this would mean that a
+source code using the @,{c} (c-cedilla character) is runnable in
+France but not in the U.S.
+
+Some systems also have problems with parsing number using the
+@code{scanf} functions if an other but the @code{LC_ALL} locale is used.
+The standards say that additional formats but the one known in the
+@code{"C"} locale might be recognized. But some systems seem to reject
+numbers in the @code{"C"} locale format. In some situation, it might
+also be a problem with the notation itself which makes it impossible to
+recognize whether the number is in the @code{"C"} locale or the local
+format. This can happen if thousands separator characters are used.
+Some locales define this character accordfing to the national
+conventions to @code{'.'} which is the same character used in the
+@code{"C"} locale to denote the decimal point.
+
+So it is sometimes necessary to replace the @code{LC_ALL} line in the
+code above by a sequence of @code{setlocale} lines
+
+@example
+@group
+@{
+ @dots{}
+ setlocale (LC_TIME, "");
+ setlocale (LC_MESSAGES, "");
+ @dots{}
+@}
+@end group
+@end example
+
+@noindent
+or to switch for and back to the character class in question. On all
+POSIX conformant systems the locale categories @code{LC_CTYPE},
+@code{LC_COLLATE}, @code{LC_MONETARY}, @code{LC_NUMERIC}, and
+@code{LC_TIME} are available. On some modern systems there is also a
+locale @code{LC_MESSAGES} which is called on some old, XPG2 compliant
+systems @code{LC_RESPONSES}.
+
+@node Mark Keywords, Marking, Triggering, Sources
+@section How Marks Appears in Sources
+
+All strings requiring translation should be marked in the C sources. Marking
+is done in such a way that each translatable string appears to be
+the sole argument of some function or preprocessor macro. There are
+only a few such possible functions or macros meant for translation,
+and their names are said to be marking keywords. The marking is
+attached to strings themselves, rather than to what we do with them.
+This approach has more uses. A blatant example is an error message
+produced by formatting. The format string needs translation, as
+well as some strings inserted through some @samp{%s} specification
+in the format, while the result from @code{sprintf} may have so many
+different instances that it is impractical to list them all in some
+@samp{error_string_out()} routine, say.
+
+This marking operation has two goals. The first goal of marking
+is for triggering the retrieval of the translation, at run time.
+The keyword are possibly resolved into a routine able to dynamically
+return the proper translation, as far as possible or wanted, for the
+argument string. Most localizable strings are found in executable
+positions, that is, attached to variables or given as parameters to
+functions. But this is not universal usage, and some translatable
+strings appear in structured initializations. @xref{Special cases}.
+
+The second goal of the marking operation is to help @code{xgettext}
+at properly extracting all translatable strings when it scans a set
+of program sources and produces PO file templates.
+
+The canonical keyword for marking translatable strings is
+@samp{gettext}, it gave its name to the whole GNU @code{gettext}
+package. For packages making only light use of the @samp{gettext}
+keyword, macro or function, it is easily used @emph{as is}. However,
+for packages using the @code{gettext} interface more heavily, it
+is usually more convenient to give the main keyword a shorter, less
+obtrusive name. Indeed, the keyword might appear on a lot of strings
+all over the package, and programmers usually do not want nor need
+their program sources to remind them forcefully, all the time, that they
+are internationalized. Further, a long keyword has the disadvantage
+of using more horizontal space, forcing more indentation work on
+sources for those trying to keep them within 79 or 80 columns.
+
+Many packages use @samp{_} (a simple underline) as a keyword,
+and write @samp{_("Translatable string")} instead of @samp{gettext
+("Translatable string")}. Further, the coding rule, from GNU standards,
+wanting that there is a space between the keyword and the opening
+parenthesis is relaxed, in practice, for this particular usage.
+So, the textual overhead per translatable string is reduced to
+only three characters: the underline and the two parentheses.
+However, even if GNU @code{gettext} uses this convention internally,
+it does not offer it officially. The real, genuine keyword is truly
+@samp{gettext} indeed. It is fairly easy for those wanting to use
+@samp{_} instead of @samp{gettext} to declare:
+
+@example
+#include <libintl.h>
+#define _(String) gettext (String)
+@end example
+
+@noindent
+instead of merely using @samp{#include <libintl.h>}.
+
+Later on, the maintenance is relatively easy. If, as a programmer,
+you add or modify a string, you will have to ask yourself if the
+new or altered string requires translation, and include it within
+@samp{_()} if you think it should be translated. @samp{"%s: %d"} is
+an example of string @emph{not} requiring translation!
+
+@node Marking, c-format, Mark Keywords, Sources
+@section Marking Translatable Strings
+
+In PO mode, one set of features is meant more for the programmer than
+for the translator, and allows him to interactively mark which strings,
+in a set of program sources, are translatable, and which are not.
+Even if it is a fairly easy job for a programmer to find and mark
+such strings by other means, using any editor of his choice, PO mode
+makes this work more comfortable. Further, this gives translators
+who feel a little like programmers, or programmers who feel a little
+like translators, a tool letting them work at marking translatable
+strings in the program sources, while simultaneously producing a set of
+translation in some language, for the package being internationalized.
+
+The set of program sources, targetted by the PO mode commands describe
+here, should have an Emacs tags table constructed for your project,
+prior to using these PO file commands. This is easy to do. In any
+shell window, change the directory to the root of your project, then
+execute a command resembling:
+
+@example
+etags src/*.[hc] lib/*.[hc]
+@end example
+
+@noindent
+presuming here you want to process all @file{.h} and @file{.c} files
+from the @file{src/} and @file{lib/} directories. This command will
+explore all said files and create a @file{TAGS} file in your root
+directory, somewhat summarizing the contents using a special file
+format Emacs can understand.
+
+For packages following the GNU coding standards, there is
+a make goal @code{tags} or @code{TAGS} which construct the tag files in
+all directories and for all files containing source code.
+
+Once your @file{TAGS} file is ready, the following commands assist
+the programmer at marking translatable strings in his set of sources.
+But these commands are necessarily driven from within a PO file
+window, and it is likely that you do not even have such a PO file yet.
+This is not a problem at all, as you may safely open a new, empty PO
+file, mainly for using these commands. This empty PO file will slowly
+fill in while you mark strings as translatable in your program sources.
+
+@table @kbd
+@item ,
+Search through program sources for a string which looks like a
+candidate for translation.
+
+@item M-,
+Mark the last string found with @samp{_()}.
+
+@item M-.
+Mark the last string found with a keyword taken from a set of possible
+keywords. This command with a prefix allows some management of these
+keywords.
+
+@end table
+
+The @kbd{,} (@code{po-tags-search}) command search for the next
+occurrence of a string which looks like a possible candidate for
+translation, and displays the program source in another Emacs window,
+positioned in such a way that the string is near the top of this other
+window. If the string is too big to fit whole in this window, it is
+positioned so only its end is shown. In any case, the cursor
+is left in the PO file window. If the shown string would be better
+presented differently in different native languages, you may mark it
+using @kbd{M-,} or @kbd{M-.}. Otherwise, you might rather ignore it
+and skip to the next string by merely repeating the @kbd{,} command.
+
+A string is a good candidate for translation if it contains a sequence
+of three or more letters. A string containing at most two letters in
+a row will be considered as a candidate if it has more letters than
+non-letters. The command disregards strings containing no letters,
+or isolated letters only. It also disregards strings within comments,
+or strings already marked with some keyword PO mode knows (see below).
+
+If you have never told Emacs about some @file{TAGS} file to use, the
+command will request that you specify one from the minibuffer, the
+first time you use the command. You may later change your @file{TAGS}
+file by using the regular Emacs command @w{@kbd{M-x visit-tags-table}},
+which will ask you to name the precise @file{TAGS} file you want
+to use. @xref{Tags, , Tag Tables, emacs, The Emacs Editor}.
+
+Each time you use the @kbd{,} command, the search resumes from where it was
+left by the previous search, and goes through all program sources,
+obeying the @file{TAGS} file, until all sources have been processed.
+However, by giving a prefix argument to the command @w{(@kbd{C-u
+,})}, you may request that the search be restarted all over again
+from the first program source; but in this case, strings that you
+recently marked as translatable will be automatically skipped.
+
+Using this @kbd{,} command does not prevent using of other regular
+Emacs tags commands. For example, regular @code{tags-search} or
+@code{tags-query-replace} commands may be used without disrupting the
+independent @kbd{,} search sequence. However, as implemented, the
+@emph{initial} @kbd{,} command (or the @kbd{,} command is used with a
+prefix) might also reinitialize the regular Emacs tags searching to the
+first tags file, this reinitialization might be considered spurious.
+
+The @kbd{M-,} (@code{po-mark-translatable}) command will mark the
+recently found string with the @samp{_} keyword. The @kbd{M-.}
+(@code{po-select-mark-and-mark}) command will request that you type
+one keyword from the minibuffer and use that keyword for marking
+the string. Both commands will automatically create a new PO file
+untranslated entry for the string being marked, and make it the
+current entry (making it easy for you to immediately proceed to its
+translation, if you feel like doing it right away). It is possible
+that the modifications made to the program source by @kbd{M-,} or
+@kbd{M-.} render some source line longer than 80 columns, forcing you
+to break and re-indent this line differently. You may use the @kbd{O}
+command from PO mode, or any other window changing command from
+Emacs, to break out into the program source window, and do any
+needed adjustments. You will have to use some regular Emacs command
+to return the cursor to the PO file window, if you want command
+@kbd{,} for the next string, say.
+
+The @kbd{M-.} command has a few built-in speedups, so you do not
+have to explicitly type all keywords all the time. The first such
+speedup is that you are presented with a @emph{preferred} keyword,
+which you may accept by merely typing @kbd{@key{RET}} at the prompt.
+The second speedup is that you may type any non-ambiguous prefix of the
+keyword you really mean, and the command will complete it automatically
+for you. This also means that PO mode has to @emph{know} all
+your possible keywords, and that it will not accept mistyped keywords.
+
+If you reply @kbd{?} to the keyword request, the command gives a
+list of all known keywords, from which you may choose. When the
+command is prefixed by an argument @w{(@kbd{C-u M-.})}, it inhibits
+updating any program source or PO file buffer, and does some simple
+keyword management instead. In this case, the command asks for a
+keyword, written in full, which becomes a new allowed keyword for
+later @kbd{M-.} commands. Moreover, this new keyword automatically
+becomes the @emph{preferred} keyword for later commands. By typing
+an already known keyword in response to @w{@kbd{C-u M-.}}, one merely
+changes the @emph{preferred} keyword and does nothing more.
+
+All keywords known for @kbd{M-.} are recognized by the @kbd{,} command
+when scanning for strings, and strings already marked by any of those
+known keywords are automatically skipped. If many PO files are opened
+simultaneously, each one has its own independent set of known keywords.
+There is no provision in PO mode, currently, for deleting a known
+keyword, you have to quit the file (maybe using @kbd{q}) and reopen
+it afresh. When a PO file is newly brought up in an Emacs window, only
+@samp{gettext} and @samp{_} are known as keywords, and @samp{gettext}
+is preferred for the @kbd{M-.} command. In fact, this is not useful to
+prefer @samp{_}, as this one is already built in the @kbd{M-,} command.
+
+@node c-format, Special cases, Marking, Sources
+@section Special Comments preceding Keywords
+
+@c FIXME document c-format and no-c-format.
+
+In C programs strings are often used within calls of functions from the
+@code{printf} family. The special thing about these format strings is
+that they can contain format specifiers introduced with @kbd{%}. Assume
+we have the code
+
+@example
+printf (gettext ("String `%s' has %d characters\n"), s, strlen (s));
+@end example
+
+@noindent
+A possible German translation for the above string might be:
+
+@example
+"%d Zeichen lang ist die Zeichenkette `%s'"
+@end example
+
+A C programmer, even if he cannot speak German, will recognize that
+there is something wrong here. The order of the two format specifiers
+is changed but of course the arguments in the @code{printf} don't have.
+This will most probably lead to problems because now the length of the
+string is regarded as the address.
+
+To prevent errors at runtime caused by translations the @code{msgfmt}
+tool can check statically whether the arguments in the original and the
+translation string match in type and number. If this is not the case a
+warning will be given and the error cannot causes problems at runtime.
+
+@noindent
+If the word order in the above German translation would be correct one
+would have to write
+
+@example
+"%2$d Zeichen lang ist die Zeichenkette `%1$s'"
+@end example
+
+@noindent
+The routines in @code{msgfmt} know about this special notation.
+
+Because not all strings in a program must be format strings it is not
+useful for @code{msgfmt} to test all the strings in the @file{.po} file.
+This might cause problems because the string might contain what looks
+like a format specifier, but the string is not used in @code{printf}.
+
+Therefore the @code{xgettext} adds a special tag to those messages it
+thinks might be a format string. There is no absolute rule for this,
+only a heuristic. In the @file{.po} file the entry is marked using the
+@code{c-format} flag in the @kbd{#,} comment line (@pxref{PO Files}).
+
+The careful reader now might say that this again can cause problems.
+The heuristic might guess it wrong. This is true and therefore
+@code{xgettext} knows about special kind of comment which lets
+the programmer take over the decision. If in the same line or
+the immediately preceding line of the @code{gettext} keyword
+the @code{xgettext} program find a comment containing the words
+@kbd{xgettext:c-format} it will mark the string in any case with
+the @kbd{c-format} flag. This kind of comment should be used when
+@code{xgettext} does not recognize the string as a format string but
+is really is one and it should be tested. Please note that when the
+comment is in the same line of the @code{gettext} keyword, it must be
+before the string to be translated.
+
+This situation happens quite often. The @code{printf} function is often
+called with strings which do not contain a format specifier. Of course
+one would normally use @code{fputs} but it does happen. In this case
+@code{xgettext} does not recognize this as a format string but what
+happens if the translation introduces a valid format specifier? The
+@code{printf} function will try to access one of the parameter but none
+exists because the original code does not refer to any parameter.
+
+@code{xgettext} of course could make a wrong decision the other way
+round. A string marked as a format string is not really a format
+string. In this case the @code{msgfmt} might give too many warnings and
+would prevent translating the @file{.po} file. The method to prevent
+this wrong decision is similar to the one used above, only the comment
+to use must contain the string @kbd{xgettext:no-c-format}.
+
+If a string is marked with @kbd{c-format} and this is not correct the
+user can find out who is responsible for the decision. See
+@ref{xgettext Invocation} to see how the @kbd{--debug} option can be
+used for solving this problem.
+
+@node Special cases, , c-format, Sources
+@section Special Cases of Translatable Strings
+
+The attentive reader might now point out that it is not always possible
+to mark translatable string with @code{gettext} or something like this.
+Consider the following case:
+
+@example
+@group
+@{
+ static const char *messages[] = @{
+ "some very meaningful message",
+ "and another one"
+ @};
+ const char *string;
+ @dots{}
+ string
+ = index > 1 ? "a default message" : messages[index];
+
+ fputs (string);
+ @dots{}
+@}
+@end group
+@end example
+
+While it is no problem to mark the string @code{"a default message"} it
+is not possible to mark the string initializers for @code{messages}.
+What is to be done? We have to fulfill two tasks. First we have to mark the
+strings so that the @code{xgettext} program (@pxref{xgettext Invocation})
+can find them, and second we have to translate the string at runtime
+before printing them.
+
+The first task can be fulfilled by creating a new keyword, which names a
+no-op. For the second we have to mark all access points to a string
+from the array. So one solution can look like this:
+
+@example
+@group
+#define gettext_noop(String) (String)
+
+@{
+ static const char *messages[] = @{
+ gettext_noop ("some very meaningful message"),
+ gettext_noop ("and another one")
+ @};
+ const char *string;
+ @dots{}
+ string
+ = index > 1 ? gettext ("a default message") : gettext (messages[index]);
+
+ fputs (string);
+ @dots{}
+@}
+@end group
+@end example
+
+Please convince yourself that the string which is written by
+@code{fputs} is translated in any case. How to get @code{xgettext} know
+the additional keyword @code{gettext_noop} is explained in @ref{xgettext
+Invocation}.
+
+The above is of course not the only solution. You could also come along
+with the following one:
+
+@example
+@group
+#define gettext_noop(String) (String)
+
+@{
+ static const char *messages[] = @{
+ gettext_noop ("some very meaningful message",
+ gettext_noop ("and another one")
+ @};
+ const char *string;
+ @dots{}
+ string
+ = index > 1 ? gettext_noop ("a default message") : messages[index];
+
+ fputs (gettext (string));
+ @dots{}
+@}
+@end group
+@end example
+
+But this has some drawbacks. First the programmer has to take care that
+he uses @code{gettext_noop} for the string @code{"a default message"}.
+A use of @code{gettext} could have in rare cases unpredictable results.
+The second reason is found in the internals of the GNU @code{gettext}
+Library which will make this solution less efficient.
+
+One advantage is that you need not make control flow analysis to make
+sure the output is really translated in any case. But this analysis is
+generally not very difficult. If it should be in any situation you can
+use this second method in this situation.
+
+@node Initial, Updating, Sources, Top
+@chapter Making the Initial PO File
+
+@c FIXME: Rewrite.
+
+@menu
+* xgettext Invocation:: Invoking the @code{xgettext} Program
+* C Sources Context:: C Sources Context
+* Compendium:: Using Translation Compendiums
+@end menu
+
+@node xgettext Invocation, C Sources Context, Initial, Initial
+@section Invoking the @code{xgettext} Program
+
+@c FIXME: Rewrite.
+
+@example
+xgettext [@var{option}] @var{inputfile} @dots{}
+@end example
+
+@table @samp
+@item -a
+@itemx --extract-all
+Extract all strings.
+
+@item -c [@var{tag}]
+@itemx --add-comments[=@var{tag}]
+Place comment block with @var{tag} (or those preceding keyword lines)
+in output file.
+
+@item -C
+@itemx --c++
+Recognize C++ style comments.
+
+@itemx --debug
+Use the flags @kbd{c-format} and @kbd{possible-c-format} to show who was
+responsible for marking a message as a format string. The later form is
+used if the @code{xgettext} program decided, the format form is used if
+the programmer prescribed it.
+
+By default only the @kbd{c-format} form is used. The translator should
+not have to care about these details.
+
+@item -d @var{name}
+@itemx --default-domain=@var{name}
+Use @file{@var{name}.po} for output (instead of @file{messages.po}).
+
+The special domain name @file{-} or @file{/dev/stdout} means to write
+the output to @file{stdout}.
+
+@item -D @var{directory}
+@itemx --directory=@var{directory}
+Change to @var{directory} before beginning to search and scan source
+files. The resulting @file{.po} file will be written relative to the
+original directory, though.
+
+@item -f @var{file}
+@itemx --files-from=@var{file}
+Read the names of the input files from @var{file} instead of getting
+them from the command line.
+
+@itemx --force
+Always write output file even if no message is defined.
+
+@item -h
+@itemx --help
+Display this help and exit.
+
+@item -I @var{list}
+@itemx --input-path=@var{list}
+List of directories searched for input files.
+
+@item -j
+@itemx --join-existing
+Join messages with existing file.
+
+@item -k @var{word}
+@itemx --keyword[=@var{word}]
+Additonal keyword to be looked for (without @var{word} means not to
+use default keywords).
+
+The default keywords, which are always looked for if not explicitly
+disabled, are @code{gettext}, @code{dgettext}, @code{dcgettext} and
+@code{gettext_noop}.
+
+@item -m [@var{string}]
+@itemx --msgstr-prefix[=@var{string}]
+Use @var{string} or "" as prefix for msgstr entries.
+
+@item -M [@var{string}]
+@itemx --msgstr-suffix[=@var{string}]
+Use @var{string} or "" as suffix for msgstr entries.
+
+@item --no-location
+Do not write @samp{#: @var{filename}:@var{line}} lines.
+
+@item -n
+@itemx --add-location
+Generate @samp{#: @var{filename}:@var{line}} lines (default).
+
+@item --omit-header
+Don't write header with @samp{msgid ""} entry.
+
+This is useful for testing purposes because it eliminates a source
+of variance for generated @code{.gmo} files. We can ship some of
+these files in the GNU @code{gettext} package, and the result of
+regenerating them through @code{msgfmt} should yield the same values.
+
+@item -p @var{dir}
+@itemx --output-dir=@var{dir}
+Output files will be placed in directory @var{dir}.
+
+@item -s
+@itemx --sort-output
+Generate sorted output and remove duplicates.
+
+@item --strict
+Write out strict Uniforum conforming PO file.
+
+@item -v
+@itemx --version
+Output version information and exit.
+
+@item -x @var{file}
+@itemx --exclude-file=@var{file}
+Entries from @var{file} are not extracted.
+
+@end table
+
+Search path for supplementary PO files is:
+@file{/usr/local/share/nls/src/}.
+
+If @var{inputfile} is @samp{-}, standard input is read.
+
+This implementation of @code{xgettext} is able to process a few awkward
+cases, like strings in preprocessor macros, ANSI concatenation of
+adjacent strings, and escaped end of lines for continued strings.
+
+@node C Sources Context, Compendium, xgettext Invocation, Initial
+@section C Sources Context
+
+PO mode is particularily powerful when used with PO files
+created through GNU @code{gettext} utilities, as those utilities
+insert special comments in the PO files they generate.
+Some of these special comments relate the PO file entry to
+exactly where the untranslated string appears in the program sources.
+
+When the translator gets to an untranslated entry, she is fairly
+often faced with an original string which is not as informative as
+it normally should be, being succinct, cryptic, or otherwise ambiguous.
+Before chosing how to translate the string, she needs to understand
+better what the string really means and how tight the translation has
+to be. Most of times, when problems arise, the only way left to make
+her judgment is looking at the true program sources from where this
+string originated, searching for surrounding comments the programmer
+might have put in there, and looking around for helping clues of
+@emph{any} kind.
+
+Surely, when looking at program sources, the translator will receive
+more help if she is a fluent programmer. However, even if she is
+not versed in programming and feels a little lost in C code, the
+translator should not be shy at taking a look, once in a while.
+It is most probable that she will still be able to find some of the
+hints she needs. She will learn quickly to not feel uncomfortable
+in program code, paying more attention to programmer's comments,
+variable and function names (if he dared chosing them well), and
+overall organization, than to programmation itself.
+
+The following commands are meant to help the translator at getting
+program source context for a PO file entry.
+
+@table @kbd
+@item s
+Resume the display of a program source context, or cycle through them.
+
+@item M-s
+Display of a program source context selected by menu.
+
+@item S
+Add a directory to the search path for source files.
+
+@item M-S
+Delete a directory from the search path for source files.
+
+@end table
+
+The commands @kbd{s} (@code{po-cycle-reference}) and @kbd{M-s}
+(@code{po-select-source-reference}) both open another window displaying
+some source program file, and already positioned in such a way that
+it shows an actual use of the string to be translated. By doing
+so, the command gives source program context for the string. But if
+the entry has no source context references, or if all references
+are unresolved along the search path for program sources, then the
+command diagnoses this as an error.
+
+Even if @kbd{s} (or @kbd{M-s}) opens a new window, the cursor stays
+in the PO file window. If the translator really wants to
+get into the program source window, she ought to do it explicitly,
+maybe by using command @kbd{O}.
+
+When @kbd{s} is typed for the first time, or for a PO file entry which
+is different of the last one used for getting source context, then the
+command reacts by giving the first context available for this entry,
+if any. If some context has already been recently displayed for the
+current PO file entry, and the translator wandered off to do other
+things, typing @kbd{s} again will merely resume, in another window,
+the context last displayed. In particular, if the translator moved
+the cursor away from the context in the source file, the command will
+bring the cursor back to the context. By using @kbd{s} many times
+in a row, with no other commands intervening, PO mode will cycle to
+the next available contexts for this particular entry, getting back
+to the first context once the last has been shown.
+
+The command @kbd{M-s} behaves differently. Instead of cycling through
+references, it lets the translator choose of particular reference among
+many, and displays that reference. It is best used with completion,
+if the translator types @kbd{@key{TAB}} immediately after @kbd{M-s}, in
+response to the question, she will be offered a menu of all possible
+references, as a reminder of which are the acceptable answers.
+This command is useful only where there are really many contexts
+available for a single string to translate.
+
+Program source files are usually found relative to where the PO
+file stands. As a special provision, when this fails, the file is
+also looked for, but relative to the directory immediately above it.
+Those two cases take proper care of most PO files. However, it might
+happen that a PO file has been moved, or is edited in a different
+place than its normal location. When this happens, the translator
+should tell PO mode in which directory normally sits the genuine PO
+file. Many such directories may be specified, and all together, they
+constitute what is called the @dfn{search path} for program sources.
+The command @kbd{S} (@code{po-consider-source-path}) is used to interactively
+enter a new directory at the front of the search path, and the command
+@kbd{M-S} (@code{po-ignore-source-path}) is used to select, with completion,
+one of the directories she does not want anymore on the search path.
+
+@node Compendium, , C Sources Context, Initial
+@section Using Translation Compendiums
+
+@c FIXME: Rewrite.
+
+Compendiums are yet to be implemented.
+
+An incoming PO mode feature will let the translator maintain a
+compendium of already achieved translations. A @dfn{compendium}
+is a special PO file containing a set of translations recurring in
+many different packages. The translator will be given commands for
+adding entries to her compendium, and later initializing untranslated
+entries, or updating already translated entries, from translations
+kept in the compendium. For this to work, however, the compendium
+would have to be normalized. @xref{Normalizing}.
+
+@c It is not useful that I modify the @file{lib/} routines if not done in
+@c the true sources. How do you/I/they proceed for getting this job done?
+@c I presume that @file{lib/} routines will all use @code{gettext} for
+@c the time being.
+
+@node Updating, Binaries, Initial, Top
+@chapter Updating Existing PO Files
+
+@c FIXME: Rewrite.
+
+@menu
+* msgmerge Invocation:: Invoking the @code{msgmerge} Program
+* Translated Entries:: Translated Entries
+* Fuzzy Entries:: Fuzzy Entries
+* Untranslated Entries:: Untranslated Entries
+* Obsolete Entries:: Obsolete Entries
+* Modifying Translations:: Modifying Translations
+* Modifying Comments:: Modifying Comments
+* Subedit:: Mode for Editing Translations
+* Auxiliary:: Consulting Auxiliary PO Files
+@end menu
+
+@node msgmerge Invocation, Translated Entries, Updating, Updating
+@section Invoking the @code{msgmerge} Program
+
+@c FIXME: Rewrite.
+
+@c @example
+@c tupdate --help
+@c tupdate --version
+@c tupdate @var{new} @var{old}
+@c @end example
+
+@c File @var{new} is the last created PO file (generally by
+@c @code{xgettext}). It need not contain any translations. File
+@c @var{old} is the PO file including the old translations which will
+@c be taken over to the newly created file as long as they still match.
+
+@c When English messages change in the programs, this is reflected in
+@c the PO file as extracted by @code{xgettext}. In large messages, that
+@c can be hard to detect, and will obviously result in an incomplete
+@c translation. One of the virtues of @code{tupdate} is that it detects
+@c such changes, saving the previous translation into a PO file comment,
+@c so marking the entry as obsolete, and giving the modified string with
+@c an empty translation, that is, marking the entry as untranslated.
+
+@node Translated Entries, Fuzzy Entries, msgmerge Invocation, Updating
+@section Translated Entries
+
+Each PO file entry for which the @code{msgstr} field has been filled with
+a translation, and which is not marked as fuzzy (@pxref{Fuzzy Entries}),
+is a said to be a @dfn{translated} entry. Only translated entries will
+later be compiled by GNU @code{msgfmt} and become usable in programs.
+Other entry types will be excluded; translation will not occur for them.
+
+Some commands are more specifically related to translated entry processing.
+
+@table @kbd
+@item t
+Find the next translated entry.
+
+@item M-t
+Find the previous translated entry.
+
+@end table
+
+The commands @kbd{t} (@code{po-next-translated-entry}) and @kbd{M-t}
+(@code{po-previous-transted-entry}) move forwards or backwards, chasing
+for an translated entry. If none is found, the search is extended and
+wraps around in the PO file buffer.
+
+Translated entries usually result from the translator having edited in
+a translation for them, @ref{Modifying Translations}. However, if the
+variable @code{po-auto-fuzzy-on-edit} is not @code{nil}, the entry having
+received a new translation first becomes a fuzzy entry, which ought to
+be later unfuzzied before becoming an official, genuine translated entry.
+@xref{Fuzzy Entries}.
+
+@node Fuzzy Entries, Untranslated Entries, Translated Entries, Updating
+@section Fuzzy Entries
+
+Each PO file entry may have a set of @dfn{attributes}, which are
+qualities given an name and explicitely associated with the entry
+translation, using a special system comment. One of these attributes
+has the name @code{fuzzy}, and entries having this attribute are said
+to have a fuzzy translation. They are called fuzzy entries, for short.
+
+Fuzzy entries, even if they account for translated entries for
+most other purposes, usually call for revision by the translator.
+Those may be produced by applying the program @code{msgmerge} to
+update an older translated PO files according to a new PO template
+file, when this tool hypothesises that some new @code{msgid} has
+been modified only slightly out of an older one, and chooses to pair
+what it thinks to be the old translation for the new modified entry.
+The slight alteration in the original string (the @code{msgid} string)
+should often be reflected in the translated string, and this requires
+the intervention of the translator. For this reason, @code{msgmerge}
+might mark some entries as being fuzzy.
+
+Also, the translator may decide herself to mark an entry as fuzzy
+for her own convenience, when she wants to remember that the entry
+has to be later revisited. So, some commands are more specifically
+related to fuzzy entry processing.
+
+@table @kbd
+@item f
+Find the next fuzzy entry.
+
+@item M-f
+Find the previous fuzzy entry.
+
+@item @key{TAB}
+Remove the fuzzy attribute of the current entry.
+
+@end table
+
+The commands @kbd{f} (@code{po-next-fuzzy}) and @kbd{M-f}
+(@code{po-previous-fuzzy}) move forwards or backwards, chasing for
+a fuzzy entry. If none is found, the search is extended and wraps
+around in the PO file buffer.
+
+The command @kbd{@key{TAB}} (@code{po-unfuzzy}) removes the fuzzy
+attribute associated with an entry, usually leaving it translated.
+Further, if the variable @code{po-auto-select-on-unfuzzy} has not
+the @code{nil} value, the @kbd{@key{TAB}} command will automatically chase
+for another interesting entry to work on. The initial value of
+@code{po-auto-select-on-unfuzzy} is @code{nil}.
+
+The initial value of @code{po-auto-fuzzy-on-edit} is @code{nil}. However,
+if the variable @code{po-auto-fuzzy-on-edit} is set to @code{t}, any entry
+edited through the @kbd{@key{RET}} command is marked fuzzy, as a way to
+ensure some kind of double check, later. In this case, the usual paradigm
+is that an entry becomes fuzzy (if not already) whenever the translator
+modifies it. If she is satisfied with the translation, she then uses
+@kbd{@key{TAB}} to pick another entry to work on, clearing the fuzzy attribute
+on the same blow. If she is not satisfied yet, she merely uses @kbd{@key{SPC}}
+to chase another entry, leaving the entry fuzzy.
+
+The translator may also use the @kbd{@key{DEL}} command
+(@code{po-fade-out-entry}) over any translated entry to mark it as being
+fuzzy, when she wants to easily leave a trace she wants to later return
+working at this entry.
+
+Also, when time comes to quit working on a PO file buffer with the @kbd{q}
+command, the translator is asked for confirmation, if fuzzy string
+still exists.
+
+@node Untranslated Entries, Obsolete Entries, Fuzzy Entries, Updating
+@section Untranslated Entries
+
+When @code{xgettext} originally creates a PO file, unless told
+otherwise, it initializes the @code{msgid} field with the untranslated
+string, and leaves the @code{msgstr} string to be empty. Such entries,
+having an empty translation, are said to be @dfn{untranslated} entries.
+Later, when the programmer slightly modifies some string right in
+the program, this change is later reflected in the PO file
+by the appearance of a new untranslated entry for the modified string.
+
+The usual commands moving from entry to entry consider untranslated
+entries on the same level as active entries. Untranslated entries
+are easily recognizable by the fact they end with @w{@samp{msgstr ""}}.
+
+The work of the translator might be (quite naively) seen as the process
+of seeking after an untranslated entry, editing a translation for
+it, and repeating these actions until no untranslated entries remain.
+Some commands are more specifically related to untranslated entry
+processing.
+
+@table @kbd
+@item u
+Find the next untranslated entry.
+
+@item M-u
+Find the previous untranslated entry.
+
+@item k
+Turn the current entry into an untranslated one.
+
+@end table
+
+The commands @kbd{u} (@code{po-next-untranslated-entry}) and @kbd{M-u}
+(@code{po-previous-untransted-entry}) move forwards or backwards,
+chasing for an untranslated entry. If none is found, the search is
+extended and wraps around in the PO file buffer.
+
+An entry can be turned back into an untranslated entry by
+merely emptying its translation, using the command @kbd{k}
+(@code{po-kill-msgstr}). @xref{Modifying Translations}.
+
+Also, when time comes to quit working on a PO file buffer
+with the @kbd{q} command, the translator is asked for confirmation,
+if some untranslated string still exists.
+
+@node Obsolete Entries, Modifying Translations, Untranslated Entries, Updating
+@section Obsolete Entries
+
+By @dfn{obsolete} PO file entries, we mean those entries which are
+commented out, usually by @code{msgmerge} when it found that the
+translation is not needed anymore by the package being localized.
+
+The usual commands moving from entry to entry consider obsolete
+entries on the same level as active entries. Obsolete entries are
+easily recognizable by the fact that all their lines start with
+@kbd{#}, even those lines containing @code{msgid} or @code{msgstr}.
+
+Commands exist for emptying the translation or reinitializing it
+to the original untranslated string. Commands interfacing with the
+kill ring may force some previously saved text into the translation.
+The user may interactively edit the translation. All these commands
+may apply to obsolete entries, carefully leaving the entry obsolete
+after the fact.
+
+Moreover, some commands are more specifically related to obsolete
+entry processing.
+
+@table @kbd
+@item o
+Find the next obsolete entry.
+
+@item M-o
+Find the previous obsolete entry.
+
+@item @key{DEL}
+Make an active entry obsolete, or zap out an obsolete entry.
+
+@end table
+
+The commands @kbd{o} (@code{po-next-obsolete-entry}) and @kbd{M-o}
+(@code{po-previous-obsolete-entry}) move forwards or backwards,
+chasing for an obsolete entry. If none is found, the search is
+extended and wraps around in the PO file buffer.
+
+PO mode does not provide ways for un-commenting an obsolete entry
+and making it active, because this would reintroduce an original
+untranslated string which does not correspond to any marked string
+in the program sources. This goes with the philosophy of never
+introducing useless @code{msgid} values.
+
+However, it is possible to comment out an active entry, so making
+it obsolete. GNU @code{gettext} utilities will later react to the
+disappearance of a translation by using the untranslated string.
+The command @kbd{@key{DEL}} (@code{po-fade-out-entry}) pushes the current entry
+a little further towards annihilation. If the entry is active (it is a
+translated entry), then it is first made fuzzy. If it is already fuzzy,
+then the entry is merely commented out, with confirmation. If the entry
+is already obsolete, then it is completely deleted from the PO file.
+It is easy to recycle the translation so deleted into some other PO file
+entry, usually one which is untranslated. @xref{Modifying Translations}.
+
+Here is a quite interesting problem to solve for later development of
+PO mode, for those nights you are not sleepy. The idea would be that
+PO mode might become bright enough, one of these days, to make good
+guesses at retrieving the most probable candidate, among all obsolete
+entries, for initializing the translation of a newly appeared string.
+I think it might be a quite hard problem to do this algorithmically, as
+we have to develop good and efficient measures of string similarity.
+Right now, PO mode completely lets the decision to the translator,
+when the time comes to find the adequate obsolete translation, it
+merely tries to provide handy tools for helping her to do so.
+
+@node Modifying Translations, Modifying Comments, Obsolete Entries, Updating
+@section Modifying Translations
+
+PO mode prevents direct edition of the PO file, by the usual
+means Emacs give for altering a buffer's contents. By doing so,
+it pretends helping the translator to avoid little clerical errors
+about the overall file format, or the proper quoting of strings,
+as those errors would be easily made. Other kinds of errors are
+still possible, but some may be caught and diagnosed by the batch
+validation process, which the translator may always trigger by the
+@kbd{V} command. For all other errors, the translator has to rely on
+her own judgment, and also on the linguistic reports submitted to her
+by the users of the translated package, having the same mother tongue.
+
+When the time comes to create a translation, correct an error diagnosed
+mechanically or reported by a user, the translators have to resort to
+using the following commands for modifying the translations.
+
+@table @kbd
+@item @key{RET}
+Interactively edit the translation.
+
+@item @key{LFD}
+Reinitialize the translation with the original, untranslated string.
+
+@item k
+Save the translation on the kill ring, and delete it.
+
+@item w
+Save the translation on the kill ring, without deleting it.
+
+@item y
+Replace the translation, taking the new from the kill ring.
+
+@end table
+
+The command @kbd{@key{RET}} (@code{po-edit-msgstr}) opens a new Emacs
+window meant to edit in a new translation, or to modify an already existing
+translation. The new window contains a copy of the translation taken from
+the current PO file entry, all ready for edition, expunged of all quoting
+marks, fully modifiable and with the complete extent of Emacs modifying
+commands. When the translator is done with her modifications, she may use
+@w{@kbd{C-c C-c}} to close the subedit window with the automatically requoted
+results, or @w{@kbd{C-c C-k}} to abort her modifications. @xref{Subedit},
+for more information.
+
+The command @kbd{@key{LFD}} (@code{po-msgid-to-msgstr}) initializes, or
+reinitializes the translation with the original string. This command is
+normally used when the translator wants to redo a fresh translation of
+the original string, disregarding any previous work.
+
+It is possible to arrange so, whenever editing an untranslated
+entry, the @kbd{@key{LFD}} command be automatically executed. If you set
+@code{po-auto-edit-with-msgid} to @code{t}, the translation gets
+initialised with the original string, in case none exist already.
+The default value for @code{po-auto-edit-with-msgid} is @code{nil}.
+
+In fact, whether it is best to start a translation with an empty
+string, or rather with a copy of the original string, is a matter of
+taste or habit. Sometimes, the source language and the
+target language are so different that is simply best to start writing
+on an empty page. At other times, the source and target languages
+are so close that it would be a waste to retype a number of words
+already being written in the original string. A translator may also
+like having the original string right under her eyes, as she will
+progressively overwrite the original text with the translation, even
+if this requires some extra editing work to get rid of the original.
+
+The command @kbd{k} (@code{po-kill-msgstr}) merely empties the
+translation string, so turning the entry into an untranslated
+one. But while doing so, its previous contents is put apart in
+a special place, known as the kill ring. The command @kbd{w}
+(@code{po-kill-ring-save-msgstr}) has also the effect of taking a
+copy of the translation onto the kill ring, but it otherwise leaves
+the entry alone, and does @emph{not} remove the translation from the
+entry. Both commands use exactly the Emacs kill ring, which is shared
+between buffers, and which is well known already to Emacs lovers.
+
+The translator may use @kbd{k} or @kbd{w} many times in the course
+of her work, as the kill ring may hold several saved translations.
+From the kill ring, strings may later be reinserted in various
+Emacs buffers. In particular, the kill ring may be used for moving
+translation strings between different entries of a single PO file
+buffer, or if the translator is handling many such buffers at once,
+even between PO files.
+
+To facilitate exchanges with buffers which are not in PO mode, the
+translation string put on the kill ring by the @kbd{k} command is fully
+unquoted before being saved: external quotes are removed, multi-lines
+strings are concatenated, and backslashed escaped sequences are turned
+into their corresponding characters. In the special case of obsolete
+entries, the translation is also uncommented prior to saving.
+
+The command @kbd{y} (@code{po-yank-msgstr}) completely replaces the
+translation of the current entry by a string taken from the kill ring.
+Following Emacs terminology, we then say that the replacement
+string is @dfn{yanked} into the PO file buffer.
+@xref{Yanking, , , emacs, The Emacs Editor}.
+The first time @kbd{y} is used, the translation receives the value of
+the most recent addition to the kill ring. If @kbd{y} is typed once
+again, immediately, without intervening keystrokes, the translation
+just inserted is taken away and replaced by the second most recent
+addition to the kill ring. By repeating @kbd{y} many times in a row,
+the translator may travel along the kill ring for saved strings,
+until she finds the string she really wanted.
+
+When a string is yanked into a PO file entry, it is fully and
+automatically requoted for complying with the format PO files should
+have. Further, if the entry is obsolete, PO mode then appropriately
+push the inserted string inside comments. Once again, translators
+should not burden themselves with quoting considerations besides, of
+course, the necessity of the translated string itself respective to
+the program using it.
+
+Note that @kbd{k} or @kbd{w} are not the only commands pushing strings
+on the kill ring, as almost any PO mode command replacing translation
+strings (or the translator comments) automatically save the old string
+on the kill ring. The main exceptions to this general rule are the
+yanking commands themselves.
+
+To better illustrate the operation of killing and yanking, let's
+use an actual example, taken from a common situation. When the
+programmer slightly modifies some string right in the program, his
+change is later reflected in the PO file by the appearance
+of a new untranslated entry for the modified string, and the fact
+that the entry translating the original or unmodified string becomes
+obsolete. In many cases, the translator might spare herself some work
+by retrieving the unmodified translation from the obsolete entry,
+then initializing the untranslated entry @code{msgstr} field with
+this retrieved translation. Once this done, the obsolete entry is
+not wanted anymore, and may be safely deleted.
+
+When the translator finds an untranslated entry and suspects that a
+slight variant of the translation exists, she immediately uses @kbd{m}
+to mark the current entry location, then starts chasing obsolete
+entries with @kbd{o}, hoping to find some translation corresponding
+to the unmodified string. Once found, she uses the @kbd{@key{DEL}} command
+for deleting the obsolete entry, knowing that @kbd{@key{DEL}} also @emph{kills}
+the translation, that is, pushes the translation on the kill ring.
+Then, @kbd{r} returns to the initial untranslated entry, @kbd{y}
+then @emph{yanks} the saved translation right into the @code{msgstr}
+field. The translator is then free to use @kbd{@key{RET}} for fine
+tuning the translation contents, and maybe to later use @kbd{u},
+then @kbd{m} again, for going on with the next untranslated string.
+
+When some sequence of keys has to be typed over and over again, the
+translator may find it useful to become better acquainted with the Emacs
+capability of learning these sequences and playing them back under request.
+@xref{Keyboard Macros, , , emacs, The Emacs Editor}.
+
+@node Modifying Comments, Subedit, Modifying Translations, Updating
+@section Modifying Comments
+
+Any translation work done seriously will raise many linguistic
+difficulties, for which decisions have to be made, and the choices
+further documented. These documents may be saved within the
+PO file in form of translator comments, which the translator
+is free to create, delete, or modify at will. These comments may
+be useful to herself when she returns to this PO file after a while.
+
+Comments not having whitespace after the initial @samp{#}, for example,
+those beginning with @samp{#.} or @samp{#:}, are @emph{not} translator
+comments, they are exclusively created by other @code{gettext} tools.
+So, the commands below will never alter such system added comments,
+they are not meant for the translator to modify. @xref{PO Files}.
+
+The following commands are somewhat similar to those modifying translations,
+so the general indications given for those apply here. @xref{Modifying
+Translations}.
+
+@table @kbd
+
+@item #
+Interactively edit the translator comments.
+
+@item K
+Save the translator comments on the kill ring, and delete it.
+
+@item W
+Save the translator comments on the kill ring, without deleting it.
+
+@item Y
+Replace the translator comments, taking the new from the kill ring.
+
+@end table
+
+These commands parallel PO mode commands for modifying the translation
+strings, and behave much the same way as they do, except that they handle
+this part of PO file comments meant for translator usage, rather
+than the translation strings. So, if the descriptions given below are
+slightly succinct, it is because the full details have already been given.
+@xref{Modifying Translations}.
+
+The command @kbd{#} (@code{po-edit-comment}) opens a new Emacs window
+containing a copy of the translator comments on the current PO file entry.
+If there are no such comments, PO mode understands that the translator wants
+to add a comment to the entry, and she is presented with an empty screen.
+Comment marks (@kbd{#}) and the space following them are automatically
+removed before edition, and reinstated after. For translator comments
+pertaining to obsolete entries, the uncommenting and recommenting operations
+are done twice. Once in the editing window, the keys @w{@kbd{C-c C-c}}
+allow the translator to tell she is finished with editing the comment.
+@xref{Subedit}, for further details.
+
+Functions found on @code{po-subedit-mode-hook}, if any, are executed after
+the string has been inserted in the edit buffer.
+
+The command @kbd{K} (@code{po-kill-comment}) get rid of all
+translator comments, while saving those comments on the kill ring.
+The command @kbd{W} (@code{po-kill-ring-save-comment}) takes
+a copy of the translator comments on the kill ring, but leaves
+them undisturbed in the current entry. The command @kbd{Y}
+(@code{po-yank-comment}) completely replaces the translator comments
+by a string taken at the front of the kill ring. When this command
+is immediately repeated, the comments just inserted are withdrawn,
+and replaced by other strings taken along the kill ring.
+
+On the kill ring, all strings have the same nature. There is no
+distinction between @emph{translation} strings and @emph{translator
+comments} strings. So, for example, let's presume the translator
+has just finished editing a translation, and wants to create a new
+translator comment to document why the previous translation was
+not good, just to remember what was the problem. Foreseeing that she
+will do that in her documentation, the translator may want to quote
+the previous translation in her translator comments. To do so, she
+may initialize the translator comments with the previous translation,
+still at the head of the kill ring. Because editing already pushed the
+previous translation on the kill ring, she merely has to type @kbd{M-w}
+prior to @kbd{#}, and the previous translation will be right there,
+all ready for being introduced by some explanatory text.
+
+On the other hand, presume there are some translator comments already
+and that the translator wants to add to those comments, instead
+of wholly replacing them. Then, she should edit the comment right
+away with @kbd{#}. Once inside the editing window, she can use the
+regular Emacs commands @kbd{C-y} (@code{yank}) and @kbd{M-y}
+(@code{yank-pop}) to get the previous translation where she likes.
+
+@node Subedit, Auxiliary, Modifying Comments, Updating
+@section Details of Sub Edition
+
+The PO subedit minor mode has a few peculiarities worth being described
+in fuller detail. It installs a few commands over the usual editing set
+of Emacs, which are described below.
+
+@table @kbd
+@item C-c C-c
+Complete edition.
+
+@item C-c C-k
+Abort edition.
+
+@item C-c C-a
+Consult auxiliary PO files.
+
+@end table
+
+The windows contents represents a translation for a given message,
+or a translator comment. The translator may modify this window to
+her heart's content. Once this done, the command @w{@kbd{C-c C-c}}
+(@code{po-subedit-exit}) may be used to return the edited translation into
+the PO file, replacing the original translation, even if it moved out of
+sight or if buffers were switched.
+
+If the translator becomes unsatisfied with her translation or comment,
+to the extent she prefers keeping what was existent prior to the
+@kbd{@key{RET}} or @kbd{#} command, she may use the command @w{@kbd{C-c C-k}}
+(@code{po-subedit-abort}) to merely get rid of edition, while preserving
+the original translation or comment. Another way would be for her to exit
+normally with @w{@kbd{C-c C-c}}, then type @code{U} once for undoing the
+whole effect of last edition.
+
+The command @w{@kbd{C-c C-a}} allows for glancing through translations
+already achieved in other languages, directly while editing the current
+translation. This may be quite convenient when the translator is fluent
+at many languages, but of course, only makes sense when such completed
+auxiliary PO files are already available to her (@pxref{Auxiliary}).
+
+Functions found on @code{po-subedit-mode-hook}, if any, are executed after
+the string has been inserted in the edit buffer.
+
+While editing her translation, the translator should pay attention to not
+inserting unwanted @kbd{@key{RET}} (carriage returns) characters at the end
+of the translated string if those are not meant to be there, or to removing
+such characters when they are required. Since these characters are not
+visible in the editing buffer, they are easily introduced by mistake.
+To help her, @kbd{@key{RET}} automatically puts the character @kbd{<}
+at the end of the string being edited, but this @kbd{<} is not really
+part of the string. On exiting the editing window with @w{@kbd{C-c C-c}},
+PO mode automatically removes such @kbd{<} and all whitespace added after
+it. If the translator adds characters after the terminating @kbd{<}, it
+looses its delimiting property and integrally becomes part of the string.
+If she removes the delimiting @kbd{<}, then the edited string is taken
+@emph{as is}, with all trailing newlines, even if invisible. Also, if
+the translated string ought to end itself with a genuine @kbd{<}, then
+the delimiting @kbd{<} may not be removed; so the string should appear,
+in the editing window, as ending with two @kbd{<} in a row.
+
+When a translation (or a comment) is being edited, the translator may move
+the cursor back into the PO file buffer and freely move to other entries,
+browsing at will. If, with an edition pending, the translator wanders in the
+PO file buffer, she may decide to start modifying another entry. Each entry
+being edited has its own subedit buffer. It is possible to simultaneously
+edit the translation @emph{and} the comment of a single entry, or to
+edit entries in different PO files, all at once. Typing @kbd{@key{RET}}
+on a field already being edited merely resume that particular edit. Yet,
+the translator should better be comfortable at handling many Emacs windows!
+
+Pending subedits may be completed or aborted in any order, regardless
+of how or when they were started. When many subedits are pending and the
+translator asks for quitting the PO file (with the @kbd{q} command), subedits
+are automatically resumed one at a time, so she may decide for each of them.
+
+@node Auxiliary, , Subedit, Updating
+@section Consulting Auxiliary PO Files
+
+PO mode is able to help the knowledgeable translator, being fluent in
+many languages, at taking advantage of translations already achieved
+in other languages she just happens to know. It provides these other
+language translations as additional context for her own work. Moreover,
+it has features to ease the production of translations for many languages
+at once, for translators preferring to work in this way.
+
+An @dfn{auxiliary} PO file is an existing PO file meant for the same
+package the translator is working on, but targeted to a different mother
+tongue language. Commands exist for declaring and handling auxiliary
+PO files, and also for showing contexts for the entry under work.
+
+Here are the auxiliary file commands available in PO mode.
+
+@table @kbd
+@item a
+Seek auxiliary files for another translation for the same entry.
+
+@item M-a
+Switch to a particular auxiliary file.
+
+@item A
+Declare this PO file as an auxiliary file.
+
+@item M-A
+Remove this PO file from the list of auxiliary files.
+
+@end table
+
+Command @kbd{A} (@code{po-consider-as-auxiliary}) adds the current
+PO file to the list of auxiliary files, while command @kbd{M-A}
+(@code{po-ignore-as-auxiliary} just removes it.
+
+The command @kbd{a} (@code{po-cycle-auxiliary}) seeks all auxiliary PO
+files, round-robin, searching for a translated entry in some other language
+having an @code{msgid} field identical as the one for the current entry.
+The found PO file, if any, takes the place of the current PO file in
+the display (its window gets on top). Before doing so, the current PO
+file is also made into an auxiliary file, if not already. So, @kbd{a}
+in this newly displayed PO file will seek another PO file, and so on,
+so repeating @kbd{a} will eventually yield back the original PO file.
+
+The command @kbd{M-a} (@code{po-select-auxiliary}) asks the translator
+for her choice of a particular auxiliary file, with completion, and
+then switches to that selected PO file. The command also checks if
+the selected file has an @code{msgid} field identical as the one for
+the current entry, and if yes, this entry becomes current. Otherwise,
+the cursor of the selected file is left undisturbed.
+
+For all this to work fully, auxiliary PO files will have to be normalized,
+in that way that @code{msgid} fields should be written @emph{exactly}
+the same way. It is possible to write @code{msgid} fields in various
+ways for representing the same string, different writing would break the
+proper behaviour of the auxiliary file commands of PO mode. This is not
+expected to be much a problem in practice, as most existing PO files have
+their @code{msgid} entries written by the same GNU @code{gettext} tools.
+
+However, PO files initially created by PO mode itself, while marking
+strings in source files, are normalised differently. So are PO
+files resulting of the the @samp{M-x normalize} command. Until these
+discrepancies between PO mode and other GNU @code{gettext} tools get
+fully resolved, the translator should stay aware of normalisation issues.
+
+@node Binaries, Users, Updating, Top
+@chapter Producing Binary MO Files
+
+@c FIXME: Rewrite.
+
+@menu
+* msgfmt Invocation:: Invoking the @code{msgfmt} Program
+* MO Files:: The Format of GNU MO Files
+@end menu
+
+@node msgfmt Invocation, MO Files, Binaries, Binaries
+@section Invoking the @code{msgfmt} Program
+
+@c FIXME: Rewrite.
+
+@example
+Usage: msgfmt [@var{option}] @var{filename}.po @dots{}
+@end example
+
+@table @samp
+@item -a @var{number}
+@itemx --alignment=@var{number}
+Align strings to @var{number} bytes (default: 1).
+@c Currently the README mentions that this constant could be changed by
+@c the installer by changing the value in config.h. Should this go away?
+
+@item -h
+@itemx --help
+Display this help and exit.
+
+@item --no-hash
+Binary file will not include the hash table.
+
+@item -o @var{file}
+@itemx --output-file=@var{file}
+Specify output file name as @var{file}.
+
+@itemx --strict
+Direct the program to work strictly following the Uniforum/Sun
+implementation. Currently this only affects the naming of the output
+file. If this option is not given the name of the output file is the
+same as the domain name. If the strict Uniforum mode is enable the
+suffix @file{.mo} is added to the file name if it is not already
+present.
+
+We find this behaviour of Sun's implementation rather silly and so by
+default this mode is @emph{not} selected.
+
+@item -v
+@itemx --verbose
+Detect and diagnose input file anomalies which might represent
+translation errors. The @code{msgid} and @code{msgstr} strings are
+studied and compared. It is considered abnormal that one string
+starts or ends with a newline while the other does not.
+
+Also, if the string represents a format sring used in a
+@code{printf}-like function both strings should have the same number of
+@samp{%} format specifiers, with matching types. If the flag
+@code{c-format} or @code{possible-c-format} appears in the special
+comment @key{#,} for this entry a check is performed. For example, the
+check will diagnose using @samp{%.*s} against @samp{%s}, or @samp{%d}
+against @samp{%s}, or @samp{%d} against @samp{%x}. It can even handle
+positional parameters.
+
+Normally the @code{xgettext} program automatically decides whether a
+string is a format string or not. This algorithm is not perfect,
+though. It might regard a string as a format string though it is not
+used in a @code{printf}-like function and so @code{msgfmt} might report
+errors where there are none. Or the other way round: a string is not
+regarded as a format string but it is used in a @code{printf}-like
+function.
+
+So solve this problem the programmer can dictate the decision to the
+@code{xgettext} program (@pxref{c-format}). The translator should not
+consider removing the flag from the @key{#,} line. This "fix" would be
+reversed again as soon as @code{msgmerge} is called the next time.
+
+@item -V
+@itemx --version
+Output version information and exit.
+
+@end table
+
+If input file is @samp{-}, standard input is read. If output file
+is @samp{-}, output is written to standard output.
+
+@node MO Files, , msgfmt Invocation, Binaries
+@section The Format of GNU MO Files
+
+The format of the generated MO files is best described by a picture,
+which appears below.
+
+The first two words serve the identification of the file. The magic
+number will always signal GNU MO files. The number is stored in the
+byte order of the generating machine, so the magic number really is
+two numbers: @code{0x950412de} and @code{0xde120495}. The second
+word describes the current revision of the file format. For now the
+revision is 0. This might change in future versions, and ensures
+that the readers of MO files can distinguish new formats from old
+ones, so that both can be handled correctly. The version is kept
+separate from the magic number, instead of using different magic
+numbers for different formats, mainly because @file{/etc/magic} is
+not updated often. It might be better to have magic separated from
+internal format version identification.
+
+Follow a number of pointers to later tables in the file, allowing
+for the extension of the prefix part of MO files without having to
+recompile programs reading them. This might become useful for later
+inserting a few flag bits, indication about the charset used, new
+tables, or other things.
+
+Then, at offset @var{O} and offset @var{T} in the picture, two tables
+of string descriptors can be found. In both tables, each string
+descriptor uses two 32 bits integers, one for the string length,
+another for the offset of the string in the MO file, counting in bytes
+from the start of the file. The first table contains descriptors
+for the original strings, and is sorted so the original strings
+are in increasing lexicographical order. The second table contains
+descriptors for the translated strings, and is parallel to the first
+table: to find the corresponding translation one has to access the
+array slot in the second array with the same index.
+
+Having the original strings sorted enables the use of simple binary
+search, for when the MO file does not contain an hashing table, or
+for when it is not practical to use the hashing table provided in
+the MO file. This also has another advantage, as the empty string
+in a PO file GNU @code{gettext} is usually @emph{translated} into
+some system information attached to that particular MO file, and the
+empty string necessarily becomes the first in both the original and
+translated tables, making the system information very easy to find.
+
+The size @var{S} of the hash table can be zero. In this case, the
+hash table itself is not contained in the MO file. Some people might
+prefer this because a precomputed hashing table takes disk space, and
+does not win @emph{that} much speed. The hash table contains indices
+to the sorted array of strings in the MO file. Conflict resolution is
+done by double hashing. The precise hashing algorithm used is fairly
+dependent of GNU @code{gettext} code, and is not documented here.
+
+As for the strings themselves, they follow the hash file, and each
+is terminated with a @key{NUL}, and this @key{NUL} is not counted in
+the length which appears in the string descriptor. The @code{msgfmt}
+program has an option selecting the alignment for MO file strings.
+With this option, each string is separately aligned so it starts at
+an offset which is a multiple of the alignment value. On some RISC
+machines, a correct alignment will speed things up.
+
+Nothing prevents a MO file from having embedded @key{NUL}s in strings.
+However, the program interface currently used already presumes
+that strings are @key{NUL} terminated, so embedded @key{NUL}s are
+somewhat useless. But MO file format is general enough so other
+interfaces would be later possible, if for example, we ever want to
+implement wide characters right in MO files, where @key{NUL} bytes may
+accidently appear.
+
+This particular issue has been strongly debated in the GNU
+@code{gettext} development forum, and it is expectable that MO file
+format will evolve or change over time. It is even possible that many
+formats may later be supported concurrently. But surely, we have to
+start somewhere, and the MO file format described here is a good start.
+Nothing is cast in concrete, and the format may later evolve fairly
+easily, so we should feel comfortable with the current approach.
+
+@example
+@group
+ byte
+ +------------------------------------------+
+ 0 | magic number = 0x950412de |
+ | |
+ 4 | file format revision = 0 |
+ | |
+ 8 | number of strings | == N
+ | |
+ 12 | offset of table with original strings | == O
+ | |
+ 16 | offset of table with translation strings | == T
+ | |
+ 20 | size of hashing table | == S
+ | |
+ 24 | offset of hashing table | == H
+ | |
+ . .
+ . (possibly more entries later) .
+ . .
+ | |
+ O | length & offset 0th string ----------------.
+ O + 8 | length & offset 1st string ------------------.
+ ... ... | |
+O + ((N-1)*8)| length & offset (N-1)th string | | |
+ | | | |
+ T | length & offset 0th translation ---------------.
+ T + 8 | length & offset 1st translation -----------------.
+ ... ... | | | |
+T + ((N-1)*8)| length & offset (N-1)th translation | | | | |
+ | | | | | |
+ H | start hash table | | | | |
+ ... ... | | | |
+ H + S * 4 | end hash table | | | | |
+ | | | | | |
+ | NUL terminated 0th string <----------------' | | |
+ | | | | |
+ | NUL terminated 1st string <------------------' | |
+ | | | |
+ ... ... | |
+ | | | |
+ | NUL terminated 0th translation <---------------' |
+ | | |
+ | NUL terminated 1st translation <-----------------'
+ | |
+ ... ...
+ | |
+ +------------------------------------------+
+@end group
+@end example
+
+@node Users, Programmers, Binaries, Top
+@chapter The User's View
+
+When GNU @code{gettext} will truly have reached is goal, average users
+should feel some kind of astonished pleasure, seeing the effect of
+that strange kind of magic that just makes their own native language
+appear everywhere on their screens. As for naive users, they would
+ideally have no special pleasure about it, merely taking their own
+language for @emph{granted}, and becoming rather unhappy otherwise.
+
+So, let's try to describe here how we would like the magic to operate,
+as we want the users' view to be the simplest, among all ways one
+could look at GNU @code{gettext}. All other software engineers:
+programmers, translators, maintainers, should work together in such a
+way that the magic becomes possible. This is a long and progressive
+undertaking, and information is available about the progress of the
+Translation Project.
+
+When a package is distributed, there are two kind of users:
+@dfn{installers} who fetch the distribution, unpack it, configure
+it, compile it and install it for themselves or others to use; and
+@dfn{end users} that call programs of the package, once these have
+been installed at their site. GNU @code{gettext} is offering magic
+for both installers and end users.
+
+@menu
+* Matrix:: The Current @file{ABOUT-NLS} Matrix
+* Installers:: Magic for Installers
+* End Users:: Magic for End Users
+@end menu
+
+@node Matrix, Installers, Users, Users
+@section The Current @file{ABOUT-NLS} Matrix
+
+Languages are not equally supported in all packages using GNU
+@code{gettext}. To know if some package uses GNU @code{gettext}, one
+may check the distribution for the @file{ABOUT-NLS} information file, for
+some @file{@var{ll}.po} files, often kept together into some @file{po/}
+directory, or for an @file{intl/} directory. Internationalized packages
+have usually many @file{@var{ll}.po} files, where @var{ll} represents
+the language. @ref{End Users} for a complete description of the format
+for @var{ll}.
+
+More generally, a matrix is available for showing the current state
+of the Translation Project, listing which packages are prepared for
+multi-lingual messages, and which languages is supported by each.
+Because this information changes often, this matrix is not kept within
+this GNU @code{gettext} manual. This information is often found in
+file @file{ABOUT-NLS} from various distributions, but is also as old as
+the distribution itself. A recent copy of this @file{ABOUT-NLS} file,
+containing up-to-date information, should generally be found on the
+Translation Project sites, and also on most GNU archive sites.
+
+@node Installers, End Users, Matrix, Users
+@section Magic for Installers
+
+By default, packages fully using GNU @code{gettext}, internally,
+are installed in such a way that they to allow translation of
+messages. At @emph{configuration} time, those packages should
+automatically detect whether the underlying host system provides usable
+@code{catgets} or @code{gettext} functions. If neither is present,
+the GNU @code{gettext} library should be automatically prepared
+and used. Installers may use special options at configuration
+time for changing this behavior. The command @samp{./configure
+--with-included-gettext} bypasses system @code{catgets} or @code{gettext} to
+use GNU @code{gettext} instead, while @samp{./configure --disable-nls}
+produces program totally unable to translate messages.
+
+Internationalized packages have usually many @file{@var{ll}.po}
+files. Unless
+translations are disabled, all those available are installed together
+with the package. However, the environment variable @code{LINGUAS}
+may be set, prior to configuration, to limit the installed set.
+@code{LINGUAS} should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+@node End Users, , Installers, Users
+@section Magic for End Users
+
+We consider here those packages using GNU @code{gettext} internally,
+and for which the installers did not disable translation at
+@emph{configure} time. Then, users only have to set the @code{LANG}
+environment variable to the appropriate @samp{@var{ll}} prior to
+using the programs in the package. @xref{Matrix}. For example,
+let's presume a German site. At the shell prompt, users merely have to
+execute @w{@samp{setenv LANG de}} (in @code{csh}) or @w{@samp{export
+LANG; LANG=de}} (in @code{sh}). They could even do this from their
+@file{.login} or @file{.profile} file.
+
+@node Programmers, Translators, Users, Top
+@chapter The Programmer's View
+
+@c FIXME: Reorganize whole chapter.
+
+One aim of the current message catalog implementation provided by
+GNU @code{gettext} was to use the systems message catalog handling, if the
+installer wishes to do so. So we perhaps should first take a look at
+the solutions we know about. The people in the POSIX committee does not
+manage to agree on one of the semi-official standards which we'll
+describe below. In fact they couldn't agree on anything, so nothing
+decide only to include an example of an interface. The major Unix vendors
+are split in the usage of the two most important specifications: X/Opens
+catgets vs. Uniforums gettext interface. We'll describe them both and
+later explain our solution of this dilemma.
+
+@menu
+* catgets:: About @code{catgets}
+* gettext:: About @code{gettext}
+* Comparison:: Comparing the two interfaces
+* Using libintl.a:: Using libintl.a in own programs
+* gettext grok:: Being a @code{gettext} grok
+* Temp Programmers:: Temporary Notes for the Programmers Chapter
+@end menu
+
+@node catgets, gettext, Programmers, Programmers
+@section About @code{catgets}
+
+The @code{catgets} implementation is defined in the X/Open Portability
+Guide, Volume 3, XSI Supplementary Definitions, Chapter 5. But the
+process of creating this standard seemed to be too slow for some of
+the Unix vendors so they created their implementations on preliminary
+versions of the standard. Of course this leads again to problems while
+writing platform independent programs: even the usage of @code{catgets}
+does not guarantee a unique interface.
+
+Another, personal comment on this that only a bunch of committee members
+could have made this interface. They never really tried to program
+using this interface. It is a fast, memory-saving implementation, an
+user can happily live with it. But programmers hate it (at least me and
+some others do@dots{})
+
+But we must not forget one point: after all the trouble with transfering
+the rights on Unix(tm) they at last came to X/Open, the very same who
+published this specifications. This leads me to making the prediction
+that this interface will be in future Unix standards (e.g. Spec1170) and
+therefore part of all Unix implementation (implementations, which are
+@emph{allowed} to wear this name).
+
+@menu
+* Interface to catgets:: The interface
+* Problems with catgets:: Problems with the @code{catgets} interface?!
+@end menu
+
+@node Interface to catgets, Problems with catgets, catgets, catgets
+@subsection The Interface
+
+The interface to the @code{catgets} implementation consists of three
+functions which correspond to those used in file access: @code{catopen}
+to open the catalog for using, @code{catgets} for accessing the message
+tables, and @code{catclose} for closing after work is done. Prototypes
+for the functions and the needed definitions are in the
+@code{<nl_types.h>} header file.
+
+@code{catopen} is used like in this:
+
+@example
+nl_catd catd = catopen ("catalog_name", 0);
+@end example
+
+The function takes as the argument the name of the catalog. This usual
+refers to the name of the program or the package. The second parameter
+is not further specified in the standard. I don't even know whether it
+is implemented consistently among various systems. So the common advice
+is to use @code{0} as the value. The return value is a handle to the
+message catalog, equivalent to handles to file returned by @code{open}.
+
+This handle is of course used in the @code{catgets} function which can
+be used like this:
+
+@example
+char *translation = catgets (catd, set_no, msg_id, "original string");
+@end example
+
+The first parameter is this catalog descriptor. The second parameter
+specifies the set of messages in this catalog, in which the message
+described by @code{msg_id} is obtained. @code{catgets} therefore uses a
+three-stage addressing:
+
+@display
+catalog name @result{} set number @result{} message ID @result{} translation
+@end display
+
+@c Anybody else loving Haskell??? :-) -- Uli
+
+The fourth argument is not used to address the translation. It is given
+as a default value in case when one of the addressing stages fail. One
+important thing to remember is that although the return type of catgets
+is @code{char *} the resulting string @emph{must not} be changed. It
+should better @code{const char *}, but the standard is published in
+1988, one year before ANSI C.
+
+@noindent
+The last of these function functions is used and behaves as expected:
+
+@example
+catclose (catd);
+@end example
+
+After this no @code{catgets} call using the descriptor is legal anymore.
+
+@node Problems with catgets, , Interface to catgets, catgets
+@subsection Problems with the @code{catgets} Interface?!
+
+Now that this descriptions seemed to be really easy where are the
+problem we speak of. In fact the interface could be used in a
+reasonable way, but constructing the message catalogs is a pain. The
+reason for this lies in the third argument of @code{catgets}: the unique
+message ID. This has to be a numeric value for all messages in a single
+set. Perhaps you could imagine the problems keeping such list while
+changing the source code. Add a new message here, remove one there. Of
+course there have been developed a lot of tools helping to organize this
+chaos but one as the other fails in one aspect or the other. We don't
+want to say that the other approach has no problems but they are far
+more easily to manage.
+
+@node gettext, Comparison, catgets, Programmers
+@section About @code{gettext}
+
+The definition of the @code{gettext} interface comes from a Uniforum
+proposal and it is followed by at least one major Unix vendor
+(Sun) in its last developments. It is not specified in any official
+standard, though.
+
+The main points about this solution is that it does not follow the
+method of normal file handling (open-use-close) and that it does not
+burden the programmer so many task, especially the unique key handling.
+Of course here is also a unique key needed, but this key is the message
+itself (how long or short it is). See @ref{Comparison} for a more
+detailed comparison of the two methods.
+
+The following section contains a rather detailed description of the
+interface. We make it that detailed because this is the interface
+we chose for the GNU @code{gettext} Library. Programmers interested
+in using this library will be interested in this description.
+
+@menu
+* Interface to gettext:: The interface
+* Ambiguities:: Solving ambiguities
+* Locating Catalogs:: Locating message catalog files
+* Optimized gettext:: Optimization of the *gettext functions
+@end menu
+
+@node Interface to gettext, Ambiguities, gettext, gettext
+@subsection The Interface
+
+The minimal functionality an interface must have is a) to select a
+domain the strings are coming from (a single domain for all programs is
+not reasonable because its construction and maintenance is difficult,
+perhaps impossible) and b) to access a string in a selected domain.
+
+This is principally the description of the @code{gettext} interface. It
+has an global domain which unqualified usages reference. Of course this
+domain is selectable by the user.
+
+@example
+char *textdomain (const char *domain_name);
+@end example
+
+This provides the possibility to change or query the current status of
+the current global domain of the @code{LC_MESSAGE} category. The
+argument is a null-terminated string, whose characters must be legal in
+the use in filenames. If the @var{domain_name} argument is @code{NULL},
+the function return the current value. If no value has been set
+before, the name of the default domain is returned: @emph{messages}.
+Please note that although the return value of @code{textdomain} is of
+type @code{char *} no changing is allowed. It is also important to know
+that no checks of the availability are made. If the name is not
+available you will see this by the fact that no translations are provided.
+
+@noindent
+To use a domain set by @code{textdomain} the function
+
+@example
+char *gettext (const char *msgid);
+@end example
+
+is to be used. This is the simplest reasonable form one can imagine.
+The translation of the string @var{msgid} is returned if it is available
+in the current domain. If not available the argument itself is
+returned. If the argument is @code{NULL} the result is undefined.
+
+One things which should come into mind is that no explicit dependency to
+the used domain is given. The current value of the domain for the
+@code{LC_MESSAGES} locale is used. If this changes between two
+executions of the same @code{gettext} call in the program, both calls
+reference a different message catalog.
+
+For the easiest case, which is normally used in internationalized
+packages, once at the beginning of execution a call to @code{textdomain}
+is issued, setting the domain to a unique name, normally the package
+name. In the following code all strings which have to be translated are
+filtered through the gettext function. That's all, the package speaks
+your language.
+
+@node Ambiguities, Locating Catalogs, Interface to gettext, gettext
+@subsection Solving Ambiguities
+
+While this single name domain work good for most applications there
+might be the need to get translations from more than one domain. Of
+course one could switch between different domains with calls to
+@code{textdomain}, but this is really not convenient nor is it fast. A
+possible situation could be one case discussing while this writing: all
+error messages of functions in the set of common used functions should
+go into a separate domain @code{error}. By this mean we would only need
+to translate them once.
+
+@noindent
+For this reasons there are two more functions to retrieve strings:
+
+@example
+char *dgettext (const char *domain_name, const char *msgid);
+char *dcgettext (const char *domain_name, const char *msgid,
+ int category);
+@end example
+
+Both take an additional argument at the first place, which corresponds
+to the argument of @code{textdomain}. The third argument of
+@code{dcgettext} allows to use another locale but @code{LC_MESSAGES}.
+But I really don't know where this can be useful. If the
+@var{domain_name} is @code{NULL} or @var{category} has an value beside
+the known ones, the result is undefined. It should also be noted that
+this function is not part of the second known implementation of this
+function family, the one found in Solaris.
+
+A second ambiguity can arise by the fact, that perhaps more than one
+domain has the same name. This can be solved by specifying where the
+needed message catalog files can be found.
+
+@example
+char *bindtextdomain (const char *domain_name,
+ const char *dir_name);
+@end example
+
+Calling this function binds the given domain to a file in the specified
+directory (how this file is determined follows below). Especially a
+file in the systems default place is not favored against the specified
+file anymore (as it would be by solely using @code{textdomain}). A
+@code{NULL} pointer for the @var{dir_name} parameter returns the binding
+associated with @var{domain_name}. If @var{domain_name} itself is
+@code{NULL} nothing happens and a @code{NULL} pointer is returned. Here
+again as for all the other functions is true that none of the return
+value must be changed!
+
+It is important to remember that relative path names for the
+@var{dir_name} parameter can be trouble. Since the path is always
+computed relative to the current directory different results will be
+achieved when the program executes a @code{chdir} command. Relative
+paths should always be avoided to avoid dependencies and
+unreliabilities.
+
+@node Locating Catalogs, Optimized gettext, Ambiguities, gettext
+@subsection Locating Message Catalog Files
+
+Because many different languages for many different packages have to be
+stored we need some way to add these information to file message catalog
+files. The way usually used in Unix environments is have this encoding
+in the file name. This is also done here. The directory name given in
+@code{bindtextdomain}s second argument (or the default directory),
+followed by the value and name of the locale and the domain name are
+concatenated:
+
+@example
+@var{dir_name}/@var{locale}/LC_@var{category}/@var{domain_name}.mo
+@end example
+
+The default value for @var{dir_name} is system specific. For the GNU
+library, and for packages adhering to its conventions, it's:
+@example
+/usr/local/share/locale
+@end example
+
+@noindent
+@var{locale} is the value of the locale whose name is this
+@code{LC_@var{category}}. For @code{gettext} and @code{dgettext} this
+locale is always @code{LC_MESSAGES}. @code{dcgettext} specifies the
+locale by the third argument.@footnote{Some
+system, eg Ultrix, don't have @code{LC_MESSAGES}. Here we use a more or
+less arbitrary value for it.} @footnote{When the system does not support
+@code{setlocale} its behavior in setting the locale values is simulated
+by looking at the environment variables.}
+
+@node Optimized gettext, , Locating Catalogs, gettext
+@subsection Optimization of the *gettext functions
+
+At this point of the discussion we should talk about an advantage of the
+GNU @code{gettext} implementation. Some readers might have pointed out
+that an internationalized program might have a poor performance if some
+string has to be translated in an inner loop. While this is unavoidable
+when the string varies from one run of the loop to the other it is
+simply a waste of time when the string is always the same. Take the
+following example:
+
+@example
+@group
+@{
+ while (@dots{})
+ @{
+ puts (gettext ("Hello world"));
+ @}
+@}
+@end group
+@end example
+
+@noindent
+When the locale selection does not change between two runs the resulting
+string is always the same. One way to use this is:
+
+@example
+@group
+@{
+ str = gettext ("Hello world");
+ while (@dots{})
+ @{
+ puts (str);
+ @}
+@}
+@end group
+@end example
+
+@noindent
+But this solution is not usable in all situation (e.g. when the locale
+selection changes) nor is it good readable.
+
+The GNU C compiler, version 2.7 and above, provide another solution for
+this. To describe this we show here some lines of the
+@file{intl/libgettext.h} file. For an explanation of the expression
+command block see @ref{Statement Exprs, , Statements and Declarations in
+Expressions, gcc, The GNU CC Manual}.
+
+@example
+@group
+# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
+extern int _nl_msg_cat_cntr;
+# define dcgettext(domainname, msgid, category) \
+ (__extension__ \
+ (@{ \
+ char *result; \
+ if (__builtin_constant_p (msgid)) \
+ @{ \
+ static char *__translation__; \
+ static int __catalog_counter__; \
+ if (! __translation__ \
+ || __catalog_counter__ != _nl_msg_cat_cntr) \
+ @{ \
+ __translation__ = \
+ dcgettext__ ((domainname), (msgid), (category)); \
+ __catalog_counter__ = _nl_msg_cat_cntr; \
+ @} \
+ result = __translation__; \
+ @} \
+ else \
+ result = dcgettext__ ((domainname), (msgid), (category)); \
+ result; \
+ @}))
+# endif
+@end group
+@end example
+
+The interesting thing here is the @code{__builtin_constant_p} predicate.
+This is evaluated at compile time and so optimization can take place
+immediately. Here two cases are distinguished: the argument to
+@code{gettext} is not a constant value in which case simply the function
+@code{dcgettext__} is called, the real implementation of the
+@code{dcgettext} function.
+
+If the string argument @emph{is} constant we can reuse the once gained
+translation when the locale selection has not changed. This is exactly
+what is done here. The @code{_nl_msg_cat_cntr} variable is defined in
+the @file{loadmsgcat.c} which is available in @file{libintl.a} and is
+changed whenever a new message catalog is loaded.
+
+@node Comparison, Using libintl.a, gettext, Programmers
+@section Comparing the Two Interfaces
+
+@c FIXME: arguments to catgets vs. gettext
+@c Partly done 950718 -- drepper
+
+The following discussion is perhaps a little bit colored. As said
+above we implemented GNU @code{gettext} following the Uniforum
+proposal and this surely has its reasons. But it should show how we
+came to this decision.
+
+First we take a look at the developing process. When we write an
+application using NLS provided by @code{gettext} we proceed as always.
+Only when we come to a string which might be seen by the users and thus
+has to be translated we use @code{gettext("@dots{}")} instead of
+@code{"@dots{}"}. At the beginning of each source file (or in a central
+header file) we define
+
+@example
+#define gettext(String) (String)
+@end example
+
+Even this definition can be avoided when the system supports the
+@code{gettext} function in its C library. When we compile this code the
+result is the same as if no NLS code is used. When you take a look at
+the GNU @code{gettext} code you will see that we use @code{_("@dots{}")}
+instead of @code{gettext("@dots{}")}. This reduces the number of
+additional characters per translatable string to @emph{3} (in words:
+three).
+
+When now a production version of the program is needed we simply replace
+the definition
+
+@example
+#define _(String) (String)
+@end example
+
+@noindent
+by
+
+@example
+#include <libintl.h>
+#define _(String) gettext (String)
+@end example
+
+@noindent
+Additionally we run the program @file{xgettext} on all source code file
+which contain translatable strings and that's it: we have a running
+program which does not depend on translations to be available, but which
+can use any that becomes available.
+
+The same procedure can be done for the @code{gettext_noop} invocations
+(@pxref{Special cases}). First you can define @code{gettext_noop} to a
+no-op macro and later use the definition from @file{libintl.h}. Because
+this name is not used in Suns implementation of @file{libintl.h},
+you should consider the following code for your project:
+
+@example
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+# define N_(String) (String)
+#endif
+@end example
+
+@code{N_} is a short form similar to @code{_}. The @file{Makefile} in
+the @file{po/} directory of GNU @code{gettext} knows by default both of the
+mentioned short forms so you are invited to follow this proposal for
+your own ease.
+
+Now to @code{catgets}. The main problem is the work for the
+programmer. Every time he comes to a translatable string he has to
+define a number (or a symbolic constant) which has also be defined in
+the message catalog file. He also has to take care for duplicate
+entries, duplicate message IDs etc. If he wants to have the same
+quality in the message catalog as the GNU @code{gettext} program
+provides he also has to put the descriptive comments for the strings and
+the location in all source code files in the message catalog. This is
+nearly a Mission: Impossible.
+
+But there are also some points people might call advantages speaking for
+@code{catgets}. If you have a single word in a string and this string
+is used in different contexts it is likely that in one or the other
+language the word has different translations. Example:
+
+@example
+printf ("%s: %d", gettext ("number"), number_of_errors)
+
+printf ("you should see %d %s", number_count,
+ number_count == 1 ? gettext ("number") : gettext ("numbers"))
+@end example
+
+Here we have to translate two times the string @code{"number"}. Even
+if you do not speak a language beside English it might be possible to
+recognize that the two words have a different meaning. In German the
+first appearance has to be translated to @code{"Anzahl"} and the second
+to @code{"Zahl"}.
+
+Now you can say that this example is really esoteric. And you are
+right! This is exactly how we felt about this problem and decide that
+it does not weight that much. The solution for the above problem could
+be very easy:
+
+@example
+printf ("%s %d", gettext ("number:"), number_of_errors)
+
+printf (number_count == 1 ? gettext ("you should see %d number")
+ : gettext ("you should see %d numbers"),
+ number_count)
+@end example
+
+We believe that we can solve all conflicts with this method. If it is
+difficult one can also consider changing one of the conflicting string a
+little bit. But it is not impossible to overcome.
+
+@c Should this be here?
+Translator note: It is perhaps appropriate here to tell those English
+speaking programmers that the plural form of a noun cannot be formed by
+appending a single `s'. Most other languages use different methods.
+Even the above form is not general enough to cope with all languages.
+Rafal Maszkowski <rzm@@mat.uni.torun.pl> reports:
+
+@quotation
+In Polish we use e.g. plik (file) this way:
+@example
+1 plik
+2,3,4 pliki
+5-21 pliko'w
+22-24 pliki
+25-31 pliko'w
+@end example
+and so on (o' means 8859-2 oacute which should be rather okreska,
+similar to aogonek).
+@end quotation
+
+A workable approach might be to consider methods like the one used for
+@code{LC_TIME} in the POSIX.2 standard. The value of the
+@code{alt_digits} field can be up to 100 strings which represent the
+numbers 1 to 100. Using this in a situation of an internationalized
+program means that an array of translatable strings should be indexed by
+the number which should represent. A small example:
+
+@example
+@group
+void
+print_month_info (int month)
+@{
+ const char *month_pos[12] =
+ @{ N_("first"), N_("second"), N_("third"), N_("fourth"),
+ N_("fifth"), N_("sixth"), N_("seventh"), N_("eighth"),
+ N_("ninth"), N_("tenth"), N_("eleventh"), N_("twelfth") @};
+ printf (_("%s is the %s month\n"), nl_langinfo (MON_1 + month),
+ _(month_pos[month]));
+@}
+@end group
+@end example
+
+@noindent
+It should be obvious that this method is only reasonable for small
+ranges of numbers.
+
+@c catgets allows same original entry to have different translations
+
+@node Using libintl.a, gettext grok, Comparison, Programmers
+@section Using libintl.a in own programs
+
+Starting with version 0.9.4 the library @code{libintl.h} should be
+self-contained. I.e., you can use it in your own programs without
+providing additional functions. The @file{Makefile} will put the header
+and the library in directories selected using the @code{$(prefix)}.
+
+One exception of the above is found on HP-UX systems. Here the C library
+does not contain the @code{alloca} function (and the HP compiler does
+not generate it inlined). But it is not intended to rewrite the whole
+library just because of this dumb system. Instead include the
+@code{alloca} function in all package you use the @code{libintl.a} in.
+
+@node gettext grok, Temp Programmers, Using libintl.a, Programmers
+@section Being a @code{gettext} grok
+
+To fully exploit the functionality of the GNU @code{gettext} library it
+is surely helpful to read the source code. But for those who don't want
+to spend that much time in reading the (sometimes complicated) code here
+is a list comments:
+
+@itemize @bullet
+@item Changing the language at runtime
+
+For interactive programs it might be useful to offer a selection of the
+used language at runtime. To understand how to do this one need to know
+how the used language is determined while executing the @code{gettext}
+function. The method which is presented here only works correctly
+with the GNU implementation of the @code{gettext} functions. It is not
+possible with underlying @code{catgets} functions or @code{gettext}
+functions from the systems C library. The exception is of course the
+GNU C Library which uses the GNU @code{gettext} Library for message handling.
+
+In the function @code{dcgettext} at every call the current setting of
+the highest priority environment variable is determined and used.
+Highest priority means here the following list with decreasing
+priority:
+
+@enumerate
+@item @code{LANGUAGE}
+@item @code{LC_ALL}
+@item @code{LC_xxx}, according to selected locale
+@item @code{LANG}
+@end enumerate
+
+Afterwards the path is constructed using the found value and the
+translation file is loaded if available.
+
+What is now when the value for, say, @code{LANGUAGE} changes. According
+to the process explained above the new value of this variable is found
+as soon as the @code{dcgettext} function is called. But this also means
+the (perhaps) different message catalog file is loaded. In other
+words: the used language is changed.
+
+But there is one little hook. The code for gcc-2.7.0 and up provides
+some optimization. This optimization normally prevents the calling of
+the @code{dcgettext} function as long as no new catalog is loaded. But
+if @code{dcgettext} is not called the program also cannot find the
+@code{LANGUAGE} variable be changed (@pxref{Optimized gettext}). A
+solution for this is very easy. Include the following code in the
+language switching function.
+
+@example
+ /* Change language. */
+ setenv ("LANGUAGE", "fr", 1);
+
+ /* Make change known. */
+ @{
+ extern int _nl_msg_cat_cntr;
+ ++_nl_msg_cat_cntr;
+ @}
+@end example
+
+The variable @code{_nl_msg_cat_cntr} is defined in @file{loadmsgcat.c}.
+The programmer will find himself in need for a construct like this only
+when developing programs which do run longer and provide the user to
+select the language at runtime. Non-interactive programs (like all
+these little Unix tools) should never need this.
+
+@end itemize
+
+@node Temp Programmers, , gettext grok, Programmers
+@section Temporary Notes for the Programmers Chapter
+
+@menu
+* Temp Implementations:: Temporary - Two Possible Implementations
+* Temp catgets:: Temporary - About @code{catgets}
+* Temp WSI:: Temporary - Why a single implementation
+* Temp Notes:: Temporary - Notes
+@end menu
+
+@node Temp Implementations, Temp catgets, Temp Programmers, Temp Programmers
+@subsection Temporary - Two Possible Implementations
+
+There are two competing methods for language independent messages:
+the X/Open @code{catgets} method, and the Uniforum @code{gettext}
+method. The @code{catgets} method indexes messages by integers; the
+@code{gettext} method indexes them by their English translations.
+The @code{catgets} method has been around longer and is supported
+by more vendors. The @code{gettext} method is supported by Sun,
+and it has been heard that the COSE multi-vendor initiative is
+supporting it. Neither method is a POSIX standard; the POSIX.1
+committee had a lot of disagreement in this area.
+
+Neither one is in the POSIX standard. There was much disagreement
+in the POSIX.1 committee about using the @code{gettext} routines
+vs. @code{catgets} (XPG). In the end the committee couldn't
+agree on anything, so no messaging system was included as part
+of the standard. I believe the informative annex of the standard
+includes the XPG3 messaging interfaces, ``@dots{}as an example of
+a messaging system that has been implemented@dots{}''
+
+They were very careful not to say anywhere that you should use one
+set of interfaces over the other. For more on this topic please
+see the Programming for Internationalization FAQ.
+
+@node Temp catgets, Temp WSI, Temp Implementations, Temp Programmers
+@subsection Temporary - About @code{catgets}
+
+There have been a few discussions of late on the use of
+@code{catgets} as a base. I think it important to present both
+sides of the argument and hence am opting to play devil's advocate
+for a little bit.
+
+I'll not deny the fact that @code{catgets} could have been designed
+a lot better. It currently has quite a number of limitations and
+these have already been pointed out.
+
+However there is a great deal to be said for consistency and
+standardization. A common recurring problem when writing Unix
+software is the myriad portability problems across Unix platforms.
+It seems as if every Unix vendor had a look at the operating system
+and found parts they could improve upon. Undoubtedly, these
+modifications are probably innovative and solve real problems.
+However, software developers have a hard time keeping up with all
+these changes across so many platforms.
+
+And this has prompted the Unix vendors to begin to standardize their
+systems. Hence the impetus for Spec1170. Every major Unix vendor
+has committed to supporting this standard and every Unix software
+developer waits with glee the day they can write software to this
+standard and simply recompile (without having to use autoconf)
+across different platforms.
+
+As I understand it, Spec1170 is roughly based upon version 4 of the
+X/Open Portability Guidelines (XPG4). Because @code{catgets} and
+friends are defined in XPG4, I'm led to believe that @code{catgets}
+is a part of Spec1170 and hence will become a standardized component
+of all Unix systems.
+
+@node Temp WSI, Temp Notes, Temp catgets, Temp Programmers
+@subsection Temporary - Why a single implementation
+
+Now it seems kind of wasteful to me to have two different systems
+installed for accessing message catalogs. If we do want to remedy
+@code{catgets} deficiencies why don't we try to expand @code{catgets}
+(in a compatible manner) rather than implement an entirely new system.
+Otherwise, we'll end up with two message catalog access systems installed
+with an operating system - one set of routines for packages using GNU
+@code{gettext} for their internationalization, and another set of routines
+(catgets) for all other software. Bloated?
+
+Supposing another catalog access system is implemented. Which do
+we recommend? At least for Linux, we need to attract as many
+software developers as possible. Hence we need to make it as easy
+for them to port their software as possible. Which means supporting
+@code{catgets}. We will be implementing the @code{glocale} code
+within our @code{libc}, but does this mean we also have to incorporate
+another message catalog access scheme within our @code{libc} as well?
+And what about people who are going to be using the @code{glocale}
++ non-@code{catgets} routines. When they port their software to
+other platforms, they're now going to have to include the front-end
+(@code{glocale}) code plus the back-end code (the non-@code{catgets}
+access routines) with their software instead of just including the
+@code{glocale} code with their software.
+
+Message catalog support is however only the tip of the iceberg.
+What about the data for the other locale categories. They also have
+a number of deficiencies. Are we going to abandon them as well and
+develop another duplicate set of routines (should @code{glocale}
+expand beyond message catalog support)?
+
+Like many parts of Unix that can be improved upon, we're stuck with balancing
+compatibility with the past with useful improvements and innovations for
+the future.
+
+@node Temp Notes, , Temp WSI, Temp Programmers
+@subsection Temporary - Notes
+
+X/Open agreed very late on the standard form so that many
+implementations differ from the final form. Both of my system (old
+Linux catgets and Ultrix-4) have a strange variation.
+
+OK. After incorporating the last changes I have to spend some time on
+making the GNU/Linux @code{libc} @code{gettext} functions. So in future
+Solaris is not the only system having @code{gettext}.
+
+@node Translators, Maintainers, Programmers, Top
+@chapter The Translator's View
+
+@c FIXME: Reorganize whole chapter.
+
+@menu
+* Trans Intro 0:: Introduction 0
+* Trans Intro 1:: Introduction 1
+* Discussions:: Discussions
+* Organization:: Organization
+* Information Flow:: Information Flow
+@end menu
+
+@node Trans Intro 0, Trans Intro 1, Translators, Translators
+@section Introduction 0
+
+Free software is going international! The Translation Project is a way
+to get maintainers, translators and users all together, so free software
+will gradually become able to speak many native languages.
+
+The GNU @code{gettext} tool set contains @emph{everything} maintainers
+need for internationalizing their packages for messages. It also
+contains quite useful tools for helping translators at localizing
+messages to their native language, once a package has already been
+internationalized.
+
+To achieve the Translation Project, we need many interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+If you'd like to volunteer to @emph{work} at translating messages,
+please send mail to your translating team.
+
+Each team has its own mailing list, courtesy of Linux
+International. You may reach your translating team at the address
+@file{@var{ll}@@li.org}, replacing @var{ll} by the two-letter @w{ISO 639}
+code for your language. Language codes are @emph{not} the same as
+country codes given in @w{ISO 3166}. The following translating teams
+exist:
+
+@quotation
+Chinese @code{zh}, Czech @code{cs}, Danish @code{da}, Dutch @code{nl},
+Esperanto @code{eo}, Finnish @code{fi}, French @code{fr}, Irish
+@code{ga}, German @code{de}, Greek @code{el}, Italian @code{it},
+Japanese @code{ja}, Indonesian @code{in}, Norwegian @code{no}, Polish
+@code{pl}, Portuguese @code{pt}, Russian @code{ru}, Spanish @code{es},
+Swedish @code{sv} and Turkish @code{tr}.
+@end quotation
+
+@noindent
+For example, you may reach the Chinese translating team by writing to
+@file{zh@@li.org}. When you become a member of the translating team
+for your own language, you may subscribe to its list. For example,
+Swedish people can send a message to @w{@file{sv-request@@li.org}},
+having this message body:
+
+@example
+subscribe
+@end example
+
+Keep in mind that team members should be interested in @emph{working}
+at translations, or at solving translational difficulties, rather than
+merely lurking around. If your team does not exist yet and you want to
+start one, please write to @w{@file{translation@@iro.umontreal.ca}};
+you will then reach the coordinator for all translator teams.
+
+A handful of GNU packages have already been adapted and provided
+with message translations for several languages. Translation
+teams have begun to organize, using these packages as a starting
+point. But there are many more packages and many languages for
+which we have no volunteer translators. If you would like to
+volunteer to work at translating messages, please send mail to
+@file{translation@@iro.umontreal.ca} indicating what language(s)
+you can work on.
+
+@node Trans Intro 1, Discussions, Trans Intro 0, Translators
+@section Introduction 1
+
+This is now official, GNU is going international! Here is the
+announcement submitted for the January 1995 GNU Bulletin:
+
+@quotation
+A handful of GNU packages have already been adapted and provided
+with message translations for several languages. Translation
+teams have begun to organize, using these packages as a starting
+point. But there are many more packages and many languages
+for which we have no volunteer translators. If you'd like to
+volunteer to work at translating messages, please send mail to
+@samp{translation@@iro.umontreal.ca} indicating what language(s)
+you can work on.
+@end quotation
+
+This document should answer many questions for those who are curious about
+the process or would like to contribute. Please at least skim over it,
+hoping to cut down a little of the high volume of e-mail generated by this
+collective effort towards internationalization of free software.
+
+Most free programming which is widely shared is done in English, and
+currently, English is used as the main communicating language between
+national communities collaborating to free software. This very document
+is written in English. This will not change in the foreseeable future.
+
+However, there is a strong appetite from national communities for
+having more software able to write using national language and habits,
+and there is an on-going effort to modify free software in such a way
+that it becomes able to do so. The experiments driven so far raised
+an enthusiastic response from pretesters, so we believe that
+internationalization of free software is dedicated to succeed.
+
+For suggestion clarifications, additions or corrections to this
+document, please e-mail to @file{translation@@iro.umontreal.ca}.
+
+@node Discussions, Organization, Trans Intro 1, Translators
+@section Discussions
+
+Facing this internationalization effort, a few users expressed their
+concerns. Some of these doubts are presented and discussed, here.
+
+@itemize @bullet
+@item Smaller groups
+
+Some languages are not spoken by a very large number of people, so people
+speaking them sometimes consider that there may not be all that much
+demand such versions of free software packages. Moreover, many people
+being @emph{into computers}, in some countries, generally seem to prefer
+English versions of their software.
+
+On the other end, people might enjoy their own language a lot, and be
+very motivated at providing to themselves the pleasure of having their
+beloved free software speaking their mother tongue. They do themselves
+a personal favor, and do not pay that much attention to the number of
+people beneficiating of their work.
+
+@item Misinterpretation
+
+Other users are shy to push forward their own language, seeing in this
+some kind of misplaced propaganda. Someone thought there must be some
+users of the language over the networks pestering other people with it.
+
+But any spoken language is worth localization, because there are
+people behind the language for whom the language is important and
+dear to their hearts.
+
+@item Odd translations
+
+The biggest problem is to find the right translations so that
+everybody can understand the messages. Translations are usually a
+little odd. Some people get used to English, to the extent they may
+find translations into their own language ``rather pushy, obnoxious
+and sometimes even hilarious.'' As a French speaking man, I have
+the experience of those instruction manuals for goods, so poorly
+translated in French in Korea or Taiwan@dots{}
+
+The fact is that we sometimes have to create a kind of national
+computer culture, and this is not easy without the collaboration of
+many people liking their mother tongue. This is why translations are
+better achieved by people knowing and loving their own language, and
+ready to work together at improving the results they obtain.
+
+@item Dependencies over the GPL
+
+Some people wonder if using GNU @code{gettext} necessarily brings their package
+under the protective wing of the GNU General Public License, when they
+do not want to make their program free, or want other kinds of freedom.
+The simplest answer is yes.
+
+The mere marking of localizable strings in a package, or conditional
+inclusion of a few lines for initialization, is not really including
+GPL'ed code. However, the localization routines themselves are under
+the GPL and would bring the remainder of the package under the GPL
+if they were distributed with it. So, I presume that, for those
+for which this is a problem, it could be circumvented by letting to
+the end installers the burden of assembling a package prepared for
+localization, but not providing the localization routines themselves.
+
+@end itemize
+
+@node Organization, Information Flow, Discussions, Translators
+@section Organization
+
+On a larger scale, the true solution would be to organize some kind of
+fairly precise set up in which volunteers could participate. I gave
+some thought to this idea lately, and realize there will be some
+touchy points. I thought of writing to Richard Stallman to launch
+such a project, but feel it might be good to shake out the ideas
+between ourselves first. Most probably that Linux International has
+some experience in the field already, or would like to orchestrate
+the volunteer work, maybe. Food for thought, in any case!
+
+I guess we have to setup something early, somehow, that will help
+many possible contributors of the same language to interlock and avoid
+work duplication, and further be put in contact for solving together
+problems particular to their tongue (in most languages, there are many
+difficulties peculiar to translating technical English). My Swedish
+contributor acknowledged these difficulties, and I'm well aware of
+them for French.
+
+This is surely not a technical issue, but we should manage so the
+effort of locale contributors be maximally useful, despite the national
+team layer interface between contributors and maintainers.
+
+The Translation Project needs some setup for coordinating language
+coordinators. Localizing evolving programs will surely
+become a permanent and continuous activity in the free software community,
+once well started.
+The setup should be minimally completed and tested before GNU
+@code{gettext} becomes an official reality. The e-mail address
+@file{translation@@iro.umontreal.ca} has been setup for receiving
+offers from volunteers and general e-mail on these topics. This address
+reaches the Translation Project coordinator.
+
+@menu
+* Central Coordination:: Central Coordination
+* National Teams:: National Teams
+* Mailing Lists:: Mailing Lists
+@end menu
+
+@node Central Coordination, National Teams, Organization, Organization
+@subsection Central Coordination
+
+I also think GNU will need sooner than it thinks, that someone setup
+a way to organize and coordinate these groups. Some kind of group
+of groups. My opinion is that it would be good that GNU delegates
+this task to a small group of collaborating volunteers, shortly.
+Perhaps in @file{gnu.announce} a list of this national committee's
+can be published.
+
+My role as coordinator would simply be to refer to Ulrich any German
+speaking volunteer interested to localization of free software packages, and
+maybe helping national groups to initially organize, while maintaining
+national registries for until national groups are ready to take over.
+In fact, the coordinator should ease volunteers to get in contact with
+one another for creating national teams, which should then select
+one coordinator per language, or country (regionalized language).
+If well done, the coordination should be useful without being an
+overwhelming task, the time to put delegations in place.
+
+@node National Teams, Mailing Lists, Central Coordination, Organization
+@subsection National Teams
+
+I suggest we look for volunteer coordinators/editors for individual
+languages. These people will scan contributions of translation files
+for various programs, for their own languages, and will ensure high
+and uniform standards of diction.
+
+From my current experience with other people in these days, those who
+provide localizations are very enthusiastic about the process, and are
+more interested in the localization process than in the program they
+localize, and want to do many programs, not just one. This seems
+to confirm that having a coordinator/editor for each language is a
+good idea.
+
+We need to choose someone who is good at writing clear and concise
+prose in the language in question. That is hard---we can't check
+it ourselves. So we need to ask a few people to judge each others'
+writing and select the one who is best.
+
+I announce my prerelease to a few dozen people, and you would not
+believe all the discussions it generated already. I shudder to think
+what will happen when this will be launched, for true, officially,
+world wide. Who am I to arbitrate between two Czekolsovak users
+contradicting each other, for example?
+
+I assume that your German is not much better than my French so that
+I would not be able to judge about these formulations. What I would
+suggest is that for each language there is a group for people who
+maintain the PO files and judge about changes. I suspect there will
+be cultural differences between how such groups of people will behave.
+Some will have relaxed ways, reach consensus easily, and have anyone
+of the group relate to the maintainers, while others will fight to
+death, organize heavy administrations up to national standards, and
+use strict channels.
+
+The German team is putting out a good example. Right now, they are
+maybe half a dozen people revising translations of each other and
+discussing the linguistic issues. I do not even have all the names.
+Ulrich Drepper is taking care of coordinating the German team.
+He subscribed to all my pretest lists, so I do not even have to warn
+him specifically of incoming releases.
+
+I'm sure, that is a good idea to get teams for each language working
+on translations. That will make the translations better and more
+consistent.
+
+@menu
+* Sub-Cultures:: Sub-Cultures
+* Organizational Ideas:: Organizational Ideas
+@end menu
+
+@node Sub-Cultures, Organizational Ideas, National Teams, National Teams
+@subsubsection Sub-Cultures
+
+Taking French for example, there are a few sub-cultures around computers
+which developed diverging vocabularies. Picking volunteers here and
+there without addressing this problem in an organized way, soon in the
+project, might produce a distasteful mix of internationalized programs,
+and possibly trigger endless quarrels among those who really care.
+
+Keeping some kind of unity in the way French localization of
+internationalized programs is achieved is a difficult (and delicate) job.
+Knowing the latin character of French people (:-), if we take this
+the wrong way, we could end up nowhere, or spoil a lot of energies.
+Maybe we should begin to address this problem seriously @emph{before}
+GNU @code{gettext} become officially published. And I suspect that this
+means soon!
+
+@node Organizational Ideas, , Sub-Cultures, National Teams
+@subsubsection Organizational Ideas
+
+I expect the next big changes after the official release. Please note
+that I use the German translation of the short GPL message. We need
+to set a few good examples before the localization goes out for true
+in the free software community. Here are a few points to discuss:
+
+@itemize @bullet
+@item
+Each group should have one FTP server (at least one master).
+
+@item
+The files on the server should reflect the latest version (of
+course!) and it should also contain a RCS directory with the
+corresponding archives (I don't have this now).
+
+@item
+There should also be a ChangeLog file (this is more useful than the
+RCS archive but can be generated automatically from the later by
+Emacs).
+
+@item
+A @dfn{core group} should judge about questionable changes (for now
+this group consists solely by me but I ask some others occasionally;
+this also seems to work).
+
+@end itemize
+
+@node Mailing Lists, , National Teams, Organization
+@subsection Mailing Lists
+
+If we get any inquiries about GNU @code{gettext}, send them on to:
+
+@example
+@file{translation@@iro.umontreal.ca}
+@end example
+
+The @file{*-pretest} lists are quite useful to me, maybe the idea could
+be generalized to many GNU, and non-GNU packages. But each maintainer
+his/her way!
+
+Fran@,{c}ois, we have a mechanism in place here at
+@file{gnu.ai.mit.edu} to track teams, support mailing lists for
+them and log members. We have a slight preference that you use it.
+If this is OK with you, I can get you clued in.
+
+Things are changing! A few years ago, when Daniel Fekete and I
+asked for a mailing list for GNU localization, nested at the FSF, we
+were politely invited to organize it anywhere else, and so did we.
+For communicating with my pretesters, I later made a handful of
+mailing lists located at iro.umontreal.ca and administrated by
+@code{majordomo}. These lists have been @emph{very} dependable
+so far@dots{}
+
+I suspect that the German team will organize itself a mailing list
+located in Germany, and so forth for other countries. But before they
+organize for true, it could surely be useful to offer mailing lists
+located at the FSF to each national team. So yes, please explain me
+how I should proceed to create and handle them.
+
+We should create temporary mailing lists, one per country, to help
+people organize. Temporary, because once regrouped and structured, it
+would be fair the volunteers from country bring back @emph{their} list
+in there and manage it as they want. My feeling is that, in the long
+run, each team should run its own list, from within their country.
+There also should be some central list to which all teams could
+subscribe as they see fit, as long as each team is represented in it.
+
+@node Information Flow, , Organization, Translators
+@section Information Flow
+
+There will surely be some discussion about this messages after the
+packages are finally released. If people now send you some proposals
+for better messages, how do you proceed? Jim, please note that
+right now, as I put forward nearly a dozen of localizable programs, I
+receive both the translations and the coordination concerns about them.
+
+If I put one of my things to pretest, Ulrich receives the announcement
+and passes it on to the German team, who make last minute revisions.
+Then he submits the translation files to me @emph{as the maintainer}.
+For free packages I do not maintain, I would not even hear about it.
+This scheme could be made to work for the whole Translation Project,
+I think. For security reasons, maybe Ulrich (national coordinators,
+in fact) should update central registry kept at the Translation Project
+(Jim, me, or Len's recruits) once in a while.
+
+In December/January, I was aggressively ready to internationalize
+all of GNU, giving myself the duty of one small GNU package per week
+or so, taking many weeks or months for bigger packages. But it does
+not work this way. I first did all the things I'm responsible for.
+I've nothing against some missionary work on other maintainers, but
+I'm also loosing a lot of energy over it---same debates over again.
+
+And when the first localized packages are released we'll get a lot of
+responses about ugly translations :-). Surely, and we need to have
+beforehand a fairly good idea about how to handle the information
+flow between the national teams and the package maintainers.
+
+Please start saving somewhere a quick history of each PO file. I know
+for sure that the file format will change, allowing for comments.
+It would be nice that each file has a kind of log, and references for
+those who want to submit comments or gripes, or otherwise contribute.
+I sent a proposal for a fast and flexible format, but it is not
+receiving acceptance yet by the GNU deciders. I'll tell you when I
+have more information about this.
+
+@node Maintainers, Conclusion, Translators, Top
+@chapter The Maintainer's View
+
+The maintainer of a package has many responsibilities. One of them
+is ensuring that the package will install easily on many platforms,
+and that the magic we described earlier (@pxref{Users}) will work
+for installers and end users.
+
+Of course, there are many possible ways by which GNU @code{gettext}
+might be integrated in a distribution, and this chapter does not cover
+them in all generality. Instead, it details one possible approach which
+is especially adequate for many free software distributions following GNU
+standards, or even better, Gnits standards, because GNU @code{gettext}
+is purposely for helping the internationalization of the whole GNU
+project, and as many other good free packages as possible. So, the
+maintainer's view presented here presumes that the package already has
+a @file{configure.in} file and uses GNU Autoconf.
+
+Nevertheless, GNU @code{gettext} may surely be useful for free packages
+not following GNU standards and conventions, but the maintainers of such
+packages might have to show imagination and initiative in organizing
+their distributions so @code{gettext} work for them in all situations.
+There are surely many, out there.
+
+Even if @code{gettext} methods are now stabilizing, slight adjustments
+might be needed between successive @code{gettext} versions, so you
+should ideally revise this chapter in subsequent releases, looking
+for changes.
+
+@menu
+* Flat and Non-Flat:: Flat or Non-Flat Directory Structures
+* Prerequisites:: Prerequisite Works
+* gettextize Invocation:: Invoking the @code{gettextize} Program
+* Adjusting Files:: Files You Must Create or Alter
+@end menu
+
+@node Flat and Non-Flat, Prerequisites, Maintainers, Maintainers
+@section Flat or Non-Flat Directory Structures
+
+Some free software packages are distributed as @code{tar} files which unpack
+in a single directory, these are said to be @dfn{flat} distributions.
+Other free software packages have a one level hierarchy of subdirectories, using
+for example a subdirectory named @file{doc/} for the Texinfo manual and
+man pages, another called @file{lib/} for holding functions meant to
+replace or complement C libraries, and a subdirectory @file{src/} for
+holding the proper sources for the package. These other distributions
+are said to be @dfn{non-flat}.
+
+For now, we cannot say much about flat distributions. A flat
+directory structure has the disadvantage of increasing the difficulty
+of updating to a new version of GNU @code{gettext}. Also, if you have
+many PO files, this could somewhat pollute your single directory.
+In the GNU @code{gettext} distribution, the @file{misc/} directory
+contains a shell script named @file{combine-sh}. That script may
+be used for combining all the C files of the @file{intl/} directory
+into a pair of C files (one @file{.c} and one @file{.h}). Those two
+generated files would fit more easily in a flat directory structure,
+and you will then have to add these two files to your project.
+
+Maybe because GNU @code{gettext} itself has a non-flat structure,
+we have more experience with this approach, and this is what will be
+described in the remaining of this chapter. Some maintainers might
+use this as an opportunity to unflatten their package structure.
+Only later, once gained more experience adapting GNU @code{gettext}
+to flat distributions, we might add some notes about how to proceed
+in flat situations.
+
+@node Prerequisites, gettextize Invocation, Flat and Non-Flat, Maintainers
+@section Prerequisite Works
+
+There are some works which are required for using GNU @code{gettext}
+in one of your package. These works have some kind of generality
+that escape the point by point descriptions used in the remainder
+of this chapter. So, we describe them here.
+
+@itemize @bullet
+@item
+Before attempting to use you should install some other packages first.
+Ensure that recent versions of GNU @code{m4}, GNU Autoconf and GNU
+@code{gettext} are already installed at your site, and if not, proceed
+to do this first. If you got to install these things, beware that
+GNU @code{m4} must be fully installed before GNU Autoconf is even
+@emph{configured}.
+
+To further ease the task of a package maintainer the @code{automake}
+package was designed and implemented. GNU @code{gettext} now uses this
+tool and the @file{Makefile}s in the @file{intl/} and @file{po/}
+therefore know about all the goals necessary for using @code{automake}
+and @file{libintl} in one project.
+
+Those four packages are only needed to you, as a maintainer; the
+installers of your own package and end users do not really need any of
+GNU @code{m4}, GNU Autoconf, GNU @code{gettext}, or GNU @code{automake}
+for successfully installing and running your package, with messages
+properly translated. But this is not completely true if you provide
+internationalized shell scripts within your own package: GNU
+@code{gettext} shall then be installed at the user site if the end users
+want to see the translation of shell script messages.
+
+@item
+Your package should use Autoconf and have a @file{configure.in} file.
+If it does not, you have to learn how. The Autoconf documentation
+is quite well written, it is a good idea that you print it and get
+familiar with it.
+
+@item
+Your C sources should have already been modified according to
+instructions given earlier in this manual. @xref{Sources}.
+
+@item
+Your @file{po/} directory should receive all PO files submitted to you
+by the translator teams, each having @file{@var{ll}.po} as a name.
+This is not usually easy to get translation
+work done before your package gets internationalized and available!
+Since the cycle has to start somewhere, the easiest for the maintainer
+is to start with absolutely no PO files, and wait until various
+translator teams get interested in your package, and submit PO files.
+
+@end itemize
+
+It is worth adding here a few words about how the maintainer should
+ideally behave with PO files submissions. As a maintainer, your role is
+to authentify the origin of the submission as being the representative
+of the appropriate translating teams of the Translation Project (forward
+the submission to @file{translation@@iro.umontreal.ca} in case of doubt),
+to ensure that the PO file format is not severely broken and does not
+prevent successful installation, and for the rest, to merely to put these
+PO files in @file{po/} for distribution.
+
+As a maintainer, you do not have to take on your shoulders the
+responsibility of checking if the translations are adequate or
+complete, and should avoid diving into linguistic matters. Translation
+teams drive themselves and are fully responsible of their linguistic
+choices for the Translation Project. Keep in mind that translator teams are @emph{not}
+driven by maintainers. You can help by carefully redirecting all
+communications and reports from users about linguistic matters to the
+appropriate translation team, or explain users how to reach or join
+their team. The simplest might be to send them the @file{ABOUT-NLS} file.
+
+Maintainers should @emph{never ever} apply PO file bug reports
+themselves, short-cutting translation teams. If some translator has
+difficulty to get some of her points through her team, it should not be
+an issue for her to directly negotiate translations with maintainers.
+Teams ought to settle their problems themselves, if any. If you, as
+a maintainer, ever think there is a real problem with a team, please
+never try to @emph{solve} a team's problem on your own.
+
+@node gettextize Invocation, Adjusting Files, Prerequisites, Maintainers
+@section Invoking the @code{gettextize} Program
+
+Some files are consistently and identically needed in every package
+internationalized through GNU @code{gettext}. As a matter of
+convenience, the @code{gettextize} program puts all these files right
+in your package. This program has the following synopsis:
+
+@example
+gettextize [ @var{option}@dots{} ] [ @var{directory} ]
+@end example
+
+@noindent
+and accepts the following options:
+
+@table @samp
+@item -c
+@itemx --copy
+Copy the needed files instead of making symbolic links. Using links
+would allow the package to always use the latest @code{gettext} code
+available on the system, but it might disturb some mechanism the
+maintainer is used to apply to the sources. Because running
+@code{gettextize} is easy there shouldn't be problems with using copies.
+
+@item -f
+@itemx --force
+Force replacement of files which already exist.
+
+@item -h
+@itemx --help
+Display this help and exit.
+
+@item --version
+Output version information and exit.
+
+@end table
+
+If @var{directory} is given, this is the top level directory of a
+package to prepare for using GNU @code{gettext}. If not given, it
+is assumed that the current directory is the top level directory of
+such a package.
+
+The program @code{gettextize} provides the following files. However,
+no existing file will be replaced unless the option @code{--force}
+(@code{-f}) is specified.
+
+@enumerate
+@item
+The @file{ABOUT-NLS} file is copied in the main directory of your package,
+the one being at the top level. This file gives the main indications
+about how to install and use the Native Language Support features
+of your program. You might elect to use a more recent copy of this
+@file{ABOUT-NLS} file than the one provided through @code{gettextize},
+if you have one handy. You may also fetch a more recent copy of file
+@file{ABOUT-NLS} from Translation Project sites, and from most GNU
+archive sites.
+
+@item
+A @file{po/} directory is created for eventually holding
+all translation files, but initially only containing the file
+@file{po/Makefile.in.in} from the GNU @code{gettext} distribution.
+(beware the double @samp{.in} in the file name). If the @file{po/}
+directory already exists, it will be preserved along with the files
+it contains, and only @file{Makefile.in.in} will be overwritten.
+
+@item
+A @file{intl/} directory is created and filled with most of the files
+originally in the @file{intl/} directory of the GNU @code{gettext}
+distribution. Also, if option @code{--force} (@code{-f}) is given,
+the @file{intl/} directory is emptied first.
+
+@end enumerate
+
+If your site support symbolic links, @code{gettextize} will not
+actually copy the files into your package, but establish symbolic
+links instead. This avoids duplicating the disk space needed in
+all packages. Merely using the @samp{-h} option while creating the
+@code{tar} archive of your distribution will resolve each link by an
+actual copy in the distribution archive. So, to insist, you really
+should use @samp{-h} option with @code{tar} within your @code{dist}
+goal of your main @file{Makefile.in}.
+
+It is interesting to understand that most new files for supporting
+GNU @code{gettext} facilities in one package go in @file{intl/}
+and @file{po/} subdirectories. One distinction between these two
+directories is that @file{intl/} is meant to be completely identical
+in all packages using GNU @code{gettext}, while all newly created
+files, which have to be different, go into @file{po/}. There is a
+common @file{Makefile.in.in} in @file{po/}, because the @file{po/}
+directory needs its own @file{Makefile}, and it has been designed so
+it can be identical in all packages.
+
+@node Adjusting Files, , gettextize Invocation, Maintainers
+@section Files You Must Create or Alter
+
+Besides files which are automatically added through @code{gettextize},
+there are many files needing revision for properly interacting with
+GNU @code{gettext}. If you are closely following GNU standards for
+Makefile engineering and auto-configuration, the adaptations should
+be easier to achieve. Here is a point by point description of the
+changes needed in each.
+
+So, here comes a list of files, each one followed by a description of
+all alterations it needs. Many examples are taken out from the GNU
+@code{gettext} @value{VERSION} distribution itself. You may indeed
+refer to the source code of the GNU @code{gettext} package, as it
+is intended to be a good example and master implementation for using
+its own functionality.
+
+@menu
+* po/POTFILES.in:: @file{POTFILES.in} in @file{po/}
+* configure.in:: @file{configure.in} at top level
+* aclocal:: @file{aclocal.m4} at top level
+* acconfig:: @file{acconfig.h} at top level
+* Makefile:: @file{Makefile.in} at top level
+* src/Makefile:: @file{Makefile.in} in @file{src/}
+@end menu
+
+@node po/POTFILES.in, configure.in, Adjusting Files, Adjusting Files
+@subsection @file{POTFILES.in} in @file{po/}
+
+The @file{po/} directory should receive a file named
+@file{POTFILES.in}. This file tells which files, among all program
+sources, have marked strings needing translation. Here is an example
+of such a file:
+
+@example
+@group
+# List of source files containing translatable strings.
+# Copyright (C) 1995 Free Software Foundation, Inc.
+
+# Common library files
+lib/error.c
+lib/getopt.c
+lib/xmalloc.c
+
+# Package source files
+src/gettextp.c
+src/msgfmt.c
+src/xgettext.c
+@end group
+@end example
+
+@noindent
+Dashed comments and white lines are ignored. All other lines
+list those source files containing strings marked for translation
+(@pxref{Mark Keywords}), in a notation relative to the top level
+of your whole distribution, rather than the location of the
+@file{POTFILES.in} file itself.
+
+@node configure.in, aclocal, po/POTFILES.in, Adjusting Files
+@subsection @file{configure.in} at top level
+
+@enumerate
+@item Declare the package and version.
+
+This is done by a set of lines like these:
+
+@example
+PACKAGE=gettext
+VERSION=@value{VERSION}
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+@end example
+
+@noindent
+Of course, you replace @samp{gettext} with the name of your package,
+and @samp{@value{VERSION}} by its version numbers, exactly as they
+should appear in the packaged @code{tar} file name of your distribution
+(@file{gettext-@value{VERSION}.tar.gz}, here).
+
+@item Declare the available translations.
+
+This is done by defining @code{ALL_LINGUAS} to the white separated,
+quoted list of available languages, in a single line, like this:
+
+@example
+ALL_LINGUAS="de fr"
+@end example
+
+@noindent
+This example means that German and French PO files are available, so
+that these languages are currently supported by your package. If you
+want to further restrict, at installation time, the set of installed
+languages, this should not be done by modifying @code{ALL_LINGUAS} in
+@file{configure.in}, but rather by using the @code{LINGUAS} environment
+variable (@pxref{Installers}).
+
+@item Check for internationalization support.
+
+Here is the main @code{m4} macro for triggering internationalization
+support. Just add this line to @file{configure.in}:
+
+@example
+AM_GNU_GETTEXT
+@end example
+
+@noindent
+This call is purposely simple, even if it generates a lot of configure
+time checking and actions.
+
+@item Have output files created.
+
+The @code{AC_OUTPUT} directive, at the end of your @file{configure.in}
+file, needs to be modified in two ways:
+
+@example
+AC_OUTPUT([@var{existing configuration files} intl/Makefile po/Makefile.in],
+@var{existing additional actions}])
+@end example
+
+The modification to the first argument to @code{AC_OUTPUT} asks
+for substitution in the @file{intl/} and @file{po/} directories.
+Note the @samp{.in} suffix used for @file{po/} only. This is because
+the distributed file is really @file{po/Makefile.in.in}.
+
+@end enumerate
+
+@node aclocal, acconfig, configure.in, Adjusting Files
+@subsection @file{aclocal.m4} at top level
+
+If you do not have an @file{aclocal.m4} file in your distribution,
+the simplest is taking a copy of @file{aclocal.m4} from
+GNU @code{gettext}. But to be precise, you only need macros
+@code{AM_LC_MESSAGES}, @code{AM_WITH_NLS} and @code{AM_GNU_GETTEXT},
+and @code{AM_PATH_PROG_WITH_TEST}, which is called by @code{AM_WITH_NLS},
+so you may use an editor and remove macros you do not need.
+
+If you already have an @file{aclocal.m4} file, then you will have
+to merge the said macros into your @file{aclocal.m4}. Note that if
+you are upgrading from a previous release of GNU @code{gettext}, you
+should most probably @emph{replace} the said macros, as they usually
+change a little from one release of GNU @code{gettext} to the next.
+Their contents may vary as we get more experience with strange systems
+out there.
+
+These macros check for the internationalization support functions
+and related informations. Hopefully, once stabilized, these macros
+might be integrated in the standard Autoconf set, because this
+piece of @code{m4} code will be the same for all projects using GNU
+@code{gettext}.
+
+@node acconfig, Makefile, aclocal, Adjusting Files
+@subsection @file{acconfig.h} at top level
+
+If you do not have an @file{acconfig.h} file in your distribution, the
+simplest is use take a copy of @file{acconfig.h} from GNU
+@code{gettext}. But to be precise, you only need the lines and comments
+for @code{ENABLE_NLS}, @code{HAVE_CATGETS}, @code{HAVE_GETTEXT} and
+@code{HAVE_LC_MESSAGES}, @code{HAVE_STPCPY}, @code{PACKAGE} and
+@code{VERSION}, so you may use an editor and remove everything else. If
+you already have an @file{acconfig.h} file, then you should merge the
+said definitions into your @file{acconfig.h}.
+
+@node Makefile, src/Makefile, acconfig, Adjusting Files
+@subsection @file{Makefile.in} at top level
+
+Here are a few modifications you need to make to your main, top-level
+@file{Makefile.in} file.
+
+@enumerate
+@item
+Add the following lines near the beginning of your @file{Makefile.in},
+so the @samp{dist:} goal will work properly (as explained further down):
+
+@example
+PACKAGE = @@PACKAGE@@
+VERSION = @@VERSION@@
+@end example
+
+@item
+Add file @file{ABOUT-NLS} to the @code{DISTFILES} definition, so the file gets
+distributed.
+
+@item
+Wherever you process subdirectories in your @file{Makefile.in}, be sure
+you also process dir subdirectories @samp{intl} and @samp{po}. Special
+rules in the @file{Makefiles} take care for the case where no
+internationalization is wanted.
+
+If you are using Makefiles, either generated by automake, or hand-written
+so they carefully follow the GNU coding standards, the effected goals for
+which the new subdirectories must be handled include @samp{installdirs},
+@samp{install}, @samp{uninstall}, @samp{clean}, @samp{distclean}.
+
+Here is an example of a canonical order of processing. In this
+example, we also define @code{SUBDIRS} in @code{Makefile.in} for it
+to be further used in the @samp{dist:} goal.
+
+@example
+SUBDIRS = doc lib @@INTLSUB@@ src @@POSUB@@
+@end example
+
+@noindent
+that you will have to adapt to your own package.
+
+@item
+A delicate point is the @samp{dist:} goal, as both
+@file{intl/Makefile} and @file{po/Makefile} will later assume that the
+proper directory has been set up from the main @file{Makefile}. Here is
+an example at what the @samp{dist:} goal might look like:
+
+@example
+distdir = $(PACKAGE)-$(VERSION)
+dist: Makefile
+ rm -fr $(distdir)
+ mkdir $(distdir)
+ chmod 777 $(distdir)
+ for file in $(DISTFILES); do \
+ ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
+ done
+ for subdir in $(SUBDIRS); do \
+ mkdir $(distdir)/$$subdir || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $@@) || exit 1; \
+ done
+ tar chozf $(distdir).tar.gz $(distdir)
+ rm -fr $(distdir)
+@end example
+
+@end enumerate
+
+@node src/Makefile, , Makefile, Adjusting Files
+@subsection @file{Makefile.in} in @file{src/}
+
+Some of the modifications made in the main @file{Makefile.in} will
+also be needed in the @file{Makefile.in} from your package sources,
+which we assume here to be in the @file{src/} subdirectory. Here are
+all the modifications needed in @file{src/Makefile.in}:
+
+@enumerate
+@item
+In view of the @samp{dist:} goal, you should have these lines near the
+beginning of @file{src/Makefile.in}:
+
+@example
+PACKAGE = @@PACKAGE@@
+VERSION = @@VERSION@@
+@end example
+
+@item
+If not done already, you should guarantee that @code{top_srcdir}
+gets defined. This will serve for @code{cpp} include files. Just add
+the line:
+
+@example
+top_srcdir = @@top_srcdir@@
+@end example
+
+@item
+You might also want to define @code{subdir} as @samp{src}, later
+allowing for almost uniform @samp{dist:} goals in all your
+@file{Makefile.in}. At list, the @samp{dist:} goal below assume that
+you used:
+
+@example
+subdir = src
+@end example
+
+@item
+You should ensure that the final linking will use @code{@@INTLLIBS@@} as
+a library. An easy way to achieve this is to manage that it gets into
+@code{LIBS}, like this:
+
+@example
+LIBS = @@INTLLIBS@@ @@LIBS@@
+@end example
+
+In most packages internationalized with GNU @code{gettext}, one will
+find a directory @file{lib/} in which a library containing some helper
+functions will be build. (You need at least the few functions which the
+GNU @code{gettext} Library itself needs.) However some of the functions
+in the @file{lib/} also give messages to the user which of course should be
+translated, too. Taking care of this it is not enough to place the support
+library (say @file{libsupport.a}) just between the @code{@@INTLLIBS@@}
+and @code{@@LIBS@@} in the above example. Instead one has to write this:
+
+@example
+LIBS = ../lib/libsupport.a @@INTLLIBS@@ ../lib/libsupport.a @@LIBS@@
+@end example
+
+@item
+You should also ensure that directory @file{intl/} will be searched for
+C preprocessor include files in all circumstances. So, you have to
+manage so both @samp{-I../intl} and @samp{-I$(top_srcdir)/intl} will
+be given to the C compiler.
+
+@item
+Your @samp{dist:} goal has to conform with others. Here is a
+reasonable definition for it:
+
+@example
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist: Makefile $(DISTFILES)
+ for file in $(DISTFILES); do \
+ ln $$file $(distdir) 2>/dev/null || cp -p $$file $(distdir); \
+ done
+@end example
+
+@end enumerate
+
+@node Conclusion, Country Codes, Maintainers, Top
+@chapter Concluding Remarks
+
+We would like to conclude this GNU @code{gettext} manual by presenting
+an history of the Translation Project so far. We finally give
+a few pointers for those who want to do further research or readings
+about Native Language Support matters.
+
+@menu
+* History:: History of GNU @code{gettext}
+* References:: Related Readings
+@end menu
+
+@node History, References, Conclusion, Conclusion
+@section History of GNU @code{gettext}
+
+Internationalization concerns and algorithms have been informally
+and casually discussed for years in GNU, sometimes around GNU
+@code{libc}, maybe around the incoming @code{Hurd}, or otherwise
+(nobody clearly remembers). And even then, when the work started for
+real, this was somewhat independently of these previous discussions.
+
+This all began in July 1994, when Patrick D'Cruze had the idea and
+initiative of internationalizing version 3.9.2 of GNU @code{fileutils}.
+He then asked Jim Meyering, the maintainer, how to get those changes
+folded into an official release. That first draft was full of
+@code{#ifdef}s and somewhat disconcerting, and Jim wanted to find
+nicer ways. Patrick and Jim shared some tries and experimentations
+in this area. Then, feeling that this might eventually have a deeper
+impact on GNU, Jim wanted to know what standards were, and contacted
+Richard Stallman, who very quickly and verbally described an overall
+design for what was meant to become @code{glocale}, at that time.
+
+Jim implemented @code{glocale} and got a lot of exhausting feedback
+from Patrick and Richard, of course, but also from Mitchum DSouza
+(who wrote a @code{catgets}-like package), Roland McGrath, maybe David
+MacKenzie, Fran@,{c}ois Pinard, and Paul Eggert, all pushing and
+pulling in various directions, not always compatible, to the extent
+that after a couple of test releases, @code{glocale} was torn apart.
+
+While Jim took some distance and time and became dad for a second
+time, Roland wanted to get GNU @code{libc} internationalized, and
+got Ulrich Drepper involved in that project. Instead of starting
+from @code{glocale}, Ulrich rewrote something from scratch, but
+more conformant to the set of guidelines who emerged out of the
+@code{glocale} effort. Then, Ulrich got people from the previous
+forum to involve themselves into this new project, and the switch
+from @code{glocale} to what was first named @code{msgutils}, renamed
+@code{nlsutils}, and later @code{gettext}, became officially accepted
+by Richard in May 1995 or so.
+
+Let's summarize by saying that Ulrich Drepper wrote GNU @code{gettext}
+in April 1995. The first official release of the package, including
+PO mode, occurred in July 1995, and was numbered 0.7. Other people
+contributed to the effort by providing a discussion forum around
+Ulrich, writing little pieces of code, or testing. These are quoted
+in the @code{THANKS} file which comes with the GNU @code{gettext}
+distribution.
+
+While this was being done, Fran@,{c}ois adapted half a dozen of
+GNU packages to @code{glocale} first, then later to @code{gettext},
+putting them in pretest, so providing along the way an effective
+user environment for fine tuning the evolving tools. He also took
+the responsibility of organizing and coordinating the Translation
+Project. After nearly a year of informal exchanges between people from
+many countries, translator teams started to exist in May 1995, through
+the creation and support by Patrick D'Cruze of twenty unmoderated
+mailing lists for that many native languages, and two moderated
+lists: one for reaching all teams at once, the other for reaching
+all willing maintainers of internationalized free software packages.
+
+Fran@,{c}ois also wrote PO mode in June 1995 with the collaboration
+of Greg McGary, as a kind of contribution to Ulrich's package.
+He also gave a hand with the GNU @code{gettext} Texinfo manual.
+
+@node References, , History, Conclusion
+@section Related Readings
+
+Eugene H. Dorr (@file{dorre@@well.com}) maintains an interesting
+bibliography on internationalization matters, called
+@cite{Internationalization Reference List}, which is available as:
+@example
+ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/i18n-books.txt
+@end example
+
+Michael Gschwind (@file{mike@@vlsivie.tuwien.ac.at}) maintains a
+Frequently Asked Questions (FAQ) list, entitled @cite{Programming for
+Internationalisation}. This FAQ discusses writing programs which
+can handle different language conventions, character sets, etc.;
+and is applicable to all character set encodings, with particular
+emphasis on @w{ISO 8859-1}. It is regularly published in Usenet
+groups @file{comp.unix.questions}, @file{comp.std.internat},
+@file{comp.software.international}, @file{comp.lang.c},
+@file{comp.windows.x}, @file{comp.std.c}, @file{comp.answers}
+and @file{news.answers}. The home location of this document is:
+@example
+ftp://ftp.vlsivie.tuwien.ac.at/pub/8bit/ISO-programming
+@end example
+
+Patrick D'Cruze (@file{pdcruze@@li.org}) wrote a tutorial about NLS
+matters, and Jochen Hein (@file{Hein@@student.tu-clausthal.de}) took
+over the responsibility of maintaining it. It may be found as:
+@example
+ftp://sunsite.unc.edu/pub/Linux/utils/nls/catalogs/Incoming/...
+ ...locale-tutorial-0.8.txt.gz
+@end example
+@noindent
+This site is mirrored in:
+@example
+ftp://ftp.ibp.fr/pub/linux/sunsite/
+@end example
+
+A French version of the same tutorial should be findable at:
+@example
+ftp://ftp.ibp.fr/pub/linux/french/docs/
+@end example
+@noindent
+together with French translations of many Linux-related documents.
+
+@node Country Codes, , Conclusion, Top
+@appendix Country Codes
+
+The @w{ISO 639} standard defines two character codes for many countries.
+All abreviations for countries or languages used in the Translation
+Project should come from this standard.
+
+@table @samp
+@include iso-apdx.texi
+@end table
+
+@contents
+@bye
+
+@c Local variables:
+@c texinfo-column-for-description: 32
+@c End:
diff --git a/doc/iso-apdx.sed b/doc/iso-apdx.sed
new file mode 100644
index 0000000..1f9948b
--- /dev/null
+++ b/doc/iso-apdx.sed
@@ -0,0 +1,19 @@
+#! /usr/bin/sed -f
+#
+# each line of the form ^.. .* contains the code for a country.
+#
+/^.. / {
+ h
+ s/^.. \(.*\)/\1./
+ x
+ s/^\(..\).*/@item \1/
+ G
+ p
+}
+#
+# delete the rest
+#
+d
+
+
+
diff --git a/doc/iso-apdx.texi b/doc/iso-apdx.texi
new file mode 100644
index 0000000..df50921
--- /dev/null
+++ b/doc/iso-apdx.texi
@@ -0,0 +1,278 @@
+@item aa
+Afar.
+@item ab
+Abkhazian.
+@item af
+Afrikaans.
+@item am
+Amharic.
+@item ar
+Arabic.
+@item as
+Assamese.
+@item ay
+Aymara.
+@item az
+Azerbaijani.
+@item ba
+Bashkir.
+@item be
+Byelorussian.
+@item bg
+Bulgarian.
+@item bh
+Bihari.
+@item bi
+Bislama.
+@item bn
+Bengali; Bangla.
+@item bo
+Tibetan.
+@item br
+Breton.
+@item ca
+Catalan.
+@item co
+Corsican.
+@item cs
+Czech.
+@item cy
+Welsh.
+@item da
+Danish.
+@item de
+German.
+@item dz
+Bhutani.
+@item el
+Greek.
+@item en
+English.
+@item eo
+Esperanto.
+@item es
+Spanish.
+@item et
+Estonian.
+@item eu
+Basque.
+@item fa
+Persian.
+@item fi
+Finnish.
+@item fj
+Fiji.
+@item fo
+Faroese.
+@item fr
+French.
+@item fy
+Frisian.
+@item ga
+Irish.
+@item gd
+Scots Gaelic.
+@item gl
+Galician.
+@item gn
+Guarani.
+@item gu
+Gujarati.
+@item ha
+Hausa.
+@item he
+Hebrew (formerly iw).
+@item hi
+Hindi.
+@item hr
+Croatian.
+@item hu
+Hungarian.
+@item hy
+Armenian.
+@item ia
+Interlingua.
+@item id
+Indonesian (formerly in).
+@item ie
+Interlingue.
+@item ik
+Inupiak.
+@item is
+Icelandic.
+@item it
+Italian.
+@item iu
+Inuktitut.
+@item ja
+Japanese.
+@item jw
+Javanese.
+@item ka
+Georgian.
+@item kk
+Kazakh.
+@item kl
+Greenlandic.
+@item km
+Cambodian.
+@item kn
+Kannada.
+@item ko
+Korean.
+@item ks
+Kashmiri.
+@item ku
+Kurdish.
+@item ky
+Kirghiz.
+@item la
+Latin.
+@item ln
+Lingala.
+@item lo
+Laothian.
+@item lt
+Lithuanian.
+@item lv
+Latvian, Lettish.
+@item mg
+Malagasy.
+@item mi
+Maori.
+@item mk
+Macedonian.
+@item ml
+Malayalam.
+@item mn
+Mongolian.
+@item mo
+Moldavian.
+@item mr
+Marathi.
+@item ms
+Malay.
+@item mt
+Maltese.
+@item my
+Burmese.
+@item na
+Nauru.
+@item ne
+Nepali.
+@item nl
+Dutch.
+@item no
+Norwegian.
+@item oc
+Occitan.
+@item om
+(Afan) Oromo.
+@item or
+Oriya.
+@item pa
+Punjabi.
+@item pl
+Polish.
+@item ps
+Pashto, Pushto.
+@item pt
+Portuguese.
+@item qu
+Quechua.
+@item rm
+Rhaeto-Romance.
+@item rn
+Kirundi.
+@item ro
+Romanian.
+@item ru
+Russian.
+@item rw
+Kinyarwanda.
+@item sa
+Sanskrit.
+@item sd
+Sindhi.
+@item sg
+Sangro.
+@item sh
+Serbo-Croatian.
+@item si
+Sinhalese.
+@item sk
+Slovak.
+@item sl
+Slovenian.
+@item sm
+Samoan.
+@item sn
+Shona.
+@item so
+Somali.
+@item sq
+Albanian.
+@item sr
+Serbian.
+@item ss
+Siswati.
+@item st
+Sesotho.
+@item su
+Sundanese.
+@item sv
+Swedish.
+@item sw
+Swahili.
+@item ta
+Tamil.
+@item te
+Telugu.
+@item tg
+Tajik.
+@item th
+Thai.
+@item ti
+Tigrinya.
+@item tk
+Turkmen.
+@item tl
+Tagalog.
+@item tn
+Setswana.
+@item to
+Tonga.
+@item tr
+Turkish.
+@item ts
+Tsonga.
+@item tt
+Tatar.
+@item tw
+Twi.
+@item ug
+Uighur.
+@item uk
+Ukrainian.
+@item ur
+Urdu.
+@item uz
+Uzbek.
+@item vi
+Vietnamese.
+@item vo
+Volapuk.
+@item wo
+Wolof.
+@item xh
+Xhosa.
+@item yi
+Yiddish (formerly ji).
+@item yo
+Yoruba.
+@item za
+Zhuang.
+@item zh
+Chinese.
+@item zu
+Zulu.
diff --git a/doc/matrix.texi b/doc/matrix.texi
new file mode 100644
index 0000000..c3b8995
--- /dev/null
+++ b/doc/matrix.texi
@@ -0,0 +1,75 @@
+@example
+@group
+Ready PO files cs da de el en es fi fr it
+ .----------------------------.
+bash | [] [] |
+bison | [] [] |
+clisp | [] [] [] [] |
+cpio | [] [] [] |
+diffutils | [] [] [] |
+enscript | [] [] [] [] |
+fileutils | [] [] [] [] |
+findutils | [] [] [] [] |
+flex | [] [] |
+gcal | [] [] |
+gettext | [] [] [] [] [] |
+grep | [] [] [] [] |
+hello | [] [] [] [] [] |
+id-utils | [] [] |
+indent | [] [] |
+libc | [] [] [] |
+m4 | [] [] |
+make | [] [] [] |
+music | [] |
+ptx | [] [] [] |
+recode | [] [] [] [] |
+sed | |
+sh-utils | [] [] [] |
+sharutils | [] [] [] [] [] |
+tar | [] [] [] [] |
+texinfo | [] [] [] |
+textutils | [] [] [] [] |
+wdiff | [] [] [] [] |
+wget | [] [] [] [] |
+ `----------------------------'
+ cs da de el en es fi fr it
+ 7 4 26 4 1 18 1 26 4
+@end group
+
+@group
+ ja ko nl no pl pt ru sl sv
+ .----------------------------.
+bash | [] | 3
+bison | [] | 3
+clisp | | 4
+cpio | [] [] [] | 6
+diffutils | [] [] | 5
+enscript | [] [] | 6
+fileutils | [] [] [] [] [] [] [] | 11
+findutils | [] [] [] [] [] | 9
+flex | [] [] | 4
+gcal | [] [] [] | 5
+gettext | [] [] [] [] [] [] [] | 13
+grep | [] [] [] [] [] [] [] | 11
+hello | [] [] [] [] [] [] [] | 12
+id-utils | [] | 3
+indent | [] [] [] | 5
+libc | [] [] [] [] [] | 8
+m4 | [] [] [] [] | 6
+make | [] [] [] | 6
+music | [] | 2
+ptx | [] [] [] [] [] | 8
+recode | [] [] [] [] [] | 9
+sed | | 0
+sh-utils | [] [] [] [] [] | 8
+sharutils | [] [] | 7
+tar | [] [] [] [] [] [] [] | 11
+texinfo | [] | 4
+textutils | [] [] [] [] [] | 9
+wdiff | [] [] [] [] | 8
+wget | [] | 5
+ `----------------------------'
+ 18 teams ja ko nl no pl pt ru sl sv
+ 29 domains 1 12 21 11 19 7 5 7 17 191
+@end group
+@end example
diff --git a/doc/mdate-sh b/doc/mdate-sh
new file mode 100755
index 0000000..37171f2
--- /dev/null
+++ b/doc/mdate-sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# Get the extended ls output of the file or directory.
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ set - x`ls -L -l -d $1`
+else
+ set - x`ls -l -d $1`
+fi
+# The month is at least the fourth argument
+# (3 shifts here, the next inside the loop).
+shift
+shift
+shift
+
+# Find the month. Next argument is day, followed by the year or time.
+month=
+until test $month
+do
+ shift
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+day=$2
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
diff --git a/doc/nls.texi b/doc/nls.texi
new file mode 100644
index 0000000..a7797e8
--- /dev/null
+++ b/doc/nls.texi
@@ -0,0 +1,254 @@
+@node Translation Intro
+@chapter Notes on the Free Translation Project
+
+@set STATUS August 1998
+
+Free software is going international! The Free Translation Project is
+a way to get maintainers of free software, translators, and users all
+together, so that will gradually become able to speak many languages.
+A few packages already provide translations for their messages.
+
+If you found this @file{ABOUT-NLS} file inside a distribution, you
+may assume that the distributed package does use GNU @code{gettext}
+internally, itself available at your nearest GNU archive site. But you
+do @emph{not} need to install GNU @code{gettext} prior to configuring,
+installing or using this package with messages translated.
+
+Installers will find here some useful hints. These notes also explain
+how users should proceed for getting the programs to use the available
+translations. They tell how people wanting to contribute and work
+at translations should contact the appropriate team.
+
+When reporting bugs in the @file{intl/} directory or bugs which may
+be related to internationalization, you should tell about the version
+of @code{gettext} which is used. The information can be found in
+the @file{intl/VERSION} file, in internationalized packages.
+
+@menu
+* One advise::
+* INSTALL Matters::
+* Using This Package::
+* Translating Teams::
+* Available Packages::
+* Using gettext in own code::
+@end menu
+
+@node One advise
+@section One advise in advance
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+@example
+./configure --with-included-gettext
+@end example
+
+@noindent
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed. So far, only
+the @code{gettext} implementation in the GNU C library version 2
+provides as many features (such as locale alias or message inheritance)
+as the implementation here. It is also not possible to offer this
+additional functionality on top of a @code{catgets} implementation.
+Future versions of GNU @code{gettext} will very likely convey even more
+functionality. So it might be a good idea to change to GNU
+@code{gettext} as soon as possible.
+
+So you need not provide this option if you are using GNU libc 2 or you
+have installed a recent copy of the GNU gettext package with the
+included @file{libintl}.
+
+
+@node INSTALL Matters
+@section INSTALL Matters
+
+Some packages are @dfn{localizable} when properly installed; the
+programs they contain can be made to speak your own native language.
+Most such packages use GNU @code{gettext}. Other packages have their
+own ways to internationalization, predating GNU @code{gettext}.
+
+By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system provides
+usable @code{catgets} (if using this is selected by the installer) or
+@code{gettext} functions. If neither is available, the GNU
+@code{gettext} own library will be used. This library is wholly
+contained within this package, usually in the @file{intl/} subdirectory,
+so prior installation of the GNU @code{gettext} package is @emph{not}
+required. Installers may use special options at configuration time for
+changing the default behaviour. The commands:
+
+@example
+./configure --with-included-gettext
+./configure --with-catgets
+./configure --disable-nls
+@end example
+
+@noindent
+will respectively bypass any pre-existing @code{catgets} or
+@code{gettext} to use the internationalizing routines provided within
+this package, enable the use of the @code{catgets} functions (if found
+on the locale system), or else, @emph{totally} disable translation of
+messages.
+
+When you already have GNU @code{gettext} installed on your system and
+run configure without an option for your new package, @code{configure}
+will probably detect the previously built and installed @file{libintl.a}
+file and will decide to use this. This might be not what is desirable.
+You should use the more recent version of the GNU @code{gettext}
+library. I.e. if the file @file{intl/VERSION} shows that the library
+which comes with this package is more recent, you should use
+
+@example
+./configure --with-included-gettext
+@end example
+
+@noindent
+to prevent auto-detection.
+
+By default the configuration process will not test for the
+@code{catgets} function and therefore they will not be used. The
+reasons are already given above: the emulation on top of @code{catgets}
+cannot provide all the extensions provided by the GNU @code{gettext}
+library. If you nevertheless want to use the @code{catgets} functions
+use
+
+@example
+./configure --with-catgets
+@end example
+
+@noindent
+to enable the test for @code{catgets} (this causes no harm if
+@code{catgets} is not available on your system). If you really select
+this option we would like to hear about the reasons because we cannot
+think of any good one ourself.
+
+Internationalized packages have usually many @file{po/@var{ll}.po}
+files, where @var{ll} gives an @w{ISO 639} two-letter code
+identifying the language. Unless translations have been forbidden
+at @code{configure} time by using the @samp{--disable-nls} switch,
+all available translations are installed together with the package.
+However, the environment variable @code{LINGUAS} may be set, prior
+to configuration, to limit the installed set. @code{LINGUAS} should
+then contain a space separated list of two-letter codes, stating
+which languages are allowed.
+
+@node Using This Package
+@section Using This Package
+
+@c --
+@c FIXME: rewrite to document LANGUAGE, the long names, and aliases.
+@c --
+As a user, if your language has been installed for this package, you
+only have to set the @code{LANG} environment variable to the appropriate
+@w{ISO 639} @samp{@var{ll}} two-letter code prior to using the programs
+in the package. For example, let's suppose that you speak German. At
+the shell prompt, merely execute @w{@samp{setenv LANG de}} (in
+@code{csh}), @w{@samp{export LANG; LANG=de}} (in @code{sh}) or
+@w{@samp{export LANG=de}} (in @code{bash}). This can be done from your
+@file{.login} or @file{.profile} file, once and for all.
+@c Packages which are not internationalized will merely ignore the
+@c setting of this variable.
+@c FIXME: This last sentence is not true!! --drepper
+
+An operating system might already offer message localization for many of
+its programs, while other programs have been
+installed locally with the full capabilities of GNU @code{gettext}.
+Just using @code{gettext} extended syntax for @code{LANG} would break
+proper localization of already available operating system programs. In
+this case, users should set both @code{LANGUAGE} and @code{LANG}
+variables in their environment, as programs using GNU @code{gettext}
+give preference to @code{LANGUAGE}. For example, some Swedish users
+would rather read translations in German than English for when Swedish
+is not available. This is easily accomplished by setting
+@code{LANGUAGE} to @samp{sv:de} while leaving @code{LANG} to @samp{sv}.
+
+
+@node Translating Teams
+@section Translating Teams
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list, courtesy of Linux
+International. You may reach your translation team at the address
+@file{@var{ll}@@li.org}, replacing @var{ll} by the two-letter @w{ISO
+639} code for your language. Language codes are @emph{not} the same as
+the country codes given in @w{ISO 3166}. The following translation
+teams exist, as of @value{STATUS}:
+
+@quotation
+Chinese @code{zh}, Czech @code{cs}, Danish @code{da}, Dutch @code{nl},
+English @code{en}, Esperanto @code{eo}, Finnish @code{fi}, French
+@code{fr}, German @code{de}, Hungarian @code{hu}, Irish @code{ga},
+Italian @code{it}, Indonesian @code{id}, Japanese @code{ja}, Korean
+@code{ko}, Latin @code{la}, Norwegian @code{no}, Persian @code{fa},
+Polish @code{pl}, Portuguese @code{pt}, Russian @code{ru}, Slovenian
+@code{sl}, Spanish @code{es}, Swedish @code{sv}, and Turkish @code{tr}.
+@end quotation
+
+@noindent
+For example, you may reach the Chinese translation team by writing to
+@file{zh@@li.org}.
+
+If you'd like to volunteer to @emph{work} at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is @emph{not} the same as the list itself, it
+has @samp{-request} appended. For example, speakers of Swedish can send
+a message to @w{@file{sv-request@@li.org}}, having this message body:
+
+@example
+subscribe
+@end example
+
+Keep in mind that team members are expected to participate
+@emph{actively} in translations, or at solving translational
+difficulties, rather than merely lurking around. If your team does not
+exist yet and you want to start one, or if you are unsure about what to
+do or how to get started, please write to
+@w{@file{translation@@iro.umontreal.ca}} to reach the
+coordinator for all translator teams.
+
+The English team is special. It works at improving and uniformizing
+the terminology in use. Proven linguistic skill are praised
+more than programming skill, here.
+
+@node Available Packages
+@section Available Packages
+
+Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of
+@value{STATUS}. The matrix shows, in regard of each package, for which
+languages PO files have been submitted to translation coordination.
+
+@include matrix.texi
+
+Some counters in the preceding matrix are higher than the number of visible
+blocks let us expect. This is because a few extra PO files are used for
+implementing regional variants of languages, or language dialects.
+
+For a PO file in the matrix above to be effective, the package to which
+it applies should also have been internationalized and distributed as
+such by its maintainer. There might be an observable lag between the
+mere existence a PO file and its wide availability in a distribution.
+
+If @value{STATUS} seems to be old, you may fetch a more recent copy
+of this @file{ABOUT-NLS} file on most GNU archive sites.
+
+
+@node Using gettext in own code
+@section Using @code{gettext} in new packages
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU @file{gettext} in your
+package. Of course the GNU Public License applies to your sources from
+then if you include @code{gettext} directly in your distribution on but
+since you are writing free software anyway this is no restriction.
+
+Once the sources are change appropriately and the setup can handle to
+use of @code{gettext} the only thing missing are the translations. The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project. Therefore the information given above
+applies also for every other Free Software Project. Contact
+@w{@file{translation@@iro.umontreal.ca}} to make the @file{.pot} files
+available to the translation teams.
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
new file mode 100644
index 0000000..5469103
--- /dev/null
+++ b/doc/texinfo.tex
@@ -0,0 +1,5302 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+% $Id: texinfo.tex,v 1.1 2000/06/16 07:49:23 drepper Exp $
+%
+% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98
+% Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2, or (at
+% your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this texinfo.tex file; see the file COPYING. If not, write
+% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+% Boston, MA 02111-1307, USA.
+%
+% In other words, you are welcome to use, share and improve this program.
+% You are forbidden to forbid anyone else to use, share and improve
+% what you give them. Help stamp out software-hoarding!
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% /home/gd/gnu/doc/texinfo.tex on the GNU machines.
+% ftp://ftp.gnu.org/pub/gnu/texinfo.tex
+% (and all GNU mirrors, see ftp://ftp.gnu.org/pub/gnu/README.mirrors)
+% ftp://tug.org/tex/texinfo.tex
+% ftp://ctan.org/macros/texinfo/texinfo.tex
+% (and all CTAN mirrors, finger ctan@tug.org for a list).
+%
+% Send bug reports to bug-texinfo@gnu.org.
+% Please include a precise test case in each bug report,
+% including a complete document with which we can reproduce the problem.
+%
+% Texinfo macros (with @macro) are *not* supported by texinfo.tex. You
+% have to run makeinfo -E to expand macros first; the texi2dvi script
+% does this.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For simple
+% manuals, you can get away with:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever, to process the dvi file.
+% The extra runs of TeX get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+
+
+% Make it possible to create a .fmt file just by loading this file:
+% if the underlying format is not loaded, start by loading it now.
+% Added by gildea November 1993.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+
+% This automatically updates the version number based on RCS.
+\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
+\deftexinfoversion$Revision: 1.1 $
+\message{Loading texinfo package [Version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}\message{}
+ \catcode`+=\active \catcode`\_=\active}
+
+% Save some parts of plain tex whose names we will redefine.
+
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexi=\i
+\let\ptexlbrace=\{
+\let\ptexrbrace=\}
+\let\ptexstar=\*
+\let\ptext=\t
+
+% We never want plain's outer \+ definition in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+
+\message{Basics,}
+\chardef\other=12
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordInfo\undefined \gdef\putwordfile{Info}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortContents\undefined \gdef\putwordShortContents{Short Contents}\fi
+\ifx\putwordTableofContents\undefined\gdef\putwordTableofContents{Table of Contents}\fi
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+\hyphenation{ap-pen-dix}
+\hyphenation{mini-buf-fer mini-buf-fers}
+\hyphenation{eshell}
+\hyphenation{white-space}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen \bindingoffset
+\newdimen \normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{\tracingcommands2 \tracingstats2
+ \tracingpages1 \tracingoutput1 \tracinglostchars1
+ \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+ \showboxbreadth\maxdimen\showboxdepth\maxdimen
+}%
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\cornerlong \newdimen\cornerthick
+\newdimen\topandbottommargin
+\newdimen\outerhsize \newdimen\outervsize
+\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
+\outerhsize=7in
+%\outervsize=9.5in
+% Alternative @smallbook page size is 9.25in
+\outervsize=9.25in
+\topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \escapechar = `\\ % use backslash in output files.
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ \shipout\vbox{%
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingxxx.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 2\baselineskip
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \turnoffactive
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg#1{%
+ \let\next = #1%
+ \begingroup
+ \obeylines
+ \futurelet\temp\parseargx
+}
+
+% If the next token is an obeyed space (from an @example environment or
+% the like), remove it and recurse. Otherwise, we're done.
+\def\parseargx{%
+ % \obeyedspace is defined far below, after the definition of \sepspaces.
+ \ifx\obeyedspace\temp
+ \expandafter\parseargdiscardspace
+ \else
+ \expandafter\parseargline
+ \fi
+}
+
+% Remove a single space (as the delimiter token to the macro call).
+{\obeyspaces %
+ \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ %
+ % First remove any @c comment, then any @comment.
+ % Result of each macro is put in \toks0.
+ \argremovec #1\c\relax %
+ \expandafter\argremovecomment \the\toks0 \comment\relax %
+ %
+ % Call the caller's macro, saved as \next in \parsearg.
+ \expandafter\next\expandafter{\the\toks0}%
+ }%
+}
+
+% Since all \c{,omment} does is throw away the argument, we can let TeX
+% do that for us. The \relax here is matched by the \relax in the call
+% in \parseargline; it could be more or less anything, its purpose is
+% just to delimit the argument to the \c.
+\def\argremovec#1\c#2\relax{\toks0 = {#1}}
+\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
+
+% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
+% @end itemize @c foo
+% will have two active spaces as part of the argument with the
+% `itemize'. Here we remove all active spaces from #1, and assign the
+% result to \toks0.
+%
+% This loses if there are any *other* active characters besides spaces
+% in the argument -- _ ^ +, for example -- since they get expanded.
+% Fortunately, Texinfo does not define any such commands. (If it ever
+% does, the catcode of the characters in questionwill have to be changed
+% here.) But this means we cannot call \removeactivespaces as part of
+% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
+% that \parsearg gets might well have any character at all in it.
+%
+\def\removeactivespaces#1{%
+ \begingroup
+ \ignoreactivespaces
+ \edef\temp{#1}%
+ \global\toks0 = \expandafter{\temp}%
+ \endgroup
+}
+
+% Change the active space to expand to nothing.
+%
+\begingroup
+ \obeyspaces
+ \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
+\endgroup
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+%% These are used to keep @begin/@end levels from running away
+%% Call \inENV within environments (after a \begingroup)
+\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
+\def\ENVcheck{%
+\ifENV\errmessage{Still within an environment. Type Return to continue.}
+\endgroup\fi} % This is not perfect, but it should reduce lossage
+
+% @begin foo is the same as @foo, for now.
+\newhelp\EMsimple{Type <Return> to continue.}
+
+\outer\def\begin{\parsearg\beginxxx}
+
+\def\beginxxx #1{%
+\expandafter\ifx\csname #1\endcsname\relax
+{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
+\csname #1\endcsname\fi}
+
+% @end foo executes the definition of \Efoo.
+%
+\def\end{\parsearg\endxxx}
+\def\endxxx #1{%
+ \removeactivespaces{#1}%
+ \edef\endthing{\the\toks0}%
+ %
+ \expandafter\ifx\csname E\endthing\endcsname\relax
+ \expandafter\ifx\csname \endthing\endcsname\relax
+ % There's no \foo, i.e., no ``environment'' foo.
+ \errhelp = \EMsimple
+ \errmessage{Undefined command `@end \endthing'}%
+ \else
+ \unmatchedenderror\endthing
+ \fi
+ \else
+ % Everything's ok; the right environment has been started.
+ \csname E\endthing\endcsname
+ \fi
+}
+
+% There is an environment #1, but it hasn't been started. Give an error.
+%
+\def\unmatchedenderror#1{%
+ \errhelp = \EMsimple
+ \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+}
+
+% Define the control sequence \E#1 to give an unmatched @end error.
+%
+\def\defineunmatchedend#1{%
+ \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+}
+
+
+% Single-spacing is done by various environments (specifically, in
+% \nonfillstart and \quotations).
+\newskip\singlespaceskip \singlespaceskip = 12.5pt
+\def\singlespace{%
+ % Why was this kern here? It messes up equalizing space above and below
+ % environments. --karl, 6may93
+ %{\advance \baselineskip by -\singlespaceskip
+ %\kern \baselineskip}%
+ \setleading \singlespaceskip
+}
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+ % Definitions to produce actual \{ & \} command in an index.
+ \catcode`\{ = 12 \catcode`\} = 12
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\@ = 0 \catcode`\\ = 12
+ @gdef@lbracecmd[\{]%
+ @gdef@rbracecmd[\}]%
+@endgroup
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown
+% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ptexi
+ \else\ifx\temp\jmacro \j
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=3000 }
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+\def\group{\begingroup
+ \ifnum\catcode13=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ %
+ % The \vtop we start below produces a box with normal height and large
+ % depth; thus, TeX puts \baselineskip glue before it, and (when the
+ % next line of text is done) \lineskip glue after it. (See p.82 of
+ % the TeXbook.) Thus, space below is not quite equal to space
+ % above. But it's pretty close.
+ \def\Egroup{%
+ \egroup % End the \vtop.
+ \endgroup % End the \group.
+ }%
+ %
+ \vtop\bgroup
+ % We have to put a strut on the last line in case the @group is in
+ % the midst of an example, rather than completely enclosing it.
+ % Otherwise, the interline space between the last line of the group
+ % and the first line afterwards is too small. But we can't put the
+ % strut in \Egroup, since there it would be on a line by itself.
+ % Hence this just inserts a strut at the beginning of each line.
+ \everypar = {\strut}%
+ %
+ % Since we have a strut on every line, we don't need any of TeX's
+ % normal interline spacing.
+ \offinterlineskip
+ %
+ % OK, but now we have to do something about blank
+ % lines in the input in @example-like environments, which normally
+ % just turn into \lisppar, which will insert no space now that we've
+ % turned off the interline space. Simplest is to make them be an
+ % empty paragraph.
+ \ifx\par\lisppar
+ \edef\par{\leavevmode \par}%
+ %
+ % Reset ^^M's definition to new definition of \par.
+ \obeylines
+ \fi
+ %
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\def\need{\parsearg\needx}
+
+% Old definition--didn't work.
+%\def\needx #1{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000
+%\prevdepth=-1000pt
+%}}
+
+\def\needx#1{%
+ % Go into vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % Don't add any leading before our big empty box, but allow a page
+ % break, since the best break might be right here.
+ \allowbreak
+ \nointerlineskip
+ \vtop to #1\mil{\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+}
+
+% @br forces paragraph break
+
+\let\br = \par
+
+% @dots{} output an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{\hbox to 1.5em{%
+ \hskip 0pt plus 0.25fil minus 0.25fil
+ .\hss.\hss.%
+ \hskip 0pt plus 0.5fil minus 0.5fil
+}}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \hbox to 2em{%
+ \hskip 0pt plus 0.25fil minus 0.25fil
+ .\hss.\hss.\hss.%
+ \hskip 0pt plus 0.5fil minus 0.5fil
+ }%
+ \spacefactor=3000
+}
+
+
+% @page forces the start of a new page
+
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\def\exdent{\parsearg\exdentyyy}
+\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
+
+% This defn is used inside nofill environments such as @example.
+\def\nofillexdent{\parsearg\nofillexdentyyy}
+\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
+\leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph.
+
+\def\inmargin#1{%
+\strut\vadjust{\nobreak\kern-\strutdepth
+ \vtop to \strutdepth{\baselineskip\strutdepth\vss
+ \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}}
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+
+%\hbox{{\rm#1}}\hfil\break}}
+
+% @include file insert text of that file as input.
+% Allow normal characters that we make active in the argument (a file name).
+\def\include{\begingroup
+ \catcode`\\=12
+ \catcode`~=12
+ \catcode`^=12
+ \catcode`_=12
+ \catcode`|=12
+ \catcode`<=12
+ \catcode`>=12
+ \catcode`+=12
+ \parsearg\includezzz}
+% Restore active chars for included file.
+\def\includezzz#1{\endgroup\begingroup
+ % Read the included file in a group so nested @include's work.
+ \def\thisfile{#1}%
+ \input\thisfile
+\endgroup}
+
+\def\thisfile{}
+
+% @center line outputs that line, centered
+
+\def\center{\parsearg\centerzzz}
+\def\centerzzz #1{{\advance\hsize by -\leftskip
+\advance\hsize by -\rightskip
+\centerline{#1}}}
+
+% @sp n outputs n lines of vertical space
+
+\def\sp{\parsearg\spxxx}
+\def\spxxx #1{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other%
+\parsearg \commentxxx}
+
+\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 }
+
+\let\c=\comment
+
+% @paragraphindent is defined for the Info formatting commands only.
+\let\paragraphindent=\comment
+
+% Prevent errors for section commands.
+% Used in @ignore and in failing conditionals.
+\def\ignoresections{%
+\let\chapter=\relax
+\let\unnumbered=\relax
+\let\top=\relax
+\let\unnumberedsec=\relax
+\let\unnumberedsection=\relax
+\let\unnumberedsubsec=\relax
+\let\unnumberedsubsection=\relax
+\let\unnumberedsubsubsec=\relax
+\let\unnumberedsubsubsection=\relax
+\let\section=\relax
+\let\subsec=\relax
+\let\subsubsec=\relax
+\let\subsection=\relax
+\let\subsubsection=\relax
+\let\appendix=\relax
+\let\appendixsec=\relax
+\let\appendixsection=\relax
+\let\appendixsubsec=\relax
+\let\appendixsubsection=\relax
+\let\appendixsubsubsec=\relax
+\let\appendixsubsubsection=\relax
+\let\contents=\relax
+\let\smallbook=\relax
+\let\titlepage=\relax
+}
+
+% Used in nested conditionals, where we have to parse the Texinfo source
+% and so want to turn off most commands, in case they are used
+% incorrectly.
+%
+\def\ignoremorecommands{%
+ \let\defcodeindex = \relax
+ \let\defcv = \relax
+ \let\deffn = \relax
+ \let\deffnx = \relax
+ \let\defindex = \relax
+ \let\defivar = \relax
+ \let\defmac = \relax
+ \let\defmethod = \relax
+ \let\defop = \relax
+ \let\defopt = \relax
+ \let\defspec = \relax
+ \let\deftp = \relax
+ \let\deftypefn = \relax
+ \let\deftypefun = \relax
+ \let\deftypevar = \relax
+ \let\deftypevr = \relax
+ \let\defun = \relax
+ \let\defvar = \relax
+ \let\defvr = \relax
+ \let\ref = \relax
+ \let\xref = \relax
+ \let\printindex = \relax
+ \let\pxref = \relax
+ \let\settitle = \relax
+ \let\setchapternewpage = \relax
+ \let\setchapterstyle = \relax
+ \let\everyheading = \relax
+ \let\evenheading = \relax
+ \let\oddheading = \relax
+ \let\everyfooting = \relax
+ \let\evenfooting = \relax
+ \let\oddfooting = \relax
+ \let\headings = \relax
+ \let\include = \relax
+ \let\lowersections = \relax
+ \let\down = \relax
+ \let\raisesections = \relax
+ \let\up = \relax
+ \let\set = \relax
+ \let\clear = \relax
+ \let\item = \relax
+}
+
+% Ignore @ignore ... @end ignore.
+%
+\def\ignore{\doignore{ignore}}
+
+% Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text.
+%
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\html{\doignore{html}}
+\def\menu{\doignore{menu}}
+\def\direntry{\doignore{direntry}}
+
+% Also ignore @macro ... @end macro. The user must run texi2dvi,
+% which runs makeinfo to do macro expansion. Ignore @unmacro, too.
+\def\macro{\doignore{macro}}
+\def\macrocsname{macro}
+\let\unmacro = \comment
+
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory = \comment
+
+% Ignore text until a line `@end #1'.
+%
+\def\doignore#1{\begingroup
+ % Don't complain about control sequences we have declared \outer.
+ \ignoresections
+ %
+ % Define a command to swallow text until we reach `@end #1'.
+ % This @ is a catcode 12 token (that is the normal catcode of @ in
+ % this texinfo.tex file). We change the catcode of @ below to match.
+ \long\def\doignoretext##1@end #1{\enddoignore}%
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \catcode32 = 10
+ %
+ % Ignore braces, too, so mismatched braces don't cause trouble.
+ \catcode`\{ = 9
+ \catcode`\} = 9
+ %
+ % We must not have @c interpreted as a control sequence.
+ \catcode`\@ = 12
+ %
+ % Make the letter c a comment character so that the rest of the line
+ % will be ignored. This way, the document can have (for example)
+ % @c @end ifinfo
+ % and the @end ifinfo will be properly ignored.
+ % (We've just changed @ to catcode 12.)
+ %
+ % But we can't do this if #1 is `macro', since that actually contains a c.
+ % Happily, none of the other conditionals have the letter `c' in their names!
+ \def\temp{#1}%
+ \ifx\temp\macrocsname \else
+ \catcode`\c = 14
+ \fi
+ %
+ % And now expand that command.
+ \doignoretext
+}
+
+% What we do to finish off ignored text.
+%
+\def\enddoignore{\endgroup\ignorespaces}%
+
+\newif\ifwarnedobs\warnedobsfalse
+\def\obstexwarn{%
+ \ifwarnedobs\relax\else
+ % We need to warn folks that they may have trouble with TeX 3.0.
+ % This uses \immediate\write16 rather than \message to get newlines.
+ \immediate\write16{}
+ \immediate\write16{***WARNING*** for users of Unix TeX 3.0!}
+ \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
+ \immediate\write16{If you are running another version of TeX, relax.}
+ \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
+ \immediate\write16{ Then upgrade your TeX installation if you can.}
+ \immediate\write16{ (See ftp://ftp.gnu.ai.mit.edu/pub/gnu/TeX.README.)}
+ \immediate\write16{If you are stuck with version 3.0, run the}
+ \immediate\write16{ script ``tex3patch'' from the Texinfo distribution}
+ \immediate\write16{ to use a workaround.}
+ \immediate\write16{}
+ \global\warnedobstrue
+ \fi
+}
+
+% **In TeX 3.0, setting text in \nullfont hangs tex. For a
+% workaround (which requires the file ``dummy.tfm'' to be installed),
+% uncomment the following line:
+%%%%%\font\nullfont=dummy\let\obstexwarn=\relax
+
+% Ignore text, except that we keep track of conditional commands for
+% purposes of nesting, up to an `@end #1' command.
+%
+\def\nestedignore#1{%
+ \obstexwarn
+ % We must actually expand the ignored text to look for the @end
+ % command, so that nested ignore constructs work. Thus, we put the
+ % text into a \vbox and then do nothing with the result. To minimize
+ % the change of memory overflow, we follow the approach outlined on
+ % page 401 of the TeXbook: make the current font be a dummy font.
+ %
+ \setbox0 = \vbox\bgroup
+ % Don't complain about control sequences we have declared \outer.
+ \ignoresections
+ %
+ % Define `@end #1' to end the box, which will in turn undefine the
+ % @end command again.
+ \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
+ %
+ % We are going to be parsing Texinfo commands. Most cause no
+ % trouble when they are used incorrectly, but some commands do
+ % complicated argument parsing or otherwise get confused, so we
+ % undefine them.
+ %
+ % We can't do anything about stray @-signs, unfortunately;
+ % they'll produce `undefined control sequence' errors.
+ \ignoremorecommands
+ %
+ % Set the current font to be \nullfont, a TeX primitive, and define
+ % all the font commands to also use \nullfont. We don't use
+ % dummy.tfm, as suggested in the TeXbook, because not all sites
+ % might have that installed. Therefore, math mode will still
+ % produce output, but that should be an extremely small amount of
+ % stuff compared to the main input.
+ %
+ \nullfont
+ \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont
+ \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont
+ \let\tensf = \nullfont
+ % Similarly for index fonts (mostly for their use in
+ % smallexample)
+ \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont
+ \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont
+ \let\indsf = \nullfont
+ %
+ % Don't complain when characters are missing from the fonts.
+ \tracinglostchars = 0
+ %
+ % Don't bother to do space factor calculations.
+ \frenchspacing
+ %
+ % Don't report underfull hboxes.
+ \hbadness = 10000
+ %
+ % Do minimal line-breaking.
+ \pretolerance = 10000
+ %
+ % Do not execute instructions in @tex
+ \def\tex{\doignore{tex}}%
+}
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it. Make sure the catcode of space is correct to avoid
+% losing inside @example, for instance.
+%
+\def\set{\begingroup\catcode` =10
+ \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
+ \parsearg\setxxx}
+\def\setxxx#1{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ \def\temp{#2}%
+ \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
+ \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
+ \fi
+ \endgroup
+}
+% Can't use \xdef to pre-expand #2 and save some time, since \temp or
+% \next or other control sequences that we've defined might get us into
+% an infinite loop. Consider `@set foo @cite{bar}'.
+\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\def\clear{\parsearg\clearxxx}
+\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
+
+% @value{foo} gets the text saved in variable foo.
+%
+\def\value{\begingroup
+ \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
+ \valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we \let\value to this in \indexdummies). Ones
+% whose names contain - or _ still won't work, but we can't do anything
+% about that. The command has to be fully expandable, since the result
+% winds up in the index file. This means that if the variable's value
+% contains other Texinfo commands, it's almost certain it will fail
+% (although perhaps we could fix that with sufficient work to do a
+% one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']v}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+\def\ifset{\parsearg\ifsetxxx}
+\def\ifsetxxx #1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \expandafter\ifsetfail
+ \else
+ \expandafter\ifsetsucceed
+ \fi
+}
+\def\ifsetsucceed{\conditionalsucceed{ifset}}
+\def\ifsetfail{\nestedignore{ifset}}
+\defineunmatchedend{ifset}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+\def\ifclear{\parsearg\ifclearxxx}
+\def\ifclearxxx #1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \expandafter\ifclearsucceed
+ \else
+ \expandafter\ifclearfail
+ \fi
+}
+\def\ifclearsucceed{\conditionalsucceed{ifclear}}
+\def\ifclearfail{\nestedignore{ifclear}}
+\defineunmatchedend{ifclear}
+
+% @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text
+% following, through the first @end iftex (etc.). Make `@end iftex'
+% (etc.) valid only after an @iftex.
+%
+\def\iftex{\conditionalsucceed{iftex}}
+\def\ifnothtml{\conditionalsucceed{ifnothtml}}
+\def\ifnotinfo{\conditionalsucceed{ifnotinfo}}
+\defineunmatchedend{iftex}
+\defineunmatchedend{ifnothtml}
+\defineunmatchedend{ifnotinfo}
+
+% We can't just want to start a group at @iftex (for example) and end it
+% at @end iftex, since then @set commands inside the conditional have no
+% effect (they'd get reverted at the end of the group). So we must
+% define \Eiftex to redefine itself to be its previous value. (We can't
+% just define it to fail again with an ``unmatched end'' error, since
+% the @ifset might be nested.)
+%
+\def\conditionalsucceed#1{%
+ \edef\temp{%
+ % Remember the current value of \E#1.
+ \let\nece{prevE#1} = \nece{E#1}%
+ %
+ % At the `@end #1', redefine \E#1 to be its previous value.
+ \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}%
+ }%
+ \temp
+}
+
+% We need to expand lots of \csname's, but we don't want to expand the
+% control sequences after we've constructed them.
+%
+\def\nece#1{\expandafter\noexpand\csname#1\endcsname}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math means output in math mode.
+% We don't use $'s directly in the definition of \math because control
+% sequences like \math are expanded when the toc file is written. Then,
+% we read the toc file back, the $'s will be normal characters (as they
+% should be, according to the definition of Texinfo). So we must use a
+% control sequence to switch into and out of math mode.
+%
+% This isn't quite enough for @math to work properly in indices, but it
+% seems unlikely it will ever be needed there.
+%
+\let\implicitmath = $
+\def\math#1{\implicitmath #1\implicitmath}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{\implicitmath\ptexbullet\implicitmath}
+\def\minus{\implicitmath-\implicitmath}
+
+\def\node{\ENVcheck\parsearg\nodezzz}
+\def\nodezzz#1{\nodexxx [#1,]}
+\def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
+\let\nwnode=\node
+\let\lastnode=\relax
+
+\def\donoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\setref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\unnumbnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\appendixnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \iflinks
+ \readauxfile
+ \opencontents
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ % Just to be on the safe side, close the input stream before the \input.
+ \openin 1 texinfo.cnf
+ \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi
+ \closein1
+ \temp
+ %
+ \comment % Ignore the actual filename.
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+% \def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx}
+% \def\macroxxx#1#2 \end macro{%
+% \expandafter\gdef\macrotemp#1{#2}%
+% \endgroup}
+
+%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx}
+%\def\linemacroxxx#1#2 \end linemacro{%
+%\let\parsearg=\relax
+%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}%
+%\expandafter\xdef\macrotemp{\parsearg\macrotempx}%
+%\expandafter\gdef\macrotempx#1{#2}%
+%\endgroup}
+
+%\def\butfirst#1{}
+
+
+\message{fonts,}
+
+% Font-change commands.
+
+% Texinfo supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf analogous to plain's \rm, etc.
+\newfam\sffam
+\def\sf{\fam=\sffam \tensf}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this one.
+\def\ttsl{\tenttsl}
+
+% Use Computer Modern fonts at \magstephalf (11pt).
+\newcount\mainmagstep
+\mainmagstep=\magstephalf
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+\ifx\bigger\relax
+\let\mainmagstep=\magstep1
+\setfont\textrm\rmshape{12}{1000}
+\setfont\texttt\ttshape{12}{1000}
+\else
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\fi
+% Instead of cmb10, you many want to use cmbx10.
+% cmbx10 is a prettier font on its own, but cmb10
+% looks better when embedded in a line with cmr10.
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun, etc.
+\setfont\defbf\bxshape{10}{\magstep1} %was 1314
+\setfont\deftt\ttshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+
+% Fonts for indices and small examples (9pt).
+% We actually use the slanted font rather than the italic,
+% because texinfo normally uses the slanted fonts for that.
+% Do not make many font distinctions in general in the index, since they
+% aren't very useful.
+\setfont\ninett\ttshape{9}{1000}
+\setfont\indrm\rmshape{9}{1000}
+\setfont\indit\slshape{9}{1000}
+\let\indsl=\indit
+\let\indtt=\ninett
+\let\indttsl=\ninett
+\let\indsf=\indrm
+\let\indbf=\indrm
+\setfont\indsc\scshape{10}{900}
+\font\indi=cmmi9
+\font\indsy=cmsy9
+
+% Fonts for title page:
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad.
+% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded.
+% \setfont\ssecsl\slshape{10}{\magstep1}
+% \setfont\ssectt\ttshape{10}{\magstep1}
+% \setfont\ssecsf\sfshape{10}{\magstep1}
+
+%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx.
+%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than
+%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1.
+%\setfont\ssectt\ttshape{10}{1315}
+%\setfont\ssecsf\sfshape{10}{1315}
+
+%\let\ssecbf=\ssecrm
+
+% Subsection fonts (13.15pt).
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{\magstep1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+% but that is not a standard magnification.
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts, we
+% don't bother to reset \scriptfont and \scriptscriptfont (which would
+% also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy
+ \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf
+ \textfont\ttfam = \tentt \textfont\sffam = \tensf
+}
+
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this so that font changes will continue to work
+% in math mode, where it is the current \fam that is relevant in most
+% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam
+% \tenbf}, for example. By redefining \tenbf, we obviate the need to
+% redefine \bf itself.
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
+ \resetmathfonts}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
+\def\indexfonts{%
+ \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
+ \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
+ \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl
+ \resetmathfonts \setleading{12pt}}
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bxshape{12}{1000}
+\setfont\shortcontsl\slshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
+\def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\var=\smartitalic
+\let\dfn=\smartitalic
+\let\emph=\smartitalic
+\let\cite=\smartitalic
+
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+\def\t#1{%
+ {\tt \rawbackslash \frenchspacing #1}%
+ \null
+}
+\let\ttfont=\t
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\smallrm\rmshape{8}{1000}
+\font\smallsy=cmsy9
+\def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{%
+ \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+ \vbox{\hrule\kern-0.4pt
+ \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+ \kern-0.4pt\hrule}%
+ \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+\let\file=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \frenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in \code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+\catcode`\-=\active
+\catcode`\_=\active
+\catcode`\|=\active
+\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
+% The following is used by \doprintindex to insure that long function names
+% wrap around. It is necessary for - and _ to be active before the index is
+% read from the file, as \entry parses the arguments long before \code is
+% ever called. -- mycroft
+% _ is always active; and it shouldn't be \let = to an _ that is a
+% subscript character anyway. Then, @cindex @samp{_} (for example)
+% fails. --karl
+\global\def\indexbreaks{%
+ \catcode`\-=\active \let-\realdash
+}
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}}
+\def\codex #1{\tclose{#1}\endgroup}
+
+%\let\exp=\tclose %Was temporary
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\def\kbdinputstyle{\parsearg\kbdinputstylexxx}
+\def\kbdinputstylexxx#1{%
+ \def\arg{#1}%
+ \ifx\arg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\arg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\arg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is kbdinputdistinct. (Too much of a hassle to call the macro,
+% the catcodes are wrong for parsearg to work.)
+\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% @url. Quotes do not seem necessary, so use \code.
+\let\url=\code
+
+% @uref (abbreviation for `urlref') takes an optional second argument
+% specifying the text to display. First (mandatory) arg is the url.
+% Perhaps eventually put in a hypertex \special here.
+%
+\def\uref#1{\urefxxx #1,,\finish}
+\def\urefxxx#1,#2,#3\finish{%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \unhbox0\ (\code{#1})%
+ \else
+ \code{#1}%
+ \fi
+}
+
+% rms does not like the angle brackets --karl, 17may97.
+% So now @email is just like @uref.
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\let\email=\uref
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of
+% @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+\def\r#1{{\rm #1}} % roman font
+% Use of \lowercase was suggested.
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @pounds{} is a sterling sign.
+\def\pounds{{\it\$}}
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+\def\shorttitlepage{\parsearg\shorttitlepagezzz}
+\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\def\titlepage{\begingroup \parindent=0pt \textfonts
+ \let\subtitlerm=\tenrm
+% I deinstalled the following change because \cmr12 is undefined.
+% This change was not in the ChangeLog anyway. --rms.
+% \let\subtitlerm=\cmr12
+ \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
+ %
+ \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
+ %
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ %
+ % Now you can print the title using @title.
+ \def\title{\parsearg\titlezzz}%
+ \def\titlezzz##1{\leftline{\titlefonts\rm ##1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Now you can put text using @subtitle.
+ \def\subtitle{\parsearg\subtitlezzz}%
+ \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
+ %
+ % @author should come last, but may come many times.
+ \def\author{\parsearg\authorzzz}%
+ \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
+ {\authorfont \leftline{##1}}}%
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \oldpage
+ \let\page = \oldpage
+ \hbox{}}%
+% \def\page{\oldpage \hbox{}}
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ \HEADINGSon
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks \evenheadline % Token sequence for heading line of even pages
+\newtoks \oddheadline % Token sequence for heading line of odd pages
+\newtoks \evenfootline % Token sequence for footing line of even pages
+\newtoks \oddfootline % Token sequence for footing line of odd pages
+
+% Now make Tex use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\everyheading{\parsearg\everyheadingxxx}
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\everyfooting{\parsearg\everyfootingxxx}
+
+{\catcode`\@=0 %
+
+\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
+\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
+\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
+\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
+\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -\baselineskip
+ \global\advance\vsize by -\baselineskip
+}
+
+\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+%
+}% unbind the catcode of @.
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% Produces Day Month Year style of output.
+\def\today{\number\day\space
+\ifcase\month\or
+January\or February\or March\or April\or May\or June\or
+July\or August\or September\or October\or November\or December\fi
+\space\number\year}
+
+% Use this if you want the Month Day, Year style of output.
+%\def\today{\ifcase\month\or
+%January\or February\or March\or April\or May\or June\or
+%July\or August\or September\or October\or November\or December\fi
+%\space\number\day, \number\year}
+
+% @settitle line... specifies the title of the document, for headings
+% It generates no output of its own
+
+\def\thistitle{No Title}
+\def\settitle{\parsearg\settitlezzz}
+\def\settitlezzz #1{\gdef\thistitle{#1}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
+\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
+
+\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
+\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
+
+\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
+ \itemzzz {#1}}
+
+\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
+ \itemzzz {#1}}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemfont{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % Be sure we are not still in the middle of a paragraph.
+ %{\parskip = 0in
+ %\par
+ %}%
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. Unfortunately
+ % we can't prevent a possible page break at the following
+ % \baselineskip glue.
+ \nobreak
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line. Since that
+ % text will be indented by \tableindent, we make the item text be in
+ % a zero-width box.
+ \noindent
+ \rlap{\hskip -\tableindent\box0}\ignorespaces%
+ \endgroup%
+ \itemxneedsnegativevskiptrue%
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a table}}
+\def\itemx{\errmessage{@itemx while not in a table}}
+\def\kitem{\errmessage{@kitem while not in a table}}
+\def\kitemx{\errmessage{@kitemx while not in a table}}
+\def\xitem{\errmessage{@xitem while not in a table}}
+\def\xitemx{\errmessage{@xitemx while not in a table}}
+
+%% Contains a kludge to get @end[description] to work
+\def\description{\tablez{\dontindex}{1}{}{}{}{}}
+
+\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
+{\obeylines\obeyspaces%
+\gdef\tablex #1^^M{%
+\tabley\dontindex#1 \endtabley}}
+
+\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
+{\obeylines\obeyspaces%
+\gdef\ftablex #1^^M{%
+\tabley\fnitemindex#1 \endtabley
+\def\Eftable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
+{\obeylines\obeyspaces%
+\gdef\vtablex #1^^M{%
+\tabley\vritemindex#1 \endtabley
+\def\Evtable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\dontindex #1{}
+\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
+\def\vritemindex #1{\doind {vr}{\code{#1}}}%
+
+{\obeyspaces %
+\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
+\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
+
+\def\tablez #1#2#3#4#5#6{%
+\aboveenvbreak %
+\begingroup %
+\def\Edescription{\Etable}% Necessary kludge.
+\let\itemindex=#1%
+\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
+\ifnum 0#4>0 \tableindent=#4\mil \fi %
+\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
+\def\itemfont{#2}%
+\itemmax=\tableindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \tableindent %
+\exdentamount=\tableindent
+\parindent = 0pt
+\parskip = \smallskipamount
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def\Etable{\endgraf\afterenvbreak\endgroup}%
+\let\item = \internalBitem %
+\let\itemx = \internalBitemx %
+\let\kitem = \internalBkitem %
+\let\kitemx = \internalBkitemx %
+\let\xitem = \internalBxitem %
+\let\xitemx = \internalBxitemx %
+}
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\def\itemize{\parsearg\itemizezzz}
+
+\def\itemizezzz #1{%
+ \begingroup % ended by the @end itemize
+ \itemizey {#1}{\Eitemize}
+}
+
+\def\itemizey #1#2{%
+\aboveenvbreak %
+\itemmax=\itemindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \itemindent %
+\exdentamount=\itemindent
+\parindent = 0pt %
+\parskip = \smallskipamount %
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def#2{\endgraf\afterenvbreak\endgroup}%
+\def\itemcontents{#1}%
+\let\item=\itemizeitem}
+
+% Set sfcode to normal for the chars that usually have another value.
+% These are `.?!:;,'
+\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
+ \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\def\enumerate{\parsearg\enumeratezzz}
+\def\enumeratezzz #1{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ \begingroup % ended by the @end enumerate
+ %
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call itemizey, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \itemizey{#1.}\Eenumerate\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+% Definition of @item while inside @itemize.
+
+\def\itemizeitem{%
+\advance\itemno by 1
+{\let\par=\endgraf \smallbreak}%
+\ifhmode \errmessage{In hmode at itemizeitem}\fi
+{\parskip=0in \hskip 0pt
+\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
+\vadjust{\penalty 1200}}%
+\flushcr}
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+%
+% For those who want to use more than one line's worth of words in
+% the preamble, break the line within one argument and it
+% will parse correctly, i.e.,
+%
+% @multitable {Column 1 template} {Column 2 template} {Column 3
+% template}
+% Not:
+% @multitable {Column 1 template} {Column 2 template}
+% {Column 3 template}
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab, @multitable or @end multitable do not need to be on their
+% own lines, but it will not hurt if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% 2/1/96, to allow fractions to be given with more than one digit.
+\def\pickupwholefraction#1 {\global\advance\colcount by1 %
+\expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
+\setuptable}
+
+\newcount\colcount
+\def\setuptable#1{\def\firstarg{#1}%
+\ifx\firstarg\xendsetuptable\let\go\relax%
+\else
+ \ifx\firstarg\xcolumnfractions\global\setpercenttrue%
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction % In this case arg of setuptable
+ % is the decimal point before the
+ % number given in percent of hsize.
+ % We don't need this so we don't use it.
+ \else
+ \global\advance\colcount by1
+ \setbox0=\hbox{#1 }% Add a normal word space as a separator;
+ % typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi%
+ \fi%
+\ifx\go\pickupwholefraction\else\let\go\setuptable\fi%
+\fi\go}
+
+% multitable syntax
+\def\tab{&\hskip1sp\relax} % 2/2/96
+ % tiny skip here makes sure this column space is
+ % maintained, even if it is never used.
+
+% @multitable ... @end multitable definitions:
+
+\def\multitable{\parsearg\dotable}
+\def\dotable#1{\bgroup
+ \vskip\parskip
+ \let\item\crcr
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}%
+ %
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % \everycr will reset column counter, \colcount, at the end of
+ % each line. Every column entry will cause \colcount to advance by one.
+ % The table preamble
+ % looks at the current \colcount to find the correct column width.
+ \everycr{\noalign{%
+ %
+ % \filbreak%% keeps underfull box messages off when table breaks over pages.
+ % Maybe so, but it also creates really weird page breaks when the table
+ % breaks over pages. Wouldn't \vfil be better? Wait until the problem
+ % manifests itself, so it can be fixed for real --karl.
+ \global\colcount=0\relax}}%
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup&\global\advance\colcount by 1\relax
+ \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively marking
+ % characters.
+ \noindent\ignorespaces##\unskip\multistrut}\cr
+}
+
+\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
+% If so, do nothing. If not, give it an appropriate dimension based on
+% current baselineskip.
+\ifdim\multitablelinespace=0pt
+%% strut to put in table in case some entry doesn't have descenders,
+%% to keep lines equally spaced
+\let\multistrut = \strut
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%% If so, set to same dimension as multitablelinespace.
+\else
+\gdef\multistrut{\vrule height\multitablelinespace depth\dp0
+width0pt\relax} \fi
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi}
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within \newindex.
+{\catcode`\@=11
+\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}
+}
+
+\def\defcodeindex{\parsearg\newcodeindex}
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+% The \closeout helps reduce unnecessary open files; the limit on the
+% Acorn RISC OS is a mere 16 files.
+\def\synindex#1 #2 {%
+ \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+ \expandafter\closeout\csname#1indfile\endcsname
+ \expandafter\let\csname#1indfile\endcsname=\synindexfoo
+ \expandafter\xdef\csname#1index\endcsname{% define \xxxindex
+ \noexpand\doindex{#2}}%
+}
+
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+\def\syncodeindex#1 #2 {%
+ \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+ \expandafter\closeout\csname#1indfile\endcsname
+ \expandafter\let\csname#1indfile\endcsname=\synindexfoo
+ \expandafter\xdef\csname#1index\endcsname{% define \xxxindex
+ \noexpand\docodeindex{#2}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+\def\indexdummies{%
+\def\ { }%
+% Take care of the plain tex accent commands.
+\def\"{\realbackslash "}%
+\def\`{\realbackslash `}%
+\def\'{\realbackslash '}%
+\def\^{\realbackslash ^}%
+\def\~{\realbackslash ~}%
+\def\={\realbackslash =}%
+\def\b{\realbackslash b}%
+\def\c{\realbackslash c}%
+\def\d{\realbackslash d}%
+\def\u{\realbackslash u}%
+\def\v{\realbackslash v}%
+\def\H{\realbackslash H}%
+% Take care of the plain tex special European modified letters.
+\def\oe{\realbackslash oe}%
+\def\ae{\realbackslash ae}%
+\def\aa{\realbackslash aa}%
+\def\OE{\realbackslash OE}%
+\def\AE{\realbackslash AE}%
+\def\AA{\realbackslash AA}%
+\def\o{\realbackslash o}%
+\def\O{\realbackslash O}%
+\def\l{\realbackslash l}%
+\def\L{\realbackslash L}%
+\def\ss{\realbackslash ss}%
+% Take care of texinfo commands likely to appear in an index entry.
+% (Must be a way to avoid doing expansion at all, and thus not have to
+% laboriously list every single command here.)
+\def\@{@}% will be @@ when we switch to @ as escape char.
+%\let\{ = \lbracecmd
+%\let\} = \rbracecmd
+\def\_{{\realbackslash _}}%
+\def\w{\realbackslash w }%
+\def\bf{\realbackslash bf }%
+%\def\rm{\realbackslash rm }%
+\def\sl{\realbackslash sl }%
+\def\sf{\realbackslash sf}%
+\def\tt{\realbackslash tt}%
+\def\gtr{\realbackslash gtr}%
+\def\less{\realbackslash less}%
+\def\hat{\realbackslash hat}%
+\def\TeX{\realbackslash TeX}%
+\def\dots{\realbackslash dots }%
+\def\result{\realbackslash result}%
+\def\equiv{\realbackslash equiv}%
+\def\expansion{\realbackslash expansion}%
+\def\print{\realbackslash print}%
+\def\error{\realbackslash error}%
+\def\point{\realbackslash point}%
+\def\copyright{\realbackslash copyright}%
+\def\tclose##1{\realbackslash tclose {##1}}%
+\def\code##1{\realbackslash code {##1}}%
+\def\dotless##1{\realbackslash dotless {##1}}%
+\def\samp##1{\realbackslash samp {##1}}%
+\def\,##1{\realbackslash ,{##1}}%
+\def\t##1{\realbackslash t {##1}}%
+\def\r##1{\realbackslash r {##1}}%
+\def\i##1{\realbackslash i {##1}}%
+\def\b##1{\realbackslash b {##1}}%
+\def\sc##1{\realbackslash sc {##1}}%
+\def\cite##1{\realbackslash cite {##1}}%
+\def\key##1{\realbackslash key {##1}}%
+\def\file##1{\realbackslash file {##1}}%
+\def\var##1{\realbackslash var {##1}}%
+\def\kbd##1{\realbackslash kbd {##1}}%
+\def\dfn##1{\realbackslash dfn {##1}}%
+\def\emph##1{\realbackslash emph {##1}}%
+%
+% Handle some cases of @value -- where the variable name does not
+% contain - or _, and the value does not contain any
+% (non-fully-expandable) commands.
+\let\value = \expandablevalue
+%
+\unsepspaces
+}
+
+% If an index command is used in an @example environment, any spaces
+% therein should become regular spaces in the raw index file, not the
+% expansion of \tie (\\leavevmode \penalty \@M \ ).
+{\obeyspaces
+ \gdef\unsepspaces{\obeyspaces\let =\space}}
+
+% \indexnofonts no-ops all font-change commands.
+% This is used when outputting the strings to sort the index by.
+\def\indexdummyfont#1{#1}
+\def\indexdummytex{TeX}
+\def\indexdummydots{...}
+
+\def\indexnofonts{%
+% Just ignore accents.
+\let\,=\indexdummyfont
+\let\"=\indexdummyfont
+\let\`=\indexdummyfont
+\let\'=\indexdummyfont
+\let\^=\indexdummyfont
+\let\~=\indexdummyfont
+\let\==\indexdummyfont
+\let\b=\indexdummyfont
+\let\c=\indexdummyfont
+\let\d=\indexdummyfont
+\let\u=\indexdummyfont
+\let\v=\indexdummyfont
+\let\H=\indexdummyfont
+\let\dotless=\indexdummyfont
+% Take care of the plain tex special European modified letters.
+\def\oe{oe}%
+\def\ae{ae}%
+\def\aa{aa}%
+\def\OE{OE}%
+\def\AE{AE}%
+\def\AA{AA}%
+\def\o{o}%
+\def\O{O}%
+\def\l{l}%
+\def\L{L}%
+\def\ss{ss}%
+\let\w=\indexdummyfont
+\let\t=\indexdummyfont
+\let\r=\indexdummyfont
+\let\i=\indexdummyfont
+\let\b=\indexdummyfont
+\let\emph=\indexdummyfont
+\let\strong=\indexdummyfont
+\let\cite=\indexdummyfont
+\let\sc=\indexdummyfont
+%Don't no-op \tt, since it isn't a user-level command
+% and is used in the definitions of the active chars like <, >, |...
+%\let\tt=\indexdummyfont
+\let\tclose=\indexdummyfont
+\let\code=\indexdummyfont
+\let\file=\indexdummyfont
+\let\samp=\indexdummyfont
+\let\kbd=\indexdummyfont
+\let\key=\indexdummyfont
+\let\var=\indexdummyfont
+\let\TeX=\indexdummytex
+\let\dots=\indexdummydots
+\def\@{@}%
+}
+
+% To define \realbackslash, we must make \ not be an escape.
+% We must first make another character (@) an escape
+% so we do not become unable to do a definition.
+
+{\catcode`\@=0 \catcode`\\=\other
+ @gdef@realbackslash{\}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% For \ifx comparisons.
+\def\emptymacro{\empty}
+
+% Most index entries go through here, but \dosubind is the general case.
+%
+\def\doind#1#2{\dosubind{#1}{#2}\empty}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% \empty if called from \doind, as we usually are. The main exception
+% is with defuns, which call us directly.
+%
+\def\dosubind#1#2#3{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
+ \fi
+ {%
+ \count255=\lastpenalty
+ {%
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \escapechar=`\\
+ {%
+ \let\folio = 0% We will expand all macros now EXCEPT \folio.
+ \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ \def\thirdarg{#3}%
+ %
+ % If third arg is present, precede it with space in sort key.
+ \ifx\thirdarg\emptymacro
+ \let\subentry = \empty
+ \else
+ \def\subentry{ #3}%
+ \fi
+ %
+ % First process the index-string with all font commands turned off
+ % to get the string to sort by.
+ {\indexnofonts \xdef\indexsorttmp{#2\subentry}}%
+ %
+ % Now produce the complete index entry, with both the sort key and the
+ % original text, including any font commands.
+ \toks0 = {#2}%
+ \edef\temp{%
+ \write\csname#1indfile\endcsname{%
+ \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}%
+ }%
+ %
+ % If third (subentry) arg is present, add it to the index string.
+ \ifx\thirdarg\emptymacro \else
+ \toks0 = {#3}%
+ \edef\temp{\temp{\the\toks0}}%
+ \fi
+ %
+ % If a skip is the last thing on the list now, preserve it
+ % by backing up by \lastskip, doing the \write, then inserting
+ % the skip again. Otherwise, the whatsit generated by the
+ % \write will make \lastskip zero. The result is that sequences
+ % like this:
+ % @end defun
+ % @tindex whatever
+ % @defun ...
+ % will have extra space inserted, because the \medbreak in the
+ % start of the @defun won't see the skip inserted by the @end of
+ % the previous defun.
+ \iflinks
+ \skip0 = \lastskip \ifdim\lastskip = 0pt \else \vskip-\lastskip \fi
+ \temp
+ \ifdim\skip0 = 0pt \else \vskip\skip0 \fi
+ \fi
+ }%
+ }%
+ \penalty\count255
+ }%
+}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\def\printindex{\parsearg\doprintindex}
+\def\doprintindex#1{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \indexfonts \rm
+ \tolerance = 9500
+ \indexbreaks
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ (Index is nonexistent)
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ (Index is empty)
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\rawbackslashxx}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+% Same as \bigskipamount except no shrink.
+% \balancecolumns gets confused if there is any shrink.
+\newskip\initialskipamount \initialskipamount 12pt plus4pt
+
+\def\initial #1{%
+{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+\ifdim\lastskip<\initialskipamount
+\removelastskip \penalty-200 \vskip \initialskipamount\fi
+\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
+
+% This typesets a paragraph consisting of #1, dot leaders, and then #2
+% flush to the right margin. It is used for index and table of contents
+% entries. The paragraph is indented by \leftskip.
+%
+\def\entry #1#2{\begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent=2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % Start a ``paragraph'' for the index entry so the line breaking
+ % parameters we've set above will have an effect.
+ \noindent
+ %
+ % Insert the text of the index entry. TeX will do line-breaking on it.
+ #1%
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#2}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd\ \else%
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ #2% The page number ends the paragraph.
+ \fi%
+ \par
+\endgroup}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+
+\def\secondary #1#2{
+{\parfillskip=0in \parskip=0in
+\hangindent =1in \hangafter=1
+\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {\global\setbox\partialpage = \vbox{%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case, we must prevent the second \partialpage from
+ % simply overwriting the first, causing us to lose the page.
+ % This will preserve it until a real output routine can ship it
+ % out. Generally, \partialpage will be empty when this runs and
+ % this will be a no-op.
+ \unvbox\partialpage
+ %
+ % Unvbox the main output page.
+ \unvbox255
+ \kern-\topskip \kern\baselineskip
+ }}%
+ \eject
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+\def\pagesofar{%
+ % Re-output the contents of the output page -- any previous material,
+ % followed by the two boxes we just split.
+ \unvbox\partialpage
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}%
+}
+\def\enddoublecolumns{%
+ \output = {\balancecolumns}\eject % split what we have
+ \endgroup % started in \begindoublecolumns
+ %
+ % Back to normal single-column typesetting, but take account of the
+ % fact that we just accumulated some stuff on the output page.
+ \pagegoal = \vsize
+}
+\def\balancecolumns{%
+ % Called at the end of the double column material.
+ \setbox0 = \vbox{\unvbox255}%
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {\vbadness=10000 \loop
+ \global\setbox3=\copy0
+ \global\setbox1=\vsplit3 to\dimen@
+ \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt
+ \repeat}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Define chapters, sections, etc.
+
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+\def\appendixletter{\char\the\appendixno}
+
+\newwrite\contentsfile
+% This is called from \setfilename.
+\def\opencontents{\openout\contentsfile = \jobname.toc }
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise
+
+\def\thischapter{} \def\thissection{}
+\def\seccheck#1{\ifnum \pageno<0
+ \errmessage{@#1 not allowed after generating table of contents}%
+\fi}
+
+\def\chapternofonts{%
+ \let\rawbackslash=\relax
+ \let\frenchspacing=\relax
+ \def\result{\realbackslash result}%
+ \def\equiv{\realbackslash equiv}%
+ \def\expansion{\realbackslash expansion}%
+ \def\print{\realbackslash print}%
+ \def\TeX{\realbackslash TeX}%
+ \def\dots{\realbackslash dots}%
+ \def\result{\realbackslash result}%
+ \def\equiv{\realbackslash equiv}%
+ \def\expansion{\realbackslash expansion}%
+ \def\print{\realbackslash print}%
+ \def\error{\realbackslash error}%
+ \def\point{\realbackslash point}%
+ \def\copyright{\realbackslash copyright}%
+ \def\tt{\realbackslash tt}%
+ \def\bf{\realbackslash bf}%
+ \def\w{\realbackslash w}%
+ \def\less{\realbackslash less}%
+ \def\gtr{\realbackslash gtr}%
+ \def\hat{\realbackslash hat}%
+ \def\char{\realbackslash char}%
+ \def\tclose##1{\realbackslash tclose{##1}}%
+ \def\code##1{\realbackslash code{##1}}%
+ \def\samp##1{\realbackslash samp{##1}}%
+ \def\r##1{\realbackslash r{##1}}%
+ \def\b##1{\realbackslash b{##1}}%
+ \def\key##1{\realbackslash key{##1}}%
+ \def\file##1{\realbackslash file{##1}}%
+ \def\kbd##1{\realbackslash kbd{##1}}%
+ % These are redefined because @smartitalic wouldn't work inside xdef.
+ \def\i##1{\realbackslash i{##1}}%
+ \def\cite##1{\realbackslash cite{##1}}%
+ \def\var##1{\realbackslash var{##1}}%
+ \def\emph##1{\realbackslash emph{##1}}%
+ \def\dfn##1{\realbackslash dfn{##1}}%
+}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raise/lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% Choose a numbered-heading macro
+% #1 is heading level if unmodified by @raisesections or @lowersections
+% #2 is text for heading
+\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \chapterzzz{#2}
+\or
+ \seczzz{#2}
+\or
+ \numberedsubseczzz{#2}
+\or
+ \numberedsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \chapterzzz{#2}
+ \else
+ \numberedsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+% like \numhead, but chooses appendix heading levels
+\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \appendixzzz{#2}
+\or
+ \appendixsectionzzz{#2}
+\or
+ \appendixsubseczzz{#2}
+\or
+ \appendixsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \appendixzzz{#2}
+ \else
+ \appendixsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+% like \numhead, but chooses numberless heading levels
+\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \unnumberedzzz{#2}
+\or
+ \unnumberedseczzz{#2}
+\or
+ \unnumberedsubseczzz{#2}
+\or
+ \unnumberedsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \unnumberedzzz{#2}
+ \else
+ \unnumberedsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+
+\def\thischaptername{No Chapter Title}
+\outer\def\chapter{\parsearg\chapteryyy}
+\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz #1{\seccheck{chapter}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \chapno by 1 \message{\putwordChapter \the\chapno}%
+\chapmacro {#1}{\the\chapno}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+% We don't substitute the actual chapter name into \thischapter
+% because we don't want its macros evaluated now.
+\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash chapentry{\the\toks0}{\the\chapno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\donoderef %
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+}}
+
+\outer\def\appendix{\parsearg\appendixyyy}
+\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz #1{\seccheck{appendix}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \appendixno by 1 \message{Appendix \appendixletter}%
+\chapmacro {#1}{\putwordAppendix{} \appendixletter}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash chapentry{\the\toks0}%
+ {\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\appendixnoderef %
+\global\let\section = \appendixsec
+\global\let\subsection = \appendixsubsec
+\global\let\subsubsection = \appendixsubsubsec
+}}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\def\centerchap{\parsearg\centerchapyyy}
+\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}}
+
+\outer\def\top{\parsearg\unnumberedyyy}
+\outer\def\unnumbered{\parsearg\unnumberedyyy}
+\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz #1{\seccheck{unnumbered}%
+\secno=0 \subsecno=0 \subsubsecno=0
+%
+% This used to be simply \message{#1}, but TeX fully expands the
+% argument to \message. Therefore, if #1 contained @-commands, TeX
+% expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+% expanded @cite (which turns out to cause errors because \cite is meant
+% to be executed, not expanded).
+%
+% Anyway, we don't want the fully-expanded definition of @cite to appear
+% as a result of the \message, we just want `@cite' itself. We use
+% \the<toks register> to achieve this: TeX expands \the<toks> only once,
+% simply yielding the contents of the <toks register>.
+\toks0 = {#1}\message{(\the\toks0)}%
+%
+\unnumbchapmacro {#1}%
+\gdef\thischapter{#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash unnumbchapentry{\the\toks0}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\unnumbnoderef %
+\global\let\section = \unnumberedsec
+\global\let\subsection = \unnumberedsubsec
+\global\let\subsubsection = \unnumberedsubsubsec
+}}
+
+\outer\def\numberedsec{\parsearg\secyyy}
+\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
+\def\seczzz #1{\seccheck{section}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash secentry %
+{\the\toks0}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsection{\parsearg\appendixsecyyy}
+\outer\def\appendixsec{\parsearg\appendixsecyyy}
+\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz #1{\seccheck{appendixsection}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash secentry %
+{\the\toks0}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
+\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash unnumbsecentry{\the\toks0}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
+\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz #1{\seccheck{subsection}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash subsecentry %
+{\the\toks0}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
+\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz #1{\seccheck{appendixsubsec}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash subsecentry %
+{\the\toks0}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
+\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
+\plainsubsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash unnumbsubsecentry{\the\toks0}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
+\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz #1{\seccheck{subsubsection}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash subsubsecentry{\the\toks0}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
+ {\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
+\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash subsubsecentry{\the\toks0}%
+ {\appendixletter}
+ {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
+\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
+\plainsubsubsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\toks0 = {#1}%
+\edef\temp{{\realbackslash unnumbsubsubsecentry{\the\toks0}{\noexpand\folio}}}%
+\escapechar=`\\%
+\iflinks \write\contentsfile\temp \fi
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+% These are variants which are not "outer", so they can appear in @ifinfo.
+% Actually, they should now be obsolete; ordinary section commands should work.
+\def\infotop{\parsearg\unnumberedzzz}
+\def\infounnumbered{\parsearg\unnumberedzzz}
+\def\infounnumberedsec{\parsearg\unnumberedseczzz}
+\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
+\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
+
+\def\infoappendix{\parsearg\appendixzzz}
+\def\infoappendixsec{\parsearg\appendixseczzz}
+\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
+\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
+
+\def\infochapter{\parsearg\chapterzzz}
+\def\infosection{\parsearg\sectionzzz}
+\def\infosubsection{\parsearg\subsectionzzz}
+\def\infosubsubsection{\parsearg\subsubsectionzzz}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and
+% such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{\parsearg\majorheadingzzz}
+\def\majorheadingzzz #1{%
+{\advance\chapheadingskip by 10pt \chapbreak }%
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 200}
+
+\def\chapheading{\parsearg\chapheadingzzz}
+\def\chapheadingzzz #1{\chapbreak %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 200}
+
+% @heading, @subheading, @subsubheading.
+\def\heading{\parsearg\plainsecheading}
+\def\subheading{\parsearg\plainsubsecheading}
+\def\subsubheading{\parsearg\plainsubsubsecheading}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+\def\CHAPFplain{
+\global\let\chapmacro=\chfplain
+\global\let\unnumbchapmacro=\unnchfplain
+\global\let\centerchapmacro=\centerchfplain}
+
+% Plain chapter opening.
+% #1 is the text, #2 the chapter number or empty if unnumbered.
+\def\chfplain#1#2{%
+ \pchapsepmacro
+ {%
+ \chapfonts \rm
+ \def\chapnum{#2}%
+ \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}%
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent = \wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% Plain opening for unnumbered.
+\def\unnchfplain#1{\chfplain{#1}{}}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerchfplain#1{{%
+ \def\centerparametersmaybe{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+ }%
+ \chfplain{#1}{}%
+}}
+
+\CHAPFplain % The default
+
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rm #1}\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\CHAPFopen{
+\global\let\chapmacro=\chfopen
+\global\let\unnumbchapmacro=\unnchfopen
+\global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}}
+\def\plainsecheading#1{\sectionheading{sec}{}{#1}}
+
+% Subsection titles.
+\newskip \subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}}
+\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}}
+
+% Subsubsection titles.
+\let\subsubsecheadingskip = \subsecheadingskip
+\let\subsubsecheadingbreak = \subsecheadingbreak
+\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
+\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}}
+
+
+% Print any size section title.
+%
+% #1 is the section type (sec/subsec/subsubsec), #2 is the section
+% number (maybe empty), #3 the text.
+\def\sectionheading#1#2#3{%
+ {%
+ \expandafter\advance\csname #1headingskip\endcsname by \parskip
+ \csname #1headingbreak\endcsname
+ }%
+ {%
+ % Switch to the right set of fonts.
+ \csname #1fonts\endcsname \rm
+ %
+ % Only insert the separating space if we have a section number.
+ \def\secnum{#2}%
+ \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}%
+ %
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent = \wd0 % zero if no section number
+ \unhbox0 #3}%
+ }%
+ \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak
+}
+
+
+\message{toc printing,}
+% Finish up the main text and prepare to read what we've written
+% to \contentsfile.
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout \contentsfile
+ \ifnum \pageno>0
+ \pageno = -1 % Request roman numbered pages.
+ \fi
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \unnumbchapmacro{#1}\def\thischapter{}%
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ % We can't do this, because then an actual ^ in a section
+ % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
+ %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+}
+
+
+% Normal (long) toc.
+\outer\def\contents{%
+ \startcontents{\putwordTableofContents}%
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+
+% And just the chapters.
+\outer\def\summarycontents{%
+ \startcontents{\putwordShortContents}%
+ %
+ \let\chapentry = \shortchapentry
+ \let\unnumbchapentry = \shortunnumberedentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\secentry ##1##2##3##4{}
+ \def\unnumbsecentry ##1##2{}
+ \def\subsecentry ##1##2##3##4##5{}
+ \def\unnumbsubsecentry ##1##2{}
+ \def\subsubsecentry ##1##2##3##4##5##6{}
+ \def\unnumbsubsubsecentry ##1##2{}
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+\let\shortcontents = \summarycontents
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapter-level things, for both the long and short contents.
+\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
+
+% See comments in \dochapentry re vbox and related settings
+\def\shortchapentry#1#2#3{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}%
+}
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
+% We could simplify the code here by writing out an \appendixentry
+% command in the toc file for appendices, instead of using \chapentry
+% for both, but it doesn't seem worth it.
+\setbox0 = \hbox{\shortcontrm \putwordAppendix }
+\newdimen\shortappendixwidth \shortappendixwidth = \wd0
+
+\def\shortchaplabel#1{%
+ % We typeset #1 in a box of constant width, regardless of the text of
+ % #1, so the chapter titles will come out aligned.
+ \setbox0 = \hbox{#1}%
+ \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi
+ %
+ % This space should be plenty, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ \advance\dimen0 by 1.1em
+ \hbox to \dimen0{#1\hfil}%
+}
+
+\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
+\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}}
+
+% Sections.
+\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
+\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
+
+% Subsections.
+\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
+\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
+
+% And subsubsections.
+\def\subsubsecentry#1#2#3#4#5#6{%
+ \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
+\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
+
+% This parameter controls the indentation of the various levels.
+\newdimen\tocindent \tocindent = 3pc
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno{#2}}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+% Final typesetting of a toc entry; we use the same \entry macro as for
+% the index entries, but we want to suppress hyphenation here. (We
+% can't do that in the \entry macro, since index entries might consist
+% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
+\def\tocentry#1#2{\begingroup
+ \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
+ % Do not use \turnoffactive in these arguments. Since the toc is
+ % typeset in cmr, so characters such as _ would come out wrong; we
+ % have to do the usual translation tricks.
+ \entry{#1}{#2}%
+\endgroup}
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\let\subsecentryfonts = \textfonts
+\let\subsubsecentryfonts = \textfonts
+
+
+\message{environments,}
+
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+% Furthermore, these definitions must come after we define our fonts.
+\newbox\dblarrowbox \newbox\longdblarrowbox
+\newbox\pushcharbox \newbox\bullbox
+\newbox\equivbox \newbox\errorbox
+
+%{\tentt
+%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
+%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
+%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
+%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
+% Adapted from the manmac format (p.420 of TeXbook)
+%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
+% depth .1ex\hfil}
+%}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% Adapted from the TeXbook's \boxit.
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+
+\global\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+
+% The @error{} command.
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\def\tex{\begingroup
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
+ \catcode `\%=14
+ \catcode 43=12 % plus
+ \catcode`\"=12
+ \catcode`\==12
+ \catcode`\|=12
+ \catcode`\<=12
+ \catcode`\>=12
+ \escapechar=`\\
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\*=\ptexstar
+ \let\t=\ptext
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+\let\Etex=\endgroup}
+
+% Define @lisp ... @endlisp.
+% @lisp does a \begingroup so it can rebind things,
+% including the definition of @endlisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% Make each space character in the input produce a normal interword
+% space in the output. Don't allow a line break at this space, as this
+% is used only in environments like @example, where each line of input
+% should produce a line of output anyway.
+%
+{\obeyspaces %
+\gdef\sepspaces{\obeyspaces\let =\tie}}
+
+% Define \obeyedspace to be our active space, whatever it is. This is
+% for use in \parsearg.
+{\sepspaces%
+\global\let\obeyedspace= }
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip
+%
+\def\aboveenvbreak{{\advance\envskipamount by \parskip
+\endgraf \ifdim\lastskip<\envskipamount
+\removelastskip \penalty-50 \vskip\envskipamount \fi}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\long\def\cartouche{%
+\begingroup
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt %we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+% side, and for 6pt waste from
+% each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \hsize=\cartinner
+ \kern3pt
+ \begingroup
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+\def\Ecartouche{%
+ \endgroup
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+\endgroup
+}}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \inENV % This group ends at the end of the body
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \singlespace
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ % @cartouche defines \nonarrowing to inhibit narrowing
+ % at next level down.
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \let\exdent=\nofillexdent
+ \let\nonarrowing=\relax
+ \fi
+}
+
+% To ending an @example-like environment, we first end the paragraph
+% (via \afterenvbreak's vertical glue), and then the group. That way we
+% keep the zero \parskip that the environments set -- \parskip glue
+% will be inserted at the beginning of the next paragraph in the
+% document, after the environment.
+%
+\def\nonfillfinish{\afterenvbreak\endgroup}%
+
+\def\lisp{\begingroup
+ \nonfillstart
+ \let\Elisp = \nonfillfinish
+ \tt
+ % Make @kbd do something special, if requested.
+ \let\kbdfont\kbdexamplefont
+ \rawbackslash % have \ input char produce \ char from current font
+ \gobble
+}
+
+% Define the \E... control sequence only if we are inside the
+% environment, so the error checking in \end will work.
+%
+% We must call \lisp last in the definition, since it reads the
+% return following the @example (or whatever) command.
+%
+\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp}
+\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
+
+% @smallexample and @smalllisp. This is not used unless the @smallbook
+% command is given. Originally contributed by Pavel@xerox.
+%
+\def\smalllispx{\begingroup
+ \nonfillstart
+ \let\Esmalllisp = \nonfillfinish
+ \let\Esmallexample = \nonfillfinish
+ %
+ % Smaller fonts for small examples.
+ \indexfonts \tt
+ \rawbackslash % make \ output the \ character from the current font (tt)
+ \gobble
+}
+
+% This is @display; same as @lisp except use roman font.
+%
+\def\display{\begingroup
+ \nonfillstart
+ \let\Edisplay = \nonfillfinish
+ \gobble
+}
+
+% This is @format; same as @display except don't narrow margins.
+%
+\def\format{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eformat = \nonfillfinish
+ \gobble
+}
+
+% @flushleft (same as @format) and @flushright.
+%
+\def\flushleft{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushleft = \nonfillfinish
+ \gobble
+}
+\def\flushright{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushright = \nonfillfinish
+ \advance\leftskip by 0pt plus 1fill
+ \gobble}
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.
+%
+\def\quotation{%
+ \begingroup\inENV %This group ends at the end of the @quotation body
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \singlespace
+ \parindent=0pt
+ % We have retained a nonzero parskip for the environment, since we're
+ % doing normal filling. So to avoid extra space below the environment...
+ \def\Equotation{\parskip = 0pt \nonfillfinish}%
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \let\nonarrowing = \relax
+ \fi
+}
+
+\message{defuns,}
+% Define formatter for defuns
+% First, allow user to change definition object font (\df) internally
+\def\setdeffont #1 {\csname DEF#1\endcsname}
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deftypemargin \deftypemargin=12pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+\newcount\parencount
+% define \functionparens, which makes ( and ) and & do special things.
+% \functionparens affects the group it is contained in.
+\def\activeparens{%
+\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active
+\catcode`\[=\active \catcode`\]=\active}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+\global\let(=\lparen \global\let)=\rparen
+\global\let[=\lbrack \global\let]=\rbrack
+
+\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
+\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+% This is used to turn on special parens
+% but make & act ordinary (given that it's active).
+\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr}
+
+% Definitions of (, ) and & used in args for functions.
+% This is the definition of ( outside of all parentheses.
+\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested
+ \global\advance\parencount by 1
+}
+%
+% This is the definition of ( when already inside a level of parens.
+\gdef\opnested{\char`\(\global\advance\parencount by 1 }
+%
+\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
+ % also in that case restore the outer-level definition of (.
+ \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
+ \global\advance \parencount by -1 }
+% If we encounter &foo, then turn on ()-hacking afterwards
+\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
+%
+\gdef\normalparens{\boldbrax\let&=\ampnr}
+} % End of definition inside \activeparens
+%% These parens (in \boldbrax) actually are a little bolder than the
+%% contained text. This is especially needed for [ and ]
+\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 }
+\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 }
+\def\ampnr{\&}
+\def\lbrb{{\bf\char`\[}}
+\def\rbrb{{\bf\char`\]}}
+
+% First, defname, which formats the header line itself.
+% #1 should be the function name.
+% #2 should be the type of definition, such as "Function".
+
+\def\defname #1#2{%
+% Get the values of \leftskip and \rightskip as they were
+% outside the @def...
+\dimen2=\leftskip
+\advance\dimen2 by -\defbodyindent
+\dimen3=\rightskip
+\advance\dimen3 by -\defbodyindent
+\noindent %
+\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}%
+\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
+\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations
+\parshape 2 0in \dimen0 \defargsindent \dimen1 %
+% Now output arg 2 ("Function" or some such)
+% ending at \deftypemargin from the right margin,
+% but stuck inside a box of width 0 so it does not interfere with linebreaking
+{% Adjust \hsize to exclude the ambient margins,
+% so that \rightline will obey them.
+\advance \hsize by -\dimen2 \advance \hsize by -\dimen3
+\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}%
+% Make all lines underfull and no complaints:
+\tolerance=10000 \hbadness=10000
+\advance\leftskip by -\defbodyindent
+\exdentamount=\defbodyindent
+{\df #1}\enskip % Generate function name
+}
+
+% Actually process the body of a definition
+% #1 should be the terminating control sequence, such as \Edefun.
+% #2 should be the "another name" control sequence, such as \defunx.
+% #3 should be the control sequence that actually processes the header,
+% such as \defunheader.
+
+\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active % 61 is `='
+\obeylines\activeparens\spacesplit#3}
+
+% #1 is the \E... control sequence to end the definition (which we define).
+% #2 is the \...x control sequence for consecutive fns (which we define).
+% #3 is the control sequence to call to resume processing.
+% #4, delimited by the space, is the class name.
+%
+\def\defmethparsebody#1#2#3#4 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
+
+% @deftypemethod has an extra argument that nothing else does. Sigh.
+% #1 is the \E... control sequence to end the definition (which we define).
+% #2 is the \...x control sequence for consecutive fns (which we define).
+% #3 is the control sequence to call to resume processing.
+% #4, delimited by the space, is the class name.
+% #5 is the method's return type.
+%
+\def\deftypemethparsebody#1#2#3#4 #5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#4}{#5}}}
+
+\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
+
+% These parsing functions are similar to the preceding ones
+% except that they do not make parens into active characters.
+% These are used for "variables" since they have no arguments.
+
+\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active %
+\obeylines\spacesplit#3}
+
+% This is used for \def{tp,vr}parsebody. It could probably be used for
+% some of the others, too, with some judicious conditionals.
+%
+\def\parsebodycommon#1#2#3{%
+ \begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines
+}
+
+\def\defvrparsebody#1#2#3#4 {%
+ \parsebodycommon{#1}{#2}{#3}%
+ \spacesplit{#3{#4}}%
+}
+
+% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
+% type is just `struct', because we lose the braces in `{struct
+% termios}' when \spacesplit reads its undelimited argument. Sigh.
+% \let\deftpparsebody=\defvrparsebody
+%
+% So, to get around this, we put \empty in with the type name. That
+% way, TeX won't find exactly `{...}' as an undelimited argument, and
+% won't strip off the braces.
+%
+\def\deftpparsebody #1#2#3#4 {%
+ \parsebodycommon{#1}{#2}{#3}%
+ \spacesplit{\parsetpheaderline{#3{#4}}}\empty
+}
+
+% Fine, but then we have to eventually remove the \empty *and* the
+% braces (if any). That's what this does.
+%
+\def\removeemptybraces\empty#1\relax{#1}
+
+% After \spacesplit has done its work, this is called -- #1 is the final
+% thing to call, #2 the type name (which starts with \empty), and #3
+% (which might be empty) the arguments.
+%
+\def\parsetpheaderline#1#2#3{%
+ #1{\removeemptybraces#2\relax}{#3}%
+}%
+
+\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\spacesplit{#3{#5}}}
+
+% Split up #2 at the first space token.
+% call #1 with two arguments:
+% the first is all of #2 before the space token,
+% the second is all of #2 after that space token.
+% If #2 contains no space token, all of it is passed as the first arg
+% and the second is passed as empty.
+
+{\obeylines
+\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}%
+\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{%
+\ifx\relax #3%
+#1{#2}{}\else #1{#2}{#3#4}\fi}}
+
+% So much for the things common to all kinds of definitions.
+
+% Define @defun.
+
+% First, define the processing that is wanted for arguments of \defun
+% Use this to expand the args and terminate the paragraph they make up
+
+\def\defunargs #1{\functionparens \sl
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+\hyphenchar\tensl=0
+#1%
+\hyphenchar\tensl=45
+\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi%
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+\def\deftypefunargs #1{%
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+% Use \boldbraxnoamp, not \functionparens, so that & is not special.
+\boldbraxnoamp
+\tclose{#1}% avoid \code because of side effects on active chars
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+% Do complete processing of one @defun or @defunx line already parsed.
+
+% @deffn Command forward-char nchars
+
+\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
+
+\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defun == @deffn Function
+
+\def\defun{\defparsebody\Edefun\defunx\defunheader}
+
+\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Function}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefun int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
+
+% #1 is the data type. #2 is the name and args.
+\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
+% #1 is the data type, #2 the name, #3 the args.
+\def\deftypefunheaderx #1#2 #3\relax{%
+\doind {fn}{\code{#2}}% Make entry in function index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}%
+\deftypefunargs {#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
+
+% \defheaderxcond#1\relax$$$
+% puts #1 in @code, followed by a space, but does nothing if #1 is null.
+\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi}
+
+% #1 is the classification. #2 is the data type. #3 is the name and args.
+\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
+% #1 is the classification, #2 the data type, #3 the name, #4 the args.
+\def\deftypefnheaderx #1#2#3 #4\relax{%
+\doind {fn}{\code{#3}}% Make entry in function index
+\begingroup
+\normalparens % notably, turn off `&' magic, which prevents
+% at least some C++ text from working
+\defname {\defheaderxcond#2\relax$$$#3}{#1}%
+\deftypefunargs {#4}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defmac == @deffn Macro
+
+\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
+
+\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Macro}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defspec == @deffn Special Form
+
+\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
+
+\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Special Form}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% This definition is run if you use @defunx
+% anywhere other than immediately after a @defun or @defunx.
+
+\def\deffnx #1 {\errmessage{@deffnx in invalid context}}
+\def\defunx #1 {\errmessage{@defunx in invalid context}}
+\def\defmacx #1 {\errmessage{@defmacx in invalid context}}
+\def\defspecx #1 {\errmessage{@defspecx in invalid context}}
+\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}}
+\def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}}
+\def\deftypefunx #1 {\errmessage{@deftypeunx in invalid context}}
+
+% @defmethod, and so on
+
+% @defop CATEGORY CLASS OPERATION ARG...
+
+\def\defop #1 {\def\defoptype{#1}%
+\defopparsebody\Edefop\defopx\defopheader\defoptype}
+
+\def\defopheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{\putwordon\ #1}% Make entry in function index
+\begingroup\defname {#2}{\defoptype{} on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @deftypemethod CLASS RETURN-TYPE METHOD ARG...
+%
+\def\deftypemethod{%
+ \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader}
+%
+% #1 is the class name, #2 the data type, #3 the method name, #4 the args.
+\def\deftypemethodheader#1#2#3#4{%
+ \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index
+ \begingroup
+ \defname{\defheaderxcond#2\relax$$$#3}{\putwordMethodon\ \code{#1}}%
+ \deftypefunargs{#4}%
+ \endgroup
+}
+
+% @defmethod == @defop Method
+%
+\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
+%
+% #1 is the class name, #2 the method name, #3 the args.
+\def\defmethodheader#1#2#3{%
+ \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index
+ \begingroup
+ \defname{#2}{\putwordMethodon\ \code{#1}}%
+ \defunargs{#3}%
+ \endgroup
+}
+
+% @defcv {Class Option} foo-class foo-flag
+
+\def\defcv #1 {\def\defcvtype{#1}%
+\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
+
+\def\defcvarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{\defcvtype{} of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% @defivar == @defcv {Instance Variable}
+
+\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
+
+\def\defivarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{Instance Variable of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% These definitions are run if you use @defmethodx, etc.,
+% anywhere other than immediately after a @defmethod, etc.
+
+\def\defopx #1 {\errmessage{@defopx in invalid context}}
+\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}}
+\def\defcvx #1 {\errmessage{@defcvx in invalid context}}
+\def\defivarx #1 {\errmessage{@defivarx in invalid context}}
+
+% Now @defvar
+
+% First, define the processing that is wanted for arguments of @defvar.
+% This is actually simple: just print them in roman.
+% This must expand the args and terminate the paragraph they make up
+\def\defvarargs #1{\normalparens #1%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000}
+
+% @defvr Counter foo-count
+
+\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
+
+\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
+
+% @defvar == @defvr Variable
+
+\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
+
+\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{Variable}%
+\defvarargs {#2}\endgroup %
+}
+
+% @defopt == @defvr {User Option}
+
+\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
+
+\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{User Option}%
+\defvarargs {#2}\endgroup %
+}
+
+% @deftypevar int foobar
+
+\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
+
+% #1 is the data type. #2 is the name, perhaps followed by text that
+% is actually part of the data type, which should not be put into the index.
+\def\deftypevarheader #1#2{%
+\dovarind#2 \relax% Make entry in variables index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}}
+
+% @deftypevr {Global Flag} int enable
+
+\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
+
+\def\deftypevrheader #1#2#3{\dovarind#3 \relax%
+\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% This definition is run if you use @defvarx
+% anywhere other than immediately after a @defvar or @defvarx.
+
+\def\defvrx #1 {\errmessage{@defvrx in invalid context}}
+\def\defvarx #1 {\errmessage{@defvarx in invalid context}}
+\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
+\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}}
+\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}}
+
+% Now define @deftp
+% Args are printed in bold, a slight difference from @defvar.
+
+\def\deftpargs #1{\bf \defvarargs{#1}}
+
+% @deftp Class window height width ...
+
+\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
+
+\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
+\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
+
+% This definition is run if you use @deftpx, etc
+% anywhere other than immediately after a @deftp, etc.
+
+\def\deftpx #1 {\errmessage{@deftpx in invalid context}}
+
+
+\message{macros,}
+% @macro.
+% The basic scheme is as follows:
+% We read the first line and split it up into macro name and parameter
+% list. We then walk the parameter list defining control sequences
+% named \MAC@<macro name><parameter name>. Each expands to another
+% control sequence named \MAC@<macro name>.<parameter number>. Those
+% control sequences will be defined at macro runtime to be the
+% parameter expansion text.
+%
+% The body is then read in as a single argument in a context where \
+% is an active character, and the cs \MACb.<macro name> is defined as
+% the macro body. The active character \ takes one argument delimited
+% by another \, and uses it to index the table of macro arguments
+% described above.
+%
+% Finally, we define a control sequence \<macro name> which calls one
+% of the six (!) macro execution commands. These six commands
+% correspond to recursive and nonrecursive macros with no, one, and
+% many arguments. They all take one argument, <macro name>, set up
+% the environment appropriately, and call the real macro.
+%
+% \macsave@<macro name> holds the old definition of \<macro name>.
+
+\newcount\paramno
+\newtoks\macname
+
+% This does \let #1 = #2, except with \csnames.
+\def\cslet#1#2{%
+\expandafter\expandafter\expandafter
+\let
+\expandafter\expandafter
+\csname#1\endcsname
+\csname#2\endcsname}
+
+% We have to play lots of games with the catcodes. Initially { and }
+% are made `other' so that \splitarg (below) can use them as argument
+% delimiters. Then - is made a letter so that \iimacro can recognize
+% @allow-recursion.
+\def\macro{\bgroup\catcode`\{=\other\catcode`\}=\other\parsearg\imacro}
+\def\imacro#1{\egroup % started in \macro
+ \splitarg{#1}% now \macname is the macname and \toks0 the arglist
+ \paramno=0%
+ \edef\tmp{\the\toks0}%
+ \ifx\tmp\empty % no arguments
+ \else
+ \expandafter\parsemargdef \the\toks0;%
+ \fi
+ \bgroup\catcode`\-=11\global\futurelet\nxt\iimacro}
+
+% \imacro has noted whether the macro takes one, two, or many
+% arguments (in \paramno). \iimacro figures out whether it's
+% recursive, and then uses the argument count and the recursivity to
+% select one of the six macro execution sequences. Then we save the
+% original definition of @foo in \macsave@foo, and define @foo to call
+% the selected execution sequence. \edef conveniently just expands
+% the token registers, not the deep structure.
+\def\iimacro{%
+ \egroup % started in \imacro
+ \ifx\nxt\allowrecur
+ \let\next\parserbody
+ \toks0=\expandafter{\csname dormacro\ifcase\paramno na\or oa\fi\endcsname}%
+ \else
+ \let\next\parsebody
+ \toks0=\expandafter{\csname domacro\ifcase\paramno na\or oa\fi\endcsname}%
+ \fi
+ \expandafter\ifx \csname macsave@\the\macname\endcsname \relax
+ \cslet{macsave@\the\macname}{\the\macname}%
+ \else
+ \errmessage{warning: redefining macro \the\macname}%
+ \fi
+ \expandafter\edef\csname\the\macname\endcsname{\the\toks0{\the\macname}}%
+\next}
+
+% @allow-recursion is noticed and handled by \iimacro. It should
+% never actually be executed. It has two names so we don't need
+% strange catcodes while defining \iimacro.
+\def\allowrecur{\errmessage{Internal error: \noexpand\allowrecur executed}}
+{\catcode`\-=11\global\let\allow-recursion\allowrecur}
+
+% unmacro just restores the old meaning; the MAC@<macname> macros
+% remain defined. (Memory leak!) \norecurse is defined below, near
+% the execution commands.
+\def\unmacro{\parsearg\iunmacro}
+\def\iunmacro#1{\macname={#1} \norecurse}
+
+% We need {} to be ordinary inside these commands. [] are temporary
+% grouping symbols.
+\begingroup
+\catcode`\{=\other \catcode`\}=\other
+\catcode`\[=1 \catcode`\]=2
+
+% @macro can be called with or without a brace-surrounded macro
+% argument list. These three sequences extract the macro name and arg
+% list in hopefully all cases. *Note, anything on the line after the
+% first pair of braces will be thrown out.
+\gdef\splitarg#1[\isplitarg|#1 {}|]
+\gdef\isplitarg|#1 {#2}#3|[%
+ \toks0=[#2]%
+ \edef\tmp[\the\toks0]%
+ \ifx\tmp\empty
+ \isplitargnospaces|#1{}|%
+ \else
+ \macname=[#1]%
+ \fi]
+\gdef\isplitargnospaces|#1{#2}#3|[\macname=[#1] \toks0=[#2]]
+
+% \parsebrace gets around the situation produced by \braceorline
+% (below) where the { has the wrong catcode because of \futurelet.
+% The \egroup matches a \bgroup in \braceorline.
+\gdef\parsebrace#1{#2}[\egroup\let\next=#1\next[#2]]
+
+\global\let\brace={ % used by \braceorline, below
+
+\endgroup
+
+
+% Argument parsing.
+% These routines iterate over a comma-separated list defining
+% tokens that map macro formal to actual parameters.
+% \parsemargdef sets the formal -> positional correspondence at macro
+% definition time; \parsemarg sets positional -> actual at runtime.
+%
+% The definitions are not symmetric because the callers have the
+% argument list in different places (token register and #arg)
+\def\parsemargdef#1;{\paramno=0\iparsemargdef#1,;,}
+\def\iparsemargdef#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\iparsemargdef
+ \advance\paramno by 1%
+ \expandafter\edef\csname MAC@\the\macname#1\endcsname
+ {\csname MAC@\the\macname.\the\paramno\endcsname}%
+ \fi\next}
+
+\def\parsemarg#1{\paramno=1\iparsemarg#1,;,}
+\def\iparsemarg#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\iparsemarg
+ \expandafter\def\csname MAC@\the\macname.\the\paramno\endcsname{#1}%
+ \advance\paramno by 1%
+ \fi\next}
+
+% Argument substitution.
+% \ is active when the body is read and tokenized; it converts its
+% argument to a macro-argument name and expands it. We use | as a
+% temporary escape character.
+{
+\catcode`\|=0 |catcode`|\=|active
+|gdef\#1\{|csname MAC@|the|macname#1|endcsname}
+}
+
+% These sequences read and save the macro body. \parserbody absorbs
+% the @allow-recursion in its argument, and then falls through to
+% \parsebody.
+\def\parsebody{\begingroup\catcode`\\=\active\iparsebody}
+\def\parserbody#1{\parsebody}
+
+% \iparsebody reads the entire macro in as an argument. \ was made
+% active by \parsebody while the reading occurs.
+\long\def\iparsebody#1 \end macro% The space eats the final CR.
+{\endgroup % started in \parsebody
+\expandafter\def\csname MACb.\the\macname \endcsname{#1}}
+
+% These six sequences execute recursive and nonrecursive macros of no,
+% one, and many arguments. We need to distinguish one arg from many
+% args because a one-argument macro invoked with no arguments gets the
+% rest of the line as its argument.
+%
+% Please note that all macros are executed inside a group, so any
+% changes made by a macro (@set, etc.) won't stick.
+\def\dormacrona#1{\begingroup\macname={#1}\idomacro{}}
+\def\dormacrooa#1{\begingroup\macname={#1}\braceorline}
+\def\dormacro#1{\begingroup\macname={#1}\idomacro}
+
+\def\domacrona#1{\begingroup\macname={#1}\norecurse\idomacro{}}
+\def\domacrooa#1{\begingroup\macname={#1}\norecurse\braceorline}
+\def\domacro#1{\begingroup\macname={#1}\norecurse\idomacro}
+
+% some helpers:
+\def\norecurse{\cslet{\the\macname}{macsave@\the\macname}}
+\def\idomacro#1{\parsemarg{#1}\csname MACb.\the\macname\endcsname\endgroup}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to \idomacro. \parsebrace is
+% defined above, near \splitarg, in a strange catcode environment;
+% this is necessary because \futurelet freezes the catcode of the
+% peeked-at character.
+\def\braceorline{\bgroup
+\catcode`\{=\other\catcode`\}=\other \futurelet\nxt\ibraceorline}
+\def\ibraceorline{%
+\ifx\nxt\brace
+ \expandafter\parsebrace
+ \else
+ \egroup \expandafter\parsearg
+ \fi \idomacro}
+
+
+\message{cross references,}
+\newwrite\auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @setref{foo} defines a cross-reference point named foo.
+
+\def\setref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ysectionnumberandtype}}
+
+\def\unnumbsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ynothing}}
+
+\def\appendixsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Yappendixletterandtype}}
+
+% \xref, \pxref, and \ref generate cross-references to specified points.
+% For \xrefX, #1 is the node name, #2 the name of the Info
+% cross-reference, #3 the printed node name, #4 the name of the Info
+% file, #5 the name of the printed manual. All but the node name can be
+% omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printednodename{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual}%
+ \setbox0=\hbox{\printednodename}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+ % Use the node name inside the square brackets.
+ \def\printednodename{\ignorespaces #1}%
+ \else
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1>0pt%
+ % It is in another manual, so we don't have it.
+ \def\printednodename{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printednodename{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printednodename{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printednodename'' in \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\normalturnoffactive \refx{#1-snt}{}}%
+ \space [\printednodename],\space
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+\endgroup}
+
+% \dosetq is the interface for calls from other macros
+
+% Use \normalturnoffactive so that punctuation chars such as underscore
+% and backslash work in node names. (\turnoffactive doesn't do \.)
+\def\dosetq#1#2{%
+ {\let\folio=0
+ \normalturnoffactive
+ \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}%
+ \iflinks
+ \next
+ \fi
+ }%
+}
+
+% \internalsetq {foo}{page} expands into
+% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...}
+% When the aux file is read, ' is the escape character
+
+\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}}
+
+% Things to be expanded by \internalsetq
+
+\def\Ypagenumber{\folio}
+
+\def\Ytitle{\thissection}
+
+\def\Ynothing{}
+
+\def\Ysectionnumberandtype{%
+\ifnum\secno=0 \putwordChapter\xreftie\the\chapno %
+\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\def\Yappendixletterandtype{%
+\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}%
+\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\gdef\xreftie{'tie}
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Non-3.0.
+\else
+ \def\linenumber{\the\inputlineno:\space}
+\fi
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+
+\def\refx#1#2{%
+ \expandafter\ifx\csname X#1\endcsname\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \csname X#1\endcsname
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.
+%
+\def\xrdef#1{\begingroup
+ % Reenable \ as an escape while reading the second argument.
+ \catcode`\\ = 0
+ \afterassignment\endgroup
+ \expandafter\gdef\csname X#1\endcsname
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+\def\readauxfile{\begingroup
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ % It was suggested to define this as 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ % Make the characters 128-255 be printing characters
+ {%
+ \count 1=128
+ \def\loop{%
+ \catcode\count 1=\other
+ \advance\count 1 by 1
+ \ifnum \count 1<256 \loop \fi
+ }%
+ }%
+ % The aux file uses ' as the escape (for now).
+ % Turn off \ as an escape so we do not lose on
+ % entries which were dumped with control sequences in their names.
+ % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
+ % Reference to such entries still does not work the way one would wish,
+ % but at least they do not bomb out when the aux file is read in.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\%=\other
+ \catcode`\'=0
+ \catcode`\\=\other
+ %
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \closein 1
+ \input \jobname.aux
+ \global\havexrefstrue
+ \global\warnedobstrue
+ \fi
+ % Open the new aux file. TeX will close it automatically at exit.
+ \openout\auxfile=\jobname.aux
+\endgroup}
+
+
+% Footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+\let\ptexfootnote=\footnote
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \footnotezzz
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset and anything else that uses
+% \parseargline fail inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\long\gdef\footnotezzz{\insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ % Hang the footnote text off the number.
+ \hang
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ \futurelet\next\fo@t
+}
+\def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t
+ \else\let\next\f@t\fi \next}
+\def\f@@t{\bgroup\aftergroup\@foot\let\next}
+\def\f@t#1{#1\@foot}
+\def\@foot{\strut\egroup}
+
+}%end \catcode `\@=11
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ \closein 1
+ % Do not bother showing banner with post-v2.7 epsf.tex (available in
+ % doc/epsf.tex until it shows up on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+%
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://ftp.tug.org/tex/epsf.tex.}
+%
+% Only complain once about lack of epsf.tex.
+\def\image#1{%
+ \ifx\epsfbox\undefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is just the usual extra ignored arg for parsing this stuff.
+\def\imagexxx#1,#2,#3,#4\finish{%
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ % If the image is by itself, center it.
+ \ifvmode
+ \centerline{\epsfbox{#1.eps}}%
+ \else
+ \epsfbox{#1.eps}%
+ \fi
+}
+
+% End of control word definitions.
+
+
+\message{and turning on texinfo input format.}
+
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% Set some numeric style parameters, for 8.5 x 11 format.
+
+\hsize = 6in
+\hoffset = .25in
+\newdimen\defaultparindent \defaultparindent = 15pt
+\parindent = \defaultparindent
+\parskip 3pt plus 2pt minus 1pt
+\setleading{13.2pt}
+\advance\topskip by 1.2cm
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness=10000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. This makes it come to about 9pt for the 8.5x11 format.
+%
+\ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+\else
+ \emergencystretch = \hsize
+ \divide\emergencystretch by 45
+\fi
+
+% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25)
+\def\smallbook{
+ \global\chapheadingskip = 15pt plus 4pt minus 2pt
+ \global\secheadingskip = 12pt plus 3pt minus 2pt
+ \global\subsecheadingskip = 9pt plus 2pt minus 2pt
+ %
+ \global\lispnarrowing = 0.3in
+ \setleading{12pt}
+ \advance\topskip by -1cm
+ \global\parskip 2pt plus 1pt
+ \global\hsize = 5in
+ \global\vsize=7.5in
+ \global\tolerance=700
+ \global\hfuzz=1pt
+ \global\contentsrightmargin=0pt
+ \global\deftypemargin=0pt
+ \global\defbodyindent=.5cm
+ %
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ %
+ \global\let\smalllisp=\smalllispx
+ \global\let\smallexample=\smalllispx
+ \global\def\Esmallexample{\Esmalllisp}
+}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{
+\global\tolerance=700
+\global\hfuzz=1pt
+\setleading{12pt}
+\global\parskip 15pt plus 1pt
+
+\global\vsize= 53\baselineskip
+\advance\vsize by \topskip
+%\global\hsize= 5.85in % A4 wide 10pt
+\global\hsize= 6.5in
+\global\outerhsize=\hsize
+\global\advance\outerhsize by 0.5in
+\global\outervsize=\vsize
+\global\advance\outervsize by 0.6in
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+}
+
+\bindingoffset=0pt
+\normaloffset=\hoffset
+\pagewidth=\hsize
+\pageheight=\vsize
+
+% Allow control of the text dimensions. Parameters in order: textheight;
+% textwidth; voffset; hoffset; binding offset; topskip.
+% All require a dimension;
+% header is additional; added length extends the bottom of the page.
+
+\def\changepagesizes#1#2#3#4#5#6{
+ \global\vsize= #1
+ \global\topskip= #6
+ \advance\vsize by \topskip
+ \global\voffset= #3
+ \global\hsize= #2
+ \global\outerhsize=\hsize
+ \global\advance\outerhsize by 0.5in
+ \global\outervsize=\vsize
+ \global\advance\outervsize by 0.6in
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ \global\normaloffset= #4
+ \global\bindingoffset= #5}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin
+% 29mm, hence bottom margin 28mm, nominal side margin 3cm.
+\def\afourlatex
+ {\global\tolerance=700
+ \global\hfuzz=1pt
+ \setleading{12pt}
+ \global\parskip 15pt plus 1pt
+ \advance\baselineskip by 1.6pt
+ \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}
+ }
+
+% Use @afourwide to print on European A4 paper in wide format.
+\def\afourwide{\afourpaper
+\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+
+% This macro is used to make a character print one way in ttfont
+% where it can probably just be output, and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}}
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+%\catcode 27=\active
+%\def^^[{$\diamondsuit$}
+
+% Set up an active definition for =, but don't enable it most of the time.
+{\catcode`\==\active
+\global\def={{\tt \char 61}}}
+
+\catcode`+=\active
+\catcode`\_=\active
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \rawbackslashxx output one backslash character in current font
+\global\chardef\rawbackslashxx=`\\
+%{\catcode`\\=\other
+%@gdef@rawbackslashxx{\}}
+
+% \rawbackslash redefines \ as input to do \rawbackslashxx.
+{\catcode`\\=\active
+@gdef@rawbackslash{@let\=@rawbackslashxx }}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\rawbackslashxx}}
+
+% Say @foo, not \foo, in error messages.
+\escapechar=`\@
+
+% \catcode 17=0 % Define control-q
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{@let"=@normaldoublequote
+@let\=@realbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+@def@normalturnoffactive{@let"=@normaldoublequote
+@let\=@normalbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also back turn on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active @catcode`@_=@active}
+
+% These look ok in all fonts, so just make them not special. The @rm below
+% makes sure that the current font starts out as the newly loaded cmr10
+@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
+
+@textfonts
+@rm
+
+@c Local variables:
+@c page-delimiter: "^\\\\message"
+@c End:
diff --git a/doc/version.texi b/doc/version.texi
new file mode 100644
index 0000000..4e5b91a
--- /dev/null
+++ b/doc/version.texi
@@ -0,0 +1,3 @@
+@set UPDATED 6 May 2000
+@set EDITION 0.10.36
+@set VERSION 0.10.36