# Generate Markdown documentation from Python code
This library generates Markdown documentation directly from Python code, utilizing Python type annotations.
## Features at a glance
* Each module produces a Markdown file.
* [Documentation strings](https://docs.python.org/3/library/stdtypes.html#definition.__doc__) are extracted from module, class, enumeration and function definitions.
* Cross-references may be local or fully qualified, and work across modules.
* Classes with member variable declarations produce member documentation.
* Data-class field descriptions are validated if they have a matching member variable declaration.
* Enumeration members are published, even if they lack a description.
* Magic methods (e.g. `__eq__`) are published if they have a doc-string.
* Multi-line code blocks in doc-strings are retained as Markdown code blocks.
* Forward-references and type annotations as strings are automatically evaluated.
## Documentation features
Cross-references with Sphinx-style syntax (`:mod:`, `:class:` and `:meth:`) are supported in module, class and function doc-strings:
```python
@dataclass
class SampleClass:
"""
This class is extended by :class:`DerivedClass`.
This class implements :meth:`__lt__` and :meth:`SampleClass.__gt__`.
"""
```
Class member variable and data-class field descriptions are defined with `:param ...:`:
```python
@dataclass
class DerivedClass(SampleClass):
"""
This data-class derives from another base class.
:param union: A union of several types.
:param json: A complex type with type substitution.
:param schema: A complex type without type substitution.
"""
union: SimpleType
json: JsonType
schema: Schema
```
Enumeration member description follows the member value assignment:
```python
class EnumType(enum.Enum):
enabled = "enabled"
"Documents the enumeration member `enabled`."
disabled = "disabled"
"Documents the enumeration member `disabled`."
```
## Usage
### Calling the utility in Python
```python
from markdown_doc.generator import MarkdownGenerator
MarkdownGenerator([module1, module2, module3]).generate(out_dir)
```
Pass an object of `MarkdownOptions` to configure behavior:
```python
MarkdownGenerator(
[module1, module2, module3],
options=MarkdownOptions(
anchor_style=MarkdownAnchorStyle.GITBOOK,
partition_strategy=PartitionStrategy.SINGLE,
include_private=False,
stdlib_links=True,
),
).generate(out_dir)
```
### Running the utility from the command line
```
$ python3 -m markdown_doc --help
usage: markdown_doc [-h] [-d [DIRECTORY ...]] [-m [MODULE ...]] [-r ROOT_DIR] [-o OUT_DIR] [--anchor-style {GitBook,GitHub}] [--partition {single,by_kind}]
Generates Markdown documentation from Python code
options:
-h, --help show this help message and exit
-d [DIRECTORY ...], --directory [DIRECTORY ...]
folder(s) to recurse into when looking for modules
-m [MODULE ...], --module [MODULE ...]
qualified names(s) of Python module(s) to scan
-r ROOT_DIR, --root-dir ROOT_DIR
path to act as root for converting directory paths into qualified module names (default: working directory)
-o OUT_DIR, --out-dir OUT_DIR
output directory (default: 'docs' in working directory)
--anchor-style {GitBook,GitHub}
output format for generating anchors in headings
--partition {single,by_kind}
how to split module contents across Markdown files
```
## Related work
In order to reduce added complexity, this library does not use the Sphinx framework with [autodoc](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html).
Raw data
{
"_id": null,
"home_page": null,
"name": "markdown-doc",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "Levente Hunyadi <hunyadi@gmail.com>",
"keywords": "markdown, documentation-generator, python-typing",
"author": null,
"author_email": "Levente Hunyadi <hunyadi@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/bc/5b/fed9f83ae67af9d07b45e1a06855fbfee9eadbd26b402fdc8cebb2c7d483/markdown_doc-0.1.5.tar.gz",
"platform": null,
"description": "# Generate Markdown documentation from Python code\n\nThis library generates Markdown documentation directly from Python code, utilizing Python type annotations.\n\n## Features at a glance\n\n* Each module produces a Markdown file.\n* [Documentation strings](https://docs.python.org/3/library/stdtypes.html#definition.__doc__) are extracted from module, class, enumeration and function definitions.\n* Cross-references may be local or fully qualified, and work across modules.\n* Classes with member variable declarations produce member documentation.\n* Data-class field descriptions are validated if they have a matching member variable declaration.\n* Enumeration members are published, even if they lack a description.\n* Magic methods (e.g. `__eq__`) are published if they have a doc-string.\n* Multi-line code blocks in doc-strings are retained as Markdown code blocks.\n* Forward-references and type annotations as strings are automatically evaluated.\n\n## Documentation features\n\nCross-references with Sphinx-style syntax (`:mod:`, `:class:` and `:meth:`) are supported in module, class and function doc-strings:\n\n```python\n@dataclass\nclass SampleClass:\n \"\"\"\n This class is extended by :class:`DerivedClass`.\n\n This class implements :meth:`__lt__` and :meth:`SampleClass.__gt__`.\n \"\"\"\n```\n\nClass member variable and data-class field descriptions are defined with `:param ...:`:\n\n```python\n@dataclass\nclass DerivedClass(SampleClass):\n \"\"\"\n This data-class derives from another base class.\n\n :param union: A union of several types.\n :param json: A complex type with type substitution.\n :param schema: A complex type without type substitution.\n \"\"\"\n\n union: SimpleType\n json: JsonType\n schema: Schema\n```\n\nEnumeration member description follows the member value assignment:\n\n```python\nclass EnumType(enum.Enum):\n enabled = \"enabled\"\n \"Documents the enumeration member `enabled`.\"\n\n disabled = \"disabled\"\n \"Documents the enumeration member `disabled`.\"\n```\n\n## Usage\n\n### Calling the utility in Python\n\n```python\nfrom markdown_doc.generator import MarkdownGenerator\n\nMarkdownGenerator([module1, module2, module3]).generate(out_dir)\n```\n\nPass an object of `MarkdownOptions` to configure behavior:\n\n```python\nMarkdownGenerator(\n [module1, module2, module3],\n options=MarkdownOptions(\n anchor_style=MarkdownAnchorStyle.GITBOOK,\n partition_strategy=PartitionStrategy.SINGLE,\n include_private=False,\n stdlib_links=True,\n ),\n).generate(out_dir)\n```\n\n### Running the utility from the command line\n\n```\n$ python3 -m markdown_doc --help\nusage: markdown_doc [-h] [-d [DIRECTORY ...]] [-m [MODULE ...]] [-r ROOT_DIR] [-o OUT_DIR] [--anchor-style {GitBook,GitHub}] [--partition {single,by_kind}]\n\nGenerates Markdown documentation from Python code\n\noptions:\n -h, --help show this help message and exit\n -d [DIRECTORY ...], --directory [DIRECTORY ...]\n folder(s) to recurse into when looking for modules\n -m [MODULE ...], --module [MODULE ...]\n qualified names(s) of Python module(s) to scan\n -r ROOT_DIR, --root-dir ROOT_DIR\n path to act as root for converting directory paths into qualified module names (default: working directory)\n -o OUT_DIR, --out-dir OUT_DIR\n output directory (default: 'docs' in working directory)\n --anchor-style {GitBook,GitHub}\n output format for generating anchors in headings\n --partition {single,by_kind}\n how to split module contents across Markdown files\n```\n\n## Related work\n\nIn order to reduce added complexity, this library does not use the Sphinx framework with [autodoc](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html).\n",
"bugtrack_url": null,
"license": null,
"summary": "Generate Markdown documentation from Python code",
"version": "0.1.5",
"project_urls": {
"Homepage": "https://github.com/hunyadi/markdown_doc",
"Source": "https://github.com/hunyadi/markdown_doc"
},
"split_keywords": [
"markdown",
" documentation-generator",
" python-typing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "cd987a42f1d8a8eb819c5ffa4319e06590ae32b8512be2e722fc370ab297c7dd",
"md5": "2f6ce9aee0a488a3ee462927ab18a0bd",
"sha256": "5c7a7de019b87aa75b37e21d7f95024d418a5f4ecf8c3f93311092c1d756424f"
},
"downloads": -1,
"filename": "markdown_doc-0.1.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2f6ce9aee0a488a3ee462927ab18a0bd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 18615,
"upload_time": "2025-08-20T09:53:22",
"upload_time_iso_8601": "2025-08-20T09:53:22.326290Z",
"url": "https://files.pythonhosted.org/packages/cd/98/7a42f1d8a8eb819c5ffa4319e06590ae32b8512be2e722fc370ab297c7dd/markdown_doc-0.1.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "bc5bfed9f83ae67af9d07b45e1a06855fbfee9eadbd26b402fdc8cebb2c7d483",
"md5": "814ab3cb563831bd74a06a9192c6c3e7",
"sha256": "add1d14ac4853cc997cd8bac40a87931eac1d5662ce06323f9d2873e8a9813cd"
},
"downloads": -1,
"filename": "markdown_doc-0.1.5.tar.gz",
"has_sig": false,
"md5_digest": "814ab3cb563831bd74a06a9192c6c3e7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 17608,
"upload_time": "2025-08-20T09:53:23",
"upload_time_iso_8601": "2025-08-20T09:53:23.465953Z",
"url": "https://files.pythonhosted.org/packages/bc/5b/fed9f83ae67af9d07b45e1a06855fbfee9eadbd26b402fdc8cebb2c7d483/markdown_doc-0.1.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-20 09:53:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hunyadi",
"github_project": "markdown_doc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "json_strong_typing",
"specs": [
[
">=",
"0.3.8"
]
]
},
{
"name": "build",
"specs": []
},
{
"name": "mypy",
"specs": []
},
{
"name": "ruff",
"specs": []
}
],
"lcname": "markdown-doc"
}