gettext PO — msgctxt disambiguation and multi-line strings
The English word "Open" translated four different ways in one file — three msgctxt variants plus the context-free entry — alongside a multi-line msgid that must be concatenated with no separator, a no-c-format entry whose %% is literal text, and explicit tab and quote escapes with a significant trailing space.
# French translation for the Novus example file manager.
# Sample Translator <translator@example.invalid>, 2026.
#
msgid ""
msgstr ""
"Project-Id-Version: novus-example 2.0\n"
"POT-Creation-Date: 2026-01-01 00:00+0000\n"
"PO-Revision-Date: 2026-01-02 12:00+0000\n"
"Last-Translator: Sample Translator <translator@example.invalid>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. Same English word, three different French words. msgctxt is the disambiguator, and the .mo
#. key becomes msgctxt + U+0004 + msgid — a lookup that a parser ignoring msgctxt gets wrong in
#. a way no test on the English side can detect.
msgctxt "menu"
msgid "Open"
msgstr "Ouvrir"
msgctxt "adjective|a file that is currently open"
msgid "Open"
msgstr "Ouvert"
msgctxt "button|open-source licence filter"
msgid "Open"
msgstr "Libre"
#. No context at all — a fourth, separate entry with the same msgid.
msgid "Open"
msgstr "Ouvrir"
#. A multi-line msgid: the leading empty string is required, and the reader must CONCATENATE the
#. continuation lines with no separator of its own. The \n escapes are part of the string.
#: src/dialogs.c:88
msgid ""
"The folder could not be moved.\n"
"\n"
"Check that you have permission to write to the destination and that the "
"destination is not inside the folder you are moving."
msgstr ""
"Le dossier n'a pas pu être déplacé.\n"
"\n"
"Vérifiez que vous avez le droit d'écrire dans la destination et que celle-ci "
"ne se trouve pas à l'intérieur du dossier déplacé."
#. no-c-format tells the checker NOT to validate % sequences here, because the percent sign is
#. literal text rather than a printf directive.Specifications
- Locale
- fr
- Language
- French
- Msgctxt Entries
- 3
- Same Msgid Different Context
- 4
- Multiline Entries
- 1
- Features
- msgctxt | multi-line concatenation | no-c-format | \t and \" escapes
- Mo Key Encoding
- msgctxt + U+0004 + msgid
- Charset
- UTF-8
- Seed
- 20260807
- Wave
- p7
- Line Endings
- LF
Testing contract
Expected to pass- Scenario
- Parse the file, then look up "Open" with each context and with none.
- Expected result
- Four distinct results (Ouvrir, Ouvert, Libre, Ouvrir); a parser that ignores msgctxt collapses them and returns whichever it read last. The multi-line msgid joins into a single string with no inserted spaces or newlines beyond the explicit \n escapes.
What is a .po file?
A PO file (.po, Portable Object) is a gettext translation catalog: a plain-text list of msgid (source string) and msgstr (translation) pairs, with a header defining the language and plural rules, source-location comments, and support for plural forms. It is the working file translators edit and is compiled to a binary .mo for runtime.
How to use this file
Use an example .po file to test gettext parsers, PO editors and CAT tools, translation-memory importers, and PO-to-JSON/XLIFF converters, or to exercise plural-form handling.
How to use this file for testing
“gettext PO — msgctxt disambiguation and multi-line strings” is a deterministic Novus Examples fixture for Internationalization, Localization catalogs, Editor testing. Parallel text and accented, multi-script content — for testing translation pipelines, Unicode handling, and localization tooling.
Documented properties for this file: seed 20260807 · French · LF. Compare results against paired or grouped companions on this page when present (clean↔damaged, searchable↔scanned, or format twins) so scores stay reproducible across runs.
Download the file once, keep the path stable in CI or local scripts, and treat the spec table as the contract: dimensions, seeds, field lists, and roles are intentional. Corrupt or invalid samples are labelled as such — expect parsers to fail loudly rather than silently accept them.
Translation-catalog fixtures carry the same message set across formats, each with its native placeholder syntax. Test your i18n loader, catalog converter, or translation-memory tool, and use the RTL and CJK variants to check bidirectional text and Unicode handling.
Load the catalog with your i18n framework and verify placeholder interpolation and plural handling; the RTL and CJK variants exercise bidirectional text and font fallback.
Code examples
import polib # pip install polib
po = polib.pofile("msgctxt-multiline-fr.po")
print(len(po), "entries,", round(po.percent_translated()), "% translated")
for e in po[:3]:
print(e.msgid, "->", e.msgstr)Related files
- pogettext Catalog — Spanish (.po)A translated gettext .po catalog (Spanish) with a full header, source-location and translator comments, c-format flags, and a plural-form entry — for testing PO parsers and translation-memory tools.

- potgettext Template (messages.pot)A gettext .pot template extracted from source — msgid entries with empty msgstr values, source-location comments, and a plural form — the starting point for a new language translation.

- resx.NET RESX — EnglishA .NET Resources.resx file (English) with the standard ResX schema and resheader block plus name/value string data and comments, using {0} composite-format placeholders.

- resx.NET RESX — SpanishThe Spanish satellite RESX (Resources.es.resx) — for testing .NET resource parsers and culture-based resource resolution against the same keys.

- xmlAndroid strings.xml — EnglishAn Android values/strings.xml (English) with string resources, a <plurals> block, and a <string-array>, using positional %1$s placeholders — the res/values/ default catalog.

- xmlAndroid strings.xml — SpanishThe Spanish Android strings.xml (as res/values-es/) — for testing Android resource parsers, plurals, and string-array localization.

Generated by generation/localization_p7.py. Free for any use, no attribution required — license.