Change translation parser plugin API to parse_file()

This commit is contained in:
SkyJJ 2020-07-03 20:24:54 +02:00
parent 0287508dcd
commit cae6f0bda2
6 changed files with 35 additions and 60 deletions

View File

@ -4,22 +4,39 @@
Plugin for adding custom parsers to extract strings that are to be translated from custom files (.csv, .json etc.). Plugin for adding custom parsers to extract strings that are to be translated from custom files (.csv, .json etc.).
</brief_description> </brief_description>
<description> <description>
Plugins are registered via [method EditorPlugin.add_translation_parser_plugin] method. To define the parsing and string extraction logic, override the [method parse_text] method in script. Plugins are registered via [method EditorPlugin.add_translation_parser_plugin] method. To define the parsing and string extraction logic, override the [method parse_file] method in script.
The extracted strings will be written into a POT file selected by user under "POT Generation" in "Localization" tab in "Project Settings" menu. The extracted strings will be written into a POT file selected by user under "POT Generation" in "Localization" tab in "Project Settings" menu.
Below shows an example of a custom parser that extracts strings in a CSV file to write into a POT. Below shows an example of a custom parser that extracts strings in a CSV file to write into a POT.
[codeblock] [codeblock]
tool tool
extends EditorTranslationParserPlugin extends EditorTranslationParserPlugin
func parse_text(text, extracted_strings):
func parse_file(path, extracted_strings):
var file = File.new()
file.open(path, File.READ)
var text = file.get_as_text()
var split_strs = text.split(",", false, 0) var split_strs = text.split(",", false, 0)
for s in split_strs: for s in split_strs:
extracted_strings.append(s) extracted_strings.append(s)
#print("Extracted string: " + s) #print("Extracted string: " + s)
func get_recognized_extensions(): func get_recognized_extensions():
return ["csv"] return ["csv"]
[/codeblock] [/codeblock]
[b]Note:[/b] If you override parsing logic for standard script types (GDScript, C#, etc.), it would be better to load the [code]path[/code] argument using [method ResourceLoader.load]. This is because built-in scripts are loaded as [Resource] type, not [File] type.
For example:
[codeblock]
func parse_file(path, extracted_strings):
var res = ResourceLoader.load(path, "Script")
var text = res.get_source_code()
# Parsing logic.
func get_recognized_extensions():
return ["gd"]
[/codeblock]
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>
@ -31,10 +48,10 @@
Gets the list of file extensions to associate with this parser, e.g. [code]["csv"][/code]. Gets the list of file extensions to associate with this parser, e.g. [code]["csv"][/code].
</description> </description>
</method> </method>
<method name="parse_text" qualifiers="virtual"> <method name="parse_file" qualifiers="virtual">
<return type="void"> <return type="void">
</return> </return>
<argument index="0" name="text" type="String"> <argument index="0" name="path" type="String">
</argument> </argument>
<argument index="1" name="extracted_strings" type="Array"> <argument index="1" name="extracted_strings" type="Array">
</argument> </argument>

View File

@ -41,33 +41,16 @@ Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<Str
if (!get_script_instance()) if (!get_script_instance())
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
if (get_script_instance()->has_method("parse_text")) { if (get_script_instance()->has_method("parse_file")) {
Error err;
FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &err);
if (err != OK) {
ERR_PRINT("Failed to open " + p_path);
return err;
}
parse_text(file->get_as_utf8_string(), r_extracted_strings);
return OK;
} else {
ERR_PRINT("Custom translation parser plugin's \"func parse_text(text, extracted_strings)\" is undefined.");
return ERR_UNAVAILABLE;
}
}
void EditorTranslationParserPlugin::parse_text(const String &p_text, Vector<String> *r_extracted_strings) {
if (!get_script_instance())
return;
if (get_script_instance()->has_method("parse_text")) {
Array extracted_strings; Array extracted_strings;
get_script_instance()->call("parse_text", p_text, extracted_strings); get_script_instance()->call("parse_file", p_path, extracted_strings);
for (int i = 0; i < extracted_strings.size(); i++) { for (int i = 0; i < extracted_strings.size(); i++) {
r_extracted_strings->append(extracted_strings[i]); r_extracted_strings->append(extracted_strings[i]);
} }
return OK;
} else { } else {
ERR_PRINT("Custom translation parser plugin's \"func parse_text(text, extracted_strings)\" is undefined."); ERR_PRINT("Custom translation parser plugin's \"func parse_file(path, extracted_strings)\" is undefined.");
return ERR_UNAVAILABLE;
} }
} }
@ -86,7 +69,7 @@ void EditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_ex
} }
void EditorTranslationParserPlugin::_bind_methods() { void EditorTranslationParserPlugin::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::NIL, "parse_text", PropertyInfo(Variant::STRING, "text"), PropertyInfo(Variant::ARRAY, "extracted_strings"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::NIL, "parse_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::ARRAY, "extracted_strings")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::ARRAY, "get_recognized_extensions")); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::ARRAY, "get_recognized_extensions"));
} }

View File

@ -42,7 +42,6 @@ protected:
public: public:
virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings); virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings);
virtual void parse_text(const String &p_text, Vector<String> *r_extracted_strings);
virtual void get_recognized_extensions(List<String> *r_extensions) const; virtual void get_recognized_extensions(List<String> *r_extensions) const;
}; };

View File

@ -71,7 +71,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
String extension = s->get_language()->get_extension(); String extension = s->get_language()->get_extension();
if (EditorTranslationParser::get_singleton()->can_parse(extension)) { if (EditorTranslationParser::get_singleton()->can_parse(extension)) {
Vector<String> temp; Vector<String> temp;
EditorTranslationParser::get_singleton()->get_parser(extension)->parse_text(s->get_source_code(), &temp); EditorTranslationParser::get_singleton()->get_parser(extension)->parse_file(s->get_path(), &temp);
parsed_strings.append_array(temp); parsed_strings.append_array(temp);
} }
} else if (property_name == "filters") { } else if (property_name == "filters") {

View File

@ -38,25 +38,8 @@ void GDScriptEditorTranslationParserPlugin::get_recognized_extensions(List<Strin
} }
Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_extracted_strings) { Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_extracted_strings) {
List<String> extensions; // Parse and match all GDScript function API that involves translation string.
get_recognized_extensions(&extensions); // E.g get_node("Label").text = "something", var test = tr("something"), "something" will be matched and collected.
bool extension_valid = false;
for (auto E = extensions.front(); E; E = E->next()) {
if (p_path.get_extension() == E->get()) {
extension_valid = true;
break;
}
}
if (!extension_valid) {
Vector<String> temp;
for (auto E = extensions.front(); E; E = E->next()) {
temp.push_back(E->get());
}
String valid_extensions = String(", ").join(temp);
ERR_PRINT("Argument p_path \"" + p_path + "\" has wrong extension. List of valid extensions: " + valid_extensions);
return ERR_INVALID_PARAMETER;
}
Error err; Error err;
RES loaded_res = ResourceLoader::load(p_path, "", false, &err); RES loaded_res = ResourceLoader::load(p_path, "", false, &err);
@ -66,26 +49,18 @@ Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Ve
} }
Ref<GDScript> gdscript = loaded_res; Ref<GDScript> gdscript = loaded_res;
parse_text(gdscript->get_source_code(), r_extracted_strings); String source_code = gdscript->get_source_code();
return OK;
}
void GDScriptEditorTranslationParserPlugin::parse_text(const String &p_text, Vector<String> *r_extracted_strings) {
// Parse and match all GDScript function API that involves translation string.
// E.g get_node("Label").text = "something", var test = tr("something"), "something" will be matched and collected.
Vector<String> parsed_strings; Vector<String> parsed_strings;
// Search translation strings with RegEx. // Search translation strings with RegEx.
regex.clear(); regex.clear();
regex.compile(String("|").join(patterns)); regex.compile(String("|").join(patterns));
Array results = regex.search_all(p_text); Array results = regex.search_all(source_code);
_get_captured_strings(results, &parsed_strings); _get_captured_strings(results, &parsed_strings);
// Special handling for FileDialog. // Special handling for FileDialog.
Vector<String> temp; Vector<String> temp;
_parse_file_dialog(p_text, &temp); _parse_file_dialog(source_code, &temp);
parsed_strings.append_array(temp); parsed_strings.append_array(temp);
// Filter out / and + // Filter out / and +
@ -97,6 +72,8 @@ void GDScriptEditorTranslationParserPlugin::parse_text(const String &p_text, Vec
} }
r_extracted_strings->append_array(parsed_strings); r_extracted_strings->append_array(parsed_strings);
return OK;
} }
void GDScriptEditorTranslationParserPlugin::_parse_file_dialog(const String &p_source_code, Vector<String> *r_output) { void GDScriptEditorTranslationParserPlugin::_parse_file_dialog(const String &p_source_code, Vector<String> *r_output) {

View File

@ -48,7 +48,6 @@ class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlug
public: public:
virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings); virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings);
virtual void parse_text(const String &p_text, Vector<String> *r_extracted_strings);
virtual void get_recognized_extensions(List<String> *r_extensions) const; virtual void get_recognized_extensions(List<String> *r_extensions) const;
GDScriptEditorTranslationParserPlugin(); GDScriptEditorTranslationParserPlugin();