diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-07-13 21:34:21 +0000 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-08-11 22:59:38 +0000 |
| commit | f833d26e5a14519bfd363d5c79f3227c4419f5d1 (patch) | |
| tree | ab679a5e33066b221de22ca3d6a180e19d1dc041 /android | |
| parent | 03b7ab4bacb627198ee45ec9dbce627c29f871a5 (diff) | |
| download | mullvadvpn-f833d26e5a14519bfd363d5c79f3227c4419f5d1.tar.xz mullvadvpn-f833d26e5a14519bfd363d5c79f3227c4419f5d1.zip | |
Refactor Android string resource normalization
Diffstat (limited to 'android')
| -rw-r--r-- | android/translations-converter/Cargo.toml | 1 | ||||
| -rw-r--r-- | android/translations-converter/src/android.rs | 28 | ||||
| -rw-r--r-- | android/translations-converter/src/main.rs | 19 |
3 files changed, 38 insertions, 10 deletions
diff --git a/android/translations-converter/Cargo.toml b/android/translations-converter/Cargo.toml index fab9c4484d..2b32cd9303 100644 --- a/android/translations-converter/Cargo.toml +++ b/android/translations-converter/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +lazy_static = "1" regex = "1" serde = { version = "1", features = ["derive"] } serde-xml-rs = "0.4" diff --git a/android/translations-converter/src/android.rs b/android/translations-converter/src/android.rs index 9a7fd1c99a..2481d27a4e 100644 --- a/android/translations-converter/src/android.rs +++ b/android/translations-converter/src/android.rs @@ -1,9 +1,16 @@ +use lazy_static::lazy_static; +use regex::Regex; use serde::{Deserialize, Serialize}; use std::{ fmt::{self, Display, Formatter}, ops::{Deref, DerefMut}, }; +lazy_static! { + static ref LINE_BREAKS: Regex = Regex::new(r"\s*\n\s*").unwrap(); + static ref APOSTROPHES: Regex = Regex::new(r"\\'").unwrap(); +} + /// Contents of an Android string resources file. /// /// This type can be created directly deserializing the `strings.xml` file. @@ -31,6 +38,15 @@ impl StringResources { entries: Vec::new(), } } + + /// Normalize the strings into a common format. + /// + /// Allows the string values to be compared to the gettext messages. + pub fn normalize(&mut self) { + for entry in &mut self.entries { + entry.normalize(); + } + } } impl Deref for StringResources { @@ -68,6 +84,18 @@ impl StringResource { StringResource { name, value } } + + /// Normalize the string value into a common format. + /// + /// Makes it possible to compare the Android strings with the gettext messages. + pub fn normalize(&mut self) { + // Collapse line breaks present in the XML file + let value = LINE_BREAKS.replace_all(&self.value, " "); + // Unescape apostrophes + let value = APOSTROPHES.replace_all(&value, "'"); + + self.value = value.into_owned(); + } } // Unfortunately, direct serialization to XML isn't working correctly. diff --git a/android/translations-converter/src/main.rs b/android/translations-converter/src/main.rs index 09296f87fe..24bf06a574 100644 --- a/android/translations-converter/src/main.rs +++ b/android/translations-converter/src/main.rs @@ -3,8 +3,12 @@ //! The procedure for converting the translations is relatively simple. The base Android string //! resources file is first loaded, and then each gettext translation file is loaded and compared to //! the Android base strings. For every translation string that matches exactly the Android base -//! string value, the translated string is used in the new Android strings file for the respective -//! locale. +//! string value (after a normalization pass described below), the translated string is used in the +//! new Android strings file for the respective locale. +//! +//! To make the comparison work on most strings, the Android and gettext messages are normalized +//! first. This means that new lines in the XML files are removed and collapsed into a single space +//! and apostrophes are unescaped. //! //! Note that this conversion procedure is very raw and likely very brittle, so while it works for //! most cases, it is important to keep in mind that this is just a helper tool and manual steps are @@ -13,7 +17,6 @@ mod android; mod gettext; -use regex::Regex; use std::{ collections::HashMap, fs::{self, File}, @@ -24,21 +27,17 @@ fn main() { let resources_dir = Path::new("../src/main/res"); let strings_file = File::open(resources_dir.join("values/strings.xml")) .expect("Failed to open string resources file"); - let string_resources: android::StringResources = + let mut string_resources: android::StringResources = serde_xml_rs::from_reader(strings_file).expect("Failed to read string resources file"); - let line_breaks = Regex::new(r"\s*\n\s*").unwrap(); - let apostrophes = Regex::new(r"\\'").unwrap(); + string_resources.normalize(); let known_strings: HashMap<_, _> = string_resources .into_iter() .map(|string| { let android_id = string.name; - let without_line_breaks = line_breaks.replace_all(&string.value, " "); - let without_escaped_apostrophes = apostrophes.replace_all(&without_line_breaks, "'"); - let string_value = without_escaped_apostrophes.into_owned(); - (string_value, android_id) + (string.value, android_id) }) .collect(); |
