The jstools applications (and other wellbehaved applications built with the jstools libraries) support localisation of text (labels, command names, etc.) presented by the application. That is, just because the author of the application wrote it in English (or German) doesn't mean you have to use it in English (or German) - it can be customised to display it's messages and labels in any language that Tk supports.
This document describes the language database mechanism distributed with version 4.0/4.0b of the jstools application suite and the jstools libraries.
When jstools applications display naturallanguage strings, they look them up with a key in a database, called the language database. They then display the result. So in order to make jedit display strings in Romanian, you need a Romanian naturallanguage database for jedit. (Actually, you also need a naturallanguage database for the strings displayed by the jstools libraries, which jedit uses, and a font capable of displaying Romanian accented characters.)
In theory this database can be provided by the author or distributor of the application, by the person who installed it at your site, or by you, the end user of the application. Moreover, if you already have a database that has most of what you want, but you want to make a few changes in it, you don't need to create an entirely new database, you can just create one that has the changes you want in it and inherit most of your strings from the `parent' database. (You could handle differences between Australian and US English this way - or you could just change a few strings to match terminology used at your site, or to make them more concise or more descriptive.)
Language databases are organised into a treestructured hierarchy according to how specific they are. This hierarchy is reflected in their names.
The least specific form of a language database name is just the official ISO 639 twoletter abbreviation for a language, such as en for English or fr for French. Optionally, a twoletter country abbreviation can be appended, separated by a period, such as es.ar for Argentine Spanish or la.fr for Latin as spoken in Gaul. (The country abbreviation is the same as a twoletter toplevel Internet domain name, which mostly agrees with the ISO 3166 standard, except for uk instead of gb for Great Britain.) This can optionally be followed by another period and an arbitrary string to identify a more specific language practise, such as en.us.mit for English as used at the Massachusetts Institute of Technology. The process of tacking on more specific identifiers can continue indefinitely, so in theory you could specify US English as spoken by the President as en.us.dc.whitehouse.president, but in practise I suspect three levels - language, country, and perhaps an additional specifier for an organisation, a region within a country, or an individual - will be enough for most people.
When an application starts, it tries to read in your preferred language database, and all more general `parent' databases, starting with the most general database. For instance, if your preferred database is en.uk.susan, then the application will first try to read in the en database, then the en.uk database, and finally the en.uk.susan database. That way, strings specified in en.uk override strings in en, and strings in en.uk.susan override strings in either en or en.uk. Only those strings which differ between UK English and other varieties of English need be specified in en.uk, and Susan only needs to specify those strings she wants to change in en.uk.susan.
It's perfectly fine for not all language databases in the hierarchy to exist. For instance, if Sam's language preference is en.us.mit.sam and the are language databases called en and en.us.mit.sam for a particular application, but no databases called en.us or en.us.mit, then both existing databases will be read, and strings in en.us.mit.sam will override definitions in en.
If no language database at all is found for an application, it will use defaults specified by the application's author.
Language databases are searched for in the following directories, in order:
* ~/.tk/jldb/app
* ~/.tk/jldb/default
* jstools_library/jldb/app
* jstools_library/jldb/default
where app is the name of the application or package, and jstools_library is the place where the jstools library files are installed, typically /usr/local/jstools/lib.
The directory path above is searched for each database (e.g., for de and then again for de.ch), but when a particular database is found in one of these directories, it is used, and the remaining directories are skipped for this database (although they may be searched again for a more specific database). An example will make this clearer:
Suppose you are running an application called notebook and you have a database called en.us.bill in your ~/.tk/jldb/notebook directory and there's also a systemwide Englishlanguage database for the application in /usr/local/jstools/lib/jldb/notebook/en (but no en.us database). If your language database preference is en.us.bill, then when it starts, the notebook application will first look for a database named en. It will check your ~/.tk/jldb/notebook and ~/.tk/jldb/default directories, but won't find anything. It will then check /usr/local/jstools/jldb/notebook and find an en database there, so it will read it in. It won't check /usr/local/jstools/lib/jldb/default, because it's already found a database. Then it will search for a database named en.us, but (for our example) no such database will be found in any of the directories. Finally, it will search for a database called en.us.bill. This will be found in the first directory checked: ~/.tk/jldb/notebook, so it will be read in and none of the other directories will be checked. The net result is that, presumably, most of the strings in the application are defined in the file /usr/local/jstools/lib/jldb/notebook/en, but some of them are overridden by definitions in the file ~/.tk/jldb/notebook/en.us.bill. (Alternatively, you could have copied the entire en database for notebook to your directory and modified it, but it's better just to override the strings you want to change.)
Actually, even the above is a slight simplification. When an application that uses the jstools libraries starts up, it actually reads in two sets of databases: one for the jstools libraries and one for the application itself. The library database is searched using jstools as the application/package name (i.e., it's searched for in ~/.tk/jldb/jstools, ~/.tk/jldb/default, jstools_library/jldb/jstools, and jstools_library/jldb/default). Strings from both sets of files are loaded into the application. The jstools library database is read first, so strings in any of the applicationspecific databases will override strings in any of the jstools library databases. (E.g., a string in notebook/en can override a string in jstools/en.us.dc.whitehouse.) It is intended, however, that there should be no conflicts - the jstools databases are for strings used by procedures in the jstools library, and the applicationspecific databases are for strings used by the application code itself.
To create a database for a new language for a jstools application, you should copy an existing database (provided by the application author) to a new name, and modify the naturallanguage strings. You should use the twoletter language code in the ISO 639 international standard for your language as the name of your new database. You will then need to choose the appropriate database as your preferred language in the jstools Global Preferences panel in order to see the new strings. You need to do this both for the application's own database and for the database for the jstools libraries.
For instance, if you wanted to translate the strings used in jdoc into Welsh, you would copy the provided Englishlanguage database from (perhaps) /usr/local/lib/jstools/jldb/jdoc/en to /usr/local/lib/jstools/jldb/jdoc/cy (because cy is the twoletter code for Welsh in ISO 639) and replace the English strings with Welsh ones. (Alternatively, you can copy it to ~/.tk/jldb/jdoc/cy, in case you don't have write permission under /usr/local.) You'd also need to copy and modify the jstools library database, (e.g.) /usr/local/lib/jstools/jldb/jstools/en, unless you'd already done so for a different application.
For details of the syntax used in language databases, you should see the documentation for the j:ldb:set_strings procedure in the jldb.tcl library. To summarise, however, the bulk of the database file consists of a series of entries, where each entry starts with a key. The key is fixed and should not be changed, even if it looks like a naturallanguage string, because it's how the application looks things up in the database. The second element of an entry is a string, which is the naturallanguage expression corresponding to the key in this particular language. (The string can contain embedded references to Tcl variables or Tcl commands, which will be substituted before the string is used.)
Some keys have up to three additional values as well as the string: a numeric underline position in the string (used to indicate an Altkey shortcut in a menu entry), a Tk event specification used to create an accelerator binding (not necessarily involving the Alt key), and a short string to indicate the accelerator binding in a menu entry. All of these are optional. Again, for more details, see the documentation for the jldb.tcl library.
If you translate strings for any of the jstools applications (or the library) into any other languages, I would be very grateful to receive copies, so I can incorporate support for languages other than English into future releases.
To customise the strings displayed in an existing language database for a particular language group (whether that's your country, your region, your site, or just your own personal preferences), you create a new language database (named as specified above in The Language Database Hierarchy) which contains just those strings you want to override. For instance, if you were adapting an application that had something to do with cars, which was provided with an American English language database, you might take the en database (English, which variety not defined) containing:
#!/mode/tclsh
j:ldb:set_strings {
{tires {Tires}}
{hood {Hood}}
{seats {Seats}}
{paint {Paint Job}}
{windows {Windows}}
{radio {Radio}}
{red {Red}}
{black {Black}}
{silver {Silver}}
{gray {Gray}}
{gold {Gold}}
{yellow {Yellow}}
}
and create a new database en.uk specifying just those strings you want to change:
#!/mode/tclsh
j:ldb:set_strings {
{tires {Tyres}}
{hood {Bonnet}}
{gray {Grey}}
}
Now, assuming your new database is installed systemwide, anyone whose language preference is en (or en.us, assuming there isn't a separate en.us database - or en.za, for that matter) will see the original strings in the database distributed with the application, but anyone whose language preference is en.uk will see the modified versions of those strings that differ.