jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:
jpayne@68:[ << ] | jpayne@68:[ >> ] | jpayne@68:jpayne@68: | jpayne@68: | jpayne@68: | jpayne@68: | jpayne@68: | [Top] | jpayne@68:[Contents] | jpayne@68:[Index] | jpayne@68:[ ? ] | jpayne@68:
For those of you being jpayne@68: the lucky users of Emacs, PO mode has been specifically created jpayne@68: for providing a cozy environment for editing or modifying PO files. jpayne@68: While editing a PO file, PO mode allows for the easy browsing of jpayne@68: auxiliary and compendium PO files, as well as for following references into jpayne@68: the set of C program sources from which PO files have been derived. jpayne@68: It has a few special features, among which are the interactive marking jpayne@68: of program strings as translatable, and the validation of PO files jpayne@68: with easy repositioning to PO file lines showing errors. jpayne@68:
jpayne@68:For the beginning, besides main PO mode commands jpayne@68: (see section Main PO mode Commands), you should know how to move between entries jpayne@68: (see section Entry Positioning), and how to handle untranslated entries jpayne@68: (see section Untranslated Entries). jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:gettext
Installation Once you have received, unpacked, configured and compiled the GNU
jpayne@68: gettext
distribution, the ‘make install’ command puts in
jpayne@68: place the programs xgettext
, msgfmt
, gettext
, and
jpayne@68: msgmerge
, as well as their available message catalogs. To
jpayne@68: top off a comfortable installation, you might also want to make the
jpayne@68: PO mode available to your Emacs users.
jpayne@68:
During the installation of the PO mode, you might want to modify your jpayne@68: file ‘.emacs’, once and for all, so it contains a few lines looking jpayne@68: like: jpayne@68:
jpayne@68:(setq auto-mode-alist jpayne@68: (cons '("\\.po\\'\\|\\.po\\." . po-mode) auto-mode-alist)) jpayne@68: (autoload 'po-mode "po-mode" "Major mode for translators to edit PO files" t) jpayne@68: |
Later, whenever you edit some ‘.po’ jpayne@68: file, or any file having the string ‘.po.’ within its name, jpayne@68: Emacs loads ‘po-mode.elc’ (or ‘po-mode.el’) as needed, and jpayne@68: automatically activates PO mode commands for the associated buffer. jpayne@68: The string PO appears in the mode line for any buffer for jpayne@68: which PO mode is active. Many PO files may be active at once in a jpayne@68: single Emacs session. jpayne@68:
jpayne@68:If you are using Emacs version 20 or newer, and have already installed jpayne@68: the appropriate international fonts on your system, you may also tell jpayne@68: Emacs how to determine automatically the coding system of every PO file. jpayne@68: This will often (but not always) cause the necessary fonts to be loaded jpayne@68: and used for displaying the translations on your Emacs screen. For this jpayne@68: to happen, add the lines: jpayne@68:
jpayne@68:(modify-coding-system-alist 'file "\\.po\\'\\|\\.po\\." jpayne@68: 'po-find-file-coding-system) jpayne@68: (autoload 'po-find-file-coding-system "po-mode") jpayne@68: |
to your ‘.emacs’ file. If, with this, you still see boxes instead jpayne@68: of international characters, try a different font set (via Shift Mouse jpayne@68: button 1). jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:After setting up Emacs with something similar to the lines in
jpayne@68: Completing GNU gettext
Installation, PO mode is activated for a window when Emacs finds a
jpayne@68: PO file in that window. This puts the window read-only and establishes a
jpayne@68: po-mode-map, which is a genuine Emacs mode, in a way that is not derived
jpayne@68: from text mode in any way. Functions found on po-mode-hook
,
jpayne@68: if any, will be executed.
jpayne@68:
When PO mode is active in a window, the letters ‘PO’ appear jpayne@68: in the mode line for that window. The mode line also displays how jpayne@68: many entries of each kind are held in the PO file. For example, jpayne@68: the string ‘132t+3f+10u+2o’ would tell the translator that the jpayne@68: PO mode contains 132 translated entries (see section Translated Entries, jpayne@68: 3 fuzzy entries (see section Fuzzy Entries), 10 untranslated entries jpayne@68: (see section Untranslated Entries) and 2 obsolete entries (see section Obsolete Entries). Zero-coefficients items are not shown. So, in this example, if jpayne@68: the fuzzy entries were unfuzzied, the untranslated entries were translated jpayne@68: and the obsolete entries were deleted, the mode line would merely display jpayne@68: ‘145t’ for the counters. jpayne@68:
jpayne@68:The main PO commands are those which do not fit into the other categories of jpayne@68: subsequent sections. These allow for quitting PO mode or for managing windows jpayne@68: in special ways. jpayne@68:
jpayne@68:Undo last modification to the PO file (po-undo
).
jpayne@68:
Quit processing and save the PO file (po-quit
).
jpayne@68:
Quit processing, possibly after confirmation (po-confirm-and-quit
).
jpayne@68:
Temporary leave the PO file window (po-other-window
).
jpayne@68:
Show help about PO mode (po-help
).
jpayne@68:
Give some PO file statistics (po-statistics
).
jpayne@68:
Batch validate the format of the whole PO file (po-validate
).
jpayne@68:
The command _ (po-undo
) interfaces to the Emacs
jpayne@68: undo facility. See (emacs)Undo section `Undoing Changes' in The Emacs Editor. Each time _ is typed, modifications which the translator
jpayne@68: did to the PO file are undone a little more. For the purpose of
jpayne@68: undoing, each PO mode command is atomic. This is especially true for
jpayne@68: the <RET> command: the whole edition made by using a single
jpayne@68: use of this command is undone at once, even if the edition itself
jpayne@68: implied several actions. However, while in the editing window, one
jpayne@68: can undo the edition work quite parsimoniously.
jpayne@68:
The commands Q (po-quit
) and q
jpayne@68: (po-confirm-and-quit
) are used when the translator is done with the
jpayne@68: PO file. The former is a bit less verbose than the latter. If the file
jpayne@68: has been modified, it is saved to disk first. In both cases, and prior to
jpayne@68: all this, the commands check if any untranslated messages remain in the
jpayne@68: PO file and, if so, the translator is asked if she really wants to leave
jpayne@68: off working with this PO file. This is the preferred way of getting rid
jpayne@68: of an Emacs PO file buffer. Merely killing it through the usual command
jpayne@68: C-x k (kill-buffer
) is not the tidiest way to proceed.
jpayne@68:
The command 0 (po-other-window
) is another, softer way,
jpayne@68: to leave PO mode, temporarily. It just moves the cursor to some other
jpayne@68: Emacs window, and pops one if necessary. For example, if the translator
jpayne@68: just got PO mode to show some source context in some other, she might
jpayne@68: discover some apparent bug in the program source that needs correction.
jpayne@68: This command allows the translator to change sex, become a programmer,
jpayne@68: and have the cursor right into the window containing the program she
jpayne@68: (or rather he) wants to modify. By later getting the cursor back
jpayne@68: in the PO file window, or by asking Emacs to edit this file once again,
jpayne@68: PO mode is then recovered.
jpayne@68:
The command h (po-help
) displays a summary of all available PO
jpayne@68: mode commands. The translator should then type any character to resume
jpayne@68: normal PO mode operations. The command ? has the same effect
jpayne@68: as h.
jpayne@68:
The command = (po-statistics
) computes the total number of
jpayne@68: entries in the PO file, the ordinal of the current entry (counted from
jpayne@68: 1), the number of untranslated entries, the number of obsolete entries,
jpayne@68: and displays all these numbers.
jpayne@68:
The command V (po-validate
) launches msgfmt
in
jpayne@68: checking and verbose
jpayne@68: mode over the current PO file. This command first offers to save the
jpayne@68: current PO file on disk. The msgfmt
tool, from GNU gettext
,
jpayne@68: has the purpose of creating a MO file out of a PO file, and PO mode uses
jpayne@68: the features of this program for checking the overall format of a PO file,
jpayne@68: as well as all individual entries.
jpayne@68:
The program msgfmt
runs asynchronously with Emacs, so the
jpayne@68: translator regains control immediately while her PO file is being studied.
jpayne@68: Error output is collected in the Emacs ‘*compilation*’ buffer,
jpayne@68: displayed in another window. The regular Emacs command C-x`
jpayne@68: (next-error
), as well as other usual compile commands, allow the
jpayne@68: translator to reposition quickly to the offending parts of the PO file.
jpayne@68: Once the cursor is on the line in error, the translator may decide on
jpayne@68: any PO mode action which would help correcting the error.
jpayne@68:
The cursor in a PO file window is almost always part of jpayne@68: an entry. The only exceptions are the special case when the cursor jpayne@68: is after the last entry in the file, or when the PO file is jpayne@68: empty. The entry where the cursor is found to be is said to be the jpayne@68: current entry. Many PO mode commands operate on the current entry, jpayne@68: so moving the cursor does more than allowing the translator to browse jpayne@68: the PO file, this also selects on which entry commands operate. jpayne@68:
jpayne@68: jpayne@68:Some PO mode commands alter the position of the cursor in a specialized jpayne@68: way. A few of those special purpose positioning are described here, jpayne@68: the others are described in following sections (for a complete list try jpayne@68: C-h m): jpayne@68:
jpayne@68:Redisplay the current entry (po-current-entry
).
jpayne@68:
Select the entry after the current one (po-next-entry
).
jpayne@68:
Select the entry before the current one (po-previous-entry
).
jpayne@68:
Select the first entry in the PO file (po-first-entry
).
jpayne@68:
Select the last entry in the PO file (po-last-entry
).
jpayne@68:
Record the location of the current entry for later use
jpayne@68: (po-push-location
).
jpayne@68:
Return to a previously saved entry location (po-pop-location
).
jpayne@68:
Exchange the current entry location with the previously saved one
jpayne@68: (po-exchange-location
).
jpayne@68:
Any Emacs command able to reposition the cursor may be used
jpayne@68: to select the current entry in PO mode, including commands which
jpayne@68: move by characters, lines, paragraphs, screens or pages, and search
jpayne@68: commands. However, there is a kind of standard way to display the
jpayne@68: current entry in PO mode, which usual Emacs commands moving
jpayne@68: the cursor do not especially try to enforce. The command .
jpayne@68: (po-current-entry
) has the sole purpose of redisplaying the
jpayne@68: current entry properly, after the current entry has been changed by
jpayne@68: means external to PO mode, or the Emacs screen otherwise altered.
jpayne@68:
It is yet to be decided if PO mode helps the translator, or otherwise jpayne@68: irritates her, by forcing a rigid window disposition while she jpayne@68: is doing her work. We originally had quite precise ideas about jpayne@68: how windows should behave, but on the other hand, anyone used to jpayne@68: Emacs is often happy to keep full control. Maybe a fixed window jpayne@68: disposition might be offered as a PO mode option that the translator jpayne@68: might activate or deactivate at will, so it could be offered on an jpayne@68: experimental basis. If nobody feels a real need for using it, or jpayne@68: a compulsion for writing it, we should drop this whole idea. jpayne@68: The incentive for doing it should come from translators rather than jpayne@68: programmers, as opinions from an experienced translator are surely jpayne@68: more worth to me than opinions from programmers thinking about jpayne@68: how others should do translation. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:The commands n (po-next-entry
) and p
jpayne@68: (po-previous-entry
) move the cursor the entry following,
jpayne@68: or preceding, the current one. If n is given while the
jpayne@68: cursor is on the last entry of the PO file, or if p
jpayne@68: is given while the cursor is on the first entry, no move is done.
jpayne@68:
The commands < (po-first-entry
) and >
jpayne@68: (po-last-entry
) move the cursor to the first entry, or last
jpayne@68: entry, of the PO file. When the cursor is located past the last
jpayne@68: entry in a PO file, most PO mode commands will return an error saying
jpayne@68: ‘After last entry’. Moreover, the commands < and >
jpayne@68: have the special property of being able to work even when the cursor
jpayne@68: is not into some PO file entry, and one may use them for nicely
jpayne@68: correcting this situation. But even these commands will fail on a
jpayne@68: truly empty PO file. There are development plans for the PO mode for it
jpayne@68: to interactively fill an empty PO file from sources. See section Marking Translatable Strings.
jpayne@68:
The translator may decide, before working at the translation of jpayne@68: a particular entry, that she needs to browse the remainder of the jpayne@68: PO file, maybe for finding the terminology or phraseology used jpayne@68: in related entries. She can of course use the standard Emacs idioms jpayne@68: for saving the current cursor location in some register, and use that jpayne@68: register for getting back, or else, use the location ring. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:PO mode offers another approach, by which cursor locations may be saved
jpayne@68: onto a special stack. The command m (po-push-location
)
jpayne@68: merely adds the location of current entry to the stack, pushing
jpayne@68: the already saved locations under the new one. The command
jpayne@68: r (po-pop-location
) consumes the top stack element and
jpayne@68: repositions the cursor to the entry associated with that top element.
jpayne@68: This position is then lost, for the next r will move the cursor
jpayne@68: to the previously saved location, and so on until no locations remain
jpayne@68: on the stack.
jpayne@68:
If the translator wants the position to be kept on the location stack, jpayne@68: maybe for taking a look at the entry associated with the top jpayne@68: element, then go elsewhere with the intent of getting back later, she jpayne@68: ought to use m immediately after r. jpayne@68:
jpayne@68: jpayne@68: jpayne@68:The command x (po-exchange-location
) simultaneously
jpayne@68: repositions the cursor to the entry associated with the top element of
jpayne@68: the stack of saved locations, and replaces that top element with the
jpayne@68: location of the current entry before the move. Consequently, repeating
jpayne@68: the x command toggles alternatively between two entries.
jpayne@68: For achieving this, the translator will position the cursor on the
jpayne@68: first entry, use m, then position to the second entry, and
jpayne@68: merely use x for making the switch.
jpayne@68:
There are many different ways for encoding a particular string into a
jpayne@68: PO file entry, because there are so many different ways to split and
jpayne@68: quote multi-line strings, and even, to represent special characters
jpayne@68: by backslashed escaped sequences. Some features of PO mode rely on
jpayne@68: the ability for PO mode to scan an already existing PO file for a
jpayne@68: particular string encoded into the msgid
field of some entry.
jpayne@68: Even if PO mode has internally all the built-in machinery for
jpayne@68: implementing this recognition easily, doing it fast is technically
jpayne@68: difficult. To facilitate a solution to this efficiency problem,
jpayne@68: we decided on a canonical representation for strings.
jpayne@68:
A conventional representation of strings in a PO file is currently
jpayne@68: under discussion, and PO mode experiments with a canonical representation.
jpayne@68: Having both xgettext
and PO mode converging towards a uniform
jpayne@68: way of representing equivalent strings would be useful, as the internal
jpayne@68: normalization needed by PO mode could be automatically satisfied
jpayne@68: when using xgettext
from GNU gettext
. An explicit
jpayne@68: PO mode normalization should then be only necessary for PO files
jpayne@68: imported from elsewhere, or for when the convention itself evolves.
jpayne@68:
So, for achieving normalization of at least the strings of a given jpayne@68: PO file needing a canonical representation, the following PO mode jpayne@68: command is available: jpayne@68:
jpayne@68: jpayne@68:Tidy the whole PO file by making entries more uniform. jpayne@68:
jpayne@68:The special command M-x po-normalize, which has no associated
jpayne@68: keys, revises all entries, ensuring that strings of both original
jpayne@68: and translated entries use uniform internal quoting in the PO file.
jpayne@68: It also removes any crumb after the last entry. This command may be
jpayne@68: useful for PO files freshly imported from elsewhere, or if we ever
jpayne@68: improve on the canonical quoting format we use. This canonical format
jpayne@68: is not only meant for getting cleaner PO files, but also for greatly
jpayne@68: speeding up msgid
string lookup for some other PO mode commands.
jpayne@68:
M-x po-normalize presently makes three passes over the entries.
jpayne@68: The first implements heuristics for converting PO files for GNU
jpayne@68: gettext
0.6 and earlier, in which msgid
and msgstr
jpayne@68: fields were using K&R style C string syntax for multi-line strings.
jpayne@68: These heuristics may fail for comments not related to obsolete
jpayne@68: entries and ending with a backslash; they also depend on subsequent
jpayne@68: passes for finalizing the proper commenting of continued lines for
jpayne@68: obsolete entries. This first pass might disappear once all oldish PO
jpayne@68: files would have been adjusted. The second and third pass normalize
jpayne@68: all msgid
and msgstr
strings respectively. They also
jpayne@68: clean out those trailing backslashes used by XView's msgfmt
jpayne@68: for continued lines.
jpayne@68:
Having such an explicit normalizing command allows for importing PO
jpayne@68: files from other sources, but also eases the evolution of the current
jpayne@68: convention, evolution driven mostly by aesthetic concerns, as of now.
jpayne@68: It is easy to make suggested adjustments at a later time, as the
jpayne@68: normalizing command and eventually, other GNU gettext
tools
jpayne@68: should greatly automate conformance. A description of the canonical
jpayne@68: string format is given below, for the particular benefit of those not
jpayne@68: having Emacs handy, and who would nevertheless want to handcraft
jpayne@68: their PO files in nice ways.
jpayne@68:
Right now, in PO mode, strings are single line or multi-line. A string jpayne@68: goes multi-line if and only if it has embedded newlines, that jpayne@68: is, if it matches ‘[^\n]\n+[^\n]’. So, we would have: jpayne@68:
jpayne@68:msgstr "\n\nHello, world!\n\n\n" jpayne@68: |
but, replacing the space by a newline, this becomes: jpayne@68:
jpayne@68:msgstr "" jpayne@68: "\n" jpayne@68: "\n" jpayne@68: "Hello,\n" jpayne@68: "world!\n" jpayne@68: "\n" jpayne@68: "\n" jpayne@68: |
We are deliberately using a caricatural example, here, to make the jpayne@68: point clearer. Usually, multi-lines are not that bad looking. jpayne@68: It is probable that we will implement the following suggestion. jpayne@68: We might lump together all initial newlines into the empty string, jpayne@68: and also all newlines introducing empty lines (that is, for n jpayne@68: > 1, the n-1'th last newlines would go together on a separate jpayne@68: string), so making the previous example appear: jpayne@68:
jpayne@68:msgstr "\n\n" jpayne@68: "Hello,\n" jpayne@68: "world!\n" jpayne@68: "\n\n" jpayne@68: |
There are a few yet undecided little points about string normalization, jpayne@68: to be documented in this manual, once these questions settle. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:Each PO file entry for which the msgstr
field has been filled with
jpayne@68: a translation, and which is not marked as fuzzy (see section Fuzzy Entries),
jpayne@68: is said to be a translated entry. Only translated entries will
jpayne@68: later be compiled by GNU msgfmt
and become usable in programs.
jpayne@68: Other entry types will be excluded; translation will not occur for them.
jpayne@68:
Some commands are more specifically related to translated entry processing. jpayne@68:
jpayne@68:Find the next translated entry (po-next-translated-entry
).
jpayne@68:
Find the previous translated entry (po-previous-translated-entry
).
jpayne@68:
The commands t (po-next-translated-entry
) and T
jpayne@68: (po-previous-translated-entry
) move forwards or backwards, chasing
jpayne@68: for an translated entry. If none is found, the search is extended and
jpayne@68: wraps around in the PO file buffer.
jpayne@68:
Translated entries usually result from the translator having edited in
jpayne@68: a translation for them, Modifying Translations. However, if the
jpayne@68: variable po-auto-fuzzy-on-edit
is not nil
, the entry having
jpayne@68: received a new translation first becomes a fuzzy entry, which ought to
jpayne@68: be later unfuzzied before becoming an official, genuine translated entry.
jpayne@68: See section Fuzzy Entries.
jpayne@68:
Each PO file entry may have a set of attributes, which are
jpayne@68: qualities given a name and explicitly associated with the translation,
jpayne@68: using a special system comment. One of these attributes
jpayne@68: has the name fuzzy
, and entries having this attribute are said
jpayne@68: to have a fuzzy translation. They are called fuzzy entries, for short.
jpayne@68:
Fuzzy entries, even if they account for translated entries for
jpayne@68: most other purposes, usually call for revision by the translator.
jpayne@68: Those may be produced by applying the program msgmerge
to
jpayne@68: update an older translated PO files according to a new PO template
jpayne@68: file, when this tool hypothesises that some new msgid
has
jpayne@68: been modified only slightly out of an older one, and chooses to pair
jpayne@68: what it thinks to be the old translation for the new modified entry.
jpayne@68: The slight alteration in the original string (the msgid
string)
jpayne@68: should often be reflected in the translated string, and this requires
jpayne@68: the intervention of the translator. For this reason, msgmerge
jpayne@68: might mark some entries as being fuzzy.
jpayne@68:
Also, the translator may decide herself to mark an entry as fuzzy jpayne@68: for her own convenience, when she wants to remember that the entry jpayne@68: has to be later revisited. So, some commands are more specifically jpayne@68: related to fuzzy entry processing. jpayne@68:
jpayne@68:Find the next fuzzy entry (po-next-fuzzy-entry
).
jpayne@68:
Find the previous fuzzy entry (po-previous-fuzzy-entry
).
jpayne@68:
Remove the fuzzy attribute of the current entry (po-unfuzzy
).
jpayne@68:
The commands f (po-next-fuzzy-entry
) and F
jpayne@68: (po-previous-fuzzy-entry
) move forwards or backwards, chasing for
jpayne@68: a fuzzy entry. If none is found, the search is extended and wraps
jpayne@68: around in the PO file buffer.
jpayne@68:
The command <TAB> (po-unfuzzy
) removes the fuzzy
jpayne@68: attribute associated with an entry, usually leaving it translated.
jpayne@68: Further, if the variable po-auto-select-on-unfuzzy
has not
jpayne@68: the nil
value, the <TAB> command will automatically chase
jpayne@68: for another interesting entry to work on. The initial value of
jpayne@68: po-auto-select-on-unfuzzy
is nil
.
jpayne@68:
The initial value of po-auto-fuzzy-on-edit
is nil
. However,
jpayne@68: if the variable po-auto-fuzzy-on-edit
is set to t
, any entry
jpayne@68: edited through the <RET> command is marked fuzzy, as a way to
jpayne@68: ensure some kind of double check, later. In this case, the usual paradigm
jpayne@68: is that an entry becomes fuzzy (if not already) whenever the translator
jpayne@68: modifies it. If she is satisfied with the translation, she then uses
jpayne@68: <TAB> to pick another entry to work on, clearing the fuzzy attribute
jpayne@68: on the same blow. If she is not satisfied yet, she merely uses <SPC>
jpayne@68: to chase another entry, leaving the entry fuzzy.
jpayne@68:
The translator may also use the <DEL> command
jpayne@68: (po-fade-out-entry
) over any translated entry to mark it as being
jpayne@68: fuzzy, when she wants to easily leave a trace she wants to later return
jpayne@68: working at this entry.
jpayne@68:
Also, when time comes to quit working on a PO file buffer with the q jpayne@68: command, the translator is asked for confirmation, if fuzzy string jpayne@68: still exists. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:When xgettext
originally creates a PO file, unless told
jpayne@68: otherwise, it initializes the msgid
field with the untranslated
jpayne@68: string, and leaves the msgstr
string to be empty. Such entries,
jpayne@68: having an empty translation, are said to be untranslated entries.
jpayne@68: Later, when the programmer slightly modifies some string right in
jpayne@68: the program, this change is later reflected in the PO file
jpayne@68: by the appearance of a new untranslated entry for the modified string.
jpayne@68:
The usual commands moving from entry to entry consider untranslated jpayne@68: entries on the same level as active entries. Untranslated entries jpayne@68: are easily recognizable by the fact they end with ‘msgstr ""’. jpayne@68:
jpayne@68: jpayne@68:The work of the translator might be (quite naively) seen as the process jpayne@68: of seeking for an untranslated entry, editing a translation for jpayne@68: it, and repeating these actions until no untranslated entries remain. jpayne@68: Some commands are more specifically related to untranslated entry jpayne@68: processing. jpayne@68:
jpayne@68:Find the next untranslated entry (po-next-untranslated-entry
).
jpayne@68:
Find the previous untranslated entry (po-previous-untransted-entry
).
jpayne@68:
Turn the current entry into an untranslated one (po-kill-msgstr
).
jpayne@68:
The commands u (po-next-untranslated-entry
) and U
jpayne@68: (po-previous-untransted-entry
) move forwards or backwards,
jpayne@68: chasing for an untranslated entry. If none is found, the search is
jpayne@68: extended and wraps around in the PO file buffer.
jpayne@68:
An entry can be turned back into an untranslated entry by
jpayne@68: merely emptying its translation, using the command k
jpayne@68: (po-kill-msgstr
). See section Modifying Translations.
jpayne@68:
Also, when time comes to quit working on a PO file buffer jpayne@68: with the q command, the translator is asked for confirmation, jpayne@68: if some untranslated string still exists. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:By obsolete PO file entries, we mean those entries which are
jpayne@68: commented out, usually by msgmerge
when it found that the
jpayne@68: translation is not needed anymore by the package being localized.
jpayne@68:
The usual commands moving from entry to entry consider obsolete
jpayne@68: entries on the same level as active entries. Obsolete entries are
jpayne@68: easily recognizable by the fact that all their lines start with
jpayne@68: #
, even those lines containing msgid
or msgstr
.
jpayne@68:
Commands exist for emptying the translation or reinitializing it jpayne@68: to the original untranslated string. Commands interfacing with the jpayne@68: kill ring may force some previously saved text into the translation. jpayne@68: The user may interactively edit the translation. All these commands jpayne@68: may apply to obsolete entries, carefully leaving the entry obsolete jpayne@68: after the fact. jpayne@68:
jpayne@68: jpayne@68:Moreover, some commands are more specifically related to obsolete jpayne@68: entry processing. jpayne@68:
jpayne@68:Find the next obsolete entry (po-next-obsolete-entry
).
jpayne@68:
Find the previous obsolete entry (po-previous-obsolete-entry
).
jpayne@68:
Make an active entry obsolete, or zap out an obsolete entry
jpayne@68: (po-fade-out-entry
).
jpayne@68:
The commands o (po-next-obsolete-entry
) and O
jpayne@68: (po-previous-obsolete-entry
) move forwards or backwards,
jpayne@68: chasing for an obsolete entry. If none is found, the search is
jpayne@68: extended and wraps around in the PO file buffer.
jpayne@68:
PO mode does not provide ways for un-commenting an obsolete entry
jpayne@68: and making it active, because this would reintroduce an original
jpayne@68: untranslated string which does not correspond to any marked string
jpayne@68: in the program sources. This goes with the philosophy of never
jpayne@68: introducing useless msgid
values.
jpayne@68:
However, it is possible to comment out an active entry, so making
jpayne@68: it obsolete. GNU gettext
utilities will later react to the
jpayne@68: disappearance of a translation by using the untranslated string.
jpayne@68: The command <DEL> (po-fade-out-entry
) pushes the current entry
jpayne@68: a little further towards annihilation. If the entry is active (it is a
jpayne@68: translated entry), then it is first made fuzzy. If it is already fuzzy,
jpayne@68: then the entry is merely commented out, with confirmation. If the entry
jpayne@68: is already obsolete, then it is completely deleted from the PO file.
jpayne@68: It is easy to recycle the translation so deleted into some other PO file
jpayne@68: entry, usually one which is untranslated. See section Modifying Translations.
jpayne@68:
Here is a quite interesting problem to solve for later development of jpayne@68: PO mode, for those nights you are not sleepy. The idea would be that jpayne@68: PO mode might become bright enough, one of these days, to make good jpayne@68: guesses at retrieving the most probable candidate, among all obsolete jpayne@68: entries, for initializing the translation of a newly appeared string. jpayne@68: I think it might be a quite hard problem to do this algorithmically, as jpayne@68: we have to develop good and efficient measures of string similarity. jpayne@68: Right now, PO mode completely lets the decision to the translator, jpayne@68: when the time comes to find the adequate obsolete translation, it jpayne@68: merely tries to provide handy tools for helping her to do so. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:PO mode prevents direct modification of the PO file, by the usual jpayne@68: means Emacs gives for altering a buffer's contents. By doing so, jpayne@68: it pretends helping the translator to avoid little clerical errors jpayne@68: about the overall file format, or the proper quoting of strings, jpayne@68: as those errors would be easily made. Other kinds of errors are jpayne@68: still possible, but some may be caught and diagnosed by the batch jpayne@68: validation process, which the translator may always trigger by the jpayne@68: V command. For all other errors, the translator has to rely on jpayne@68: her own judgment, and also on the linguistic reports submitted to her jpayne@68: by the users of the translated package, having the same mother tongue. jpayne@68:
jpayne@68:When the time comes to create a translation, correct an error diagnosed jpayne@68: mechanically or reported by a user, the translators have to resort to jpayne@68: using the following commands for modifying the translations. jpayne@68:
jpayne@68:Interactively edit the translation (po-edit-msgstr
).
jpayne@68:
Reinitialize the translation with the original, untranslated string
jpayne@68: (po-msgid-to-msgstr
).
jpayne@68:
Save the translation on the kill ring, and delete it (po-kill-msgstr
).
jpayne@68:
Save the translation on the kill ring, without deleting it
jpayne@68: (po-kill-ring-save-msgstr
).
jpayne@68:
Replace the translation, taking the new from the kill ring
jpayne@68: (po-yank-msgstr
).
jpayne@68:
The command <RET> (po-edit-msgstr
) opens a new Emacs
jpayne@68: window meant to edit in a new translation, or to modify an already existing
jpayne@68: translation. The new window contains a copy of the translation taken from
jpayne@68: the current PO file entry, all ready for edition, expunged of all quoting
jpayne@68: marks, fully modifiable and with the complete extent of Emacs modifying
jpayne@68: commands. When the translator is done with her modifications, she may use
jpayne@68: C-c C-c to close the subedit window with the automatically requoted
jpayne@68: results, or C-c C-k to abort her modifications. See section Details of Sub Edition,
jpayne@68: for more information.
jpayne@68:
The command <LFD> (po-msgid-to-msgstr
) initializes, or
jpayne@68: reinitializes the translation with the original string. This command is
jpayne@68: normally used when the translator wants to redo a fresh translation of
jpayne@68: the original string, disregarding any previous work.
jpayne@68:
It is possible to arrange so, whenever editing an untranslated
jpayne@68: entry, the <LFD> command be automatically executed. If you set
jpayne@68: po-auto-edit-with-msgid
to t
, the translation gets
jpayne@68: initialised with the original string, in case none exists already.
jpayne@68: The default value for po-auto-edit-with-msgid
is nil
.
jpayne@68:
In fact, whether it is best to start a translation with an empty jpayne@68: string, or rather with a copy of the original string, is a matter of jpayne@68: taste or habit. Sometimes, the source language and the jpayne@68: target language are so different that is simply best to start writing jpayne@68: on an empty page. At other times, the source and target languages jpayne@68: are so close that it would be a waste to retype a number of words jpayne@68: already being written in the original string. A translator may also jpayne@68: like having the original string right under her eyes, as she will jpayne@68: progressively overwrite the original text with the translation, even jpayne@68: if this requires some extra editing work to get rid of the original. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:The command k (po-kill-msgstr
) merely empties the
jpayne@68: translation string, so turning the entry into an untranslated
jpayne@68: one. But while doing so, its previous contents is put apart in
jpayne@68: a special place, known as the kill ring. The command w
jpayne@68: (po-kill-ring-save-msgstr
) has also the effect of taking a
jpayne@68: copy of the translation onto the kill ring, but it otherwise leaves
jpayne@68: the entry alone, and does not remove the translation from the
jpayne@68: entry. Both commands use exactly the Emacs kill ring, which is shared
jpayne@68: between buffers, and which is well known already to Emacs lovers.
jpayne@68:
The translator may use k or w many times in the course jpayne@68: of her work, as the kill ring may hold several saved translations. jpayne@68: From the kill ring, strings may later be reinserted in various jpayne@68: Emacs buffers. In particular, the kill ring may be used for moving jpayne@68: translation strings between different entries of a single PO file jpayne@68: buffer, or if the translator is handling many such buffers at once, jpayne@68: even between PO files. jpayne@68:
jpayne@68:To facilitate exchanges with buffers which are not in PO mode, the jpayne@68: translation string put on the kill ring by the k command is fully jpayne@68: unquoted before being saved: external quotes are removed, multi-line jpayne@68: strings are concatenated, and backslash escaped sequences are turned jpayne@68: into their corresponding characters. In the special case of obsolete jpayne@68: entries, the translation is also uncommented prior to saving. jpayne@68:
jpayne@68: jpayne@68: jpayne@68:The command y (po-yank-msgstr
) completely replaces the
jpayne@68: translation of the current entry by a string taken from the kill ring.
jpayne@68: Following Emacs terminology, we then say that the replacement
jpayne@68: string is yanked into the PO file buffer.
jpayne@68: See (emacs)Yanking section `Yanking' in The Emacs Editor.
jpayne@68: The first time y is used, the translation receives the value of
jpayne@68: the most recent addition to the kill ring. If y is typed once
jpayne@68: again, immediately, without intervening keystrokes, the translation
jpayne@68: just inserted is taken away and replaced by the second most recent
jpayne@68: addition to the kill ring. By repeating y many times in a row,
jpayne@68: the translator may travel along the kill ring for saved strings,
jpayne@68: until she finds the string she really wanted.
jpayne@68:
When a string is yanked into a PO file entry, it is fully and jpayne@68: automatically requoted for complying with the format PO files should jpayne@68: have. Further, if the entry is obsolete, PO mode then appropriately jpayne@68: push the inserted string inside comments. Once again, translators jpayne@68: should not burden themselves with quoting considerations besides, of jpayne@68: course, the necessity of the translated string itself respective to jpayne@68: the program using it. jpayne@68:
jpayne@68:Note that k or w are not the only commands pushing strings jpayne@68: on the kill ring, as almost any PO mode command replacing translation jpayne@68: strings (or the translator comments) automatically saves the old string jpayne@68: on the kill ring. The main exceptions to this general rule are the jpayne@68: yanking commands themselves. jpayne@68:
jpayne@68: jpayne@68:To better illustrate the operation of killing and yanking, let's
jpayne@68: use an actual example, taken from a common situation. When the
jpayne@68: programmer slightly modifies some string right in the program, his
jpayne@68: change is later reflected in the PO file by the appearance
jpayne@68: of a new untranslated entry for the modified string, and the fact
jpayne@68: that the entry translating the original or unmodified string becomes
jpayne@68: obsolete. In many cases, the translator might spare herself some work
jpayne@68: by retrieving the unmodified translation from the obsolete entry,
jpayne@68: then initializing the untranslated entry msgstr
field with
jpayne@68: this retrieved translation. Once this done, the obsolete entry is
jpayne@68: not wanted anymore, and may be safely deleted.
jpayne@68:
When the translator finds an untranslated entry and suspects that a
jpayne@68: slight variant of the translation exists, she immediately uses m
jpayne@68: to mark the current entry location, then starts chasing obsolete
jpayne@68: entries with o, hoping to find some translation corresponding
jpayne@68: to the unmodified string. Once found, she uses the <DEL> command
jpayne@68: for deleting the obsolete entry, knowing that <DEL> also kills
jpayne@68: the translation, that is, pushes the translation on the kill ring.
jpayne@68: Then, r returns to the initial untranslated entry, and y
jpayne@68: then yanks the saved translation right into the msgstr
jpayne@68: field. The translator is then free to use <RET> for fine
jpayne@68: tuning the translation contents, and maybe to later use u,
jpayne@68: then m again, for going on with the next untranslated string.
jpayne@68:
When some sequence of keys has to be typed over and over again, the jpayne@68: translator may find it useful to become better acquainted with the Emacs jpayne@68: capability of learning these sequences and playing them back under request. jpayne@68: See (emacs)Keyboard Macros section `Keyboard Macros' in The Emacs Editor. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:Any translation work done seriously will raise many linguistic jpayne@68: difficulties, for which decisions have to be made, and the choices jpayne@68: further documented. These documents may be saved within the jpayne@68: PO file in form of translator comments, which the translator jpayne@68: is free to create, delete, or modify at will. These comments may jpayne@68: be useful to herself when she returns to this PO file after a while. jpayne@68:
jpayne@68:Comments not having whitespace after the initial ‘#’, for example,
jpayne@68: those beginning with ‘#.’ or ‘#:’, are not translator
jpayne@68: comments, they are exclusively created by other gettext
tools.
jpayne@68: So, the commands below will never alter such system added comments,
jpayne@68: they are not meant for the translator to modify. See section The Format of PO Files.
jpayne@68:
The following commands are somewhat similar to those modifying translations, jpayne@68: so the general indications given for those apply here. See section Modifying Translations. jpayne@68:
jpayne@68:Interactively edit the translator comments (po-edit-comment
).
jpayne@68:
Save the translator comments on the kill ring, and delete it
jpayne@68: (po-kill-comment
).
jpayne@68:
Save the translator comments on the kill ring, without deleting it
jpayne@68: (po-kill-ring-save-comment
).
jpayne@68:
Replace the translator comments, taking the new from the kill ring
jpayne@68: (po-yank-comment
).
jpayne@68:
These commands parallel PO mode commands for modifying the translation jpayne@68: strings, and behave much the same way as they do, except that they handle jpayne@68: this part of PO file comments meant for translator usage, rather jpayne@68: than the translation strings. So, if the descriptions given below are jpayne@68: slightly succinct, it is because the full details have already been given. jpayne@68: See section Modifying Translations. jpayne@68:
jpayne@68: jpayne@68: jpayne@68:The command # (po-edit-comment
) opens a new Emacs window
jpayne@68: containing a copy of the translator comments on the current PO file entry.
jpayne@68: If there are no such comments, PO mode understands that the translator wants
jpayne@68: to add a comment to the entry, and she is presented with an empty screen.
jpayne@68: Comment marks (#
) and the space following them are automatically
jpayne@68: removed before edition, and reinstated after. For translator comments
jpayne@68: pertaining to obsolete entries, the uncommenting and recommenting operations
jpayne@68: are done twice. Once in the editing window, the keys C-c C-c
jpayne@68: allow the translator to tell she is finished with editing the comment.
jpayne@68: See section Details of Sub Edition, for further details.
jpayne@68:
Functions found on po-subedit-mode-hook
, if any, are executed after
jpayne@68: the string has been inserted in the edit buffer.
jpayne@68:
The command K (po-kill-comment
) gets rid of all
jpayne@68: translator comments, while saving those comments on the kill ring.
jpayne@68: The command W (po-kill-ring-save-comment
) takes
jpayne@68: a copy of the translator comments on the kill ring, but leaves
jpayne@68: them undisturbed in the current entry. The command Y
jpayne@68: (po-yank-comment
) completely replaces the translator comments
jpayne@68: by a string taken at the front of the kill ring. When this command
jpayne@68: is immediately repeated, the comments just inserted are withdrawn,
jpayne@68: and replaced by other strings taken along the kill ring.
jpayne@68:
On the kill ring, all strings have the same nature. There is no jpayne@68: distinction between translation strings and translator jpayne@68: comments strings. So, for example, let's presume the translator jpayne@68: has just finished editing a translation, and wants to create a new jpayne@68: translator comment to document why the previous translation was jpayne@68: not good, just to remember what was the problem. Foreseeing that she jpayne@68: will do that in her documentation, the translator may want to quote jpayne@68: the previous translation in her translator comments. To do so, she jpayne@68: may initialize the translator comments with the previous translation, jpayne@68: still at the head of the kill ring. Because editing already pushed the jpayne@68: previous translation on the kill ring, she merely has to type M-w jpayne@68: prior to #, and the previous translation will be right there, jpayne@68: all ready for being introduced by some explanatory text. jpayne@68:
jpayne@68:On the other hand, presume there are some translator comments already
jpayne@68: and that the translator wants to add to those comments, instead
jpayne@68: of wholly replacing them. Then, she should edit the comment right
jpayne@68: away with #. Once inside the editing window, she can use the
jpayne@68: regular Emacs commands C-y (yank
) and M-y
jpayne@68: (yank-pop
) to get the previous translation where she likes.
jpayne@68:
The PO subedit minor mode has a few peculiarities worth being described jpayne@68: in fuller detail. It installs a few commands over the usual editing set jpayne@68: of Emacs, which are described below. jpayne@68:
jpayne@68:Complete edition (po-subedit-exit
).
jpayne@68:
Abort edition (po-subedit-abort
).
jpayne@68:
Consult auxiliary PO files (po-subedit-cycle-auxiliary
).
jpayne@68:
The window's contents represents a translation for a given message,
jpayne@68: or a translator comment. The translator may modify this window to
jpayne@68: her heart's content. Once this is done, the command C-c C-c
jpayne@68: (po-subedit-exit
) may be used to return the edited translation into
jpayne@68: the PO file, replacing the original translation, even if it moved out of
jpayne@68: sight or if buffers were switched.
jpayne@68:
If the translator becomes unsatisfied with her translation or comment,
jpayne@68: to the extent she prefers keeping what was existent prior to the
jpayne@68: <RET> or # command, she may use the command C-c C-k
jpayne@68: (po-subedit-abort
) to merely get rid of edition, while preserving
jpayne@68: the original translation or comment. Another way would be for her to exit
jpayne@68: normally with C-c C-c, then type U
once for undoing the
jpayne@68: whole effect of last edition.
jpayne@68:
The command C-c C-a (po-subedit-cycle-auxiliary
)
jpayne@68: allows for glancing through translations
jpayne@68: already achieved in other languages, directly while editing the current
jpayne@68: translation. This may be quite convenient when the translator is fluent
jpayne@68: at many languages, but of course, only makes sense when such completed
jpayne@68: auxiliary PO files are already available to her (see section Consulting Auxiliary PO Files).
jpayne@68:
Functions found on po-subedit-mode-hook
, if any, are executed after
jpayne@68: the string has been inserted in the edit buffer.
jpayne@68:
While editing her translation, the translator should pay attention to not
jpayne@68: inserting unwanted <RET> (newline) characters at the end of
jpayne@68: the translated string if those are not meant to be there, or to removing
jpayne@68: such characters when they are required. Since these characters are not
jpayne@68: visible in the editing buffer, they are easily introduced by mistake.
jpayne@68: To help her, <RET> automatically puts the character <
jpayne@68: at the end of the string being edited, but this <
is not really
jpayne@68: part of the string. On exiting the editing window with C-c C-c,
jpayne@68: PO mode automatically removes such < and all whitespace added after
jpayne@68: it. If the translator adds characters after the terminating <
, it
jpayne@68: looses its delimiting property and integrally becomes part of the string.
jpayne@68: If she removes the delimiting <
, then the edited string is taken
jpayne@68: as is, with all trailing newlines, even if invisible. Also, if
jpayne@68: the translated string ought to end itself with a genuine <
, then
jpayne@68: the delimiting <
may not be removed; so the string should appear,
jpayne@68: in the editing window, as ending with two <
in a row.
jpayne@68:
When a translation (or a comment) is being edited, the translator may move jpayne@68: the cursor back into the PO file buffer and freely move to other entries, jpayne@68: browsing at will. If, with an edition pending, the translator wanders in the jpayne@68: PO file buffer, she may decide to start modifying another entry. Each entry jpayne@68: being edited has its own subedit buffer. It is possible to simultaneously jpayne@68: edit the translation and the comment of a single entry, or to jpayne@68: edit entries in different PO files, all at once. Typing <RET> jpayne@68: on a field already being edited merely resumes that particular edit. Yet, jpayne@68: the translator should better be comfortable at handling many Emacs windows! jpayne@68:
jpayne@68: jpayne@68:Pending subedits may be completed or aborted in any order, regardless jpayne@68: of how or when they were started. When many subedits are pending and the jpayne@68: translator asks for quitting the PO file (with the q command), subedits jpayne@68: are automatically resumed one at a time, so she may decide for each of them. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68:PO mode is particularly powerful when used with PO files
jpayne@68: created through GNU gettext
utilities, as those utilities
jpayne@68: insert special comments in the PO files they generate.
jpayne@68: Some of these special comments relate the PO file entry to
jpayne@68: exactly where the untranslated string appears in the program sources.
jpayne@68:
When the translator gets to an untranslated entry, she is fairly jpayne@68: often faced with an original string which is not as informative as jpayne@68: it normally should be, being succinct, cryptic, or otherwise ambiguous. jpayne@68: Before choosing how to translate the string, she needs to understand jpayne@68: better what the string really means and how tight the translation has jpayne@68: to be. Most of the time, when problems arise, the only way left to make jpayne@68: her judgment is looking at the true program sources from where this jpayne@68: string originated, searching for surrounding comments the programmer jpayne@68: might have put in there, and looking around for helping clues of jpayne@68: any kind. jpayne@68:
jpayne@68:Surely, when looking at program sources, the translator will receive jpayne@68: more help if she is a fluent programmer. However, even if she is jpayne@68: not versed in programming and feels a little lost in C code, the jpayne@68: translator should not be shy at taking a look, once in a while. jpayne@68: It is most probable that she will still be able to find some of the jpayne@68: hints she needs. She will learn quickly to not feel uncomfortable jpayne@68: in program code, paying more attention to programmer's comments, jpayne@68: variable and function names (if he dared choosing them well), and jpayne@68: overall organization, than to the program code itself. jpayne@68:
jpayne@68: jpayne@68:The following commands are meant to help the translator at getting jpayne@68: program source context for a PO file entry. jpayne@68:
jpayne@68:Resume the display of a program source context, or cycle through them
jpayne@68: (po-cycle-source-reference
).
jpayne@68:
Display of a program source context selected by menu
jpayne@68: (po-select-source-reference
).
jpayne@68:
Add a directory to the search path for source files
jpayne@68: (po-consider-source-path
).
jpayne@68:
Delete a directory from the search path for source files
jpayne@68: (po-ignore-source-path
).
jpayne@68:
The commands s (po-cycle-source-reference
) and M-s
jpayne@68: (po-select-source-reference
) both open another window displaying
jpayne@68: some source program file, and already positioned in such a way that
jpayne@68: it shows an actual use of the string to be translated. By doing
jpayne@68: so, the command gives source program context for the string. But if
jpayne@68: the entry has no source context references, or if all references
jpayne@68: are unresolved along the search path for program sources, then the
jpayne@68: command diagnoses this as an error.
jpayne@68:
Even if s (or M-s) opens a new window, the cursor stays jpayne@68: in the PO file window. If the translator really wants to jpayne@68: get into the program source window, she ought to do it explicitly, jpayne@68: maybe by using command O. jpayne@68:
jpayne@68:When s is typed for the first time, or for a PO file entry which jpayne@68: is different of the last one used for getting source context, then the jpayne@68: command reacts by giving the first context available for this entry, jpayne@68: if any. If some context has already been recently displayed for the jpayne@68: current PO file entry, and the translator wandered off to do other jpayne@68: things, typing s again will merely resume, in another window, jpayne@68: the context last displayed. In particular, if the translator moved jpayne@68: the cursor away from the context in the source file, the command will jpayne@68: bring the cursor back to the context. By using s many times jpayne@68: in a row, with no other commands intervening, PO mode will cycle to jpayne@68: the next available contexts for this particular entry, getting back jpayne@68: to the first context once the last has been shown. jpayne@68:
jpayne@68:The command M-s behaves differently. Instead of cycling through jpayne@68: references, it lets the translator choose a particular reference among jpayne@68: many, and displays that reference. It is best used with completion, jpayne@68: if the translator types <TAB> immediately after M-s, in jpayne@68: response to the question, she will be offered a menu of all possible jpayne@68: references, as a reminder of which are the acceptable answers. jpayne@68: This command is useful only where there are really many contexts jpayne@68: available for a single string to translate. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:Program source files are usually found relative to where the PO
jpayne@68: file stands. As a special provision, when this fails, the file is
jpayne@68: also looked for, but relative to the directory immediately above it.
jpayne@68: Those two cases take proper care of most PO files. However, it might
jpayne@68: happen that a PO file has been moved, or is edited in a different
jpayne@68: place than its normal location. When this happens, the translator
jpayne@68: should tell PO mode in which directory normally sits the genuine PO
jpayne@68: file. Many such directories may be specified, and all together, they
jpayne@68: constitute what is called the search path for program sources.
jpayne@68: The command S (po-consider-source-path
) is used to interactively
jpayne@68: enter a new directory at the front of the search path, and the command
jpayne@68: M-S (po-ignore-source-path
) is used to select, with completion,
jpayne@68: one of the directories she does not want anymore on the search path.
jpayne@68:
PO mode is able to help the knowledgeable translator, being fluent in jpayne@68: many languages, at taking advantage of translations already achieved jpayne@68: in other languages she just happens to know. It provides these other jpayne@68: language translations as additional context for her own work. Moreover, jpayne@68: it has features to ease the production of translations for many languages jpayne@68: at once, for translators preferring to work in this way. jpayne@68:
jpayne@68: jpayne@68: jpayne@68:An auxiliary PO file is an existing PO file meant for the same jpayne@68: package the translator is working on, but targeted to a different mother jpayne@68: tongue language. Commands exist for declaring and handling auxiliary jpayne@68: PO files, and also for showing contexts for the entry under work. jpayne@68:
jpayne@68:Here are the auxiliary file commands available in PO mode. jpayne@68:
jpayne@68:Seek auxiliary files for another translation for the same entry
jpayne@68: (po-cycle-auxiliary
).
jpayne@68:
Switch to a particular auxiliary file (po-select-auxiliary
).
jpayne@68:
Declare this PO file as an auxiliary file (po-consider-as-auxiliary
).
jpayne@68:
Remove this PO file from the list of auxiliary files
jpayne@68: (po-ignore-as-auxiliary
).
jpayne@68:
Command A (po-consider-as-auxiliary
) adds the current
jpayne@68: PO file to the list of auxiliary files, while command M-A
jpayne@68: (po-ignore-as-auxiliary
just removes it.
jpayne@68:
The command a (po-cycle-auxiliary
) seeks all auxiliary PO
jpayne@68: files, round-robin, searching for a translated entry in some other language
jpayne@68: having an msgid
field identical as the one for the current entry.
jpayne@68: The found PO file, if any, takes the place of the current PO file in
jpayne@68: the display (its window gets on top). Before doing so, the current PO
jpayne@68: file is also made into an auxiliary file, if not already. So, a
jpayne@68: in this newly displayed PO file will seek another PO file, and so on,
jpayne@68: so repeating a will eventually yield back the original PO file.
jpayne@68:
The command C-c C-a (po-select-auxiliary
) asks the translator
jpayne@68: for her choice of a particular auxiliary file, with completion, and
jpayne@68: then switches to that selected PO file. The command also checks if
jpayne@68: the selected file has an msgid
field identical as the one for
jpayne@68: the current entry, and if yes, this entry becomes current. Otherwise,
jpayne@68: the cursor of the selected file is left undisturbed.
jpayne@68:
For all this to work fully, auxiliary PO files will have to be normalized,
jpayne@68: in that way that msgid
fields should be written exactly
jpayne@68: the same way. It is possible to write msgid
fields in various
jpayne@68: ways for representing the same string, different writing would break the
jpayne@68: proper behaviour of the auxiliary file commands of PO mode. This is not
jpayne@68: expected to be much a problem in practice, as most existing PO files have
jpayne@68: their msgid
entries written by the same GNU gettext
tools.
jpayne@68:
However, PO files initially created by PO mode itself, while marking
jpayne@68: strings in source files, are normalised differently. So are PO
jpayne@68: files resulting of the ‘M-x normalize’ command. Until these
jpayne@68: discrepancies between PO mode and other GNU gettext
tools get
jpayne@68: fully resolved, the translator should stay aware of normalisation issues.
jpayne@68:
A compendium is a special PO file containing a set of jpayne@68: translations recurring in many different packages. The translator can jpayne@68: use gettext tools to build a new compendium, to add entries to her jpayne@68: compendium, and to initialize untranslated entries, or to update jpayne@68: already translated entries, from translations kept in the compendium. jpayne@68:
jpayne@68: jpayne@68: jpayne@68: jpayne@68: jpayne@68:Basically every PO file consisting of translated entries only can be jpayne@68: declared as a valid compendium. Often the translator wants to have jpayne@68: special compendia; let's consider two cases: concatenating PO jpayne@68: files and extracting a message subset from a PO file. jpayne@68:
jpayne@68: jpayne@68: jpayne@68:To concatenate several valid PO files into one compendium file you can jpayne@68: use ‘msgcomm’ or ‘msgcat’ (the latter preferred): jpayne@68:
jpayne@68:msgcat -o compendium.po file1.po file2.po jpayne@68: |
By default, msgcat
will accumulate divergent translations
jpayne@68: for the same string. Those occurrences will be marked as fuzzy
jpayne@68: and highly visible decorated; calling msgcat
on
jpayne@68: ‘file1.po’:
jpayne@68:
#: src/hello.c:200 jpayne@68: #, c-format jpayne@68: msgid "Report bugs to <%s>.\n" jpayne@68: msgstr "Comunicar `bugs' a <%s>.\n" jpayne@68: |
and ‘file2.po’: jpayne@68:
jpayne@68:#: src/bye.c:100 jpayne@68: #, c-format jpayne@68: msgid "Report bugs to <%s>.\n" jpayne@68: msgstr "Comunicar \"bugs\" a <%s>.\n" jpayne@68: |
will result in: jpayne@68:
jpayne@68:#: src/hello.c:200 src/bye.c:100 jpayne@68: #, fuzzy, c-format jpayne@68: msgid "Report bugs to <%s>.\n" jpayne@68: msgstr "" jpayne@68: "#-#-#-#-# file1.po #-#-#-#-#\n" jpayne@68: "Comunicar `bugs' a <%s>.\n" jpayne@68: "#-#-#-#-# file2.po #-#-#-#-#\n" jpayne@68: "Comunicar \"bugs\" a <%s>.\n" jpayne@68: |
The translator will have to resolve this “conflict” manually; she
jpayne@68: has to decide whether the first or the second version is appropriate
jpayne@68: (or provide a new translation), to delete the “marker lines”, and
jpayne@68: finally to remove the fuzzy
mark.
jpayne@68:
If the translator knows in advance the first found translation of a jpayne@68: message is always the best translation she can make use to the jpayne@68: ‘--use-first’ switch: jpayne@68:
jpayne@68:msgcat --use-first -o compendium.po file1.po file2.po jpayne@68: |
A good compendium file must not contain fuzzy
or untranslated
jpayne@68: entries. If input files are “dirty” you must preprocess the input
jpayne@68: files or postprocess the result using ‘msgattrib --translated --no-fuzzy’.
jpayne@68:
Nobody wants to translate the same messages again and again; thus you jpayne@68: may wish to have a compendium file containing ‘getopt.c’ messages. jpayne@68:
jpayne@68:To extract a message subset (e.g., all ‘getopt.c’ messages) from an jpayne@68: existing PO file into one compendium file you can use ‘msggrep’: jpayne@68:
jpayne@68:msggrep --location src/getopt.c -o compendium.po file.po jpayne@68: |
You can use a compendium file to initialize a translation from scratch jpayne@68: or to update an already existing translation. jpayne@68:
jpayne@68: jpayne@68: jpayne@68:Since a PO file with translations does not exist the translator can jpayne@68: merely use ‘/dev/null’ to fake the “old” translation file. jpayne@68:
jpayne@68:msgmerge --compendium compendium.po -o file.po /dev/null file.pot jpayne@68: |
Concatenate the compendium file(s) and the existing PO, merge the jpayne@68: result with the POT file and remove the obsolete entries (optional, jpayne@68: here done using ‘msgattrib’): jpayne@68:
jpayne@68:msgcat --use-first -o update.po compendium1.po compendium2.po file.po jpayne@68: msgmerge update.po file.pot | msgattrib --no-obsolete > file.po jpayne@68: |
[ << ] | jpayne@68:[ >> ] | jpayne@68:jpayne@68: | jpayne@68: | jpayne@68: | jpayne@68: | jpayne@68: | [Top] | jpayne@68:[Contents] | jpayne@68:[Index] | jpayne@68:[ ? ] | jpayne@68:
jpayne@68:
jpayne@68: This document was generated by Bruno Haible on February, 21 2024 using texi2html 1.78a.
jpayne@68:
jpayne@68:
jpayne@68:
jpayne@68: