Skip to content

Commit 3c1a8ec

Browse files
committed
swift i18n
1 parent 23cdc57 commit 3c1a8ec

File tree

8 files changed

+82
-2
lines changed

8 files changed

+82
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ build
33
*.tar.bz2
44
*.zip
55
meta.swift
6+
assets/en.lproj/Localizable.strings

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ add_subdirectory(engines)
101101

102102
fcitx5_get_addon_targets(COMMON_TARGETS iosnotifications fcitx5 iosfrontend uipanel)
103103

104+
set(LOCALES en zh-Hans)
105+
list(TRANSFORM LOCALES APPEND ".lproj" OUTPUT_VARIABLE LPROJS)
104106
add_subdirectory(assets)
105107
add_subdirectory(common)
106108
add_subdirectory(keyboard)

assets/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Icon
12
add_custom_command(
23
OUTPUT "${PROJECT_BINARY_DIR}/full-punc.png"
34
COMMAND rsvg-convert "${CMAKE_CURRENT_SOURCE_DIR}/full-punc.svg" "-o" "${PROJECT_BINARY_DIR}/full-punc.png"
@@ -13,3 +14,21 @@ add_custom_target(png_images ALL
1314
)
1415

1516
execute_process(COMMAND "${PROJECT_SOURCE_DIR}/scripts/generate-icons.sh")
17+
18+
# I18n
19+
list(TRANSFORM LPROJS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/" OUTPUT_VARIABLE LPROJ_DIRS)
20+
list(TRANSFORM LPROJ_DIRS APPEND "/Localizable.strings" OUTPUT_VARIABLE LOCALIZABLE_STRINGS_FILES)
21+
22+
file(GLOB_RECURSE LOCALIZABLE_SWIFT_SOURCES ${PROJECT_SOURCE_DIR}/src/*.swift)
23+
24+
add_custom_command(
25+
OUTPUT ${LOCALIZABLE_STRINGS_FILES}
26+
COMMAND genstrings ${LOCALIZABLE_SWIFT_SOURCES} -SwiftUI -o ${CMAKE_CURRENT_SOURCE_DIR}/en.lproj
27+
COMMAND ${PROJECT_SOURCE_DIR}/scripts/update_translations.py ${LOCALIZABLE_STRINGS_FILES}
28+
DEPENDS ${LOCALIZABLE_SWIFT_SOURCES}
29+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
30+
COMMENT "Generating Localizable.strings..."
31+
)
32+
add_custom_target(GenerateStrings
33+
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/en.lproj/Localizable.strings
34+
)
616 Bytes
Binary file not shown.

scripts/lint.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@ set -e
22

33
find common src keyboard iosfrontend iosnotifications uipanel -name '*.cpp' -o -name '*.h' | xargs clang-format -Werror --dry-run
44
swift-format lint -rs src keyboard iosfrontend iosnotifications uipanel protocol ipc
5+
6+
localizables=$(find assets -name 'Localizable.strings')
7+
for localizable in $localizables; do
8+
file $localizable | grep UTF-16
9+
done

scripts/update_translations.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
import re
5+
6+
7+
COMMENT_RE = re.compile(r'^/\*')
8+
DATA_LINE_RE = re.compile(r'^"(.*)" = "(.*)";$')
9+
ENCODING = 'utf16'
10+
11+
12+
class TranslationFile:
13+
def __init__(self, path: str):
14+
self.path = path
15+
self.table = {}
16+
with open(path, 'r', encoding=ENCODING) as file:
17+
for line in file:
18+
m = re.match(DATA_LINE_RE, line)
19+
if not m:
20+
continue
21+
self.table[m.group(1)] = m.group(2)
22+
23+
def update_from(self, base: 'TranslationFile'):
24+
with open(self.path, 'w', encoding=ENCODING) as out, open(base.path, 'r', encoding=ENCODING) as inp:
25+
for line in inp:
26+
if not line.strip():
27+
continue
28+
m = re.match(COMMENT_RE, line)
29+
if m:
30+
continue
31+
m = re.match(DATA_LINE_RE, line)
32+
if m:
33+
key = m.group(1)
34+
value = self.table.get(key, m.group(2))
35+
out.write(f'"{key}" = "{value}";\n')
36+
else:
37+
out.write(line)
38+
39+
40+
if __name__ == '__main__':
41+
if len(sys.argv) < 3:
42+
print('USAGE: base.strings locale1.strings locale2.strings locale3.strings ...')
43+
sys.exit(1)
44+
print(f'base = {sys.argv[1]}')
45+
base = TranslationFile(sys.argv[1])
46+
for path in sys.argv[2:]:
47+
print(f'updating {path}')
48+
translated = TranslationFile(path)
49+
translated.update_from(base)

src/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,15 @@ endforeach()
192192
generate_profile(App "." "${DEFAULT_INPUT_METHODS}")
193193
add_dependencies(${BUNDLE_NAME} AppProfile)
194194

195-
# Copy icons and profile
195+
# Copy icons, profile and translations.
196196
set(ICON_FILES "AppIcon60x60@2x.png" "AppIcon76x76@2x~ipad.png" "Assets.car")
197197
foreach(ICON_FILE IN LISTS ICON_FILES)
198198
copy_to_app(copy "${PROJECT_SOURCE_DIR}/build/assets/actool_out/${ICON_FILE}" "${ICON_FILE}")
199199
endforeach()
200200
copy_to_app(copy "${PROJECT_BINARY_DIR}/profile" profile)
201+
foreach(LPROJ IN LISTS LPROJS)
202+
copy_to_app(copy_directory "${PROJECT_SOURCE_DIR}/assets/${LPROJ}" "${LPROJ}")
203+
endforeach()
201204

202205
fcitx5_import_addons(${BUNDLE_NAME}
203206
REGISTRY_VARNAME getStaticAddon

src/ContentView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ struct ContentView: View {
6565
}
6666
}
6767
Section {
68-
ConfigLinkView(title: "Global Config", uri: globalConfigUri)
68+
ConfigLinkView(
69+
title: NSLocalizedString("Global Config", comment: ""), uri: globalConfigUri)
6970
NavigationLink(
7071
destination: AddonConfigView()
7172
) {

0 commit comments

Comments
 (0)