griffe2md 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. griffe2md-1.0.0/LICENSE +15 -0
  2. griffe2md-1.0.0/PKG-INFO +73 -0
  3. griffe2md-1.0.0/README.md +39 -0
  4. griffe2md-1.0.0/pyproject.toml +113 -0
  5. griffe2md-1.0.0/src/griffe2md/__init__.py +8 -0
  6. griffe2md-1.0.0/src/griffe2md/cli.py +61 -0
  7. griffe2md-1.0.0/src/griffe2md/debug.py +106 -0
  8. griffe2md-1.0.0/src/griffe2md/main.py +159 -0
  9. griffe2md-1.0.0/src/griffe2md/rendering.py +603 -0
  10. griffe2md-1.0.0/src/griffe2md/templates/attribute.md.jinja +47 -0
  11. griffe2md-1.0.0/src/griffe2md/templates/children.md.jinja +154 -0
  12. griffe2md-1.0.0/src/griffe2md/templates/class.md.jinja +68 -0
  13. griffe2md-1.0.0/src/griffe2md/templates/docstring/admonition.md.jinja +4 -0
  14. griffe2md-1.0.0/src/griffe2md/templates/docstring/attributes.md.jinja +17 -0
  15. griffe2md-1.0.0/src/griffe2md/templates/docstring/classes.md.jinja +17 -0
  16. griffe2md-1.0.0/src/griffe2md/templates/docstring/examples.md.jinja +13 -0
  17. griffe2md-1.0.0/src/griffe2md/templates/docstring/functions.md.jinja +17 -0
  18. griffe2md-1.0.0/src/griffe2md/templates/docstring/modules.md.jinja +17 -0
  19. griffe2md-1.0.0/src/griffe2md/templates/docstring/other_parameters.md.jinja +17 -0
  20. griffe2md-1.0.0/src/griffe2md/templates/docstring/parameters.md.jinja +17 -0
  21. griffe2md-1.0.0/src/griffe2md/templates/docstring/raises.md.jinja +17 -0
  22. griffe2md-1.0.0/src/griffe2md/templates/docstring/receives.md.jinja +18 -0
  23. griffe2md-1.0.0/src/griffe2md/templates/docstring/returns.md.jinja +18 -0
  24. griffe2md-1.0.0/src/griffe2md/templates/docstring/warns.md.jinja +17 -0
  25. griffe2md-1.0.0/src/griffe2md/templates/docstring/yields.md.jinja +18 -0
  26. griffe2md-1.0.0/src/griffe2md/templates/docstring.md.jinja +27 -0
  27. griffe2md-1.0.0/src/griffe2md/templates/expression.md.jinja +53 -0
  28. griffe2md-1.0.0/src/griffe2md/templates/function.md.jinja +37 -0
  29. griffe2md-1.0.0/src/griffe2md/templates/module.md.jinja +35 -0
  30. griffe2md-1.0.0/src/griffe2md/templates/signature.md.jinja +65 -0
  31. griffe2md-1.0.0/src/griffe2md/templates/summary/attributes.md.jinja +12 -0
  32. griffe2md-1.0.0/src/griffe2md/templates/summary/classes.md.jinja +12 -0
  33. griffe2md-1.0.0/src/griffe2md/templates/summary/functions.md.jinja +12 -0
  34. griffe2md-1.0.0/src/griffe2md/templates/summary/modules.md.jinja +12 -0
  35. griffe2md-1.0.0/src/griffe2md/templates/summary.md.jinja +17 -0
  36. griffe2md-1.0.0/tests/__init__.py +7 -0
  37. griffe2md-1.0.0/tests/test_cli.py +57 -0
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2023, Timothée Mazzucotelli
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.1
2
+ Name: griffe2md
3
+ Version: 1.0.0
4
+ Summary: Output API docs to Markdown using Griffe.
5
+ Author-Email: Timothée Mazzucotelli <pawamoy@pm.me>
6
+ License: ISC
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Documentation
18
+ Classifier: Topic :: Software Development
19
+ Classifier: Topic :: Utilities
20
+ Classifier: Typing :: Typed
21
+ Project-URL: Homepage, https://mkdocstrings.github.io/griffe2md
22
+ Project-URL: Documentation, https://mkdocstrings.github.io/griffe2md
23
+ Project-URL: Changelog, https://mkdocstrings.github.io/griffe2md/changelog
24
+ Project-URL: Repository, https://github.com/mkdocstrings/griffe2md
25
+ Project-URL: Issues, https://github.com/mkdocstrings/griffe2md/issues
26
+ Project-URL: Discussions, https://github.com/mkdocstrings/griffe2md/discussions
27
+ Project-URL: Gitter, https://gitter.im/mkdocstrings/griffe2md
28
+ Project-URL: Funding, https://github.com/sponsors/pawamoy
29
+ Requires-Python: >=3.8
30
+ Requires-Dist: griffe>=0.36.0
31
+ Requires-Dist: jinja2>=3.1.2
32
+ Requires-Dist: mdformat>=0.7.16
33
+ Description-Content-Type: text/markdown
34
+
35
+ # griffe2md
36
+
37
+ [![ci](https://github.com/mkdocstrings/griffe2md/workflows/ci/badge.svg)](https://github.com/mkdocstrings/griffe2md/actions?query=workflow%3Aci)
38
+ [![documentation](https://img.shields.io/badge/docs-mkdocs%20material-blue.svg?style=flat)](https://mkdocstrings.github.io/griffe2md/)
39
+ [![pypi version](https://img.shields.io/pypi/v/griffe2md.svg)](https://pypi.org/project/griffe2md/)
40
+ [![gitpod](https://img.shields.io/badge/gitpod-workspace-blue.svg?style=flat)](https://gitpod.io/#https://github.com/mkdocstrings/griffe2md)
41
+ [![gitter](https://badges.gitter.im/join%20chat.svg)](https://app.gitter.im/#/room/#griffe2md:gitter.im)
42
+
43
+ Output API docs to Markdown using Griffe.
44
+
45
+ ## Installation
46
+
47
+ With `pip`:
48
+
49
+ ```bash
50
+ pip install griffe2md
51
+ ```
52
+
53
+ With [`pipx`](https://github.com/pipxproject/pipx):
54
+
55
+ ```bash
56
+ python3.8 -m pip install --user pipx
57
+ pipx install griffe2md
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ Simply call `griffe2md` with a package name, or the path to a package folder:
63
+
64
+ ```bash
65
+ griffe2md markdown
66
+ griffe2md path/to/my/src/package
67
+ ```
68
+
69
+ Use the `-o`, `--output` option to write to a file instead of standard output:
70
+
71
+ ```bash
72
+ griffe2md markdown -o markdown.md
73
+ ```
@@ -0,0 +1,39 @@
1
+ # griffe2md
2
+
3
+ [![ci](https://github.com/mkdocstrings/griffe2md/workflows/ci/badge.svg)](https://github.com/mkdocstrings/griffe2md/actions?query=workflow%3Aci)
4
+ [![documentation](https://img.shields.io/badge/docs-mkdocs%20material-blue.svg?style=flat)](https://mkdocstrings.github.io/griffe2md/)
5
+ [![pypi version](https://img.shields.io/pypi/v/griffe2md.svg)](https://pypi.org/project/griffe2md/)
6
+ [![gitpod](https://img.shields.io/badge/gitpod-workspace-blue.svg?style=flat)](https://gitpod.io/#https://github.com/mkdocstrings/griffe2md)
7
+ [![gitter](https://badges.gitter.im/join%20chat.svg)](https://app.gitter.im/#/room/#griffe2md:gitter.im)
8
+
9
+ Output API docs to Markdown using Griffe.
10
+
11
+ ## Installation
12
+
13
+ With `pip`:
14
+
15
+ ```bash
16
+ pip install griffe2md
17
+ ```
18
+
19
+ With [`pipx`](https://github.com/pipxproject/pipx):
20
+
21
+ ```bash
22
+ python3.8 -m pip install --user pipx
23
+ pipx install griffe2md
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ Simply call `griffe2md` with a package name, or the path to a package folder:
29
+
30
+ ```bash
31
+ griffe2md markdown
32
+ griffe2md path/to/my/src/package
33
+ ```
34
+
35
+ Use the `-o`, `--output` option to write to a file instead of standard output:
36
+
37
+ ```bash
38
+ griffe2md markdown -o markdown.md
39
+ ```
@@ -0,0 +1,113 @@
1
+ [build-system]
2
+ requires = [
3
+ "pdm-backend",
4
+ ]
5
+ build-backend = "pdm.backend"
6
+
7
+ [project]
8
+ name = "griffe2md"
9
+ description = "Output API docs to Markdown using Griffe."
10
+ authors = [
11
+ { name = "Timothée Mazzucotelli", email = "pawamoy@pm.me" },
12
+ ]
13
+ readme = "README.md"
14
+ requires-python = ">=3.8"
15
+ keywords = []
16
+ dynamic = []
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Intended Audience :: Developers",
20
+ "Programming Language :: Python",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Topic :: Documentation",
29
+ "Topic :: Software Development",
30
+ "Topic :: Utilities",
31
+ "Typing :: Typed",
32
+ ]
33
+ dependencies = [
34
+ "griffe>=0.36.0",
35
+ "jinja2>=3.1.2",
36
+ "mdformat>=0.7.16",
37
+ ]
38
+ version = "1.0.0"
39
+
40
+ [project.license]
41
+ text = "ISC"
42
+
43
+ [project.urls]
44
+ Homepage = "https://mkdocstrings.github.io/griffe2md"
45
+ Documentation = "https://mkdocstrings.github.io/griffe2md"
46
+ Changelog = "https://mkdocstrings.github.io/griffe2md/changelog"
47
+ Repository = "https://github.com/mkdocstrings/griffe2md"
48
+ Issues = "https://github.com/mkdocstrings/griffe2md/issues"
49
+ Discussions = "https://github.com/mkdocstrings/griffe2md/discussions"
50
+ Gitter = "https://gitter.im/mkdocstrings/griffe2md"
51
+ Funding = "https://github.com/sponsors/pawamoy"
52
+
53
+ [project.scripts]
54
+ griffe2md = "griffe2md.cli:main"
55
+
56
+ [tool.pdm]
57
+ plugins = [
58
+ "pdm-multirun",
59
+ ]
60
+
61
+ [tool.pdm.version]
62
+ source = "scm"
63
+
64
+ [tool.pdm.build]
65
+ package-dir = "src"
66
+ editable-backend = "editables"
67
+
68
+ [tool.pdm.dev-dependencies]
69
+ duty = [
70
+ "duty>=0.10",
71
+ ]
72
+ ci-quality = [
73
+ "griffe2md[duty,docs,quality,typing,security]",
74
+ ]
75
+ ci-tests = [
76
+ "griffe2md[duty,tests]",
77
+ ]
78
+ docs = [
79
+ "black>=23.9",
80
+ "markdown-callouts>=0.3",
81
+ "markdown-exec>=1.7",
82
+ "mkdocs>=1.5",
83
+ "mkdocs-coverage>=1.0",
84
+ "mkdocs-gen-files>=0.5",
85
+ "mkdocs-git-committers-plugin-2>=1.2",
86
+ "mkdocs-literate-nav>=0.6",
87
+ "mkdocs-material>=9.4",
88
+ "mkdocs-minify-plugin>=0.7",
89
+ "mkdocstrings[python]>=0.23",
90
+ "tomli>=2.0; python_version < '3.11'",
91
+ ]
92
+ maintain = [
93
+ "black>=23.9",
94
+ "blacken-docs>=1.16",
95
+ "git-changelog>=2.3",
96
+ ]
97
+ quality = [
98
+ "ruff>=0.0",
99
+ ]
100
+ tests = [
101
+ "pytest>=7.4",
102
+ "pytest-cov>=4.1",
103
+ "pytest-randomly>=3.15",
104
+ "pytest-xdist>=3.3",
105
+ ]
106
+ typing = [
107
+ "mypy>=1.5",
108
+ "types-markdown>=3.5",
109
+ "types-pyyaml>=6.0",
110
+ ]
111
+ security = [
112
+ "safety>=2.3",
113
+ ]
@@ -0,0 +1,8 @@
1
+ """griffe2md package.
2
+
3
+ Output API docs to Markdown using Griffe.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ __all__: list[str] = []
@@ -0,0 +1,61 @@
1
+ """Module that contains the command line application."""
2
+
3
+ # Why does this file exist, and why not put this in `__main__`?
4
+ #
5
+ # You might be tempted to import things from `__main__` later,
6
+ # but that will cause problems: the code will get executed twice:
7
+ #
8
+ # - When you run `python -m griffe2md` python will execute
9
+ # `__main__.py` as a script. That means there won't be any
10
+ # `griffe2md.__main__` in `sys.modules`.
11
+ # - When you import `__main__` it will get executed again (as a module) because
12
+ # there's no `griffe2md.__main__` in `sys.modules`.
13
+
14
+ from __future__ import annotations
15
+
16
+ import argparse
17
+ import sys
18
+ from typing import Any
19
+
20
+ from griffe2md import debug
21
+ from griffe2md.main import write_package_docs
22
+
23
+
24
+ class _DebugInfo(argparse.Action):
25
+ def __init__(self, nargs: int | str | None = 0, **kwargs: Any) -> None:
26
+ super().__init__(nargs=nargs, **kwargs)
27
+
28
+ def __call__(self, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
29
+ debug.print_debug_info()
30
+ sys.exit(0)
31
+
32
+
33
+ def get_parser() -> argparse.ArgumentParser:
34
+ """Return the CLI argument parser.
35
+
36
+ Returns:
37
+ An argparse parser.
38
+ """
39
+ parser = argparse.ArgumentParser(prog="griffe2md")
40
+ parser.add_argument("package", help="The package to output Markdown docs for.")
41
+ parser.add_argument("-o", "--output", default=None, help="File to write to. Default: stdout.")
42
+ parser.add_argument("-V", "--version", action="version", version=f"%(prog)s {debug.get_version()}")
43
+ parser.add_argument("--debug-info", action=_DebugInfo, help="Print debug information.")
44
+ return parser
45
+
46
+
47
+ def main(args: list[str] | None = None) -> int:
48
+ """Run the main program.
49
+
50
+ This function is executed when you type `griffe2md` or `python -m griffe2md`.
51
+
52
+ Parameters:
53
+ args: Arguments passed from the command line.
54
+
55
+ Returns:
56
+ An exit code.
57
+ """
58
+ parser = get_parser()
59
+ opts = parser.parse_args(args=args)
60
+ write_package_docs(opts.package, output=opts.output)
61
+ return 0
@@ -0,0 +1,106 @@
1
+ """Debugging utilities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import platform
7
+ import sys
8
+ from dataclasses import dataclass
9
+ from importlib import metadata
10
+
11
+
12
+ @dataclass
13
+ class Variable:
14
+ """Dataclass describing an environment variable."""
15
+
16
+ name: str
17
+ """Variable name."""
18
+ value: str
19
+ """Variable value."""
20
+
21
+
22
+ @dataclass
23
+ class Package:
24
+ """Dataclass describing a Python package."""
25
+
26
+ name: str
27
+ """Package name."""
28
+ version: str
29
+ """Package version."""
30
+
31
+
32
+ @dataclass
33
+ class Environment:
34
+ """Dataclass to store environment information."""
35
+
36
+ interpreter_name: str
37
+ """Python interpreter name."""
38
+ interpreter_version: str
39
+ """Python interpreter version."""
40
+ platform: str
41
+ """Operating System."""
42
+ packages: list[Package]
43
+ """Installed packages."""
44
+ variables: list[Variable]
45
+ """Environment variables."""
46
+
47
+
48
+ def _interpreter_name_version() -> tuple[str, str]:
49
+ if hasattr(sys, "implementation"):
50
+ impl = sys.implementation.version
51
+ version = f"{impl.major}.{impl.minor}.{impl.micro}"
52
+ kind = impl.releaselevel
53
+ if kind != "final":
54
+ version += kind[0] + str(impl.serial)
55
+ return sys.implementation.name, version
56
+ return "", "0.0.0"
57
+
58
+
59
+ def get_version(dist: str = "griffe2md") -> str:
60
+ """Get version of the given distribution.
61
+
62
+ Parameters:
63
+ dist: A distribution name.
64
+
65
+ Returns:
66
+ A version number.
67
+ """
68
+ try:
69
+ return metadata.version(dist)
70
+ except metadata.PackageNotFoundError:
71
+ return "0.0.0"
72
+
73
+
74
+ def get_debug_info() -> Environment:
75
+ """Get debug/environment information.
76
+
77
+ Returns:
78
+ Environment information.
79
+ """
80
+ py_name, py_version = _interpreter_name_version()
81
+ packages = ["griffe2md"]
82
+ variables = ["PYTHONPATH", *[var for var in os.environ if var.startswith("GRIFFE2MD")]]
83
+ return Environment(
84
+ interpreter_name=py_name,
85
+ interpreter_version=py_version,
86
+ platform=platform.platform(),
87
+ variables=[Variable(var, val) for var in variables if (val := os.getenv(var))],
88
+ packages=[Package(pkg, get_version(pkg)) for pkg in packages],
89
+ )
90
+
91
+
92
+ def print_debug_info() -> None:
93
+ """Print debug/environment information."""
94
+ info = get_debug_info()
95
+ print(f"- __System__: {info.platform}")
96
+ print(f"- __Python__: {info.interpreter_name} {info.interpreter_version}")
97
+ print("- __Environment variables__:")
98
+ for var in info.variables:
99
+ print(f" - `{var.name}`: `{var.value}`")
100
+ print("- __Installed packages__:")
101
+ for pkg in info.packages:
102
+ print(f" - `{pkg.name}` v{pkg.version}")
103
+
104
+
105
+ if __name__ == "__main__":
106
+ print_debug_info()
@@ -0,0 +1,159 @@
1
+ """Main function of the program."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import IO, TYPE_CHECKING
9
+
10
+ import mdformat
11
+ from griffe.docstrings import Parser
12
+ from griffe.loader import GriffeLoader
13
+ from jinja2 import Environment, FileSystemLoader
14
+
15
+ from griffe2md import rendering
16
+
17
+ if TYPE_CHECKING:
18
+ from griffe import Object
19
+
20
+
21
+ def _output(text: str, to: IO | str | None = None) -> None:
22
+ if isinstance(to, str):
23
+ with open(to, "w") as output:
24
+ output.write(text)
25
+ else:
26
+ if to is None:
27
+ to = sys.stdout
28
+ to.write(text)
29
+
30
+
31
+ def prepare_context(obj: Object, config: dict | None = None) -> dict:
32
+ """Prepare Jinja context.
33
+
34
+ Parameters:
35
+ obj: A Griffe object.
36
+ config: The configuration options.
37
+
38
+ Returns:
39
+ The Jinja context.
40
+ """
41
+ config = config or dict(rendering.default_config)
42
+ if config["filters"]:
43
+ config["filters"] = [(re.compile(filtr.lstrip("!")), filtr.startswith("!")) for filtr in config["filters"]]
44
+
45
+ heading_level = config["heading_level"]
46
+ try:
47
+ config["members_order"] = rendering.Order(config["members_order"])
48
+ except ValueError as error:
49
+ choices = "', '".join(item.value for item in rendering.Order)
50
+ raise ValueError(
51
+ f"Unknown members_order '{config['members_order']}', choose between '{choices}'.",
52
+ ) from error
53
+
54
+ summary = config["summary"]
55
+ if summary is True:
56
+ config["summary"] = {
57
+ "attributes": True,
58
+ "functions": True,
59
+ "classes": True,
60
+ "modules": True,
61
+ }
62
+ elif summary is False:
63
+ config["summary"] = {
64
+ "attributes": False,
65
+ "functions": False,
66
+ "classes": False,
67
+ "modules": False,
68
+ }
69
+ else:
70
+ config["summary"] = {
71
+ "attributes": summary.get("attributes", False),
72
+ "functions": summary.get("functions", False),
73
+ "classes": summary.get("classes", False),
74
+ "modules": summary.get("modules", False),
75
+ }
76
+
77
+ return {
78
+ "config": config,
79
+ obj.kind.value: obj,
80
+ "heading_level": heading_level,
81
+ "root": True,
82
+ }
83
+
84
+
85
+ def prepare_env(env: Environment | None = None) -> Environment:
86
+ """Prepare Jinja environment.
87
+
88
+ Parameters:
89
+ env: A Jinja environment.
90
+
91
+ Returns:
92
+ The Jinja environment.
93
+ """
94
+ env = env or Environment(
95
+ autoescape=False, # noqa: S701
96
+ loader=FileSystemLoader([Path(__file__).parent / "templates"]),
97
+ auto_reload=False,
98
+ )
99
+ env.filters["any"] = rendering.do_any
100
+ env.filters["heading"] = rendering.do_heading
101
+ env.filters["as_attributes_section"] = rendering.do_as_attributes_section
102
+ env.filters["as_classes_section"] = rendering.do_as_classes_section
103
+ env.filters["as_functions_section"] = rendering.do_as_functions_section
104
+ env.filters["as_modules_section"] = rendering.do_as_modules_section
105
+ env.filters["filter_objects"] = rendering.do_filter_objects
106
+ env.filters["format_code"] = rendering.do_format_code
107
+ env.filters["format_signature"] = rendering.do_format_signature
108
+ env.filters["format_attribute"] = rendering.do_format_attribute
109
+ env.filters["order_members"] = rendering.do_order_members
110
+ env.filters["split_path"] = rendering.do_split_path
111
+ env.filters["stash_crossref"] = lambda ref, length: ref
112
+ env.filters["from_private_package"] = rendering.from_private_package
113
+
114
+ return env
115
+
116
+
117
+ def render_object_docs(obj: Object, config: dict | None = None) -> str:
118
+ """Render docs for a given object.
119
+
120
+ Parameters:
121
+ obj: The Griffe object to render docs for.
122
+ config: The rendering configuration.
123
+
124
+ Returns:
125
+ Markdown.
126
+ """
127
+ env = prepare_env()
128
+ context = prepare_context(obj, config)
129
+ rendered = env.get_template(f"{obj.kind.value}.md.jinja").render(**context)
130
+ return mdformat.text(rendered)
131
+
132
+
133
+ def render_package_docs(package: str, config: dict | None = None) -> str:
134
+ """Render docs for a given package.
135
+
136
+ Parameters:
137
+ package: The package (name) to render docs for.
138
+ config: The rendering configuration.
139
+
140
+ Returns:
141
+ Markdown.
142
+ """
143
+ config = config or dict(rendering.default_config)
144
+ parser = config["docstring_style"] and Parser(config["docstring_style"])
145
+ loader = GriffeLoader(docstring_parser=parser)
146
+ module = loader.load(package)
147
+ loader.resolve_aliases(external=True)
148
+ return render_object_docs(module, config)
149
+
150
+
151
+ def write_package_docs(package: str, config: dict | None = None, output: IO | str | None = None) -> None:
152
+ """Write docs for a given package to a file or stdout.
153
+
154
+ Parameters:
155
+ package: The package to render docs for.
156
+ config: The rendering configuration.
157
+ output: The file to write to.
158
+ """
159
+ _output(render_package_docs(package, config), to=output)