API
MkDocGenerator
The MkDocGenerator
generates the documentation with the links to the source code.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
Utilities | class | [description] | required |
BuilderMkDoc | class | Builder class of the abstract methods and property of | required |
generate: None
property
readonly
The property generate
of MkDocGenerator
creates the final markdown files.
Example: How to use
>>> from pathlib import Path
# Import mkdocstrings-sourcelink
>>> from mkdocstrings_sourcelink import MkDocGenerator
# Define the dictionary for the documentation
>>> pages = {
"Documentation": {
"auto_generator.md": [
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.__init__",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.render_to_markdown",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.initialize_generate",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate_docs",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate_static",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate",
]
},
"Tools": {
"toolbox.md": [
"mkdocstrings_sourcelink.toolbox.Utilities.insert_in_file",
"mkdocstrings_sourcelink.toolbox.Utilities.element_to_mkdocstrings",
"mkdocstrings_sourcelink.toolbox.Utilities.make_source_link",
"mkdocstrings_sourcelink.toolbox.Utilities.make_title",
"mkdocstrings_sourcelink.toolbox.Utilities.import_object",
"mkdocstrings_sourcelink.toolbox.Utilities.return_as_Path",
],
},
}
# Define the dictionary for the importing existing markdown files.
>>> markdown_files = {
"HOME": {"index.md": ["../README.md"]},
"CONTRIBUTING": {"contributing.md": ["../CONTRIBUTING.md"]},
"LICENSE": {"license.md": ["../LICENSE"]},
}
>>> root = Path(__file__).resolve().parents[1]
# Make use of the generate poperty of MkDocGenerator
>>> MkDocGenerator(
root / "docs" / "src",
pages,
"https://github.com/AI2Business/mkdocstrings-sourcelink/blob/main",
markdown_files=markdown_files,
underline_title=True,
source=":material-github::material-source-branch:",
).generate
>>> ...
__init__(self, dest_dir, documentation, project_url=None, template_dir=None, example_dir=None, markdown_files=None, titles_size='#', underline_title=False, source='**source code**')
special
Generates the documentation via MkDocGenerator
with the links to the source.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
dest_dir | Union[str, pathlib.Path] | Destination of the generated documentation. | required |
documentation | Dict[str, Dict[str, List[str]]] | A nested dictionary with the page title, the page filename, and the functions /classes / methods names of the page. The dictionary should look like: | required |
project_url | Union[str, Dict[str, str]] | The URL, where the project is hosted and where it should be linked to (including branch and storage). | None |
template_dir | Union[str, pathlib.Path] | Directory of template files. If template has to be automatically filled out, then the keyword {{autogenerated}} has to be used. | None |
example_dir | Union[str, pathlib.Path] | Directory of example files, especially suitable for | None |
markdown_files | Dict[str, Dict[str, List[str]]] | A nested dictionary with the page title, the page filename, and the link to already existing markdown files like README.md or LICENSE. The dictionary should look like: | None |
titles_size | str | Defines the initial title size for the headings, which are scaled down by the factor of one "#". | '#' |
underline_title | bool | Underline titles of classes, functions, and methods. | False |
source | str | Name of the source link. | '**source code**' |
About documentation
In terms of linking to the project_url, it has to be separated between specific and general linking. If functions or method has to be separately linked, then each module of the class Documentation
has to be called individually like:
pages = {
"Documentation": {
"auto_generator.md": [
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.__init__",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.render_to_markdown",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.initialize_generate",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate_docs",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate_static",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate",
]
}
}
Documentation
is enough. It will be only generated one single link to the start of the class. pages = {
"Documentation": {
"auto_generator.md": [
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator",
}
}
About source
Instead of using a string for source = "**source code**"
, icons can be used instead or as combination of string + icon(s) like.
source = ":material-github::material-source-branch: source-code"
mdl
by material
. About project_url
Keep in mind, that the name of the branch like master, main, or dev, as well as, the name of the storage like blob for GitHub has to be included.
Source code in mkdocstrings_sourcelink/auto_generator.py
def __init__(
self,
dest_dir: Union[str, Path],
documentation: Dict[str, Dict[str, List[str]]],
project_url: Union[str, Dict[str, str]] = None,
template_dir: Union[str, Path] = None,
example_dir: Union[str, Path] = None,
markdown_files: Dict[str, Dict[str, List[str]]] = None,
titles_size: str = "#",
underline_title: bool = False,
source: str = "**source code**",
) -> None:
"""Generates the documentation via `MkDocGenerator` with the links to the source.
Args:
dest_dir (Union[str, Path]): Destination of the generated documentation.
documentation (Dict[str, Dict[str, List[str]]], optional): A nested dictionary with the
page title, the page filename, and the functions /classes / methods names of the
page. The dictionary should look like:
`pages = {'page_title':{'filename.md': ['package.module.function']}}`.
project_url (Union[str, Dict[str, str]], optional): The URL, where the project is
hosted and where it should be linked to (including branch and storage).
template_dir (Union[str, Path], optional): Directory of template files. If template has
to be automatically filled out, then the keyword **{{autogenerated}}** has to be
used.
example_dir (Union[str, Path], optional): Directory of example files, especially
suitable for `Jupyter-Notebooks`.
markdown_files (Dict[str, Dict[str, List[str]]], optional): A nested dictionary with
the page title, the page filename, and the link to already existing markdown files
like **README.md** or **LICENSE**. The dictionary should look like:
`pages = {'page_title':{'filename.md': ['existing_file.md']}}`.
titles_size (str, optional): Defines the initial title size for the headings, which are
scaled down by the factor of one "#".
underline_title (bool, optional): Underline titles of classes, functions, and methods.
source (str, optional): Name of the source link.
!!! info "About *documentation*"
In terms of linking to the project_url, it has to be separated between *specific* and
*general* linking. If functions or method has to be separately linked, then each
module of the class `Documentation` has to be called individually like:
```python
pages = {
"Documentation": {
"auto_generator.md": [
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.__init__",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.render_to_markdown",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.initialize_generate",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate_docs",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate_static",
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator.generate",
]
}
}
```
If functions or method has to be generally linked, then just call the class
`Documentation` is enough. It will be only generated one single link to the start of
the class.
```python
pages = {
"Documentation": {
"auto_generator.md": [
"mkdocstrings_sourcelink.auto_generator.MkDocGenerator",
}
}
```
For more information, please check: **mkdocstrings**
https://github.com/pawamoy/mkdocstrings
!!! tip "About *source*"
Instead of using a string for `source = "**source code**"`, icons can be used instead
or as combination of string + icon(s) like.
```python
source = ":material-github::material-source-branch: source-code"
```
In case of using material-icons, please check https://pictogrammers.github.io/@mdi/font/5.4.55/
and replace `mdl` by `material`.
!!! warning "About *project_url*"
Keep in mind, that the name of the branch like *master*, *main*, or *dev*, as well as,
the name of the storage like *blob* for GitHub has to be included.
"""
self.dest_dir = Path(dest_dir)
self.documentation = documentation
self.project_url = project_url
self.template_dir = Utilities.return_as_Path(template_dir)
self.example_dir = Utilities.return_as_Path(example_dir)
self.markdown_files = markdown_files
self.titles_size = titles_size
self.underline_title = underline_title
self.source = source
generate_docs(self)
Generated dynamic documentation based on calling the elements via dictionary.
Source code in mkdocstrings_sourcelink/auto_generator.py
def generate_docs(self) -> None:
"""Generated *dynamic* documentation based on calling the elements via dictionary."""
for title, documentation in self.documentation.items():
markdown_text = f"{self.titles_size} {title}\n\n---\n\n"
for file_path, elements in documentation.items():
markdown_text += "".join(
self.render_to_markdown(element) for element in elements
)
Utilities.insert_in_file(markdown_text, self.dest_dir.joinpath(file_path))
generate_static(self)
Generate static documentation based on existing markdown files.
Source code in mkdocstrings_sourcelink/auto_generator.py
def generate_static(self) -> None:
"""Generate *static* documentation based on existing markdown files."""
if self.markdown_files:
for _, markdown_files in self.markdown_files.items():
markdown_text = ""
for file_path, elements in markdown_files.items():
markdown_text += "".join(
Path(element).read_text() for element in elements
)
Utilities.insert_in_file(
markdown_text, self.dest_dir.joinpath(file_path)
)
initialize_generate(self)
Initialization of the auto documentation generatorion.
- Firs removing a possible existing target directory (
dest_dir
). - Copy templates from the template directory the target directory(
dest_dir
). - Copy example from the example directory the target directory (
dest_dir
).
Source code in mkdocstrings_sourcelink/auto_generator.py
def initialize_generate(self) -> None:
"""Initialization of the auto documentation generatorion.
1. Firs removing a possible existing target directory (`dest_dir`).
2. Copy templates from the template directory the target directory(`dest_dir`).
3. Copy example from the example directory the target directory (`dest_dir`).
"""
if self.dest_dir.exists():
print(f"Cleaning up existing sources directory '{self.dest_dir}'.")
shutil.rmtree(self.dest_dir)
if self.template_dir:
print(
f"...copying existing sources directory '{self.template_dir}' to '{self.dest_dir}'."
)
shutil.copytree(self.template_dir, self.dest_dir)
if self.example_dir:
print(
f"...copying existing sources directory '{self.example_dir}' to '{self.dest_dir}'."
)
shutil.copytree(self.example_dir, self.dest_dir)
render_to_markdown(self, element)
Rendering the element path to mkdocstrings.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
element | str | String of they python class, function, or method, which has to be converted to a string in the mkdocstrings format. | required |
Returns:
Type | Description |
---|---|
str | str: Return of the initial string which looks like |
Source code in mkdocstrings_sourcelink/auto_generator.py
def render_to_markdown(self, element: str) -> str:
"""Rendering the element path to mkdocstrings.
Args:
element (str): String of they python class, function, or method, which has to be
converted to a string in the mkdocstrings format.
Returns:
str: Return of the initial string which looks like
`mkdocstrings_sourcelink.auto_generator.MkDocGenerator.__init__` into a markdown
conformed string.
"""
object_ = Utilities.import_object(element)
subblocks = []
if self.project_url:
subblocks.append(
Utilities.make_source_link(object_, self.project_url, self.source)
)
subblocks.append(
Utilities.make_title(object_, self.titles_size, self.underline_title)
)
subblocks.append(Utilities.element_to_mkdocstrings(element, self.titles_size))
return "\n\n".join(subblocks) + "\n\n"
Utilities
The Utilities
build the mkdocstrings and generate the hyperlinks to the source code.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
AbstractUtilities | class | Builder class of the abstract staticmethods of | required |
element_to_mkdocstrings(element, titles_size)
staticmethod
Converts point separated string into the mkdocstrings format.
For converting the elements to mkdocstrings, the element will added ::: in front of the element string. In addition to that, the the new mkdocstrings will get subheadings.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
element | str | String of they python class, function, or method, which has to be converted to a string in the mkdocstrings format. | required |
titles_size | str | Current title size in the style of '#', which defines the headings. | required |
Returns:
Type | Description |
---|---|
str | str: String of they python class, function, or method, which is converted to a string in the mkdocstrings format. |
Source code in mkdocstrings_sourcelink/toolbox.py
@staticmethod
def element_to_mkdocstrings(element: str, titles_size: str) -> str:
"""Converts point separated string into the mkdocstrings format.
For converting the elements to mkdocstrings, the element will added **:::** in front of the
element string. In addition to that, the the new mkdocstrings will get subheadings.
Args:
element (str): String of they python class, function, or method, which has to be
converted to a string in the mkdocstrings format.
titles_size (str): Current title size in the style of '#', which defines the headings.
Returns:
str: String of they python class, function, or method, which is converted to a string
in the mkdocstrings format.
"""
return f"##{titles_size} :::{element}\n"
import_object(element)
staticmethod
Import an object like class, function, or method from a string.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
element | str | String of class, function, or method, which should be converted to an object. | required |
Returns:
Type | Description |
---|---|
object | object: Class, function, or method object for the giving element. |
Source code in mkdocstrings_sourcelink/toolbox.py
@staticmethod
def import_object(element: str) -> object:
"""Import an object like class, function, or method from a string.
Args:
element (str): String of class, function, or method, which should be converted to an
object.
Returns:
object: Class, function, or method object for the giving element.
"""
last_object_got = None
seen_names = []
for name in element.split("."):
seen_names.append(name)
try:
last_object_got = importlib.import_module(".".join(seen_names))
except ModuleNotFoundError:
last_object_got = getattr(last_object_got, name)
return last_object_got
insert_in_file(markdown_text, file_path)
staticmethod
Insert the markdown formatted text into a new or existing file.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
markdown_text | str | Text as string, which follows the markdown format. | required |
file_path | Path | Filename and path as Path object. | required |
Exceptions:
Type | Description |
---|---|
RuntimeError | If {{autogenerated}} is not provided in a template file, it will cause a a RuntimeError. |
Source code in mkdocstrings_sourcelink/toolbox.py
@staticmethod
def insert_in_file(markdown_text: str, file_path: Path) -> None:
"""Insert the markdown formatted text into a new or existing file.
Args:
markdown_text (str): Text as string, which follows the markdown format.
file_path (Path): Filename and path as Path object.
Raises:
RuntimeError: If {{autogenerated}} is not provided in a template file, it will cause a
a **RuntimeError**.
"""
if file_path.exists():
template = file_path.read_text(encoding="utf-8")
if "{{autogenerated}}" not in template:
raise RuntimeError(
f"Template found for {file_path} but missing "
f"{{autogenerated}} tag."
)
markdown_text = template.replace("{{autogenerated}}", markdown_text)
print(f"...inserting autogenerated content into template:{file_path}")
else:
print(f"...creating new page with autogenerated content:{file_path}")
file_path.parent.mkdir(parents=True, exist_ok=True)
file_path.write_text(markdown_text, encoding="utf-8")
make_source_link(cls, project_url, source='**source code**')
staticmethod
Make a source link to the code basis including the linestart.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cls | classmethod | Convert a function to be a class method. | required |
project_url | Union[str, Dict[str, str]] | URL to the repository like GitHub AI2Business/mkdocstrings-sourcelink. | required |
source | str | Name or sticker name for rendering the link to the source. | '**source code**' |
Returns:
Type | Description |
---|---|
str | str: Hyperlink in html format with link to the repository. |
About source
Instead of using a string for source = "**source code**"
, icons can be used instead or as combination of string + icon(s) like.
source = ":material-github::material-source-branch: source-code"
mdl
by material
. Source code in mkdocstrings_sourcelink/toolbox.py
@staticmethod
def make_source_link(
cls: classmethod,
project_url: Union[str, Dict[str, str]],
source: str = "**source code**",
) -> str:
"""Make a source link to the code basis including the linestart.
Args:
cls (classmethod): Convert a function to be a class method.
project_url (Union[str, Dict[str, str]]): URL to the repository like GitHub
https://github.com/AI2Business/mkdocstrings-sourcelink/.
source (str, optional): Name or sticker name for rendering the link to the
source.
Returns:
str: Hyperlink in html format with link to the repository.
!!! tip "About *source*"
Instead of using a string for `source = "**source code**"`, icons can be used instead
or as combination of string + icon(s) like.
```python
source = ":material-github::material-source-branch: source-code"
```
In case of using material-icons, please check https://pictogrammers.github.io/@mdi/font/5.4.55/
and replace `mdl` by `material`.
"""
if isinstance(project_url, dict):
if isinstance(cls, property):
base_module = cls.fget.__module__.split(".")[0]
else:
base_module = cls.__module__.split(".")[0]
project_url = project_url[base_module]
if isinstance(cls, property):
path = cls.fget.__module__.replace(".", "/")
line = inspect.getsourcelines(cls.fget)[-1]
else:
path = cls.__module__.replace(".", "/")
line = inspect.getsourcelines(cls)[-1]
return (
f'<span style="float:right;">'
f"[{source}]({project_url}/{path}.py#L{line})"
f"</span>"
)
make_title(cls, titles_size, underline_title)
staticmethod
Make the title of the class, function, or method.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cls | classmethod | Convert a function to be a class method. In case of class properties | required |
titles_size | str | Current title size in the style of '#', which defines the headings. | required |
Returns:
Type | Description |
---|---|
str | str: The name of the class, function, or method in a markdown conformed title. |
Source code in mkdocstrings_sourcelink/toolbox.py
@staticmethod
def make_title(cls: classmethod, titles_size: str, underline_title: bool) -> str:
"""Make the title of the class, function, or method.
Args:
cls (classmethod): Convert a function to be a class method. In case of class properties
`fget` is used to read out the name of the module.
titles_size (str): Current title size in the style of '#', which defines the headings.
Returns:
str: The name of the class, function, or method in a markdown conformed title.
"""
title_underline = "\n---\n" if underline_title else "\n"
if isinstance(cls, property):
return f"#{titles_size} {cls.fget.__name__}{title_underline}"
return f"#{titles_size} {cls.__name__}{title_underline}"
return_as_Path(path=None)
staticmethod
Converts strings to Path of pathlib.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path | str | String of a filename. | None |
Returns:
Type | Description |
---|---|
Optional[pathlib.Path] | Optional[Path]: Path object of the initial filename. |
Source code in mkdocstrings_sourcelink/toolbox.py
@staticmethod
def return_as_Path(path: str = None) -> Optional[Path]:
"""Converts strings to Path of pathlib.
Args:
path (str, optional): String of a filename.
Returns:
Optional[Path]: Path object of the initial filename.
"""
if path:
return Path(path)
return None