Hello, we apologize but forum registrations are non-functional at this time. This issue should be fixed around mid-December. Until then, please stop by our Discord channel if you'd like to get in touch with the team. Thanks!

Getting gettext & translation into Allacrost

For discussion of the code running behind the game

Moderator: Staff

User avatar
Jetryl
Artist
Posts: 1485
Joined: Fri Aug 26, 2005 1:35 am
Location: Southern Minnesota, USA

Post by Jetryl » Sat Aug 11, 2007 4:35 pm

Viliam wrote:One argument for using "_" macro/function: It will be probably the most frequently used function in the Lua files. Really, you have to put it before each dialog line, before each displayed text, everywhere except for algorithms. So it would be better if the name is short; easier to write, easier to read -- or more importantly: to skip when reading. You probably would not want 20% of the Lua files to be the word "TranslateString" repeated endlessly. If you really don't like "_", maybe try "T" or "TS" instead.
I strongly suggest using the _ macro, mostly because it should be treated as part of the standard method of writing strings in the lua files, rather than as a function you have to type every single time you write a string. It's so common that it should feel like a language syntax feature, rather than a function being called. Because we're basically going to be translating every single string we ever use (99.5% of them, anyways).

It's easier to read if we have:

Code: Select all

	dialogue = hoa_map.MapDialogue();
	dialogue:AddText(_"Laila, what's wrong? You have a worried look on your face.", 1000, -1, -1);
	dialogue:AddText(_"You're going into the cave again, aren't you?", 2, -1, -1);
Instead of having:

Code: Select all

	dialogue = hoa_map.MapDialogue();
	dialogue:AddText(TranslatableString("Laila, what's wrong? You have a worried look on your face."), 1000, -1, -1);
	dialogue:AddText(TranslatableString("You're going into the cave again, aren't you?"), 2, -1, -1);
... because we don't need it to be obvious to the reader that this is a function being called, rather than the standard syntax for defining strings in the language. It should feel like the standard syntax for defining strings in the language; in fact the only reason I wouldn't go so far as to directly overload the basic string operators (") is because a] it's probably not possible, and b] there might be some extremely rare cases when we don't want to translate something.
User avatar
Roots
Dictator
Posts: 8669
Joined: Wed Jun 16, 2004 12:07 pm
Location: Austin TX
Contact:

Post by Roots » Sat Aug 11, 2007 5:23 pm

... because we don't need it to be obvious to the reader that this is a function being called, rather than the standard syntax for defining strings in the language. It should feel like the standard syntax for defining strings in the language; in fact the only reason I wouldn't go so far as to directly overload the basic string operators (") is because a] it's probably not possible, and b] there might be some extremely rare cases when we don't want to translate something.
There are tons of uses for non-translatable strings; it is not "extremely rare" by any means at all. Filenames, debug messages, etc. all need standard strings. Plus remember that we're not just dealing with C++ here, we're also dealing with Lua (which doesn't have operator overlording IIRC).


The reason I'm half-against using _ is because its too easy to miss. We might have a string that we need to translate, but someone forgot the _. Moreover, going through the code it is not easily apparent which strings are translated and which are not. Our code standard states that names should be descriptive. I don't care if "_" is some sort of standard in gettext or wherever, because it is unfamiliar to me and I bet it is unfamiliar to most, if not all, of the programmers here (and hence it will be unfamiliar to most programmers elsewhere). If I'm a random dude looking through the Allacrost code and I find a _"Some text.", I'd wonder what the heck is "_", and wouldn't have a damn clue where to find out what it does or where it is defined.


How about we call the function Translate()? It takes about 2 seconds to type it, and it is infinitely more apparent about its purpose than _. I know some of you will argue in favor of _ because it will be used everywhere, but guess what? ustring is used everywhere. So is int32, float.... hell, why don't we just do #defines to make int == i, float == f, etc? I know I will use ints and floats a lot more than strings which need to be translated, so if we use "_" I think we should also #define all the ints and floats to i and f as well. Lets be sloppy and lazy programmers :rolleyes:
Image
User avatar
Jetryl
Artist
Posts: 1485
Joined: Fri Aug 26, 2005 1:35 am
Location: Southern Minnesota, USA

Post by Jetryl » Sun Aug 12, 2007 1:32 am

:huh: You know, you do have a point.


Now that I think about it, that was one of the biggest problems with Wesnoth's source code, and I'm starting to think this might be properly recognized as "syntactic heroin" rather than "syntactic sugar".

Wesnoth's source code presupposes a lot of domain-specific knowledge; e.g. stuff you can only understand if you you're taught it by someone who knows the convention. These conventions aren't written down anywhere, and if you don't have someone to ask, you're screwed. I had a hideous time going through wesnoth's code; I think the thing that blew my stack was when I realized they'd overloaded the array operator to read fields out of the unit's stat file.

So actually, as much as it might take more time to write, and might make the code slightly harder to read (signal/noise), I'm starting to think that Roots is absolutely right about this.


I vote for "Translate()", based on that.



Syntactic what?
http://en.wikipedia.org/wiki/Syntactic_sugar
Syntactic heroin is the dark opposite of the above, it's code that looks like it makes things easier for humans to understand/write, but actually makes them hideously more obfusicated in the interests of making them more concise to write.
Image
ettin
Junior Member
Posts: 45
Joined: Thu Aug 31, 2006 3:23 pm

Post by ettin » Sun Aug 12, 2007 10:57 am

Linds wrote:I really think each map should have its own. Maps will be added map by map so constant edits from different sources will make this nightmarish to merge with one file.
Hmm? You don't have to deal with merges, see msgmerge(1).

Please, don't split too much in advance, it would be really annoying for tranlators to have lots of small .po files. It is always possible to split later.
Roots wrote: Actually, I'd like to ask for suggestions for our .po file structure (how many should we have, how should they be broken up, etc). Here's my suggestion (and I'm assuming that these can only be placed in a single directory because I think that was stated before):
- engine.po: contains all translations for strings embedded in the C++ code
- objects.po: all translations for global objects (items, weapons, armor, etc)
- actors.po: all translations for characters and enemies
- maps.po: all translations for anything that is contained within Lua map files
- misc.po: contains anything that is not categorized in the above files
Instead of .po, you probably mean .pot here. Note that .po files are the files that contain translations, they are usually named ll.po, where ll is the ISO 639 language code (e.g. ca.po, de.po, ko.po...). On the other hand, .pot files contain the "templates".

Translations are usually grouped by domain, and each domain has its own directory:

Code: Select all

engine/
  ca.po
  de.po
  ko.po
  engine.pot
objects/
  ca.po
  de.po
  ko.po
  objects.pot
...
User avatar
MoOshiCow
Developer
Posts: 18
Joined: Thu Jul 05, 2007 12:42 pm
Location: (currently) Pittsburgh, USA
Contact:

Post by MoOshiCow » Sun Aug 12, 2007 12:20 pm

So I'm perfectly fine with the Translate() macro..
It's one extra word to type...its clear in its purpose

And scripters have to follow the format
dialogue::AddText("string", -1, -1 -1)
in order to get dialogue into the game..
I'm sure they can handle an extra thing to follow
(of course, Translate() won't be only for scripters and dialogue..)
ettin wrote: Translations are usually grouped by domain, and each domain has its own directory:

Code: Select all

engine/
  ca.po
  de.po
  ko.po
  engine.pot
objects/
  ca.po
  de.po
  ko.po
  objects.pot
...

Hmm..so I don't really know these "standards" of doing things
regarding gettext/translation...
but if i understand how this subdirectory system works:

I bindtextdomain() with each subdirectory, meaning, when initializing gettext() i do something like:

Code: Select all

bindtextdomain( "engine", ./txt/engine)
bindtextdomain( "objects", ./txt/objects)
But as far as i have tested, the structure of this will turn out to be:

Code: Select all

./txt/
  engine/
    engine.pot
    ca/
      LC_MESSAGES/
        ca.po
        ca.mo
    de/
      LC_MESSAGES/    
        de.po
        de.mo
    ko/
      LC_MESSAGES/
        ko.po
        ko.mo
    
  objects/
    objects.pot
    ca/
      LC_MESSAGES/
        ca.po
        ca.mo
    de/
      LC_MESSAGES/    
        de.po
        de.mo
    ko/
      LC_MESSAGES/
        ko.po
        ko.mo

well..the .po files could be anywhere, so i guess they could be put in their respective ./engine or ./objects folder...but the .mo files need to be in the ca/LC_MESSAGES, etc. folders..

i have nothing against putting the .po files in ./engine or ./objects..
in fact if we're using this setup..i'll rather put them in those folders
because it would be easier for translators to access the .po files

(i usually put .po files with .mo files because its easier to create .mo files in the same folder as .po files...)


And so, for comparison, this is how our current setup looks like:

Code: Select all


bindtextdomain( "engine", ./txt/)
bindtextdomain( "object", ./txt/)


./txt/
  engine.pot
  object.pot
  ca/
    LC_MESSAGES/
      object.po
      engine.po
      object.mo
      engine.mo
  de/
    LC_MESSAGES/    
      object.po
      engine.po
      object.mo
      engine.mo
  ko/
    LC_MESSAGES/
      object.po
      engine.po
      object.mo
      engine.mo
   
i guess it doesn't follow the standards of naming .po files, and
also doesn't split up things into subdirectories..
which i think roots sounded like he wanted to do..

so yeah, that's how they compare...
in order to organize lots of .po files the subdirectories would definitely help...but i must agree that splitting up too many .po files will only make it worse for the translators...
ettin
Junior Member
Posts: 45
Joined: Thu Aug 31, 2006 3:23 pm

Post by ettin » Sun Aug 12, 2007 2:54 pm

MoOshiCow wrote: .
Hmm..so I don't really know these "standards" of doing things
regarding gettext/translation...
but if i understand how this subdirectory system works:

I bindtextdomain() with each subdirectory, meaning, when initializing gettext() i do something like:

Code: Select all

bindtextdomain( "engine", ./txt/engine)
bindtextdomain( "objects", ./txt/objects)
well..the .po files could be anywhere, so i guess they could be put in their respective ./engine or ./objects folder...but the .mo files need to be in the ca/LC_MESSAGES, etc. folders..

i have nothing against putting the .po files in ./engine or ./objects..
in fact if we're using this setup..i'll rather put them in those folders
because it would be easier for translators to access the .po files

(i usually put .po files with .mo files because its easier to create .mo files in the same folder as .po files...)
Note that .mo files are autogenerated binary files that are only important when the program is built/installed, so their location in the Allacrost hierarchy isn't that relevant (I mean, they shouldn't be kept in the repo).

ll/LC_MESSAGES can be a local path, but it is usually a system wide directory (e.g. /usr/share/locale/ko/LC_MESSAGES in unix-like systems). Also, I forgot about it, but domain names should be unique since .mo files are named after their domain. So we should use "hoa-engine", "hoa-object"s, etc. for domain names rather than "engine", "objects", etc.

Anyway I don't think this is that important... all this kind of things can be easily addressed once you commit the code to the svn repo ;)
Viliam
Contributor
Posts: 35
Joined: Tue Sep 05, 2006 4:25 pm
Location: Bratislava, Slovakia
Contact:

Post by Viliam » Tue Aug 14, 2007 3:47 pm

I think that it would be useful to look at strings as if translatable strings and nontranslatable strings were a different data type. Because in some sense they are not assignment-compatible. If a variable is supposed to contain a translatable string, it is probably a bug to put there nontranslatable value, and vice versa.

(Sometimes we put an untranslatable string inside of translatable string, for example: "Error reading file 'config.cfg'." -- we want to translate "Error reading file '%s'.", but not to translate "config.cfg".)

In this perspective, using syntax-like macro _"..." helps to emphasise that there is a literal value of different kind; a translatable string literal. It is good to think about _ as an undividable part of the string.

If we think about translating function as function, it makes some temptations. For example, which of the following code examples is better?

a)

Code: Select all

function DoSomething(s) {
  DoSomethingWithString(s);
}

DoSomething(Translate("Hello World!"));
DoSomething(Translate("Hello Another World!"));
b)

Code: Select all

function DoSomething(s) {
  DoSomethingWithString(Translate(s));
}

DoSomething("Hello World!");
DoSomething("Hello Another World!");
The version (b) seems more correct, mostly because it is shorter. However it has one problem. If you forget to write the function "Translate" inside of "DoSomething" function body, the mistake is not obvious. You must make note that the "DoSomething" function has parameter a string which yet has to be translated. But if you know that the translation symbol must be always included immediately before the translatable string literal, it would be obvious if some "Translate" function would be missing in version (a). In a simplified version, any missing translation would be obvious -- you understand that "Hello World!" has to be translated, and look next if it is translated. You do not have to know anything about "DoSomething" function.

Code: Select all

function DoSomething(s) {
  DoSomethingWithString(s);
}

DoSomething(_("Hello World!"));
DoSomething(_("Hello Another World!"));
Or consider this part of code. It is only a pseudo-code, because I do not remember Lua syntax, so just to show a point:

Code: Select all

GreenSpider = new Monster (
  id = "GreenSpider",
  name = _("Green Spider"),
  hitpoints = 20,
  attack = 5,
  description = _("Yes, this is really dangerous spider."),
  picture = "greenspider.png",
  picture_attack = "greenspider1.png",
  sound_attack = "attack1.ogg",
  description_dead = _("This is a dead body of spider."),
);
It is very easy to check whether some _ is missing, or is somewhere where it is not supposed to be... if we have a convention to always put it next to string literal. With function "Translate", there will be a temptation to call this function later. Why should it be called in each monster definition, if it is simpler to call it later when the string will be displayed.

So what I wanted to say is that technically function "Translate" and function "_" are the same. Difference is in the way of thinking. We should not think about it as a function, which may be called whereever it seems appropriate. It is safer to think about is as a part of string literal, which must be always immediately before the string. It can prevent making some bugs. Technically it is a function, but it is a very special function.
User avatar
MoOshiCow
Developer
Posts: 18
Joined: Thu Jul 05, 2007 12:42 pm
Location: (currently) Pittsburgh, USA
Contact:

Post by MoOshiCow » Thu Aug 23, 2007 12:59 pm

Viliam wrote:
a)

Code: Select all

function DoSomething(s) {
  DoSomethingWithString(s);
}

DoSomething(Translate("Hello World!"));
DoSomething(Translate("Hello Another World!"));
b)

Code: Select all

function DoSomething(s) {
  DoSomethingWithString(Translate(s));
}

DoSomething("Hello World!");
DoSomething("Hello Another World!");
The version (b) seems more correct, mostly because it is shorter. However it has one problem. If you forget to write the function "Translate" inside of "DoSomething" function body, the mistake is not obvious. You must make note that the "DoSomething" function has parameter a string which yet has to be translated. But if you know that the translation symbol must be always included immediately before the translatable string literal, it would be obvious if some "Translate" function would be missing in version (a).
Okay..so i'll admit i was trying to work my way out and use version (b), so that i dont have to put as many Translate(string) or _(string) in the code...

and also i didn't have to deal with any lua/luabind code that i'm not all too
familiar with..

but now i have been trying to work with lua/luabind code...
and have some questions:

so as i said i'm new to all this stuff..but i've been reading through
defs.cpp, defs.h and the .lua files and tried following previous examples
to implement this translation stuff to lua files..

now since i have a Translate() function defined in hoa_utils,
I put something like:

Code: Select all

module(hoa_script::ScriptManager->GetGlobalState(), "hoa_utils")
[
	def("Translate", &hoa_utils::Translate)
];
then, when i tried editing the lua files to call Translate(),
i needed to do something like this:

Code: Select all

dialogue:AddText(hoa_utils.Translate("Laila, what's wrong? You have a worried look on your face."), 1000, -1, -1); --Line 0
even if i replaced "Translate" to "_" it would still be like hoa_utils._(string)
which doesn't look all too great in my opinion..so right now i changed it to..

Code: Select all

txt = hoa_utils.Translate("Laila, what's wrong? You have a worried look on your face.");
dialogue:AddText(txt, 1000, -1, -1); --Line 0
well this works...as in the game runs and successfully translates and all..
but i'm not sure if this is the right way to do it...
User avatar
Roots
Dictator
Posts: 8669
Joined: Wed Jun 16, 2004 12:07 pm
Location: Austin TX
Contact:

Post by Roots » Thu Aug 23, 2007 1:36 pm

That is the correct way to do it :approve:


Actually seeing that gave me an idea. Its kind of bulky to put the line of text in the AddDialogue function and I like how you defined the text on a seperate line. So maybe what we could do is define a table in the load function that contains all dialogue text, and then insert each entry into the AddDialogue call as appropriate. Example:

Code: Select all

function Load(m) {
  map = m;

  dtext = {
    [1] = "This is the first line of dialogue...",
    [2] = "...And this is the second!"
  }

  dialogue:AddText(dtext[1], 1000, -1. -1);
  dialogue:AddText(dtext[2], 1000, -1, -1);
}
Image
User avatar
MoOshiCow
Developer
Posts: 18
Joined: Thu Jul 05, 2007 12:42 pm
Location: (currently) Pittsburgh, USA
Contact:

Post by MoOshiCow » Wed Sep 05, 2007 1:48 pm

Alrighty..
sorry for the lack of update recently..

with school starting again..and end of summer...
had some stuff to deal with..been kinda busy..

so i guess i got most of the "marking translatable strings" progress done..
and have a couple questions..

First, I've been trying to display Korean onto the screen
using some truetype fonts from:
http://www.wazu.jp/gallery/Fonts_Korean.html

(of course this is all temporary business...
I will have to follow proper procedure to get new fonts into Allacrost)

but have not been successful getting it to display correctly..
I get a bunch of squares instead of text..
which to my understanding has to do with unicode format issues..
which I'm not quite sure how to handle and even more so on linux platform...

So I need someone with experience to help me out with that = D
(of course it doesn't have to be limited to Korean...)

Second, I guess its time i start testing things on Windows as well..
currently I get some library compiler issues..
so I need someone to link me or provide me with the correct
libs for windows..

And thirdly,
I should ask what languages will Allacrost support?
I mainly need this so I can configure the boot menu
so that we can change the program language via the options menu..
and while we suggest languages...
if we need to discuss fonts..i believe thats over here:
http://www.allacrost.org/forum/viewtopic.php?t=1744


well..i guess that's it..
thanks~
User avatar
Roots
Dictator
Posts: 8669
Joined: Wed Jun 16, 2004 12:07 pm
Location: Austin TX
Contact:

Post by Roots » Mon Oct 08, 2007 12:45 am

I would try translations with a Latin-based language first, as asian languages (Korean, Japanese, Chinese) will be a bit trickier to do. As far as needing someone with experience, you can ask Burnsaber for help (he's a contributor and he's not around much, so send him a forum PM).


For Windows issues, hmm I think steu and Black Knight are our two active Windows programmers right now, so talk to one of them.


Allacrost will support any language that someone takes the time to do a translation to. We have no set "we are only going to do translations in these languages". So the boot menu should only show options for the languages with current translations I guess.
Image
Viliam
Contributor
Posts: 35
Joined: Tue Sep 05, 2006 4:25 pm
Location: Bratislava, Slovakia
Contact:

Post by Viliam » Wed Oct 31, 2007 2:46 pm

The languages go by increasing localization complexity like this:

0) English
-- project default language, hardcoded in game

1) Western European
-- needs translation
-- uses the same character set: Latin1, probably the same font

2) Eastern European, Russian, etc
-- uses different character set, probably also different font
-- has relatively small alphabet, can use the same font size

3a) Korean, Japanese, Chinese
-- probably needs a larger font to be legible; large alphabet may require a lot of memory

3b) Hebrew, Arabic
-- right to left, maybe horizontally reversed dialog layout

When we support one language from 3a and one language from 3b, other languages will probably not have technical problems.
User avatar
Roots
Dictator
Posts: 8669
Joined: Wed Jun 16, 2004 12:07 pm
Location: Austin TX
Contact:

Post by Roots » Wed Dec 12, 2007 1:00 pm

Hey, MC (MoOshiCow, that's your new initials because the full name is too long to type ;). Now that we have demo 0.2.1 released, its totally fine to go wrecking (beneficial) havoc on the SVN repository. We want internationalization to be a feature in our next release, so the sooner we get rolling on this the better.


Lets try to commit the least amount as possible to SVN initially with this, so that we may test that everything else still works and the library dependencies are met. After that's solid, then we can go ahead and start experimenting with translation files and such.
Image
User avatar
MoOshiCow
Developer
Posts: 18
Joined: Thu Jul 05, 2007 12:42 pm
Location: (currently) Pittsburgh, USA
Contact:

Post by MoOshiCow » Thu Jan 10, 2008 10:26 am

Alright Roots,

sorry for the delayed response..
been away during winter break..

i will try getting stuff done by this weekend
thanks for the patience

-MC (sounds like i'm a DJ or a rapper or something..)
User avatar
Roots
Dictator
Posts: 8669
Joined: Wed Jun 16, 2004 12:07 pm
Location: Austin TX
Contact:

Post by Roots » Thu Jan 10, 2008 11:03 am

Awesome, looking forward to it. :approve:
Image
Viliam
Contributor
Posts: 35
Joined: Tue Sep 05, 2006 4:25 pm
Location: Bratislava, Slovakia
Contact:

Re:

Post by Viliam » Wed Feb 27, 2008 11:24 am

MoOshiCow wrote:i needed to do something like this:

Code: Select all

dialogue:AddText(hoa_utils.Translate("Laila, what's wrong? You have a worried look on your face."), 1000, -1, -1); --Line 0
even if i replaced "Translate" to "_" it would still be like hoa_utils._(string)
I should have written it half year ago... but probably better now than never:

If the "_" symbol is a macro, you could define it in "hoa_utils.cpp" as:
#define _ Translate
and in all other "*.cpp" files as:
#define _ hoa_utils.Translate
Then, the usage of "_" would be always short.


Off-topic: sorry guys, I do not have time to check this forum often, it is only once in a few months. So I'd like to ask... is there anything for me to translate? If yes, please send me a PM. If no, please send me a PM later when there will be some text to translate.
User avatar
MoOshiCow
Developer
Posts: 18
Joined: Thu Jul 05, 2007 12:42 pm
Location: (currently) Pittsburgh, USA
Contact:

Re: Getting gettext & translation into Allacrost

Post by MoOshiCow » Thu Feb 28, 2008 7:13 am

Finally committed some changes regarding gettext..

Here are the changes and details:

Modified files
src/utils.cpp & utils.h: added helper function Translate() that invokes a gettext() call
src/defs.cpp : binded the Translate() function such that we can use it in the .lua files (hoa_utils.Translate())
src/engine/system.cpp : changes regarding initializing the gettext library
dat/maps/*.lua : some format changes to invoke the hoa_utills.Translate(). See above posts for details.

Added files/folders
txt/ folder will hold all translation related files from now on.
currently there is a txt/allacrost.pot file inside it, which contains all the strings that need to be translated
inside the 2 .lua files in dat/maps.

Things to do:
There are still a couple things that need to be done before we can get translators to work on translation.
Not all strings that need to be translated have been marked, like item names, boot menu, shop menu, etc...
Once I mark them all I will create an updated version of txt/allacrost.pot to contain all translatable strings..
Then we can decide which languages we'll be translating into..
and setup .po files for each language

-MoOshiCow
User avatar
Roots
Dictator
Posts: 8669
Joined: Wed Jun 16, 2004 12:07 pm
Location: Austin TX
Contact:

Re: Re:

Post by Roots » Thu Feb 28, 2008 11:00 am

Viliam wrote:If the "_" symbol is a macro, you could define it in "hoa_utils.cpp" as:
#define _ Translate
and in all other "*.cpp" files as:
#define _ hoa_utils.Translate
Then, the usage of "_" would be always short.
I consider using a "_" macro for gettext to be a very bad idea. I know that's commonly what people who use gettext do, but its very hard to distinguish between a normal string and a regular string, and a one-character function name is never a good idea.
Viliam wrote: Off-topic: sorry guys, I do not have time to check this forum often, it is only once in a few months. So I'd like to ask... is there anything for me to translate? If yes, please send me a PM. If no, please send me a PM later when there will be some text to translate.
We'll contact you when we're ready, but we're not quite there yet. We'll definitely be needing your services for translating demo 1.0 though, so I think you'll be able to see some action in a few months. :approve:


@MC:

Awesome work :approve: So I take it that gettext is now officially a library dependency for us? We'll need to update all our project/make files and library dependencies if that is the case. I am a happy dictator today :angel:
Image
Winter Knight
Contributor
Posts: 304
Joined: Fri Sep 21, 2007 6:35 am
Contact:

Re: Getting gettext & translation into Allacrost

Post by Winter Knight » Fri Feb 29, 2008 7:15 am

dialogue:AddText(hoa_utils.Translate("Laila, what's wrong? You have a worried look on your face."), 1000, -1, -1);
It seems long and redundant to call the Translate function for every dialog string in lua, when every dialog string is already in a function, AddText. Wouldn't it be easier to have the AddText function itself call Translate? Are there any dialog messages at all that do not need translating? If so, we can add a "AddTextNT" function (nt for no translate).

I'm not an expert in gettext, but as I understand it, there is a script that identifies translatable strings (usually by finding "_" in the code, but for us, it will find "Translate"). My suggestion will throw this script a curveball, but it could be adapted to also find strings in AddText.
User avatar
prophile
Senior Member
Posts: 324
Joined: Fri Jan 27, 2006 12:18 pm
Location: Chaldon, Surrey, UK
Contact:

Re: Getting gettext & translation into Allacrost

Post by prophile » Fri Feb 29, 2008 11:36 am

Speaking from experience, having a short form for translate functions is very convenient, but _ just makes everybody confused.

Personally, I'd just use a one or two letter acronym, like 'TS' (for Translate String) or something along those lines. Makes it clear where the translations are, less easy to miss out, and still isn't bulky.
Alastair Lynn / Resident Whinger / Allacrost
Post Reply