jcsteh / osara

OSARA: Open Source Accessibility for the REAPER Application
GNU General Public License v2.0
127 stars 46 forks source link

Make OSARA translatable #13

Closed jcsteh closed 2 years ago

jcsteh commented 9 years ago

(Filed after a query from @GianlucaApollaro.)

Right now, OSARA is English only. It'd be good if it could be translated into other languages.

OSARA currently uses C++ iostreams for string formatting, which is unfortunately terrible for translation. We need to switch to something else which allows for replacement-based formatting while still allowing for C++ strings, easy concatenation, etc. A bit of research suggests C++ Format could be just the thing.

We then need to figure out how to use GNU gettext (or maybe something else, but I'm familiar with gettext) for OSARA:

  1. I'm not sure how to handle Unicode strings. I haven't found a definite answer, but this post suggests gettext always uses the local encoding. This is not ideal; I'd prefer to always use Unicode rather than converting all over the place.
  2. We need to store the .mo files somewhere, which is a bit tricky given that we're based in REAPER's plugins directory.

Alternatively, it's probably worth investigating what SWS uses.

jcsteh commented 9 years ago

Here's the documentation for SWS localisation, which is based on Cockos's localisation code. Also, WDL's string stuff is probably worth considering. Ug; all of this stuff is such a mess.

Michael1972 commented 9 years ago

Hi Jamie, having osara translated into different languages is a very good idea. I would like to help translating into german. But I'm not a developer and have no experiences in software-development. But if I could help translating, I would be glad.

jcsteh commented 7 years ago

C++ Format is now fmt. I think this is definitely the way to go for string formatting. Adjusting all of our strings will be a pretty big, tedious chunk of work, though.

I'm really not a fan of Cockos's localisation code for our purposes. At least for now, you can only have a single language pack for REAPER and all extensions, which means you have to merge language packs for all extensions users might care about.

I'm considering using tinygettext, which would allow us to use .po files. One advantage of this is that there are nice tools for working with them already. There are a few challenges to solve, though:

  1. tinygettext depends on iconv and dirent. We can require translators to use UTF-8 and we only need UTF-8 output, so we can probably just wrap iconv with a no-op. tinygettext/tinygettext#15 discusses working around/avoiding the dirent dependency.
  2. How do we extract strings for dialogs, etc. from the .rc file? I don't think xgettext works on .rc files. rc2po might do the trick, but that would create a single .po file. I guess we could use gettext's msgcat tool to merge the two .po files.
  3. How do we actually translate the dialogs? The normal pattern in Win32 is to have separate dialog resources for every language, but this is pretty tedious and I don't think it'll work for Mac. I think it'll be easier to just walk the dialog after creation and use SetWindowText to replace the messages for all static text, check boxes, buttons, etc.
aizhidadi commented 6 years ago

Hi Jamie. I have see your analysis and solutions. That's good. But I don't know how is gettext (.po) working. If this way is best, I'll learn about it. I thought there're something important for OSARA translation. 1, the source code of translation should not be depended on the platform possible. 2, the translation is for the whole sentence or the word. So my original solution is that making a middle layer, its job is conversion from embed English string to locale string. Each infomation that will output, all needs to go through this module, then to be displayed or to be created for accessibility event. Then put all sentence into a language file. it includes the mapping of string to string. In addition, we should also add some regex for the dynamic string. All above, they may be achieved in c++. For the dialog, also call api recursively to get and translate each control string . But I have some problems.

  1. How program uses a correct lang file for current system language in the way c++.
  2. If translation is based for each word group, the regex may not be used. This will become more simple and stable. But translation effect may be bad. The word group means that each parameter of iostream operator <<, not include space " " in begin or end. This way need to modify each caller in source code. Maybe need to wrap a special API for each word group. Or overload operator <<. That's my mind.
jcsteh commented 6 years ago

Thanks for your interest, @aizhidadi.

  1. You're correct that the way we currently build strings from fragments would need to be changed for some strings. For example, instead of s << "bar " << measure, we'd want something like "bar {measure}". Translators would then translate that entire string, and {measure} would get replaced with the number. That's where the fmt library comes in, as it supports this kind of functionality. We can't do this for things like the full reporting of a track, though, because the information available changes depending on the track; e.g. if it's not muted, we don't report "muted" at all. In those cases, we would still join strings together, but I think those are okay; they're not meant to be grammatically correct.
  2. gettext allows you to mark strings in the source to be translated; e.g. _("translate me") or _("bar {measure}"). You then use a tool to generate a template which contains all these messages and translators translate the template for their language. After that, translators provide the .po file for their language and OSARA would load the correct .po file depending on the language being used. The messages are then translated at runtime based on the .po file loaded.
  3. It's easy enough to get the user's language as used by Windows; see the GetUserDefaultUILanguage and LCIDToLocaleName functions. However, we may also want to check what language REAPER is using and use that instead. I'm not exactly sure how to do this, but I imagine we can poke in the REAPER config.
betov75 commented 4 years ago

Hi! I've installed and compiled the installer for OSARA today. I don't know much about C++ (for now...), i'm a PHP, Javascript coder, a good one. But I know nothing about software programming. My native language is french, I offer myself to at least translate an installer with french translation. As of today, i have translated and tested multiple scripts and they work fine with OSARA in french. I use the english version myself but i know some people want that kind of stuff. I can't translate each version though so an include would be great! I can work with accents here on Windows. Osara recognize "éàèê" etc..

If ever I can help!

dpy013 commented 3 years ago

hello all After browsing through all the comments above I had this thought, Is it possible for osara to take all the strings that need to be translated and put the translation entries directly into the reaper language pack.

Just like the sws translation template. thanks

dpy013 commented 3 years ago

This has the added benefit that the translator only has to maintain a single translation file and does not have to use multiple editors to work on it.

jcsteh commented 3 years ago

The problem with REAPER's language packs is that you can't have individual language packs per extension. So, while it's very likely that a language pack will include strings for a commonly used extension like SWS, it's unlikely that most language packs will include OSARA. That would mean users would have a very limited set of language packs to choose from; i.e. only those where the translator has agreed to include OSARA messages.

jcsteh commented 3 years ago

I started looking into this. I got tinygettext and fmt to compile with some hackery, which is good. However, I then started thinking about how we're going to build the .pot template from both cpp and rc files, how OSARA will find the right .po file, how we will localise dialogs, etc. With all of that, I'm starting to reconsider whether we should use the Cockos localisation stuff after all, since it will handle all of this.

My concern above still applies: we'd need to have single merged language packs for REAPER, SWS and OSARA. There are lang packs for REAPER + SWS, so our translators would have to translate the OSARA messages, then merge them into the REAPER + SWS lang pack for their language. See this post for details about what SWS translators have to do, which will be the same process for OSARA. This makes life pretty difficult for translators. Also, it wouldn't really be feasible for OSARA to include translations, since they would also include REAPER and SWS messages; users would have to get the full language pack somewhere else. That said, that's how it is for REAPER and SWS right now, so maybe that's not so unreasonable.

It'd be good to get thoughts from interested translators here.

jcsteh commented 3 years ago

CC @Carlos-EstebanM @ElCrackLoko, who have also expressed interest in translating.

dpy013 commented 3 years ago
      The current simplified Chinese version of osara is mainly translated using SDL Passolo 2018. Translators who are not familiar with the code are unable to localize.
      What is the official way to maintain the translation?
jcsteh commented 3 years ago

There is no official way yet. I'm trying to work out the best option for the project. See my comment above for current thoughts on options and how they would work.

Carlos-EstebanM commented 3 years ago

Hi all. OK, I and Mauricio go to check the information about how work the translation of SWS. Yes, use the localization of cocos is a good idea. Regards.

jcsteh commented 3 years ago

I'm playing with gettext a bit more. I'd really like to bundle the translations with OSARA if I can and being able to use the more standard .po files is a nice bonus.

For translators: do your users tend to use specific REAPER language packs or do different users use different language packs? I'm thinking the .po file would be named the same as the REAPER language pack, but that isn't going to work if there are multiple language packs in use for a particular language.

dpy013 commented 3 years ago

I think it's easier to manage language specific packages using gettext.

ElCrackLoko commented 3 years ago

Hello. Reading the comments, I see that the best method that so far has apparently been found for translation is to use gettext, right? I guess it is no longer necessary to figure out how SWS is translated, although ironically, it is not translated either. About @jcsteh query For Spanish, the majority of users make use of a single language file that could be said, is the official one, or at least it is the most used and the one that, in the blind community, the Administrators share. Yes, of course there are more files of the same language but they are not that common. @Carlos-EstebanM was talking with the person who does the Spanish translation for Reaper, Javi Robledo, a Spaniard, to which Javi replied to my partner that, in effect, he was aware of the existence of Osara. Amazing! Sure? Okay. I had agreed to communicate with him these days, to ask him the method which was based to translate Reaper, to also translate Osara. Recalling, remembering, Javi had told my administration partner in Spanish ADM Accessible Musical Production, @Carlos-EstebanM that he could send him the parts of Osara to be translated so that he, that is, Javi, could take care of it. Although of course, we were not completely convinced by the idea, because we are people, together with @Carlos-EstebanM of doing trial and error. And the translator is a clairvoyant and I don't think he uses NVDA, it would be like translating Osara in a superficial way. I'm going to see if I contact him today to see what he says. Sorry bad English, greetings to all. Master successes!

jcsteh commented 3 years ago

I've just set up a Crowdin project for OSARA. My intention is that all translations will be managed and submitted via Crowdin. With Crowdin, you can either translate online on the web, upload translations from a .po file or sync with Poedit. If you've already started translating, you can just upload your .po file to Crowdin.

If you'd like to be added to the Crowdin project so you can submit translations, please create a Crowdin account and let me know your Crowdin username, what language you'd like to translate and the file name of the REAPER language pack (or packs) for your language. Thanks.

jcsteh commented 2 years ago

The translation framework has been implemented, we have active translations and I think all messages are translated now.