diff --git a/src/ytdl_sub/script/functions/array_functions.py b/src/ytdl_sub/script/functions/array_functions.py index ffff0da7..db991835 100644 --- a/src/ytdl_sub/script/functions/array_functions.py +++ b/src/ytdl_sub/script/functions/array_functions.py @@ -20,11 +20,6 @@ class ArrayFunctions: def array(maybe_array: AnyArgument) -> Array: """ Tries to cast an unknown variable type to an Array. - - Raises - ------ - FunctionRuntimeException - If the input type is not actually an Array. """ if not isinstance(maybe_array, Array): raise FunctionRuntimeException( diff --git a/src/ytdl_sub/script/functions/map_functions.py b/src/ytdl_sub/script/functions/map_functions.py index 45ca13f1..ab81b575 100644 --- a/src/ytdl_sub/script/functions/map_functions.py +++ b/src/ytdl_sub/script/functions/map_functions.py @@ -19,11 +19,6 @@ class MapFunctions: def map(maybe_mapping: AnyArgument) -> Map: """ Tries to cast an unknown variable type to a Map. - - Raises - ------ - FunctionRuntimeException - If the input type is not actually a Map. """ if not isinstance(maybe_mapping, Map): raise FunctionRuntimeException( diff --git a/tools/docgen/entry_variables.py b/tools/docgen/entry_variables.py index fd6c84ac..8b8012cf 100644 --- a/tools/docgen/entry_variables.py +++ b/tools/docgen/entry_variables.py @@ -1,4 +1,4 @@ -from tools.docgen.utils import get_property_docs +from tools.docgen.utils import get_function_docs from tools.docgen.utils import properties from tools.docgen.utils import section from ytdl_sub.entries.script.variable_definitions import VariableDefinitions @@ -8,7 +8,7 @@ def generate_variable_docs() -> str: docs = section("Entry Variables", level=0) for variable_name in properties(VariableDefinitions): - docs += get_property_docs(property_name=variable_name, obj=VariableDefinitions, level=1) + docs += get_function_docs(function_name=variable_name, obj=VariableDefinitions, level=1) return docs diff --git a/tools/docgen/functions.py b/tools/docgen/functions.py new file mode 100644 index 00000000..8e5828c2 --- /dev/null +++ b/tools/docgen/functions.py @@ -0,0 +1,50 @@ +from typing import Any +from typing import Dict +from typing import Optional +from typing import Type + +from tools.docgen.utils import get_function_docs +from tools.docgen.utils import section +from tools.docgen.utils import static_methods +from ytdl_sub.entries.script.custom_functions import CustomFunctions +from ytdl_sub.script.functions import Functions + + +def maybe_get_function_name(function_name: str) -> Optional[str]: + if function_name in ["register"]: + return None + + if function_name.endswith("_"): + return function_name[:-1] + return function_name + + +def function_class_to_name(obj: Type[Any]) -> str: + assert "Functions" in obj.__name__ + return obj.__name__.replace("Functions", " Functions") + + +def generate_function_docs() -> str: + docs = section("Scripting Functions", level=0) + + parent_objs: Dict[str, Type[Any]] = { + function_class_to_name(obj): obj for obj in Functions.__bases__ + } + parent_objs["Ytdl-Sub Functions"] = CustomFunctions + + for name in sorted(parent_objs.keys()): + docs += section(name, level=1) + + for function_name in static_methods(parent_objs[name]): + if display_function_name := maybe_get_function_name(function_name): + docs += get_function_docs( + function_name=function_name, + display_function_name=display_function_name, + obj=parent_objs[name], + level=2, + ) + + return docs + + +print(generate_function_docs()) diff --git a/tools/docgen/plugins.py b/tools/docgen/plugins.py index 843584d6..514b2a6b 100644 --- a/tools/docgen/plugins.py +++ b/tools/docgen/plugins.py @@ -2,7 +2,7 @@ import inspect from typing import Dict from typing import Type -from tools.docgen.utils import get_property_docs +from tools.docgen.utils import get_function_docs from tools.docgen.utils import properties from tools.docgen.utils import section from ytdl_sub.config.overrides import Overrides @@ -32,7 +32,7 @@ def generate_plugin_docs(name: str, options: Type[OptionsValidator], offset: int property_names = [prop for prop in properties(options) if not should_filter_property(prop)] for property_name in sorted(property_names): - docs += get_property_docs(property_name=property_name, obj=options, level=offset + 1) + docs += get_function_docs(function_name=property_name, obj=options, level=offset + 1) return docs diff --git a/tools/docgen/utils.py b/tools/docgen/utils.py index 95c50a42..24e6e06f 100644 --- a/tools/docgen/utils.py +++ b/tools/docgen/utils.py @@ -2,6 +2,7 @@ import inspect from typing import Any from typing import Dict from typing import List +from typing import Optional from typing import Type LEVEL_CHARS: Dict[int, str] = {0: "=", 1: "-", 2: "~", 3: "^"} @@ -15,8 +16,18 @@ def properties(obj: Type[Any]) -> List[str]: return [prop for prop in dir(obj) if isinstance(getattr(obj, prop), property)] -def get_property_docs(property_name: str, obj: Any, level: int) -> str: - docs = section(property_name, level=level) - docs += inspect.cleandoc(getattr(obj, property_name).__doc__) +def static_methods(obj: Type[Any]) -> List[str]: + return sorted( + name for name in dir(obj) if isinstance(inspect.getattr_static(obj, name), staticmethod) + ) + + +def get_function_docs( + function_name: str, obj: Any, level: int, display_function_name: Optional[str] = None +) -> str: + display_function_name = display_function_name if display_function_name else function_name + + docs = section(display_function_name, level=level) + docs += inspect.cleandoc(getattr(obj, function_name).__doc__) docs += "\n" return docs