AkelPad Forum Index AkelPad
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

IDEA - 'Universal' translation method
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AkelPad Forum Index -> Language modules
View previous topic :: View next topic  
Author Message
Surveyor



Joined: 08 Feb 2008
Posts: 146
Location: British Columbia, Canada

PostPosted: Mon Oct 26, 2009 3:41 pm    Post subject: IDEA - 'Universal' translation method Reply with quote

Instructor,

Current translations are compiled into resource files (English/Russian are built-in), but plugins are only in English(?). I have seen a method used by some programs which uses a text file for each language similar to:
Code:
English - translation strings
str001="&File"
...
str013="Pa&ge setup..."
etc.

Strings are loaded at startup (or as needed?) from the appropriate language flie. If this method were used, plugins could also be incorporated and additional translations or corrections could be EASILY made by anyone, without a re-compile! Text file would have to be 1200 UTF-16 LE (or similar) to allow foreign language characters.

Problem is, of course, that this would mean a major(?) change to AkelPad and plugin structure. Might be just too much work, or not practical...

Just a thought for possible future versions... Comments, anyone?
Back to top
View user's profile Send private message Send e-mail
VladSh



Joined: 29 Nov 2006
Posts: 2597
Location: Киев, Русь

PostPosted: Thu Nov 19, 2009 12:59 pm    Post subject: Reply with quote

EN (sorry... it's Google-translate text Embarassed )

This idea is already hovering in the brain ...)

1. Create a list of all the phrases used by the program, save them to file for a particular language.
For example it can be done in the image and likeness of INI-file:

Code:
IDC_COMMANDNAME = "name of command" or IDN_COMMANNUMBER = "name of command"
example:
Code:
IDC_NEW = "New" or IDN_4101 = "New"
------------
Code:
IDL_LABLE = "lable"
example:
Code:
IDL_MENU_FILE = "File"
------------
Code:
IDMC_MESSAGECAPTION = "title of the message box"
example:
Code:
IDMC_AKELPAD = "AkelPad message ..."
------------
Code:
IDMT_MESSAGETEXT = "text message"
------------
etc. ..

2. Put in folder AkelFiles\Langs these files for different languages.
If files are missing, the program takes the English (probably need to keep fnutri, as now).

3. Use in the program, plugins, scripts defined messages from lng-files.
Add to Scripts-plug method, which returns to the text on ID._. .., respectively, the current language, for example:
Code:
var txt = AkelPad.GetLangString (IDMT_QREPLACEFILE);
txt enrolled in the variable value to the message: "File already exists, replace it it?"
By the way, could be in the messages indicate variables, such as:
Code:
IDMT_QREPLACEFILE = "File %VAR1% already exists, replace it?"
and then, having received the message already in the program/plugin/script to replace %VAR1%...n on corresponding values.

In my opinion, not a bad idea Wink

P.S. Here, I once suggested that the format of the menu ... but this work is more serious and global.


RU
Подобная идея уже витала в мозгу...)

1. Создать список всех фраз, используемых программой, сохранять их в файле для определённого языка.
Например это можно сделать по образу и подобию INI-файлов:

Code:
IDC_COMMANDNAME = "Имя команды" или IDN_COMMANNUMBER = "Имя команды"
т.е. это выгледело бы так:
Code:
IDC_NEW = "Новый" или IDN_4101 = "Новый"
------------
Code:
IDL_LABLE = "надпись"
пример:
Code:
IDL_MENU_FILE = "File"
------------
Code:
IDMC_MESSAGECAPTION = "заголовок окна сообщения"
пример:
Code:
IDMC_AKELPAD = "AkelPad message..."
------------
Code:
IDMT_MESSAGETEXT = "текст сообщения"
------------
и т.д...

2. Положить в папке AkelFiles\Langs эти файлы для разных языков.
Если файлов нет, то программа берёт английский (видимо надо хранить фнутри, как и сейчас).

3. Использовать в программе, плагинах, скриптах установленные сообщения из lng-файлов.
Добавить в Scripts-плагин метод, который возвращал бы текст по ID._..., соответственно текущему языку; например:
Code:
var txt = AkelPad.GetLangString(IDMT_QREPLACEFILE);
в переменную txt записалось бы значение сообщения: "Файл уже существует, заменить его?"
Кстати, можно было бы в сообщениях указывать переменные, например:
Code:
IDMT_QREPLACEFILE = "Файл %VAR1% уже существует, заменить его?"
а затем, получив текст сообщения, уже в программе/плагине/скрипте заменять %VAR1%...n на соотвтетствующие значения.

По моему, неплохая идея Wink
Back to top
View user's profile Send private message Visit poster's website
FeyFre



Joined: 07 Aug 2007
Posts: 2033
Location: Vinnitsa, Ukraine

PostPosted: Thu Nov 19, 2009 2:45 pm    Post subject: Reply with quote

VladSh, подобным приемом пользуется Миранда, только значительно гибким.
Ты предлагаешь давать текстовым надписям идентификаторы, а внутри искать по ним подгружать строку, а в случае отсутствия такой - брать где-то строку по умолчанию. Значит нужно хранить и идентификатор, и значение по умолчанию. Не экономно это.
Потому Миранда делает так: она не хранит никаких идентификаторов вообще. Если ей нужно вывести какой-то локализированный текст, ключом для поиска перевода этого текста служит сам текст, и если он в переводе не найдет - подставляется оригинал. Таким образом не хранятся нигде лишние данные. Файлы локализации - обычные текстовые файлы лежащие в корне приложения, и имеющие простой ini-подобный формат.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
VladSh



Joined: 29 Nov 2006
Posts: 2597
Location: Киев, Русь

PostPosted: Thu Nov 19, 2009 3:53 pm    Post subject: Reply with quote

FeyFre
Таким принципом пользуются почти все проги, в которых есть локализация.

Более гибким или менее - это смотря с какой стороны посмотреть.
Конечно, только для целей локализации непонятно, зачем идентификаторы... если разобрать, к примеру, меню AutoCAD'а, то видно, что за идентификаторами команд идут не только наименования (они - только малая часть общего механизма), а и связь с соответствующим лейблом (как здесь), с текстом описания, выводимым в строке состояния при наведении курсора мыши, когда пункты меню становятся недоступными, также можно напротив идентификатора команды писать лёгкие скрипты на макроязыках или указывать вызов внешних скриптов/прог. Потом для вызова команды не надо ничего искать, - она просто вызывается по единственному идентификатору, а весь этот "паровоз" тянется следом.
Всё это становится понятным, когда пункты меню со своей кучей настроек используется в разных меню.

Если же смотреть с точки зрения удобства, то оперирование в программном коде огромными "стрингами" вместо идентификаторов - сомнительное удовольствие.

P.S. Кроме AutoCAD'а можно посмотреть как устроены файлы lng во многих прогах: Opera, KMPlayer и т.п., просто у него они лучше всего проработаны.
Back to top
View user's profile Send private message Visit poster's website
FeyFre



Joined: 07 Aug 2007
Posts: 2033
Location: Vinnitsa, Ukraine

PostPosted: Thu Nov 19, 2009 5:09 pm    Post subject: Reply with quote

VladSh
Quote:
Если же смотреть с точки зрения удобства, то оперирование в программном коде огромными "стрингами" вместо идентификаторов - сомнительное удовольствие.
А $define зачем? C - без препроцессора в практичном применении не возможен. Поэтому оперирование огромными "стрингами" сводится к оперированию дефайнов их заменяющих.
Дэфайны ложатся в отдельном H-файле, в котором только они и находятся, типа этого:
Code:
#ifndef __TRANSLATE_H__
#define __TRANSLATE_H__
#define MESSAGE_NOMOREFOUND _T("No more found")
#define MESSAGE_NOFILEFOUND _T("File not found. Create?")
....
#endif //__TRANSLATE_H__
Это файл инкладится в исходник и компилируется.
Также этот же файл является входящим файлом для утилиты генерации шаблонов файлов перевода(файл структурирован и распрасить его не проблема для составления шаблона в который осталось ввести перевод)
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
pvagner



Joined: 27 Jul 2008
Posts: 57
Location: slovakia

PostPosted: Sat Nov 21, 2009 5:57 pm    Post subject: Reply with quote

I am not sure your approach considers it but I think if we are about to introduce kind of language files, then they should be stored in UTF-8 encoded files and then they can be properly displayed on any operating system.
Currently even russian plugins need seperate language strings for unicode and ansi versions of Windows.
Back to top
View user's profile Send private message
Fr0sT



Joined: 24 Jul 2007
Posts: 876

PostPosted: Sun Mar 11, 2012 12:06 pm    Post subject: Reply with quote

Можно подумать насчет унифицированного метода локализации Акеля и плагинов, желательно без жесткого вкомпиливания ресурсов. К примеру, проверенный временем gettext.
Back to top
View user's profile Send private message
FeyFre



Joined: 07 Aug 2007
Posts: 2033
Location: Vinnitsa, Ukraine

PostPosted: Sun Mar 11, 2012 1:14 pm    Post subject: Reply with quote

Fr0sT
Подумать то можно, и уже думалось(мной точно), но всё упирается в отсутствии надобности "по зарез" а значит и наличия самого воплотителя.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Fr0sT



Joined: 24 Jul 2007
Posts: 876

PostPosted: Sun Mar 11, 2012 2:35 pm    Post subject: Reply with quote

Ну, я думаю, иностранные не-англоязычные пользователи были бы крайне рады, если бы плагины можно было переводить на их языки.
Чем хорош gettext - английский присутствует всегда, даже если все файлы с локализацией затерялись.

Можно такую полумеру сделать:
1) Локализация хранится в ресурсах, в string table - только для одного языка. В бинарниках, скачиваемых в виде архивов, стоит дефолтная локализация.
2) Переводы поставляются в виде скомпилированных res файлов, содержащих опять же string table.
3) Вместе с ними поставляется маленькая утилита, которая заменяет ресурсы в exe/dll на содержимое res файла.
4) В инсталлятор зашита эта утилита и все локализации соответственно основному языку, после установки он запускает утилиту, заменяя строковые ресурсы

Плюсы:
1) Переделать понадобится только GetLangString, плюс выделить строки в отдельный ресурс.
2) Сделать утилиту по замене ресурсов и слегка дополнить инсталлятор тоже нетрудно
3) С помощью ResHacker и подобных утилит любой сможет сделать локализацию для своего языка
4) С помощью утилиты замены также можно будет вручную локализовать любой плагин (если ставится не через инсталлятор)

Минусы:
1) Ну, единственное, что я вижу, - это затруднится синхронизация изменений. Но тут уж ничего не поделаешь.
Back to top
View user's profile Send private message
FeyFre



Joined: 07 Aug 2007
Posts: 2033
Location: Vinnitsa, Ukraine

PostPosted: Sun Mar 11, 2012 3:36 pm    Post subject: Reply with quote

1) По методу GETTEXT перевод в ресурсы в таблицу строк не всунешь.GETTEXT работает со строковым ключом, а таблица строк - целое число.
Поэтому остальные пункты сразу отпадают.
Тут скорее всего уместно сделать в виде пользовательских ini-файлов. Типа как в Миранде.
Code:
[строка для перевода]
язык1=перевод1
язык2=перевод2
Все ini файлы кучковать в одном месте, и обрабатывать пачкой. Тогда даже секртетарь сможет сделать себе перевод.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Fr0sT



Joined: 24 Jul 2007
Posts: 876

PostPosted: Mon Mar 12, 2012 6:53 am    Post subject: Reply with quote

FeyFre
ну я предложил либо gettext, либо промежуточную меру с ресурсами. Эти два метода никак не связаны между собой.
Что мне не нравится в предложенном тобой методе:
1) Дублирование ключей в коде и в ini. Кроме того, при изменении ключевой строки надо будет также исправить ВСЕ переводы. Не знаю точно насчет gettext, но вроде бы у него есть утилиты-сканеры, которые выдирают из исходника все локализуемые строки. Проблема с необходимостью изменения всех переводов, тем не менее, остается.
2) Строковый ключ ужасно медленный. Тогда надо будет ещё и хэш прикручивать, что уже реализовано в gettext (зачем изобретать велосипед?)

Плюс его - в легкости редактирования, это да.

Если же использовать ресурсы, то для каждого бинарника можно сделать так:
== LangDefs.inc ==
Code:
#define LANG_STR_FOO 1
#define LANG_STR_BAR 2
...

== LangRes.rc ==
Code:
#include "LangDefs.inc"
STRINGTABLE DISCARDABLE
BEGIN
  LANG_STR_FOO "foo"
  LANG_STR_BAR "bar"
END

В таком случае в коде идентификация будет по кодам LANG_STR_* (будет подключаться LangDefs.inc), а переводы будут предоставляться переводчиками в виде LangRes.rc, которые для юзеров потом будут компилиться в *.res
Back to top
View user's profile Send private message
FeyFre



Joined: 07 Aug 2007
Posts: 2033
Location: Vinnitsa, Ukraine

PostPosted: Mon Mar 12, 2012 9:15 am    Post subject: Reply with quote

Quote:
2) Строковый ключ ужасно медленный. Тогда надо будет ещё и хэш прикручивать, что уже реализовано в gettext (зачем изобретать велосипед?)
Мы что собираемся делать одновременно 1млн. запросов на перевод? Жалко одной микросекунды?
Quote:
Строковый ключ ужасно медленный. Тогда надо будет ещё и хэш прикручивать, что уже реализовано в gettext (зачем изобретать велосипед?)
Ресурсы ограниченны только 65534 значениями - перспективы ноль. Истощение в обозримом будущем.
Quote:
Дублирование ключей в коде и в ini.
Не страшно. Не думаю что максимум лишнего мегабайта при сегодняшних объемах кому-то позарез не будет хватать.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
Fr0sT



Joined: 24 Jul 2007
Posts: 876

PostPosted: Mon Mar 12, 2012 1:48 pm    Post subject: Reply with quote

Quote:
Ресурсы ограниченны только 65534 значениями - перспективы ноль. Истощение в обозримом будущем.

На каждый тип ресурса или всего? Потому что если на каждый, то это фигня. Файл перевода в Опере имеет всего 4.5 тысячи строк. А это ого-го какая немаленькая программа.
Quote:
Не страшно

Не в размере дело, а в усложнении накатывания изменений
Back to top
View user's profile Send private message
VladSh



Joined: 29 Nov 2006
Posts: 2597
Location: Киев, Русь

PostPosted: Mon Mar 12, 2012 10:39 pm    Post subject: Reply with quote

Шо тут думать, прыгать надо. Вверху предлагались ini-файлы, хоть даже вариант FeyFre (он удобнее тем, что нагляднее).
То есть сделать микс из 2-х вариантов:
- делать локализованную версию на определённый язык или как это сделано сейчас в АкелПаде (я до сих пор ни разу не ставил многоязычную версию, но предполагаю, что каким-то образом это там работает);
- и одновременно, если в специальной папке лежат файлы других языков, то в проге давать выбирать и из этих языков, так многие проги делают.
В проге переключил на каракалпакский, и р-раз, плаги тоже начали на каракалпакском отображать, а где нету, ну значит английский. А кто возмущаться начнёт, что ему не нравится, ты ему "А ты записался в добровольцы? Ты чем помог фронту?"
То есть, как вариант, в проге 1 язык, который вшит, а если пользователь хочет чесать левой ногой правое ухо, то пусть ini-файлы добавляет и выбирает. Да хоть пусть скрипт напишет и при каждой загрузке проги рандомно язык подставляет.
Back to top
View user's profile Send private message Visit poster's website
Fr0sT



Joined: 24 Jul 2007
Posts: 876

PostPosted: Tue Mar 13, 2012 6:13 am    Post subject: Reply with quote

В многоязычном Акеле строки и диалоги подгружаются из языковой dll. Едва ли этот способ подходит для плагинов.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AkelPad Forum Index -> Language modules All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


SourceForge.net Logo Powered by phpBB © 2001, 2005 phpBB Group