Skip to content

Commit

Permalink
Use Npp nativeLang.xml to decide how to translate
Browse files Browse the repository at this point in the history
  • Loading branch information
molsonkiko committed Jul 22, 2024
1 parent a8b6d15 commit 1e4dfe6
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

1. Rename `Choose schemas to automatically validate filename patterns` to [`Validate files with JSON schema if name matches pattern`](/docs/README.md#automatic-validation-of-json-against-json-schema), in the hopes that the new name will be less confusing.
2. Changed the wording of many JSON syntax error messages to be more consistent, per [conky77's suggestion here](https://github.com/molsonkiko/JsonToolsNppPlugin/issues/70#issuecomment-2234114308).
3. When attempting to translate to other languages, JsonTools now checks the UI language of Notepad++ before checking the Windows UI culture.

### Fixed

Expand Down
4 changes: 2 additions & 2 deletions JsonToolsNppPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("8.0.0.13")]
[assembly: AssemblyFileVersion("8.0.0.13")]
[assembly: AssemblyVersion("8.0.0.14")]
[assembly: AssemblyFileVersion("8.0.0.14")]
91 changes: 54 additions & 37 deletions JsonToolsNppPlugin/Utils/Translator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,56 +21,61 @@ public static class Translator

public static bool HasLoadedAtStartup { get; private set; } = false;

public static void LoadTranslations(bool atStartup = true)
public static string languageName { get; private set; } = DEFAULT_LANG;

public const string DEFAULT_LANG = "english";
public static readonly string translationDir = Path.Combine(Npp.pluginDllDirectory, "translation");

public static void LoadTranslations(bool atStartup = true, string preferredLang = null)
{
if (atStartup && HasLoadedAtStartup)
return;
HasLoadedAtStartup = true;
string languageName = "english";
// TODO: maybe use Notepad++ nativeLang preference to guide translation?
// Possible references include:
// * https://github.com/daddel80/notepadpp-multireplace/blob/65411ac5754878bbf8af7a35dba7b35d7d919ff4/src/MultiReplacePanel.cpp#L6347
// * https://npp-user-manual.org/docs/binary-translation/

//// first try to use the Notepad++ nativeLang.xml config file to determine the user's language preference
//string nativeLangXmlFname = Path.Combine(Npp.notepad.GetConfigDirectory(), "..", "nativeLang.xml");
//if (File.Exists(nativeLangXmlFname))
//{
// try
// {
// string nativeLangXml;
// using (var reader = new StreamReader(File.OpenRead(nativeLangXmlFname), Encoding.UTF8, true))
// {
// nativeLangXml = reader.ReadToEnd();
// }
// Match match = Regex.Match(nativeLangXml, "<Native-Langue .*? filename=\"(.*?)\\.xml\"");
// if (match.Success)
// languageName = match.Groups[1].Value.Trim().ToLower();
// }
// catch (Exception ex)
// {
// MessageBox.Show($"While attempting to determine native language preference from Notepad++ config XML, got an error:\r\n{ex}");
// }
//}
if (languageName == "english")
if (preferredLang == null)
{
// first try to use the Notepad++ nativeLang.xml config file to determine the user's language preference
string nativeLangXmlFname = Path.Combine(Npp.notepad.GetConfigDirectory(), "..", "..", "nativeLang.xml");
if (File.Exists(nativeLangXmlFname))
{
try
{
string nativeLangXml;
using (var reader = new StreamReader(File.OpenRead(nativeLangXmlFname), Encoding.UTF8, true))
{
nativeLangXml = reader.ReadToEnd();
}
Match match = Regex.Match(nativeLangXml, "<Native-Langue .*? filename=\"(.*?)\\.xml\"");
if (match.Success)
languageName = match.Groups[1].Value.Trim().ToLower();
}
catch //(Exception ex)
{
//MessageBox.Show($"While attempting to determine native language preference from Notepad++ config XML, got an error:\r\n{ex}");
}
}
// as a fallback, try to determine the user's language by asking Windows for their current culture
CultureInfo currentCulture = CultureInfo.CurrentCulture;
string languageFullname = currentCulture.EnglishName;
languageName = languageFullname.Split(' ')[0].ToLower();
if (languageName == "Unknown")
languageName = currentCulture.Parent.EnglishName.Split(' ')[0].ToLower();
if (languageName == DEFAULT_LANG || !TryGetTranslationFileName(languageName, out _))
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
string languageFullname = currentCulture.EnglishName;
languageName = languageFullname.Split(' ')[0].ToLower();
if (languageName == "Unknown")
languageName = currentCulture.Parent.EnglishName.Split(' ')[0].ToLower();
}
}
else
{
languageName = preferredLang;
}
if (languageName == "english")
if (languageName == DEFAULT_LANG)
{
//MessageBox.Show("Not loading translations, because english is the current culture language");
return;
}
string translationDir = Path.Combine(Npp.pluginDllDirectory, "translation");
string translationFilename = Path.Combine(translationDir, languageName + ".json5");
if (!File.Exists(translationFilename))
if (!TryGetTranslationFileName(languageName, out string translationFilename))
{
//MessageBox.Show($"Could not find a translation file for language {languageFirstname} in directory {translationDir}");
languageName = DEFAULT_LANG;
return;
}
FileInfo translationFile = new FileInfo(translationFilename);
Expand All @@ -87,10 +92,22 @@ public static void LoadTranslations(bool atStartup = true)
}
catch/* (exception ex)*/
{
languageName = DEFAULT_LANG;
//MessageBox.Show($"While attempting to parse translation file {translationFilename}, got an exception:\r\n{RemesParser.PrettifyException(ex)}");
}
}

private static bool TryGetTranslationFileName(string langName, out string translationFilename)
{
translationFilename = Path.Combine(translationDir, langName + ".json5");
if (!File.Exists(translationFilename))
{
translationFilename = null;
return false;
}
return true;
}

public static string GetTranslatedMenuItem(string menuItem)
{
if (translations is JObject jobj
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,11 @@ I expect you could find plenty of other good websites if you did some research.
If you are interested in helping users of JsonTools who don't speak English, JsonTools can be translated to other languages beginning in [v8.0](/CHANGELOG.md#800---2024-06-29).

JsonTools infers your preferred language and attempts to translate in the following way:
1. JsonTools looks up your [`current culture`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-culture?view=powershell-7.4) (which can be checked using the `get-culture` command in Powershell).
2. Next, we find the `EnglishName` property of the `current culture` (which can be found by the `$foo = get-culture; $foo.EnglishName` command in Powershell), take the first word, and convert it to lowercase. Call this `lowerEnglishCulture`.
- Example: the `EnglishName` of the `en-us` culture is `English (United States)`, so `lowerEnglishCulture` is `english`
- Example: the `EnglishName` of the `it-it` culture is `Italian (Italy)`, so `lowerEnglishCulture` is `italian`
1. JsonTools checks your [Notepad++ `nativeLang.xml` config file](https://npp-user-manual.org/docs/binary-translation/#creating-or-editing-a-translation) (at [XPath path](https://www.w3schools.com/xml/xml_xpath.asp) `/NotepadPlus/Native-Langue/@name`) to determine what language you prefer to use, and sets `lowerEnglishName` to the appropriate value and __skips to step 3__. For example, if this file says `galician`, we will attempt to translate JsonTools to `galician`. __If the Notepad++ native language is `english` *or* if JsonTools does not have a translation file for the Notepad++ native language, JsonTools then does the following:__
1. JsonTools looks up your [`current culture`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-culture?view=powershell-7.4) (which can be checked using the `get-culture` command in Powershell).
2. Next, we find the `EnglishName` property of the `current culture` (which can be found by the `$foo = get-culture; $foo.EnglishName` command in Powershell), take the first word, and convert it to lowercase. Call this `lowerEnglishName`.
- Example: the `EnglishName` of the `en-us` culture is `English (United States)`, so `lowerEnglishName` is `english`
- Example: the `EnglishName` of the `it-it` culture is `Italian (Italy)`, so `lowerEnglishName` is `italian`
3. JsonTools then does one of the following:
- If `lowerEnglishName` is `english`, it does nothing (because JsonTools is naturally in English)
- Otherwise, it looks in the `translation` subdirectory of the `JsonTools` plugin folder (where `JsonTools.dll` lives) for a file named `{lowerEnglishName}.json5`
Expand All @@ -151,7 +152,7 @@ JsonTools infers your preferred language and attempts to translate in the follow
- If no translation file was found, or if parsing failed, the default English will be used.
5. If parsing was successful, JsonTools will use the translation file as described below.

To be clear, *JsonTools may not be in the same language of the Notepad++ UI,* and I do not plan to change that.
JsonTools only attempts to find translation files once, when Notepad++ is starting up. If you change the UI language of Notepad++ or your operating system's UI culture, you will have to close Notepad++ and reopen it before this change will apply to JsonTools.

To translate JsonTools to another language, just look at [`english.json5` in the translations directory of this repo](https://github.com/molsonkiko/JsonToolsNppPlugin/blob/main/translation/english.json5) and follow the instructions in that file.

Expand Down

0 comments on commit 1e4dfe6

Please sign in to comment.