Comment lines come before the keyword lines of an entry. Every one starts with
#, and the character after it says what the line is. All of them are
optional. The reader of gettext itself keeps only the text after the
#; the meaning of each kind comes from the tools that write and read them.
The kinds of comment
| Starts with | Kind | Written by | Holds |
|---|---|---|---|
# (a hash and white space) | Translator comment | The translator | Notes by the translator. The tools do not touch them. |
#. | Extracted comment | xgettext | A comment of the programmer, taken from the source code next to the message. |
#: | Reference | xgettext | Where the message is in the source: see below. |
#, | Flags | The tools and the translator | A comma-separated list of flags: see below. |
#| | Previous string | msgmerge | The untranslated text before the message changed: see below. |
# and any other character | Automatic comment | The gettext tools | A comment that the tools may replace when the file goes through msgmerge. |
#~ | Obsolete entry | msgmerge | Not a comment: every line of an obsolete entry starts with it. |
Comment lines can also stand between entries. A comment at the very start of a file,
before the header entry, usually holds the title, the copyright and the translators’
names, from the template (SOME DESCRIPTIVE TITLE.,
Copyright (C) YEAR, FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.)
to be filled in.
References
Each reference on a #: line is file_name:line_number or just
file_name. Several can share a line, separated by spaces:
#: src/menu.c:41 src/toolbar.c:208 src/help.c
A file name that contains spaces is enclosed between the characters U+2068 and U+2069.
Flags
A #, line is a comma-separated list of flags. The manual groups them
into the workflow flag, the sticky flags and the evolution of the syntax.
Workflow flag
| Flag | Meaning |
|---|---|
fuzzy | The translation is not to be trusted: msgmerge found the message close to a new one and copied its translation, or the translator is unsure. The translator removes the flag after review. msgfmt leaves a fuzzy entry out of the MO file unless told to use it. |
Format flags
A flag NAME-format says that the message is a format string of that
language, and its no- form, no-NAME-format, says it is not
although it looks like one (a % directive that is not a C directive,
for example). Only xgettext adds these flags. The names the manual
lists:
c, objc, c++, python,
python-brace, java, java-printf,
csharp, javascript, scheme, lisp,
elisp, librep, rust, go,
ruby, sh, sh-printf, awk,
lua, object-pascal, modula2, d,
ocaml, smalltalk, qt, qt-plural,
kde, boost, tcl, perl,
perl-brace, php, gcc-internal,
gfc-internal and ycp, each followed by
-format. The gfc-internal-format flag is deprecated, for GCC
14.x and earlier.
Other sticky flags
| Flag | Meaning |
|---|---|
range: minimum..maximum | For a plural entry: the numbers that the message is used for, two non-negative numbers. |
no-wrap | The tools do not break this entry’s long lines when they write the file. By default, lines wider than the page are wrapped unless --no-wrap is given. |
The manual lists no wrap flag.
The #= line
The manual says that from June 2025 a line starting #= is an
alternative to #, for flags, and that a program that adds flags must put
them on the #, line.
Previous strings
When msgmerge marks an entry fuzzy it can keep the old untranslated text in
#| lines, so the translator sees what changed in the source. The lines
repeat the keywords of the entry: #| msgctxt, #| msgid and
#| msgid_plural, each followed by a quoted string. The reader accepts only
these three keywords after #|:
#, fuzzy
#| msgid "File %d"
msgid "Files: %d"
msgstr "Fichiers : %d"
Not described
Known, not yet covered
- Reference: the syntax of the format strings that each
*-formatflag announces; the manual gives them under each language’s own section, which these pages do not yet cover.