Skip to content

Commit 3e13d50

Browse files
Created I18N data, part 1 (#404)
1 parent 02c3e4c commit 3e13d50

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1382
-479
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="Collect I18N content" type="ShConfigurationType">
3+
<option name="SCRIPT_TEXT" value="dotnet run collect-i18n" />
4+
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
5+
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/Build" />
6+
<option name="SCRIPT_OPTIONS" value="" />
7+
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
8+
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/Build" />
9+
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
10+
<option name="INTERPRETER_PATH" value="/opt/homebrew/bin/nu" />
11+
<option name="INTERPRETER_OPTIONS" value="" />
12+
<option name="EXECUTE_IN_TERMINAL" value="true" />
13+
<option name="EXECUTE_SCRIPT_FILE" value="false" />
14+
<envs />
15+
<method v="2" />
16+
</configuration>
17+
</component>

app/.run/Tauri Dev.run.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<option name="EXECUTE_IN_TERMINAL" value="false" />
1313
<option name="EXECUTE_SCRIPT_FILE" value="false" />
1414
<envs />
15-
<method v="2" />
15+
<method v="2">
16+
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Collect I18N content" run_configuration_type="ShConfigurationType" />
17+
</method>
1618
</configuration>
1719
</component>

app/Build/Commands/CollectI18NKeysCommand.cs

Lines changed: 144 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public async Task CollectI18NKeys()
2525
var wwwrootPath = Path.Join(cwd, "wwwroot");
2626
var allFiles = Directory.EnumerateFiles(cwd, "*", SearchOption.AllDirectories);
2727
var counter = 0;
28-
var sb = new StringBuilder();
2928

29+
var allI18NContent = new Dictionary<string, string>();
3030
foreach (var filePath in allFiles)
3131
{
3232
counter++;
@@ -46,17 +46,155 @@ public async Task CollectI18NKeys()
4646

4747
var ns = this.DetermineNamespace(filePath);
4848
var fileInfo = new FileInfo(filePath);
49-
var name = fileInfo.Name.Replace(fileInfo.Extension, string.Empty);
50-
var langNamespace = $"{ns}::{name}".ToUpperInvariant().Replace(".", "::");
49+
var name = fileInfo.Name.Replace(fileInfo.Extension, string.Empty).Replace(".razor", string.Empty);
50+
var langNamespace = $"{ns}.{name}".ToUpperInvariant();
5151
foreach (var match in matches)
5252
{
53-
var key = $"root::{langNamespace}::T{match.ToFNV32()}";
53+
// The key in the format A.B.C.D.T{hash}:
54+
var key = $"UI_TEXT_CONTENT.{langNamespace}.T{match.ToFNV32()}";
55+
allI18NContent.TryAdd(key, match);
56+
}
57+
}
58+
59+
Console.WriteLine($" {counter:###,###} files processed, {allI18NContent.Count:###,###} keys found.");
60+
61+
Console.Write("- Creating Lua code ...");
62+
var luaCode = this.ExportToLuaTable(allI18NContent);
63+
64+
// Build the path, where we want to store the Lua code:
65+
var luaPath = Path.Join(cwd, "Assistants", "I18N", "allTexts.lua");
66+
67+
// Store the Lua code:
68+
await File.WriteAllTextAsync(luaPath, luaCode, Encoding.UTF8);
69+
70+
Console.WriteLine(" done.");
71+
}
72+
73+
private string ExportToLuaTable(Dictionary<string, string> keyValuePairs)
74+
{
75+
// Collect all nodes:
76+
var root = new Dictionary<string, object>();
77+
78+
//
79+
// Split all collected keys into nodes:
80+
//
81+
foreach (var key in keyValuePairs.Keys.Order())
82+
{
83+
var path = key.Split('.');
84+
var current = root;
85+
for (var i = 0; i < path.Length - 1; i++)
86+
{
87+
// We ignore the AISTUDIO segment of the path:
88+
if(path[i] == "AISTUDIO")
89+
continue;
5490

91+
if (!current.TryGetValue(path[i], out var child) || child is not Dictionary<string, object> childDict)
92+
{
93+
childDict = new Dictionary<string, object>();
94+
current[path[i]] = childDict;
95+
}
96+
97+
current = childDict;
5598
}
99+
100+
current[path.Last()] = keyValuePairs[key];
56101
}
102+
103+
//
104+
// Inner method to build Lua code from the collected nodes:
105+
//
106+
void ToLuaTable(StringBuilder sb, Dictionary<string, object> innerDict, int indent = 0)
107+
{
108+
sb.AppendLine("{");
109+
var prefix = new string(' ', indent * 4);
110+
foreach (var kvp in innerDict)
111+
{
112+
if (kvp.Value is Dictionary<string, object> childDict)
113+
{
114+
sb.Append($"{prefix} {kvp.Key}");
115+
sb.Append(" = ");
116+
117+
ToLuaTable(sb, childDict, indent + 1);
118+
}
119+
else if (kvp.Value is string s)
120+
{
121+
sb.AppendLine($"{prefix} -- {s.Trim().Replace("\n", " ")}");
122+
sb.Append($"{prefix} {kvp.Key}");
123+
sb.Append(" = ");
124+
sb.Append($"""
125+
"{s}"
126+
""");
127+
sb.AppendLine(",");
128+
sb.AppendLine();
129+
}
130+
}
131+
132+
sb.AppendLine(prefix + "},");
133+
sb.AppendLine();
134+
}
135+
136+
//
137+
// Write the Lua code:
138+
//
139+
var sbLua = new StringBuilder();
140+
141+
// To make the later parsing easier, we add the mandatory plugin
142+
// metadata:
143+
sbLua.AppendLine(
144+
"""
145+
-- The ID for this plugin:
146+
ID = "77c2688a-a68f-45cc-820e-fa8f3038a146"
147+
148+
-- The icon for the plugin:
149+
ICON_SVG = ""
150+
151+
-- The name of the plugin:
152+
NAME = "Collected I18N keys"
153+
154+
-- The description of the plugin:
155+
DESCRIPTION = "This plugin is not meant to be used directly. Its a collection of all I18N keys found in the project."
156+
157+
-- The version of the plugin:
158+
VERSION = "1.0.0"
159+
160+
-- The type of the plugin:
161+
TYPE = "LANGUAGE"
162+
163+
-- The authors of the plugin:
164+
AUTHORS = {"MindWork AI Community"}
165+
166+
-- The support contact for the plugin:
167+
SUPPORT_CONTACT = "MindWork AI Community"
168+
169+
-- The source URL for the plugin:
170+
SOURCE_URL = "https://github.com/MindWorkAI/AI-Studio"
171+
172+
-- The categories for the plugin:
173+
CATEGORIES = { "CORE" }
174+
175+
-- The target groups for the plugin:
176+
TARGET_GROUPS = { "EVERYONE" }
177+
178+
-- The flag for whether the plugin is maintained:
179+
IS_MAINTAINED = true
180+
181+
-- When the plugin is deprecated, this message will be shown to users:
182+
DEPRECATION_MESSAGE = ""
183+
184+
-- The IETF BCP 47 tag for the language. It's the ISO 639 language
185+
-- code followed by the ISO 3166-1 country code:
186+
IETF_TAG = "en-US"
187+
188+
-- The language name in the user's language:
189+
LANG_NAME = "English (United States)"
190+
191+
""");
192+
193+
sbLua.Append("UI_TEXT_CONTENT = ");
194+
if(root["UI_TEXT_CONTENT"] is Dictionary<string, object> dict)
195+
ToLuaTable(sbLua, dict);
57196

58-
Console.WriteLine($" {counter:###,###} files processed.");
59-
Console.WriteLine();
197+
return sbLua.ToString();
60198
}
61199

62200
private List<string> FindAllTextTags(ReadOnlySpan<char> fileContent)

app/Build/Commands/UpdateWebAssetsCommand.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// ReSharper disable UnusedType.Global
33
// ReSharper disable UnusedMember.Global
44

5-
using Build.Tools;
6-
75
using SharedTools;
86

97
namespace Build.Commands;

0 commit comments

Comments
 (0)