From 5f1416aa36f85e3c89072afe5c808d633e32e6fa Mon Sep 17 00:00:00 2001 From: Manuel YGUEL Date: Mon, 17 Mar 2025 14:40:16 +0100 Subject: [PATCH 1/3] Add ability to change exercise-title and solution-title from conf.py and open i18n for those titles. --- sphinx_exercise/__init__.py | 6 +++++- sphinx_exercise/directive.py | 6 ++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sphinx_exercise/__init__.py b/sphinx_exercise/__init__.py index 2d70cd4..b485dcf 100644 --- a/sphinx_exercise/__init__.py +++ b/sphinx_exercise/__init__.py @@ -106,7 +106,7 @@ def init_numfig(app: Sphinx, config: Config) -> None: """Initialize numfig""" config["numfig"] = True - numfig_format = {"exercise": "Exercise %s"} + numfig_format = {"exercise": config.exercise_title + " %s"} # Merge with current sphinx settings numfig_format.update(config.numfig_format) config.numfig_format = numfig_format @@ -210,6 +210,10 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(ResolveLinkTextToSolutions) app.add_css_file("exercise.css") + + #Define the extension configuration variables + app.add_config_value("exercise_title", "Exercise", "env") # The title of the exercise + app.add_config_value("solution_title", "Solution to", "env") # The title of the solution return { "version": "builtin", diff --git a/sphinx_exercise/directive.py b/sphinx_exercise/directive.py index 1a1f21d..7de68a3 100644 --- a/sphinx_exercise/directive.py +++ b/sphinx_exercise/directive.py @@ -88,7 +88,7 @@ class : str, } def run(self) -> List[Node]: - self.defaults = {"title_text": "Exercise"} + self.defaults = {"title_text": self.env.config.exercise_title} self.serial_number = self.env.new_serialno() # Initialise Registry (if needed) @@ -153,6 +153,7 @@ def run(self) -> List[Node]: node["type"] = self.name node["hidden"] = True if "hidden" in self.options else False node["serial_number"] = self.serial_number + node["node_type"] = "exercise" node.document = self.state.document self.add_name(node) @@ -216,7 +217,7 @@ class : str, solution_node = solution_node def run(self) -> List[Node]: - self.defaults = {"title_text": "Solution to"} + self.defaults = {"title_text": self.env.config.solution_title} target_label = self.arguments[0] self.serial_number = self.env.new_serialno() @@ -270,6 +271,7 @@ def run(self) -> List[Node]: node["type"] = self.name node["hidden"] = True if "hidden" in self.options else False node["serial_number"] = self.serial_number + node["node_type"] = "solution" node.document = self.state.document self.add_name(node) From d2f949d9ee8ca645387536fd044df93dcf933143 Mon Sep 17 00:00:00 2001 From: Manuel YGUEL Date: Tue, 18 Mar 2025 10:09:26 +0100 Subject: [PATCH 2/3] Allows to have multiple language definitions through conf.py using a language_map dictionary of the type: language_map = { 'en' : { 'exercise_title_text' : 'Exercise', 'solution_title_text' : 'Solution to' }, 'fr' : { 'exercise_title_text' : 'Exercice', 'solution_title_text' : 'Solution de' } } --- sphinx_exercise/__init__.py | 23 ++++++++++++++++------- sphinx_exercise/directive.py | 8 ++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/sphinx_exercise/__init__.py b/sphinx_exercise/__init__.py index b485dcf..d216f22 100644 --- a/sphinx_exercise/__init__.py +++ b/sphinx_exercise/__init__.py @@ -100,13 +100,23 @@ def merge_exercises( **env.sphinx_exercise_registry, **other.sphinx_exercise_registry, } + +def define_texts(app: Sphinx, config: Config) -> None: + if config.language is not None and config.language_map is not None: + lg = config.language_map[config.language] + if "exercise_title_text" in lg: + config.exercise_title_text = lg["exercise_title_text"] + if "solution_title_text" in lg: + config.solution_title_text = lg["solution_title_text"] def init_numfig(app: Sphinx, config: Config) -> None: """Initialize numfig""" + + define_texts(app, config) config["numfig"] = True - numfig_format = {"exercise": config.exercise_title + " %s"} + numfig_format = {"exercise": config.exercise_title_text + " %s"} # Merge with current sphinx settings numfig_format.update(config.numfig_format) config.numfig_format = numfig_format @@ -141,9 +151,12 @@ def doctree_read(app: Sphinx, document: Node) -> None: section_name = node.attributes.get("title") domain.anonlabels[name] = docname, label domain.labels[name] = docname, label, section_name - - + def setup(app: Sphinx) -> Dict[str, Any]: + #Define the extension configuration variables + app.add_config_value("exercise_title_text", "Exercise", "env") # The title of the exercise + app.add_config_value("solution_title_text", "Solution to", "env") # The title of the solution + app.add_config_value("language_map", None, "env") # A map of translated strings app.add_config_value("hide_solutions", False, "env") app.connect("config-inited", init_numfig) # event order - 1 @@ -210,10 +223,6 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(ResolveLinkTextToSolutions) app.add_css_file("exercise.css") - - #Define the extension configuration variables - app.add_config_value("exercise_title", "Exercise", "env") # The title of the exercise - app.add_config_value("solution_title", "Solution to", "env") # The title of the solution return { "version": "builtin", diff --git a/sphinx_exercise/directive.py b/sphinx_exercise/directive.py index 7de68a3..7fd9edb 100644 --- a/sphinx_exercise/directive.py +++ b/sphinx_exercise/directive.py @@ -88,7 +88,8 @@ class : str, } def run(self) -> List[Node]: - self.defaults = {"title_text": self.env.config.exercise_title} + logger.debug("Running ExerciseDirective: exercise_title_text: " + self.env.config.exercise_title_text) + self.defaults = {"title_text": self.env.config.exercise_title_text} self.serial_number = self.env.new_serialno() # Initialise Registry (if needed) @@ -153,7 +154,6 @@ def run(self) -> List[Node]: node["type"] = self.name node["hidden"] = True if "hidden" in self.options else False node["serial_number"] = self.serial_number - node["node_type"] = "exercise" node.document = self.state.document self.add_name(node) @@ -217,7 +217,8 @@ class : str, solution_node = solution_node def run(self) -> List[Node]: - self.defaults = {"title_text": self.env.config.solution_title} + logger.debug("Running SolutionDirective: solution_title_text: " + self.env.config.solution_title_text) + self.defaults = {"title_text": self.env.config.solution_title_text} target_label = self.arguments[0] self.serial_number = self.env.new_serialno() @@ -271,7 +272,6 @@ def run(self) -> List[Node]: node["type"] = self.name node["hidden"] = True if "hidden" in self.options else False node["serial_number"] = self.serial_number - node["node_type"] = "solution" node.document = self.state.document self.add_name(node) From 52067b3b1d04dc07adb7d6e9358de20956f06210 Mon Sep 17 00:00:00 2001 From: Manuel YGUEL Date: Tue, 18 Mar 2025 10:26:31 +0100 Subject: [PATCH 3/3] Make it possible to define language_map in several extensions. --- sphinx_exercise/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sphinx_exercise/__init__.py b/sphinx_exercise/__init__.py index d216f22..4fc655a 100644 --- a/sphinx_exercise/__init__.py +++ b/sphinx_exercise/__init__.py @@ -156,7 +156,8 @@ def setup(app: Sphinx) -> Dict[str, Any]: #Define the extension configuration variables app.add_config_value("exercise_title_text", "Exercise", "env") # The title of the exercise app.add_config_value("solution_title_text", "Solution to", "env") # The title of the solution - app.add_config_value("language_map", None, "env") # A map of translated strings + if not hasattr(app.config, "language_map"): + app.add_config_value("language_map", None, "env") # A map of translated strings app.add_config_value("hide_solutions", False, "env") app.connect("config-inited", init_numfig) # event order - 1