Skip to content

GeoDa Internationalization Project

Xun Li edited this page Jun 26, 2023 · 14 revisions

GeoDa I18n and L10n Project

Project Description

GeoDa Internationalization (I18n) and Localization(L10n) project aims to provide an online tool that GeoDa users could help to translate the GeoDa UI to different languages.

For crowdsourcing, we use Google Spreadsheet with the public address here. Anyone can access this spreadsheet, and edit each translation.

This infrastructure has scripts and codes to create, update and maintain GeoDa’s language packages from Google Sheets automatically.

How to contribute

Please visit Google Sheet here.

  1. Click on the sheet that you want to help to translate (see the table below)
Language Sheet Name
French fr
Russian ru
Portuguese pt
Spanish es
中文 zh_CN
Deutsch de
日本語 jp
  • Column A contains the English messages that need to be translated (not editable)
  • Column B you can contribute by inputting proper translation in each cell
  • Column C you can input your email, GitHub alias, etc. so we can include your name in GeoDa's contribution list
  1. Copy (Ctrl+C or Cmd+C) an item from Column A, and paste it (Ctrl+V or Cmd+V) to the right cell in Column B

  2. Edit the translation in the right cell (Please keep the bracket [ ])

Demo

Note

  • Empty spaces should be reserved in translation
  • Placeholders (no need to translate): %d %s %f \t \n
  • Symbols (no need to translate): > < == =

Embedded this Google Spreadsheet to a website

<iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vRRrZqXc7n6oCksp3xxgP-dRCqh_koMMCYu7ES2pZZ3MVJv_6YVIpMqWsLXeUxvMPy3M1iJ9aQQ_DlT/pubhtml?widget=true&headers=false"></iframe>

Background

One of the most classic tools for I18n and L10n is a Unix tool called Gettext, which is used in this project. There are three file types you usually deal with while working with Gettext. PO (Portable Object), MO (Machine Object) files and POT (PO Template) file.

I18n
|
├──lang
|   ├──config.ini
|   ├── es
│   |    └── geoda.mo
|   └── zh_CN
│         └── geoda.mo
|
├──profile
│   ├── es.mo
│   └── zh_CN.po
|
└── geoda.pot

The related files can be found under geoda_source_dir/internationalization.

The above example shows the directory name (e.g. es/, zh_CN/ following the Locale Code, which is simply a code that identifies one version of a language. It’s defined following the ISO 639-1 and ISO 3166-1 alpha-2 specs: two lower-case letters for the language, optionally followed by an underscore and two upper-case letters identifying the country or regional code.

For Development

Before every GeoDa release, please follow the procedures below to create language packages for GeoDa.

Get latest translated items from Google

The following scripts get the latest translations of Chinese (zh_CN) and Spanish (es) from Google Sheets, and save the results to PO files, and last creat MO files for GeoDa.

python3 google_sheets_tool.py zh_CN --output ./pofiles/zh_CN.po

python3 google_sheets_tool.py es --output ./pofiles/es.po

NOTE After creating PO files from Google Sheets, the best practice is to use Github Desktop to check and verify all changes in current PO files.

After verifying all changes in PO files, one can commit the changes and push the new PO files to Github repo. Then, one can use msgfmt to create MO files from PO files:

msgfmt ./pofiles/zh_CN.po -o ./lang/zh_CN/GeoDa.mo

msgfmt ./pofiles/es.po -o ./lang/es/GeoDa.mo

Note: the best practice is using e.g. POEditor to edit the PO file, and create a MO file. Then, one can manually copy the MO file to the right location.

Update Google Sheets from source code

Ongoing development will generate new UI items that need to be translated. One can use the following scripts to update PO files

1.1 Create geoda.pot file from source files

To create a geoda.pot file, one can run the shell script under geoda_source_dir/internationalzation directory:

./1_create_geoda_pot.sh

This script will go through all the *.cpp and *.h files under geoda_source_dir directory, and extract the strings coded in _() macro.

# 1_create_geoda_pot.sh
# the first part will use find() command to find _() strings from 
find .. \( -name '*.cpp' -o -name '*.h' \) -not -path "../BuildTools/*" | xargs xgettext -d geoda -s --keyword=_ -p ./ -o geoda.pot

1.2 Create xrc.pot file from source files

There are also strings defined in various xrc files (e.g. menu.xrc, dialogs.xrc etc). There is a python script gen_po_from_xrc.py that can be used to create a xrc.pot file.

python3 2_gen_po_from_xrc.py

1.3 Update existing PO file

Update existing PO file (e.g. zh_CN.po, specified using argument --input) using POT files (geoda.pot and xrc.pot extracted from source code. New msgid with empty msgstr will be added into existing PO file and saved into a new file specified by argument --output')

python3 3_updatePO.py ./geoda.pot ./xrc.pot --input ./pofiles/es.po --output ./new_es.po

python3 3_updatePO.py ./geoda.pot ./xrc.pot --input ./pofiles/zh_CN.po --output ./new_zh_CN.po

NOTE Please manually compare the new PO file with existing PO file to verify all newly added UI items. For example, using vimdiff to compare ./new_zh_CN.po with ./pofiles/zh_CN.po:

1.4 Create a CSV file that will be uploaded to Google Sheet to replace the current one

python po2csv.py ./new_es.po ./es.csv

python po2csv.py ./new_zh_CN.po ./zh_CN.csv

1.5 Upload CSV file to Google Sheets

Please manually check CSV file before uploading it to Google Sheets. The name of the CSV file should be the same with the name of the Sheet, which should be a locale name (e.g. zh_CN.csv)

When uploading a CSV file, please select the Sheet that you want to update ((e.g. zh_CN). Then, use File->Import menu, and choose Upload tab, and select the CSV file from your local drive. The options should be configured as below:








1. Get new "to-be-translated" items and updated Google spreadsheet

1.3 Create a .CSV file with new "to-be-translated" items

Get new items by comparing existing PO file (e.g. zh_CN.po, specified using argument --input) with new POT files (geoda.pot and xrc.pot extracted from source code). New msgid with empty msgstr will be written into a new PO file specified by argument --output

python3 3_get_diff_PO.py ./geoda.pot ./xrc.pot --input ./pofiles/zh_CN.po --output ./pofiles/new_zh_CN.po
python po2csv.py ./pofiles/new_zh_CN.po ./new_zh_CN.csv

1.4 Manually check the new items in .CSV file and update it to Google SpreadSheet

2. Use Google spreadsheet to create new PO/MO files for GeoDa language packages

2.1 Manually check the spreadsheet and download the csv file for each language

2.2 Convert .CSV file to .PO file

2.3 Use PoEdit to check .PO files

2.4 Copy .MO files to lang/ directory

3. Prepare Google spreadsheet files

The following section describes how the Google spreadsheet is prepared. They should NOT be executed again.

3.1 Create geoda.pot file from source files

3.2 Create xrc.pot file from source files

3.3 Update existing PO file

Update existing PO file (e.g. zh_CN.po, specified using argument --input) using POT files (geoda.pot and xrc.pot extracted from source code. New msgid with empty msgstr will be added into existing PO file and saved into a new file specified by argument --output')

python3 3_updatePO.py ./geoda.pot ./xrc.pot --input ./pofiles/es.po --output ./pofiles/new_es.po

python3 3_updatePO.py ./geoda.pot ./xrc.pot --input ./pofiles/zh_CN.po --output ./pofiles/new_zh_CN.po

python3 3_updatePO.py ./geoda.pot ./xrc.pot --input ./pofiles/de.po --output ./pofiles/new_de.po

python3 3_updatePO.py ./geoda.pot ./xrc.pot --input ./pofiles/jp.po --output ./pofiles/new_jp.po

3.4 Generate .CSV file from PO file

Generate a .CSV file from .PO file, so that we can upload it to Google Spreadsheet.

Please not the .CSV file uses the character ` to separate values.

python po2csv.py ./pofiles/new_es.po ./es.csv

python po2csv.py ./pofiles/new_zh_CN.po ./zh_CN.csv

python po2csv.py ./pofiles/new_jp.po ./jp.csv

python po2csv.py ./pofiles/new_de.po ./de.csv
msgfmt ./pofiles/es.po -o ./lang/es/GeoDa.mo