ACME 6: Localization for Lisp files

Many users benefit from localization. The solution is to integrate translation possibilities in your code. A user defines a language preference and is rewarded when a translation is available. Translations are defined in csv files with extension .tra that contain available translations as a structured list. It is very easy to integrate translations in your Lisp code. After installing ACME, translation functionality is fully available.

How to code

Suppose you would normally do:

(princ "Show this text.")

By simply adding a language translation function (tra <string>), the line becomes:

(princ (tra "Show this text."))

This could, in Portuguese, evaluate to (princ “Mostre este texto.”) and finally print Mostre este texto. on the command line.

Before you call function (tra …) you have to point to a translation file. This is all it takes:

(setq tra-file "filename")

Filename is the name of the file with the translation, in the search path. Include the extension, .tra is strongly suggested. You may want to name the translation file equal to the .lsp file.

An example:

(defun c:atest ( / tra-file)
   (setq tra-file "atest.tra")
   (alert (tra "Show this text."))
   (princ (strcat (tra "\nYour username is: ") (getenv "username") ". "))

Some extra examples of functions that use strings:

(prompt (tra "Translation Powder… "))
(entsel (tra "Choose product from ACME catalogue: "))
(getpoint (tra "Enter rocket launch point? "))
(getstring T (tra "Roadrunners full name? "))
(getfiled (tra "Select an ACME product drawing... ") "/ACME/Catalogue/Explosives/Rocket-driven-products/" "dwg")
(getreal (tra "Richter scale: "))

Pay attention to programs that use load to load code. If such a program also contains a statement (setq tra-file “loaded-file”) then the current tra-file setting is overwritten – unless it is a local variable. In that case, the translation no longer works well and it is advisable to do (setq tra-file “this-file”) again.

How to configure

Edit file tra.cfg. Please take care that this file is in the search path.

  • The first entry relates to whether you want to translate or not:
    • translate;1
      Value 1: Attempt to translate.
    • translate;0
      Value 0: Use the literal text string in the Lisp code.
  • The next entry is the language you want. For example, for Portuguese:
    • When a translation is not available, it will fall back on the literal text string in Lisp code.

How to translate

Translation file syntax

A translation file is nothing more than a csv file with extension .tra. The top row contains language code tags. The first should always be en (English). Each column contains translations of the first column.

Important: The file should be constructed with only strings between double quotes.

"Show this text.","Toon deze tekst.","Mostre este texto."
"\nFirst, a line break","\nEerst, een regeleinde","\nPrimeiro, uma quebra de linha"

ISO 639-1 is the base for language tags.

TIP! Please take special care to avoid syntax errors – they can crash the CAD program by causing infinite loops.

Editing translation files

Editing with an editor is possible, but using a spreadsheet is possible too (and less prone to errors).

A screen dump looks like this:

In, for example, LibreOffice Calc you can open tra files by dragging them to Calc or create a file association.

TIP! Obvious, but still… You can fill not yet translated columns with values of column A in first instance.

After editing in Calc, you can choose “Save as…” and select “Edit filter settings…“. In the “Export Text File” dialogue, select a double quote as a string delimiter and don’t forget to select “Quote all text cells“.


The way you work is probably translate and test.

It is important that function (tra …) is very fast. That is the reason that a .tra file is only parsed once, after the first (tra …) call, per CAD session.

So translating and testing would mean you have to restart your CAD program every time. This is easy to avoid by setting the blackboard variable, that contains the translation, to nil in order to force a fresh parse of the .tra file.

This is how it works. Suppose your .tra file is my-program.tra. Then enter the following on the command line:

(vl-bb-set 'tra-bb-list-my-program nil)

The next time you call (tra …), the blackboard variable contains the new translation list. You can check it by entering

(vl-bb-ref 'tra-bb-list-my-program)

on the command line.

Final notes

In its essence you want to translate strings only. Exporting to csv should not be a problem then. However, other data types, like numbers, are not enclosed in double quotes and will cause problems.

To keep things organized, you may want to consider naming .tra files equal to .lsp files.

Routine (tra …) has a small footprint. Be aware of the fact that bad translations can cause problems that are less easy to track.

Encoding and code pages

As long as you work with standard ASCII characters, you’ll not run into unexpected situations. However, if you use language related special characters, you should pay attention to the following.

Please be aware of the fact that Lisp works with “extended ASCII”. This is basically the 128 fixed ASCII character set plus a variable set of 128 additional characters. The complete set is the code page and can differ from system to system.

In notepad++ this is called “ANSI encoding” and will often boil down to code page 437. If you enter chcp in a DOS prompt, it will show the used code page.

Suppose you want to use a Cyrillic code page, it might be a good idea to use pure 128 character ASCII for your Lisp strings and do the translations based on all 256 characters of the used code page.

Developers notes

To keep the system load low, the configuration is loaded once per CAD session. The program is small and is often called. That is why it is permanently loaded with every document. In other words, there is a part that is executed during the start of the CAD program and there is a part that is loaded with every document.

At start of program

The translation functions are part of ACME. If ACME starts for the very first time, search paths are not yet set and tra.cfg, etc. will not be found. So translation functionality is not available at that stage.

At program start, after setting required things, tra.cfg is parsed and the result is a list tra-bb-cfg – a blackboard variable.

At the start of a document

Function (tra string) is firstly loaded with every document – also directly from ACME. Because the footprint is small and it is often used during work, the entire function is loaded to guarantee speed.

In order to avoid constantly parsing of translation files, this file is parsed only once after a translation request and the result is written to the blackboard variable.

ACME 6: Localization for Lisp files
Scroll to top