From a8e3264302541ceb575d6daab6a6d916f40818b3 Mon Sep 17 00:00:00 2001 From: jmacwhyte Date: Fri, 28 Apr 2017 18:55:55 -0700 Subject: [PATCH] initial (and final?) commit! --- .gitignore | 2 + README.md | 20 ++++++++++ l2l/l2l.go | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 l2l/l2l.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0c81dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Strings.swift +Localizable.strings \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..229376d --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +## Localized-to-Localizable + +This is a simple Go program that searches through a (swift or Obj-C) file of NSLocalizedStrings and generates a Localizable.strings file based on the keys, default values, and comments. + +### But why? + +XCode apparently doesn't really support exporting a `Localizable.strings` file when localized strings have a default value that doesn't match the key. This isn't a problem when you want your keys to be the same as your values, such as: + +`key: "Click here to submit", value: "Click here to submit"` + +However, what if you want your keys to be more code-friendly/platform agnostic while saving default values that represent the actual text you want to include? This script will allow you to easily generate a `Localizable.strings` file with strings that look like: + +`key: "SubmitText", value: "Click here to submit"` + +### How to use it +Simply define all of your strings with a key, default value, and (optional) comment like so: + +```let submitText = NSLocalizedString("SubmitText", value:"Click here to submit", comment: "Submit button label")``` + +Run the script by calling `l2l` and it will look in the current directory for a `Strings.swift` file. You can also pass the filename you want it to parse as an argument after `l2l`. \ No newline at end of file diff --git a/l2l/l2l.go b/l2l/l2l.go new file mode 100644 index 0000000..9ade818 --- /dev/null +++ b/l2l/l2l.go @@ -0,0 +1,105 @@ +package main + +import ( + "fmt" + "io/ioutil" + "os" + "regexp" + "sort" + "strings" +) + +func main() { + + path := "strings.swift" + + if len(os.Args) >= 2 { + path = os.Args[1] + } + + source, err := ioutil.ReadFile(path) + if err != nil { + fmt.Println("Error:", err) + return + } + // NSLocalizedString("UpdatePin.updateTitle", value:"Update PIN", comment: "Update Pin title") + + NSLocalized := regexp.MustCompile(`(?m)NSLocalizedString\((.*)\)`) + hits := NSLocalized.FindAllStringSubmatch(string(source), -1) + + if len(hits) == 0 { + fmt.Println("Found no instances of NSLocalizedString") + return + } + + type Entry struct { + comment string + key string + value string + } + + entries := make(map[string]Entry) + var keys []string + + for _, entry := range hits { + var e Entry + + details := strings.TrimSpace(entry[1]) + key := regexp.MustCompile(`^"([^"]*)"`).FindStringSubmatch(details) + if len(key) < 2 { + fmt.Println("No key found in ", entry[0]) + return + } + e.key = key[1] + + others := regexp.MustCompile(`,([ a-z:]*)"([^"]*)"`).FindAllStringSubmatch(details, -1) + + for i, v := range others { + switch strings.Replace(v[1], ` `, ``, -1) { + case `value:`: + e.value = v[2] + continue + case `comment:`: + e.comment = v[2] + continue + } + switch i { + case 3: + e.value = v[2] + case 4: + e.comment = v[2] + } + } + + if e.value == `` { + fmt.Println("No value found in ", entry[0]) + return + } + if e.comment == `` { + fmt.Println("Warning: No comment found in ", entry[0]) + e.comment = `No comment provided.` + } + entries[e.key] = e + keys = append(keys, e.key) + } + + // Sort keys + sort.Strings(keys) + + var output string + + for i := range keys { + output += `/* ` + entries[keys[i]].comment + ` */ +"` + entries[keys[i]].key + `" = "` + entries[keys[i]].value + `"; + +` + } + + err = ioutil.WriteFile("Localizable.strings", []byte(output), 0644) + if err == nil { + fmt.Println("All done!") + } else { + fmt.Println("Error writing file:", err) + } + +}