The PO File Header Explained: Every Field, Line by Line
A field-by-field reference sorted by what GNU gettext 1.0 actually does about each line, with every claim executed rather than recalled. Starts from the fact that explains all the quirks — the header is an ordinary entry whose msgid is empty, so it need not come first, unknown fields survive forever, and duplicates are accepted silently. Then the punctuation rule nobody documents: adjacent quoted strings concatenate with nothing between them, so what ends a field is the literal backslash-n, and dropping one welds two fields together and produces a diagnostic naming the field you did not touch. The spine is three tiers. Fatal: a missing header, a missing or unportable charset, the CHARSET placeholder, and Plural-Forms broken or disagreeing with the msgstr count. Warned but compiling with exit 0: Project-Id-Version, PO-Revision-Date, Last-Translator, Language-Team, MIME-Version, Content-Transfer-Encoding and Language, enumerated from one run against a header stripped to a single line. Ignored entirely: POT-Creation-Date, Report-Msgid-Bugs-To, and every X- field. Only two lines do real work. Content-Type is shown corrupting a catalog at the byte level — a UTF-8 file whose header claims Latin-1 compiles with no warning, turns C3 B6 into C3 83 C2 B6, and the resulting MO then truthfully declares UTF-8, so the corruption has become the content. Plural-Forms is shown as what it is, a C expression evaluated at runtime, with a live ngettext run selecting Russian forms at n=1, 21, 101 and 111 and the same catalog changing behaviour when only the header line is swapped. Plus the discovery that Language, the field everyone treats as a label, is what makes msgfmt print the correct plural line for you — with Language-Team as the fallback and Arabic absent from gettext's table entirely — a msgmerge matrix showing which fields the POT overwrites and which the translator keeps, why Project-Id-Version drifts forever, why POT-Creation-Date never reaches the MO, why msginit hands Windows users a CP1252 file, a copy-paste header with per-language plural rules, and a ten-line CI check.