diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 4798cab6418..70236231a25 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -38,6 +38,7 @@ #include "core/string/translation.h" #include "core/string/ucaps.h" #include "core/variant/variant.h" +#include "core/version_generated.gen.h" #include #include @@ -4868,15 +4869,20 @@ String TTRN(const String &p_text, const String &p_text_plural, int p_n, const St return p_text_plural; } +/* DTR and DTRN are used for the documentation, handling descriptions extracted + * from the XML. + * They also replace `$DOCS_URL` with the actual URL to the documentation's branch, + * to allow dehardcoding it in the XML and doing proper substitutions everywhere. + */ String DTR(const String &p_text, const String &p_context) { // Comes straight from the XML, so remove indentation and any trailing whitespace. const String text = p_text.dedent().strip_edges(); if (TranslationServer::get_singleton()) { - return TranslationServer::get_singleton()->doc_translate(text, p_context); + return String(TranslationServer::get_singleton()->doc_translate(text, p_context)).replace("$DOCS_URL", VERSION_DOCS_URL); } - return text; + return text.replace("$DOCS_URL", VERSION_DOCS_URL); } String DTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context) { @@ -4884,14 +4890,14 @@ String DTRN(const String &p_text, const String &p_text_plural, int p_n, const St const String text_plural = p_text_plural.dedent().strip_edges(); if (TranslationServer::get_singleton()) { - return TranslationServer::get_singleton()->doc_translate_plural(text, text_plural, p_n, p_context); + return String(TranslationServer::get_singleton()->doc_translate_plural(text, text_plural, p_n, p_context)).replace("$DOCS_URL", VERSION_DOCS_URL); } // Return message based on English plural rule if translation is not possible. if (p_n == 1) { - return text; + return text.replace("$DOCS_URL", VERSION_DOCS_URL); } - return text_plural; + return text_plural.replace("$DOCS_URL", VERSION_DOCS_URL); } #endif diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index fe8083f2189..5d3167a773c 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -11,10 +11,8 @@ from collections import OrderedDict # Uncomment to do type checks. I have it commented out so it works below Python 3.5 # from typing import List, Dict, TextIO, Tuple, Iterable, Optional, DefaultDict, Any, Union -# http(s)://docs.godotengine.org///path/to/page.html(#fragment-tag) -GODOT_DOCS_PATTERN = re.compile( - r"^http(?:s)?://docs\.godotengine\.org/(?:[a-zA-Z0-9.\-_]*)/(?:[a-zA-Z0-9.\-_]*)/(.*)\.html(#.*)?$" -) +# $DOCS_URL/path/to/page.html(#fragment-tag) +GODOT_DOCS_PATTERN = re.compile(r"^\$DOCS_URL/(.*)\.html(#.*)?$") def print_error(error, state): # type: (str, State) -> None @@ -857,16 +855,11 @@ def rstize_text(text, state): # type: (str, State) -> str # Handle [tags] inside_code = False - inside_url = False - url_has_name = False - url_link = "" pos = 0 tag_depth = 0 previous_pos = 0 while True: pos = text.find("[", pos) - if inside_url and (pos > previous_pos): - url_has_name = True if pos == -1: break @@ -995,17 +988,23 @@ def rstize_text(text, state): # type: (str, State) -> str elif cmd.find("image=") == 0: tag_text = "" # '![](' + cmd[6:] + ')' elif cmd.find("url=") == 0: - url_link = cmd[4:] - tag_text = "`" - tag_depth += 1 - inside_url = True - url_has_name = False - elif cmd == "/url": - tag_text = ("" if url_has_name else url_link) + " <" + url_link + ">`__" - tag_depth -= 1 - escape_post = True - inside_url = False - url_has_name = False + # URLs are handled in full here as we need to extract the optional link + # title to use `make_link`. + link_url = cmd[4:] + endurl_pos = text.find("[/url]", endq_pos + 1) + if endurl_pos == -1: + print_error( + "Tag depth mismatch for [url]: no closing [/url], file: {}".format(state.current_class), state + ) + break + link_title = text[endq_pos + 1 : endurl_pos] + tag_text = make_link(link_url, link_title) + + pre_text = text[:pos] + text = pre_text + tag_text + text[endurl_pos + 6 :] + pos = len(pre_text) + len(tag_text) + previous_pos = pos + continue elif cmd == "center": tag_depth += 1 tag_text = "" @@ -1252,21 +1251,22 @@ def make_link(url, title): # type: (str, str) -> str if match.lastindex == 2: # Doc reference with fragment identifier: emit direct link to section with reference to page, for example: # `#calling-javascript-from-script in Exporting For Web` - return "`" + groups[1] + " <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`" - # Commented out alternative: Instead just emit: - # `Subsection in Exporting For Web` - # return "`Subsection <../" + groups[0] + ".html" + groups[1] + ">`__ in :doc:`../" + groups[0] + "`" + # Or use the title if provided. + if title != "": + return "`" + title + " <../" + groups[0] + ".html" + groups[1] + ">`__" + return "`" + groups[1] + " <../" + groups[0] + ".html" + groups[1] + ">`__ in :doc:`../" + groups[0] + "`" elif match.lastindex == 1: # Doc reference, for example: # `Math` + if title != "": + return ":doc:`" + title + " <../" + groups[0] + ">`" return ":doc:`../" + groups[0] + "`" else: # External link, for example: # `http://enet.bespin.org/usergroup0.html` if title != "": return "`" + title + " <" + url + ">`__" - else: - return "`" + url + " <" + url + ">`__" + return "`" + url + " <" + url + ">`__" def sanitize_operator_name(dirty_name, state): # type: (str, State) -> str diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 192f7fc5981..05f4e385c63 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -33,13 +33,14 @@ #include "core/core_constants.h" #include "core/input/input.h" #include "core/os/keyboard.h" +#include "core/version_generated.gen.h" #include "doc_data_compressed.gen.h" #include "editor/plugins/script_editor_plugin.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" -#define CONTRIBUTE_URL "https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html" +#define CONTRIBUTE_URL vformat("%s/community/contributing/updating_the_class_reference.html", VERSION_DOCS_URL) DocTools *EditorHelp::doc = nullptr; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 984dc0a1c97..3ab0d60336f 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -34,6 +34,7 @@ #include "core/io/resource_saver.h" #include "core/os/keyboard.h" #include "core/os/os.h" +#include "core/version_generated.gen.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -384,7 +385,7 @@ void ShaderEditor::_menu_option(int p_option) { shader_editor->remove_all_bookmarks(); } break; case HELP_DOCS: { - OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/index.html"); + OS::get_singleton()->shell_open(vformat("%s/tutorials/shaders/shader_reference/index.html", VERSION_DOCS_URL)); } break; } if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) { diff --git a/editor/project_export.cpp b/editor/project_export.cpp index ad9c81458f8..d48d45d848f 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -38,6 +38,7 @@ #include "core/io/resource_saver.h" #include "core/os/os.h" #include "core/string/optimized_translation.h" +#include "core/version_generated.gen.h" #include "editor_data.h" #include "editor_node.h" #include "editor_scale.h" @@ -456,7 +457,7 @@ void ProjectExportDialog::_enc_filters_changed(const String &p_filters) { } void ProjectExportDialog::_open_key_help_link() { - OS::get_singleton()->shell_open("https://docs.godotengine.org/en/latest/development/compiling/compiling_with_script_encryption_key.html"); + OS::get_singleton()->shell_open(vformat("%s/development/compiling/compiling_with_script_encryption_key.html", VERSION_DOCS_URL)); } void ProjectExportDialog::_enc_pck_changed(bool p_pressed) { diff --git a/methods.py b/methods.py index b2eb7b7c77b..3331e159c7c 100644 --- a/methods.py +++ b/methods.py @@ -105,6 +105,8 @@ def update_version(module_version_string=""): f.write('#define VERSION_MODULE_CONFIG "' + str(version.module_config) + module_version_string + '"\n') f.write("#define VERSION_YEAR " + str(version.year) + "\n") f.write('#define VERSION_WEBSITE "' + str(version.website) + '"\n') + f.write('#define VERSION_DOCS_BRANCH "' + str(version.docs) + '"\n') + f.write('#define VERSION_DOCS_URL "https://docs.godotengine.org/en/" VERSION_DOCS_BRANCH\n') f.write("#endif // VERSION_GENERATED_GEN_H\n") f.close() diff --git a/version.py b/version.py index 517a47f568e..663f90b942b 100644 --- a/version.py +++ b/version.py @@ -7,3 +7,4 @@ status = "dev" module_config = "" year = 2021 website = "https://godotengine.org" +docs = "latest"