From 98a4b522552fce440904a4984b9cdf3a22e74b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fred=20Lef=C3=A9v=C3=A8re-Laoide?= <90181748+FredLL-Avaiga@users.noreply.github.com> Date: Thu, 27 Jun 2024 19:00:39 +0200 Subject: [PATCH] python doc html to markdown (#1458) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * python doc html to markdown resolves #1299 * handle local doc ref * read version * release doc * make ruff happy * make ruff happy --------- Co-authored-by: Fred Lefévère-Laoide --- Pipfile | 1 + taipy/config/common/_template_handler.py | 10 +++---- taipy/gui/data/array_dict_data_accessor.py | 8 ++--- tests/core/config/test_file_config.py | 18 +++++------ tools/gui/builder/block.txt | 5 ++-- tools/gui/builder/control.txt | 5 ++-- tools/gui/generate_pyi.py | 35 +++++++++++++++++++--- 7 files changed, 54 insertions(+), 28 deletions(-) diff --git a/Pipfile b/Pipfile index 4e6bf18524..fff817d26b 100644 --- a/Pipfile +++ b/Pipfile @@ -42,6 +42,7 @@ numpy = "<2.0.0" freezegun = "*" ipython = "*" ipykernel = "*" +markdownify = "*" mkdocs = "*" mkdocs-autorefs = "*" mkdocs-include-markdown-plugin = "*" diff --git a/taipy/config/common/_template_handler.py b/taipy/config/common/_template_handler.py index 2902d08251..1d913ad312 100644 --- a/taipy/config/common/_template_handler.py +++ b/taipy/config/common/_template_handler.py @@ -51,15 +51,15 @@ def _replace_template(cls, template, type, required, default): if required: raise MissingEnvVariableError(f"Environment variable {var} is not set.") return default - if type == bool: + if type is bool: return cls._to_bool(val) - elif type == int: + elif type is int: return cls._to_int(val) - elif type == float: + elif type is float: return cls._to_float(val) - elif type == Scope: + elif type is Scope: return cls._to_scope(val) - elif type == Frequency: + elif type is Frequency: return cls._to_frequency(val) else: if dynamic_type == "bool": diff --git a/taipy/gui/data/array_dict_data_accessor.py b/taipy/gui/data/array_dict_data_accessor.py index c3bba10877..c901021ed8 100644 --- a/taipy/gui/data/array_dict_data_accessor.py +++ b/taipy/gui/data/array_dict_data_accessor.py @@ -33,18 +33,18 @@ def _get_dataframe(self, value: t.Any) -> t.Union[t.List[pd.DataFrame], pd.DataF types = {type(x) for x in value} if len(types) == 1: type_elt = next(iter(types), None) - if type_elt == list: + if type_elt is list: lengths = {len(x) for x in value} return ( pd.DataFrame(value) if len(lengths) == 1 else [pd.DataFrame({f"{i}/0": v}) for i, v in enumerate(value)] ) - elif type_elt == dict: + elif type_elt is dict: return [pd.DataFrame(v) for v in value] - elif type_elt == _MapDict: + elif type_elt is _MapDict: return [pd.DataFrame(v._dict) for v in value] - elif type_elt == pd.DataFrame: + elif type_elt is pd.DataFrame: return value elif len(types) == 2 and list in types and pd.DataFrame in types: diff --git a/tests/core/config/test_file_config.py b/tests/core/config/test_file_config.py index ce1c1503a8..397e80f1d7 100644 --- a/tests/core/config/test_file_config.py +++ b/tests/core/config/test_file_config.py @@ -193,9 +193,9 @@ def test_read_configuration_file(): Config.override(file_config.filename) assert len(Config.data_nodes) == 4 - assert type(Config.data_nodes["my_datanode"]) == DataNodeConfig - assert type(Config.data_nodes["my_datanode2"]) == DataNodeConfig - assert type(Config.data_nodes["my_datanode3"]) == DataNodeConfig + assert type(Config.data_nodes["my_datanode"]) is DataNodeConfig + assert type(Config.data_nodes["my_datanode2"]) is DataNodeConfig + assert type(Config.data_nodes["my_datanode3"]) is DataNodeConfig assert Config.data_nodes["my_datanode"].path == "/data/csv" assert Config.data_nodes["my_datanode2"].path == "/data2/csv" assert Config.data_nodes["my_datanode3"].path == "/data3/csv" @@ -206,27 +206,27 @@ def test_read_configuration_file(): assert Config.data_nodes["my_datanode3"].source == "local" assert len(Config.tasks) == 2 - assert type(Config.tasks["my_task"]) == TaskConfig + assert type(Config.tasks["my_task"]) is TaskConfig assert Config.tasks["my_task"].id == "my_task" assert Config.tasks["my_task"].description == "task description" assert Config.tasks["my_task"].function == print assert len(Config.tasks["my_task"].inputs) == 1 - assert type(Config.tasks["my_task"].inputs[0]) == DataNodeConfig + assert type(Config.tasks["my_task"].inputs[0]) is DataNodeConfig assert Config.tasks["my_task"].inputs[0].path == "/data/csv" assert Config.tasks["my_task"].inputs[0].id == "my_datanode" assert len(Config.tasks["my_task"].outputs) == 1 - assert type(Config.tasks["my_task"].outputs[0]) == DataNodeConfig + assert type(Config.tasks["my_task"].outputs[0]) is DataNodeConfig assert Config.tasks["my_task"].outputs[0].path == "/data2/csv" assert Config.tasks["my_task"].outputs[0].id == "my_datanode2" assert len(Config.scenarios) == 2 - assert type(Config.scenarios["my_scenario"]) == ScenarioConfig + assert type(Config.scenarios["my_scenario"]) is ScenarioConfig assert Config.scenarios["my_scenario"].id == "my_scenario" assert Config.scenarios["my_scenario"].owner == "John Doe" assert len(Config.scenarios["my_scenario"].tasks) == 1 - assert type(Config.scenarios["my_scenario"].tasks[0]) == TaskConfig + assert type(Config.scenarios["my_scenario"].tasks[0]) is TaskConfig assert len(Config.scenarios["my_scenario"].additional_data_nodes) == 1 - assert type(Config.scenarios["my_scenario"].additional_data_nodes[0]) == DataNodeConfig + assert type(Config.scenarios["my_scenario"].additional_data_nodes[0]) is DataNodeConfig assert Config.scenarios["my_scenario"].tasks[0].id == "my_task" assert Config.scenarios["my_scenario"].tasks[0].description == "task description" assert Config.scenarios["my_scenario"].additional_data_nodes[0].id == "my_datanode3" diff --git a/tools/gui/builder/block.txt b/tools/gui/builder/block.txt index 7f09364792..e37bde2246 100644 --- a/tools/gui/builder/block.txt +++ b/tools/gui/builder/block.txt @@ -2,8 +2,7 @@ class {{name}}(_Block): _ELEMENT_NAME: str def __init__(self, {{properties}}) -> None: - """ - Arguments: - {{doc_arguments}} + """### Arguments: +{{doc_arguments}} """ ... diff --git a/tools/gui/builder/control.txt b/tools/gui/builder/control.txt index d04eefc554..7d0a2ce5e8 100644 --- a/tools/gui/builder/control.txt +++ b/tools/gui/builder/control.txt @@ -2,8 +2,7 @@ class {{name}}(_Control): _ELEMENT_NAME: str def __init__(self, {{properties}}) -> None: - """ - Arguments: - {{doc_arguments}} + """### Arguments: +{{doc_arguments}} """ ... diff --git a/tools/gui/generate_pyi.py b/tools/gui/generate_pyi.py index 2fc1314cfb..c4eba01e71 100644 --- a/tools/gui/generate_pyi.py +++ b/tools/gui/generate_pyi.py @@ -11,8 +11,11 @@ import json import os +import re import typing as t +from markdownify import markdownify + # ############################################################ # Generate Python interface definition files # ############################################################ @@ -46,6 +49,19 @@ with open(gui_pyi_file, "w") as write_file: write_file.write(replaced_content) +# ################ +# Read the version +# ################ +current_version = "latest" +with open("./taipy/gui/version.json", "r") as vfile: + version = json.load(vfile) + if "dev" in version.get("ext", ""): + current_version = "develop" + else: + current_version = f'release-{version.get("major", 0)}.{version.get("minor", 0)}' +taipy_doc_url = f"https://docs.taipy.io/en/{current_version}/manuals/gui/viselements/" + + # ############################################################ # Generate Page Builder pyi file (gui/builder/__init__.pyi) # ############################################################ @@ -80,11 +96,22 @@ def get_properties(element, viselements) -> t.List[t.Dict[str, t.Any]]: return properties -def build_doc(element: t.Dict[str, t.Any]): +def build_doc(name: str, element: t.Dict[str, t.Any]): if "doc" not in element: return "" doc = str(element["doc"]).replace("\n", f'\n{16*" "}') - return f"{element['name']} ({element['type']}): {doc} {'(default: '+element['default_value'] + ')' if 'default_value' in element else ''}" # noqa: E501 + doc = re.sub( + r"^(.*\..*\shref=\")([^h].*)(\".*\..*)$", + r"\1" + taipy_doc_url + name + r"/\2\3", + doc, + ) + doc = re.sub( + r"^(.*\.)(
|\s)(See below((?!href=).)*\.)(.*)$", + r"\1\3", + doc, + ) + doc = markdownify(doc, strip=['br']) + return f"{element['name']} ({element['type']}): {doc} {'(default: '+markdownify(element['default_value']) + ')' if 'default_value' in element else ''}" # noqa: E501 for control_element in viselements["controls"]: @@ -100,7 +127,7 @@ def build_doc(element: t.Dict[str, t.Any]): property_list.append(property) property_names.append(property["name"]) properties = ", ".join([f"{p} = ..." for p in property_names]) - doc_arguments = f"\n{12*' '}".join([build_doc(p) for p in property_list]) + doc_arguments = "\n".join([build_doc(name, p) for p in property_list]) # append properties to __init__.pyi with open(builder_pyi_file, "a") as file: file.write( @@ -118,7 +145,7 @@ def build_doc(element: t.Dict[str, t.Any]): property_list.append(property) property_names.append(property["name"]) properties = ", ".join([f"{p} = ..." for p in property_names]) - doc_arguments = f"{8*' '}".join([build_doc(p) for p in property_list]) + doc_arguments = "\n".join([build_doc(name, p) for p in property_list]) # append properties to __init__.pyi with open(builder_pyi_file, "a") as file: file.write(