Skip to content

Commit

Permalink
Add support for conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
david-swift committed Mar 2, 2024
1 parent 3a0eda7 commit f498347
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 48 deletions.
10 changes: 10 additions & 0 deletions Documentation/GenerationLibrary/enums/Generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ Generate the variables for the translations.
- defaultLanguage: The default language.
- Returns: The syntax.

### `parseValue(defaultTranslation:translations:language:arguments:)`

Parse the content of a switch case.
- Parameters:
- defaultTranslation: The translation without any conditions (always required).
- translations: All the available translations for an entry.
- language: The language.
- arguments: The arguments of the entry.
- Returns: The syntax.

### `generateLanguageFunction(dictionary:defaultLanguage:)`

Generate the function for getting the translated string for a specified language code.
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ house:
en: House
de: Haus
fr: Maison

houses(count):
en(count == "1"): There is one house.
en: There are (count) houses.
de(count == "1"): Es gibt ein Haus.
de: Es gibt (count) Häuser.
```
Then, access the localized strings safely in your code:
Expand All @@ -35,6 +41,7 @@ Then, access the localized strings safely in your code:
// Use the system language
print(Loc.hello(name: "Peter"))
print(Loc.house)
print(Loc.houses(count: "1"))

// Access the translation for a specific language
print(Localized.hello(name: "Peter").en)
Expand Down Expand Up @@ -70,11 +77,13 @@ export:
de: Exportiere das Dokument

send(message, name):
en(name == ""): Send (message).
en: Send (message) to (name).
de: Sende (message) to (name).
```
As you can see, you can add parameters using brackets after the key.
As you can see, you can add parameters using brackets after the key,
and conditions using brackets after the language (e.g. for pluralization).
The line `default: en` sets English as the fallback language.

Expand Down
49 changes: 45 additions & 4 deletions Sources/GenerationLibrary/Generation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,18 @@ public enum Generation {
guard let valueForLanguage = entry.value[language] ?? entry.value[defaultLanguage] else {
throw GenerationError.missingTranslationInDefaultLanguage(key: key.0)
}
let value = parseValue(
defaultTranslation: valueForLanguage,
translations: entry.value,
language: language,
arguments: key.1
)
if key.1.isEmpty {
variable += indent("\ncase .\(entry.key):", by: indentTwo)
variable += indent("\n\"\(valueForLanguage)\"", by: indentThree)
variable += value
} else {
let translation = parse(translation: valueForLanguage, arguments: key.1)
variable += indent("\ncase let .\(entry.key):", by: indentTwo)
variable += indent("\n\"\(translation)\"", by: indentThree)
variable += value
}
}
variable += indent("\n }\n}", by: indentOne)
Expand All @@ -169,6 +174,42 @@ public enum Generation {
return result
}

/// Parse the content of a switch case.
/// - Parameters:
/// - defaultTranslation: The translation without any conditions (always required).
/// - translations: All the available translations for an entry.
/// - language: The language.
/// - arguments: The arguments of the entry.
/// - Returns: The syntax.
static func parseValue(
defaultTranslation: String,
translations: [String: String],
language: String,
arguments: [String] = []
) -> String {
var value = "\n"
let conditionTranslations = translations.filter { $0.key.hasPrefix(language + "(") }
let lastTranslation = parse(translation: defaultTranslation, arguments: arguments)
if conditionTranslations.isEmpty {
return indent("\n\"\(lastTranslation)\"", by: indentThree)
}
for translation in conditionTranslations {
var condition = translation.key.split(separator: "(")[1]
condition.removeLast()
value.append(indent("""
if \(condition) {
\"\(parse(translation: translation.value, arguments: arguments))\"
} else
""", by: indentThree))
}
value.append("""
{
\"\(lastTranslation)\"
}
""")
return value
}

/// Generate the function for getting the translated string for a specified language code.
/// - Parameters:
/// - dictionary: The parsed YML.
Expand Down Expand Up @@ -199,7 +240,7 @@ public enum Generation {
static func getLanguages(dictionary: [String: [String: String]]) -> [String] {
var languages: Set<String> = []
for key in dictionary {
languages = languages.union(key.value.map { $0.key })
languages = languages.union(key.value.compactMap { $0.key.components(separatedBy: "(").first })
}
return .init(languages)
}
Expand Down
10 changes: 10 additions & 0 deletions Tests/PluginTests/Localized.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ house:
de: Haus
fr: Maison

houses(count):
en(count == "1"): There is one house.
en(count == "0"): There is no house.
en: There are (count) houses.
de(count == "1"): Es gibt ein Haus.
de(count == "0"): Es gibt kein Haus.
de: Es gibt (count) Häuser.
# There is no French translation for this phrase.
# The default language, in this case English, will be used.

helloPair(name1, name2):
en: Hello, (name1) and (name2)!
de: Hallo, (name1) und (name2)!
Expand Down
3 changes: 3 additions & 0 deletions Tests/PluginTests/Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ enum Tests {
print("DE_CH: \(Localized.house.string(for: "de_CH"))")
print("SYSTEM: \(Localized.house.string)")
print("EN: \(Localized.helloPair(name1: "Max", name2: "Ruedi").en)")
print(Loc.houses(count: "0"))
print(Loc.houses(count: "1"))
print(Loc.houses(count: "2"))
}

}
43 changes: 0 additions & 43 deletions Tests/Tests.swift

This file was deleted.

0 comments on commit f498347

Please sign in to comment.