<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>The DarkMod Wiki  - Recent changes [en]</title>
		<link>https://wiki.thedarkmod.com/index.php?title=Special:RecentChanges</link>
		<description>Track the most recent changes to the wiki in this feed.</description>
		<language>en</language>
		<generator>MediaWiki 1.45.5</generator>
		<lastBuildDate>Sat, 24 Oct 2026 21:01:05 GMT</lastBuildDate>
		<item>
			<title>Converting Translations with all lang to po</title>
			<link>https://wiki.thedarkmod.com/index.php?title=Converting_Translations_with_all_lang_to_po&amp;diff=34632&amp;oldid=34625</link>
			<guid isPermaLink="false">https://wiki.thedarkmod.com/index.php?title=Converting_Translations_with_all_lang_to_po&amp;diff=34632&amp;oldid=34625</guid>
			<description>&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Overview&lt;/span&gt;&lt;/p&gt;
&lt;a href=&quot;https://wiki.thedarkmod.com/index.php?title=Converting_Translations_with_all_lang_to_po&amp;amp;diff=34632&amp;amp;oldid=34625&quot;&gt;Show changes&lt;/a&gt;</description>
			<pubDate>Sat, 24 Oct 2026 19:39:45 GMT</pubDate>
			<dc:creator>Geep</dc:creator>
			<comments>https://wiki.thedarkmod.com/index.php?title=Talk:Converting_Translations_with_all_lang_to_po</comments>
		</item>
		<item>
			<title>Converting Translations with all lang to po</title>
			<link>https://wiki.thedarkmod.com/index.php?title=Converting_Translations_with_all_lang_to_po&amp;diff=34625&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.thedarkmod.com/index.php?title=Converting_Translations_with_all_lang_to_po&amp;diff=34625&amp;oldid=0</guid>
			<description>&lt;p&gt;create article&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=== Moving from LANG to POT and PO Files===&lt;br /&gt;
&amp;#039;&amp;#039;By Geep, 2026&amp;#039;&amp;#039;&lt;br /&gt;
==Overview==&lt;br /&gt;
Traditionally, TDM&amp;#039;s i18n approach has used a UTF8 &amp;quot;all.lang&amp;quot; file, which has an &amp;quot;[English]&amp;quot; section as master, followed by individual sections for each TDM-supported language. Across sections, phrases have been tied together by #str_ids. Then, from all.lang, language files (e.g., english.lang, german.lang, etc) in language-specific 8-bit encodings are generated and distributed.&lt;br /&gt;
&lt;br /&gt;
Consider specifically tdm_base01.pk4/strings/all.lang, that provides TDM&amp;#039;s main menu and other core phrases.&lt;br /&gt;
&lt;br /&gt;
For [upcoming] TDM 2.15, the [English] portion of this was substantially reworked, to provide greater and more accurate context for human and AI translators, and so assist remaining translation updates and fill-ins.&lt;br /&gt;
&lt;br /&gt;
Building off that, Geep and stgatilov are undertaking a move towards the popular GNU &amp;quot;gettext&amp;quot; translation architecture, with:&lt;br /&gt;
* an English template file (english.pot)&lt;br /&gt;
* various individual language files (*.po). The target encoding for these remains UTF8, unlike the *.lang files. Instead, the TDM engine internally converts to 8-bit form (at least for now).&lt;br /&gt;
&lt;br /&gt;
All these can be edited by third-party apps like &amp;quot;poedit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
It is desirable to retain the advantages of the reworked all.lang. So, rather than the stock workflow of using &amp;quot;xgettext&amp;quot; to generate a .pot file from marked-up *.cpp, *.hpp, and *.gui source, a further-marked-up version of all.lang [English] is used instead, as in effect the &amp;quot;source&amp;quot; material.&lt;br /&gt;
&lt;br /&gt;
In turn, this used by all_lang_to_po to generate:&lt;br /&gt;
* &amp;quot;english.pot&amp;quot;, as structured from all.lang [English].&lt;br /&gt;
* Various non-english &amp;quot;*.po&amp;quot; files. These also reflect the all.lang [English] structure, because the creation of each begins with copying the english.pot template, then adding all existing translations from the appropriate language section of all.lang .&lt;br /&gt;
* Optionally, an &amp;quot;english.po&amp;quot; file, where each English string appears twice. This is not required, since TDM will consume &amp;quot;english.pot&amp;quot; for the English phrases.&lt;br /&gt;
&lt;br /&gt;
[LATER: The exact workflow for further revisions after this transition is still being determined. Likewise applicability to FM translations.]&lt;br /&gt;
==Treatment of Unique IDs==&lt;br /&gt;
As background, some gettext-based translation projects do not use symbolic ids (like #str_), but just use unique English strings as keys. This would be represented in the english.pot file as:&lt;br /&gt;
&lt;br /&gt;
 msgid &amp;quot;Mine&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Then, in each corresponding language-specific .po, msgstr would be filled in with the translation.&lt;br /&gt;
&lt;br /&gt;
If a particular English key phrase appears multiple times with different meanings, then an additional &amp;quot;context&amp;quot; field can distinguish them:&lt;br /&gt;
&lt;br /&gt;
 msgctxt &amp;quot;weapon&amp;quot;&lt;br /&gt;
 msgid &amp;quot;Mine&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 msgctxt &amp;quot;location&amp;quot;&lt;br /&gt;
 msgid &amp;quot;Mine&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this case, pot/po considers msgctxt+msgid to be the unique key (while msgctxt by itself is not unique.)&lt;br /&gt;
&lt;br /&gt;
For projects like main-menu TDM with symbolic keys, an obvious configuration of the format would be:&lt;br /&gt;
&lt;br /&gt;
 msgid &amp;quot;#str_12345&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
But this has a significant drawback. Because the .pot file doesn&amp;#039;t contain any English strings, features of poedit that use AI (or community resources) to do draft string translations can&amp;#039;t be used. There are ways to overcome this; a reportedly popular one, adopted here, is to move the symbolic link into msgctxt:&lt;br /&gt;
&lt;br /&gt;
 msgctxt &amp;quot;#str_12345&amp;quot;&lt;br /&gt;
 msgid &amp;quot;Mine&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If further context is needed, it could be included as a comment, discussed further below.&lt;br /&gt;
&lt;br /&gt;
==Editing &amp;amp; Markup in all.lang [English]==&lt;br /&gt;
===Programmatic Considerations===&lt;br /&gt;
On each line within the [English] section, leading tabs and spaces are ignored.&lt;br /&gt;
====Po-Visible Lines====&lt;br /&gt;
We define here a &amp;quot;po-visible&amp;quot; line as one that appears as a visible, selectable row in poedit. There are two types, which we name here:&lt;br /&gt;
* &amp;quot;Translatable&amp;quot; lines&lt;br /&gt;
* &amp;quot;Structure&amp;quot; lines&lt;br /&gt;
&lt;br /&gt;
Translatable lines are indicated by retaining the traditional TDM all.lang layout:&lt;br /&gt;
 	&amp;quot;#str_12345&amp;quot;	&amp;quot;Some text here&amp;quot;&lt;br /&gt;
Structure lines (which will not be expected to be translated) serve as headlines to group translatable lines together within poedit. Arbitrarily, they are flagged with &amp;quot;//|&amp;quot;, e.g.&lt;br /&gt;
 	//| SETTINGS VIDEO SUBMENU&lt;br /&gt;
====Comments====&lt;br /&gt;
Comments must be associated with, and anchored by, a particular po-visible line. In all.lang, they are arbitrarily flagged as follows:&lt;br /&gt;
* Lines that start with &amp;quot;//&amp;quot; are BEFORE comments, associated with a po-visible line that immediately follows the group of them. (Excluded: lines starting with &amp;quot;//|&amp;quot; or &amp;quot;///&amp;quot;.)&lt;br /&gt;
* Lines that start with &amp;quot;///&amp;quot; are AFTER comments, associated with a po-visible line that immediately precedes the group of them.&lt;br /&gt;
When processed by all_lang_to_po, both types will be emitted together (as a group of consecutive individual comment lines, all preceding the po-visible line). Each comment line be flagged by starting with &amp;quot;#.&amp;quot; and omit the &amp;quot;//&amp;quot; or &amp;quot;///&amp;quot;.  In poedit, these will appear in the &amp;quot;Note to Translators&amp;quot; pane, that is shown when the po-visible line is selected.&lt;br /&gt;
&lt;br /&gt;
It was found necessary to have both types to maximize readability of both all.lang and .pot, and provide flexibility for anchoring.&lt;br /&gt;
&lt;br /&gt;
Special treatment: In all.lang, it is common with a group of before-comments for the last line to end in &amp;quot;:&amp;quot;, referring to the next line with its po-visible anchoring item. However, once converted into a &amp;quot;Note to Translators&amp;quot;, the colon is either useless or erroneously seems to address the first after-comment. So the conversion process automatically removes it. (If the all.lang editor needs to retain it, add a space after it.)&lt;br /&gt;
&lt;br /&gt;
Note: a third possibility, a &amp;quot;//&amp;quot; comment at the trailing end of a translatable line within the [English] section, is deprecated. If present, all_lang_to_po will issue a console warning, and turn it into a &amp;quot;before&amp;quot; comment line. The reworked all.lang [English] avoids this form entirely.&lt;br /&gt;
===Style Considerations===&lt;br /&gt;
====Headlines====&lt;br /&gt;
Currently, the &amp;quot;structure&amp;quot; lines are used for primarily for 3 levels of headlines/outlines:&lt;br /&gt;
 1) ALL CAPS WITH UNDERLINE&lt;br /&gt;
 =========================&lt;br /&gt;
 2) ALL CAPS&lt;br /&gt;
 3) Camel Case&lt;br /&gt;
In a few spots, a fourth style, just a sentence, is used for a group comment that needs to be visible.&lt;br /&gt;
&lt;br /&gt;
Note that the first style uses two po-visible lines, and is used sparingly to denote major chapters.&lt;br /&gt;
&lt;br /&gt;
Translators should be encouraged to click on structure lines, because often times, there are &amp;quot;Notes to Translators&amp;quot; associated with them.&lt;br /&gt;
====Comments about Source Code====&lt;br /&gt;
When there is editor-provided information about what source code file (e.g., cpp, gui) a particular #str_id appears in, this usually becomes the first line of a Notes to Translators. (This is in the spirit of, but different from, the specific-line annotation that xgettext provides. The latter, tagged with &amp;quot;#:&amp;quot;,  has a very strict syntax and is only reasonable if programmatically generated, i.e., by xgettext.)&lt;br /&gt;
====Comments about #str_ID References====&lt;br /&gt;
Within a comment, all.lang uses a leading &amp;quot;&amp;amp;&amp;quot; followed by the seeming text of a translatable line, as a &amp;quot;reference&amp;quot; to that #str_id, e.g.:&lt;br /&gt;
 //&amp;amp;	&amp;quot;#str_12345&amp;quot;	&amp;quot;Some text here&amp;quot;&lt;br /&gt;
or&lt;br /&gt;
 ///&amp;amp;	&amp;quot;#str_12345&amp;quot;	&amp;quot;Some text here&amp;quot;&lt;br /&gt;
The meaning: that #str_id was already uniquely defined elsewhere in all.lang [English], and is being listed here solely to mark for the reader where it is being used again within, say, a menu&amp;#039;s layout. (Without requiring any special processing, in the .pot/.po file, the &amp;quot;&amp;amp;&amp;quot; is retained within a comment line, and when viewed in poedit, becomes the first letter on the corresponding line within &amp;quot;Notes to Translators&amp;quot;.)&lt;br /&gt;
==Generated Preamble Header==&lt;br /&gt;
===In the POT File===&lt;br /&gt;
Below is a 2026 example of a gettext-style header in the english.pot file. By gettext convention, the fields starting with &amp;quot;X&amp;quot; are customized additions, e.g., for TDM.&lt;br /&gt;
 # TDM does not support po plural forms at this time, so this field&lt;br /&gt;
 # (with language variants) is excluded (which may cause warnings):&lt;br /&gt;
 # &amp;quot;Plural-Forms: nplurals=2; plural=(n != 1);\n&amp;quot;&lt;br /&gt;
 msgid &amp;quot;&amp;quot;&lt;br /&gt;
 msgstr &amp;quot;&amp;quot;&lt;br /&gt;
 &amp;quot;Project-Id-Version: TDM Main Menu, 2.15\n&amp;quot;&lt;br /&gt;
 &amp;quot;POT-Creation-Date: 2026-10-22T20:59:54Z\n&amp;quot;&lt;br /&gt;
 &amp;quot;Language: en\n&amp;quot;&lt;br /&gt;
 &amp;quot;Content-Type: text/plain; charset=UTF-8\n&amp;quot;&lt;br /&gt;
 &amp;quot;MIME-Version: 1.0\n&amp;quot;&lt;br /&gt;
 &amp;quot;Content-Transfer-Encoding: 8bit\n&amp;quot;&lt;br /&gt;
 &amp;quot;Language-Team: none\n&amp;quot;&lt;br /&gt;
 &amp;quot;X-TDM-All.Lang-Format-Input-File-Name: all.lang\n&amp;quot;&lt;br /&gt;
 &amp;quot;X-TDM-All.Lang-Format-Input-File-Date: 2026-10-08 16:05:35\n&amp;quot;&lt;br /&gt;
 &amp;quot;X-TDM-POT-Output-File-Name: english.pot\n&amp;quot;&lt;br /&gt;
 &amp;quot;X-TDM-Generator: Program all_lang_to_po v. 0.13\n&amp;quot;&lt;br /&gt;
===In the PO Files===&lt;br /&gt;
The *.po files have the same preamble, except the Language field has the appropriate code.&lt;br /&gt;
==Data Conversion from all.lang [English] to english.pot==&lt;br /&gt;
[TO DO - THIS INFO GOES INTO TABLE CELLS]&lt;br /&gt;
From all.lang [English]	To .pot [Note 1]	Notes&lt;br /&gt;
&amp;quot;#str_whatever&amp;quot; &amp;quot;text&amp;quot;	msgctxt &amp;quot;#str_whatever&amp;quot;&lt;br /&gt;
msgid &amp;quot;text&amp;quot;&lt;br /&gt;
msgstr &amp;quot;&amp;quot;	&lt;br /&gt;
Same, but &amp;quot;text&amp;quot; has printf specifiers	Adds line: &amp;quot;#, c-format&amp;quot;	[Note 2]&lt;br /&gt;
Same, but &amp;quot;if line &amp;gt; maxlength chars...&amp;quot;	msgid &amp;quot;&amp;quot;&lt;br /&gt;
&amp;quot;if line &amp;gt; maxlength chars, ... then &amp;quot;&lt;br /&gt;
&amp;quot;chunked, i.e., word wrapped&amp;quot;	[Note 3]&lt;br /&gt;
//| Structure text	msgctxt &amp;quot;##&amp;quot;&lt;br /&gt;
msgid &amp;quot;Structure text&amp;quot;&lt;br /&gt;
msgstr &amp;quot;&amp;quot;	[Note 3][Note 4]&lt;br /&gt;
// Before-comment	#. Before-comment	[Note 5]&lt;br /&gt;
/// After-comment	#. After-comment	[Note 5]&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
[1] Following a poedit convention, each block of data associated with a given phrase is separated by a blank line in the file (but not visible in the poedit UI). Also, in the optional english.po generated by all_lang_to_po, the &amp;quot;msgstr&amp;quot; is not an empty string, but instead the same string as &amp;quot;msgid&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[2] Only specifier substrings actually used in TDM are searched for: %d, %i, %s, %0 .&lt;br /&gt;
&lt;br /&gt;
[3] Chunking applies to msgctxt, msgid, and msgstr, and for both translatable and structure text (though the latter is not likely to need it). You can suppress chunking with an all_lang_to_po &amp;quot;-long&amp;quot; option. And change poedit to allow long lines. (Note however: poedit appears to have its own treatment of word wrap that seems idiosyncratic.) [maxLength is in theory 79 printable chars; my code is a little more conservative at moment.]&lt;br /&gt;
&lt;br /&gt;
[4] Note that msgctxt is &amp;quot;##&amp;quot; (rather than all.lang&amp;#039;s &amp;quot;//|&amp;quot; or other considered alternatives). This style choice, eventually arrived at, reflecting that:&lt;br /&gt;
* comments in po generally start with &amp;quot;#&amp;quot;&lt;br /&gt;
* in poedit, for a po-visible line, the msgctxt content is visually separated from the msgid content by a &amp;quot;|&amp;quot;, so already has that hint.&lt;br /&gt;
* Keeping this as short as possible was visually helpful in poedit.&lt;br /&gt;
&lt;br /&gt;
Also, the &amp;quot;Structure Text&amp;quot; phrase must be unique to the file (since the msgctxt &amp;quot;##&amp;quot; is not unique).&lt;br /&gt;
&lt;br /&gt;
[5] Before and after cases differ in only where lines are defined in all.lang; both are emitted into .pot before the corresponding po-visible anchor line. Also, any too-line will be broken up into multiple comment lines – similar to chunking in spirit if not details.&lt;br /&gt;
==Data Conversion from all.lang [&amp;lt;language&amp;gt;] to &amp;lt;language&amp;gt;.po==&lt;br /&gt;
The process begins by copying the english.pot file, then filing in the &amp;quot;msgstr&amp;quot; fields with all the existing translations. Within the all.lang &amp;lt;language&amp;gt; section, full-line comments are ignored. The only comments retained are those that trail phrase lines. In the .po file, such a comment becomes a separate line beginning with &amp;quot;#&amp;lt;space&amp;gt;&amp;quot; instead of &amp;quot;//&amp;quot;. In poedit this appears in the translator&amp;#039;s &amp;quot;Comment&amp;quot; pane. This treatment covers the traditional translator notation of &amp;quot;stays the same&amp;quot; specified by TDM.&lt;br /&gt;
&lt;br /&gt;
If the content of msgctxt, msgid, or msgstr is too long, and the -long option is not specified, &amp;quot;chunking&amp;quot; (word-wrap) will occur.&lt;br /&gt;
==Release Notes &amp;amp; Possible Further Work==&lt;br /&gt;
See the start of the all_lang_to_po.cpp file.&lt;br /&gt;
==Downloadable Files==&lt;br /&gt;
[This section coming soon]&lt;br /&gt;
&lt;br /&gt;
Source Code&lt;br /&gt;
&lt;br /&gt;
Executable&lt;br /&gt;
&lt;br /&gt;
==See More==&lt;br /&gt;
For more about the headers, see&lt;br /&gt;
* https://po-file.com/blog/po-file-header-explained&lt;br /&gt;
* https://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html&lt;/div&gt;</description>
			<pubDate>Fri, 23 Oct 2026 20:01:05 GMT</pubDate>
			<dc:creator>Geep</dc:creator>
			<comments>https://wiki.thedarkmod.com/index.php?title=Talk:Converting_Translations_with_all_lang_to_po</comments>
		</item>
</channel></rss>