Generating documentation from code can be a tedious and time-consuming task. By offering a simple and easy-to-use tool, this package aims to make the process of creating documentation more efficient. It allows users to extract useful information, such as function descriptions and input/output specifications, directly from the source code (DocStrings). This can save a lot of time and effort that would otherwise be spent manually writing documentation. In addition, having documentation automatically generated from code ensures that it stays up-to-date as the codebase changes. Overall, this package provides a convenient solution for generating high-quality documentation for Python projects. All the installation process has been rebuilt with Makefile and pyproject.toml.
We can find a lot of tools to generate docs from code, but we want something quick and easy to set up. This tool can be used on python file or python package.
Semantic analysis and tree traversal are not really my passions ^^, but these types of tools are still very interesting. Some time has passed since the first version. I admit that Python had started to introduce typing, but it was, not yet widespread. There have also been significant changes in the deployment of packages, and since the script setup.py has no reason to exist. I have therefore migrated to the TOML file and adapted the META import libraries. It's true that I might have done this sooner, but I ran out of time and was always using somewhat outdated versions of Python. Changes in the language are constant. This new version is therefore a complete refresh, allowing me to be more in line with what is currently being done in the Python ecosystem.
Use the script:
Usage: export_docstring2md [-h] [--version] [--debug | --quiet]
[--logfile LOGFILE] [--toc] [--private-def]
-p PACKAGE [-o OUTPUT_FILE] [-tml TOML_FILE]
[-td TODO_FILE] [-mmd MERMAID_FILE]
This script is provided by docstring2md package.
It exports google docstrings from python module to a Markdown file in order
to generate README.
Options:
-h, --help show this help message and exit
--version show version and exit
--debug print debug messages to stderr
--quiet print error messages to stderr
--logfile LOGFILE /path/to/file.log
--toc Enable the table of contents
--private-def Enable the table of contents
Required Arguments:
-p, --package PACKAGE
define the /path/to/the/package or
<package_name>
Optional Arguments:
-o, --output-file OUTPUT_FILE
/path/to/output/file (README.md)
-tml, --toml-file TOML_FILE
/path/to/toml/file.toml
-td, --todo-file TODO_FILE
/path/to/todo/file.md
-mmd, --mermaid-file MERMAID_FILE
/path/to/mermaid/file.mmd
COMPATIBILITY:
Python 3.7+ - https://www.python.org/
EXIT STATUS:
This script exits 0 on success, and >0 if an error occurs:
- EX_OK: 0 -> success
- EX_CONFIG: 78 -> config error
- EX_OSFILE: 72 -> module not found
- EX_CANTCREAT: 73 -> can not create the file
- EX_IOERR: 74 -> write error
Python 3.7+
- User:
Get the package:
git clone https://github.com/francois-le-ko4la/docstring-to-markdown.git
Change to the folder:
cd docstring-to-markdown
Install with make on Linux/Unix/MacOS or use pip3 otherwise:
make install
- Dev environment:
Get the package:
git clone https://github.com/francois-le-ko4la/docstring-to-markdown.git
Change to the folder:
cd docstring-to-markdown
Create your environment with all dev prerequisites and install the package:
make venv
source venv/bin/activate
make dev
This module has been tested and validated on Ubuntu. Test is available if you set up the package with dev environment.
make test
This package is distributed under the GPLv3 license
- Create the project
- Write code and tests
- Test installation and requirements (setup.py and/or Makefile)
- Test code
- Validate features
- Add-on : decorator
- Add-on : class properties
- Add-on : runtime & requirements
- Add-on : toc
- Add-on : remove inspect library and use AST
- Add-on : improve global performance (x3)
- Write Doc/stringdoc
- Run PEP8 validation
- Clean & last check
- Release 0.4.1
- Rebuild the cli argument
- Rebuild logging management and add more debug
- Rebuild the package management through pyproject.toml
- Rebuild the Makefile
- Add-on : typing analysis
- Create JSON module example
- Finish the typing
- AST optimisation
- Improve CONST
- improve doctest look & feel
- homogeneous doc btw Class and Function
- Include import in init file
- Improve the docstring module (MD format is not standard ^^)
- Move the todo from init to a dedicated file (new option)
- Use Enum class to define ExitStatus, Const and Tag
- Fix an issue on Atttributes management
- Fix decorator argument : add ()
- Test
- Release 0.5.0
- Detect and fix issue on Constant - Improve type detection/extraction
- Fix pyproject.toml
- Release 0.5.1
# -*- coding: utf-8 -*-
[project]
name = "docstring2md"
version = "0.5.1"
authors = [
{name = "ko4la" }
]
description = "Docstring extractor to generate readme."
license = {file = "LICENSE"}
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Development Status :: 5 - Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3 :: Only",
"OSI Approved :: GNU General Public License v3 (GPLv3)",
]
dependencies = [
"rich>=12.6.0",
"rich_argparse>=0.6.0",
"importlib-metadata ~= 1.0 ; python_version < '3.8'"
]
[project.optional-dependencies]
dev = [
"pycodestyle>=2.3.1",
"pytest>=7.2.0",
"pylint",
"mypy",
"pydocstyle",
"pytest-pylint",
"pytest-pycodestyle",
"pytest-mypy",
"pytest-pydocstyle",
"pytest-isort"]
[project.urls]
"Homepage" = "https://github.com/francois-le-ko4la/docstring-to-markdown"
[project.scripts]
export_docstring2md = "docstring2md.cli:run"
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[tool.pytest.ini_options]
minversion = "7.2"
addopts = [
"-v",
"--pycodestyle",
"--doctest-modules",
"--mypy",
"--pydocstyle",
"--pylint",
"--isort",
"--strict-markers"
]
xfail_strict = true
filterwarnings = [
"ignore:.*U.*mode is deprecated:DeprecationWarning",
"ignore::DeprecationWarning"]
[tool.mypy]
disallow_any_generics = true
disallow_untyped_defs = true
warn_redundant_casts = true
strict_equality = true
classDiagram
class DocString2MDOptions {
output
private_def
toc
todo
toml
uml
}
class EventMSG {
debug
error
info
warning
}
class MyFile {
exists
path
status
absolute() str
read() str
resolve() str
set_path(path: Optional[str]) MyFile
write(data: str) ExitStatus
}
class NodeVisitor {
generic_visit(node)
visit(node)
visit_Constant(node)
}
class ExitStatus {
name
}
class PytMod {
module
node_lst
pkg_main_docstring
ismodule() bool
read() None
}
class Enum {
name()
value()
}
class IntEnum {
}
class ReprEnum {
}
class Const {
name
}
class EventMSG {
debug : str
error : str
info : str
warning : str
}
class ExitStatus {
name
}
class LogMessages {
args
dump
elapse_time
file_not_found
io_err
logfile
new_class
new_func
new_module
node_link_analysis_beg
node_link_analysis_end
python
pytmod
pytmod_extract
pytmod_mod
pytmod_script
result
unknown_type_of_node
write_doc
}
class LoggingSetup {
default_format : str
default_level : str
encoding : str
file_format : str
logfile : str
simple_format : str
set_logfile(path: str) 'LoggingSetup'
}
class Tag {
name
}
class ModuleDef {
docstring : str
get_docstring() str
get_summary() str
}
class NodeDef {
definition : str
docstring : str
level : int
title : str
get_definition() str
get_docstring() str
get_summary() str
get_title() str
get_toc_elem() str
}
class NodeLink {
level : int
parent : Optional[ASTVisitedNode]
}
class ObjVisitor {
node_lst
parse(source: str) ast.AST
visit_ClassDef(node: ast.ClassDef) None
visit_FunctionDef(node: ast.FunctionDef) None
visit_Module(node: ast.Module) None
}
class ConvMD {
add_tag(begin_tag: str, end_tag: str) Callable[[F], F]
colorize_examples() Callable[[F], F]
dedent() Callable[[F], F]
html_escape() Callable[[F], F]
repl_beg_end(begin_regexp: str, end_regexp: str, begin_tag: str, end_tag: str) Callable[[F], F]
repl_str(old_string: str, new_string: str) Callable[[F], F]
}
class DocString2MD {
get_doc() str
import_module() ExitStatus
writedoc() ExitStatus
}
class DocString2MDOptions {
output
private_def : bool
toc : bool
todo
toml
uml
}
class MyFile {
exists : bool
path : Optional[Path]
status
absolute() str
read() str
resolve() str
set_path(path: Optional[str]) MyFile
write(data: str) ExitStatus
}
class PytMod {
module
node_lst
pkg_main_docstring
ismodule() bool
read() None
}
class NamedTuple {
}
ExitStatus --|> IntEnum
IntEnum --|> ReprEnum
ReprEnum --|> Enum
Const --|> Enum
EventMSG --|> NamedTuple
ExitStatus --|> IntEnum
LogMessages --|> NamedTuple
LoggingSetup --|> NamedTuple
Tag --|> Enum
ModuleDef --|> NamedTuple
NodeDef --|> NamedTuple
NodeLink --|> NamedTuple
ObjVisitor --|> NodeVisitor
DocString2MDOptions --|> NamedTuple
MyFile --|> NamedTuple
DocString2MDOptions --* DocString2MD : __options
DocString2MDOptions --* DocString2MD : __options
EventMSG --* LogMessages : logfile
EventMSG --* LogMessages : args
EventMSG --* LogMessages : python
EventMSG --* LogMessages : dump
EventMSG --* LogMessages : result
EventMSG --* LogMessages : elapse_time
EventMSG --* LogMessages : pytmod
EventMSG --* LogMessages : pytmod_mod
EventMSG --* LogMessages : pytmod_script
EventMSG --* LogMessages : pytmod_extract
EventMSG --* LogMessages : new_module
EventMSG --* LogMessages : new_class
EventMSG --* LogMessages : new_func
EventMSG --* LogMessages : node_link_analysis_beg
EventMSG --* LogMessages : node_link_analysis_end
EventMSG --* LogMessages : unknown_type_of_node
EventMSG --* LogMessages : io_err
EventMSG --* LogMessages : file_not_found
EventMSG --* LogMessages : write_doc
MyFile --* DocString2MDOptions : toml
MyFile --* DocString2MDOptions : uml
MyFile --* DocString2MDOptions : todo
MyFile --* DocString2MDOptions : output
ExitStatus --* MyFile : status
PytMod --* DocString2MD : __my_module
PytMod --* DocString2MD : __my_module
Const()
Tag()
LoggingSetup()
LoggingSetup.set_logfile()
EventMSG()
LogMessages()
ExitStatus()
logger_ast()
logger_ast.func_wrapper()
NodeLink()
ModuleDef()
ModuleDef.get_summary()
ModuleDef.get_docstring()
NodeDef()
NodeDef.get_summary()
NodeDef.get_toc_elem()
NodeDef.get_title()
NodeDef.get_definition()
NodeDef.get_docstring()
ObjVisitor()
ObjVisitor.init()
@Property ObjVisitor.node_lst()
ObjVisitor.parse()
ObjVisitor.__set_level()
ObjVisitor.__get_fullname()
ObjVisitor.__get_docstring()
ObjVisitor.__get_value_from_name()
ObjVisitor.__get_value_from_constant()
ObjVisitor.__get_value_from_num()
ObjVisitor.__get_value_from_str()
ObjVisitor.__get_value_from_attribute()
ObjVisitor.__get_value_from_unary()
ObjVisitor.__get_value_from_list()
ObjVisitor.__get_value_from_subscript()
ObjVisitor.__get_value_from_node()
ObjVisitor.visit_Module()
ObjVisitor.__mod_get_docstring()
ObjVisitor.visit_ClassDef()
ObjVisitor.__cla_get_title()
ObjVisitor.__cla_get_def()
ObjVisitor.__cla_get_inheritance()
ObjVisitor.__cla_get_docstring()
ObjVisitor.visit_FunctionDef()
ObjVisitor.__func_valid_name()
ObjVisitor.__func_get_title()
ObjVisitor.__func_get_def()
ObjVisitor.__func_get_args()
ObjVisitor.__func_get_args_annotation()
ObjVisitor.__func_get_args_default()
ObjVisitor.__func_get_decorator()
ObjVisitor.__func_get_decorator_args()
ObjVisitor.__func_get_return()
ObjVisitor.__func_get_docstring()
check_python()
get_argparser()
run()
ConvMD()
ConvMD.repl_str()
ConvMD.repl_str.tags_decorator()
ConvMD.repl_str.tags_decorator.func_wrapper()
ConvMD.repl_beg_end()
ConvMD.repl_beg_end.tags_decorator()
ConvMD.repl_beg_end.tags_decorator.func_wrapper()
ConvMD.add_tag()
ConvMD.add_tag.tags_decorator()
ConvMD.add_tag.tags_decorator.func_wrapper()
ConvMD.html_escape()
ConvMD.html_escape.tags_decorator()
ConvMD.html_escape.tags_decorator.func_wrapper()
ConvMD.colorize_examples()
ConvMD.colorize_examples.tags_decorator()
ConvMD.colorize_examples.tags_decorator.func_wrapper()
ConvMD.dedent()
ConvMD.dedent.tags_decorator()
ConvMD.dedent.tags_decorator.func_wrapper()
DocString2MDOptions()
DocString2MD()
DocString2MD.init()
DocString2MD.import_module()
DocString2MD.get_doc()
DocString2MD.writedoc()
MyFile()
MyFile.set_path()
MyFile.repr()
MyFile.read()
MyFile.write()
MyFile.resolve()
MyFile.absolute()
define_logfile()
PytMod()
PytMod.init()
@Property PytMod.module()
@Property PytMod.node_lst()
@Property PytMod.pkg_main_docstring()
PytMod.ismodule()
PytMod.read()
PytMod.__get_doc_from_module()
PytMod.__get_module_list()
PytMod.__get_doc_from_pkg()
class Const(Enum):
Define constants.
class Tag(Enum):
Define TAG used to build MD file.
class LoggingSetup(NamedTuple):
Define logging Parameters.
Examples:
>>> my_setup = LoggingSetup()
>>> my_setup.default_level
'INFO'
@classmethod
def LoggingSetup.set_logfile(cls, path: str) -> LoggingSetup:
Define the logfile. This function create the LoggingSetup object with the log file's path. Args: path: The file's path. Returns: MyFile
Examples:
>>> a = LoggingSetup.set_logfile('report.log')
>>> str(a)[0:32]
"LoggingSetup(logfile='report.log"
class EventMSG(NamedTuple):
Define Messages with different sev. Attributes: info (str): message for info ("" by default) warning (str): message for warning ("" by default) error (str): message for error ("" by default) debug (str): message for debug ("" by default)
Examples:
>>> logfile = EventMSG(info="Log file used: %s")
>>> logfile.info
'Log file used: %s'
class LogMessages(NamedTuple):
Set standard logging messages.
class ExitStatus(IntEnum):
Define Exit status.
def logger_ast(func: F) -> F:
Use it to decorate AST Navigator Class. This function decorate an AST function and use the logging to track the activity. Args: func: F (Callable[..., Any]) Returns: F (Callable[..., Any])
@wraps(func)
def logger_ast.func_wrapper(*args: Any, **kwargs: Any) -> Any:
None
class NodeLink(NamedTuple):
Use a NamedTuple to link a node with his parent Node. Attributes: level (int): level in the module parent (NodeType): parent
class ModuleDef(NamedTuple):
Define a module with this NamedTuple.
Examples:
>>> mydocstring = "Title:"
>>> module = ModuleDef(docstring=mydocstring)
>>> module
ModuleDef(docstring='Title:')
>>> module.get_summary()
'# Title:'
def ModuleDef.get_summary(self) -> str:
Get the module's summary. Returns: str: Summary
@ConvMD.dedent()
@ConvMD.repl_beg_end(Tag.BEG_STR, Tag.END_STRH, Tag.END_TITLE)
def ModuleDef.get_docstring(self) -> str:
Generate the module's Docstring with MD Tag. Returns: str: Docstring
class NodeDef(NamedTuple):
Define a node (class/function) with this NamedTuple. Attributes: title (str): short class/function definition definition (str): full class/function definition docstring (str): docstring level (int): level in the module
def NodeDef.get_summary(self) -> str:
Get the node's summary. Returns: str
def NodeDef.get_toc_elem(self) -> str:
Get the node's TOC entry. Returns: str
def NodeDef.get_title(self) -> str:
Get the node's title. Returns: str
@ConvMD.add_tag(Tag.BEG_PY, Tag.BEG_END_CO)
def NodeDef.get_definition(self) -> str:
Get the node's TOC entry. Returns: str
@ConvMD.repl_beg_end(Tag.BEG_STR, Tag.END_STRH, Tag.BEG_B, Tag.END_BH)
@ConvMD.colorize_examples()
@ConvMD.add_tag(Tag.CR, Tag.CR)
def NodeDef.get_docstring(self) -> str:
Get the node's Docstring with MD Tag. Returns: str: Docstring
class ObjVisitor(ast.NodeVisitor):
Define the AST NodeVisitor. This Class is an ast.NodeVisitor class and allow us to parse code tree. All methods are called according to node type. We define other private method in order to manage string format. We use decorator to keep a clean code without MD Tag. ObjVisitor(module_docstring=True|False) module_docstring: true => retrieve the module docstring This parameter is usefull to use the first docstring module in a package.
Examples:
>>> from docstring2md.file import MyFile
>>> import pathlib
>>> module = str(pathlib.Path(__file__).resolve())
>>> source = MyFile.set_path(module)
>>> # init
>>> doc = ObjVisitor(module_docstring=False)
>>> # provide source, generate the tree and use visit mechanism
>>> doc.visit(doc.parse(source.read()))
>>> result = doc.node_lst
>>> result[0].title
'logger_ast()'
>>> result[0].get_toc_elem()
'[logger_ast()](#logger_ast)<br />'
>>> result[0].definition
'def logger_ast(func: F) -> F:'
def ObjVisitor.__init__(self, module_docstring: bool = False, private_def: bool = False) -> None:
Init the AST analysis. Args: module_docstring (bool): get module docstring private_def (bool): get private functions
@property
def ObjVisitor.node_lst(self) -> NodeListType:
Get the node list.
@staticmethod
def ObjVisitor.parse(source: str) -> ast.AST:
Parse the source code and build the tree. Args: source (str): source code Returns: AST tree
@logger_ast
def ObjVisitor.__set_level(self, node: ASTVisitedNode, level: int = 0, parent: Optional[ASTVisitedNode] = None) -> None:
None
@logger_ast
def ObjVisitor.__get_fullname(self, node: ASTClassFunc) -> str:
None
@staticmethod
@logger_ast
def ObjVisitor.__get_docstring(node: ASTVisitedNode) -> str:
None
@staticmethod
def ObjVisitor.__get_value_from_name(node: ast.Name) -> str:
None
@staticmethod
def ObjVisitor.__get_value_from_constant(node: Union[ast.Constant, ast.NameConstant]) -> str:
None
@staticmethod
def ObjVisitor.__get_value_from_num(node: ast.Num) -> str:
None
@staticmethod
def ObjVisitor.__get_value_from_str(node: ast.Str) -> str:
None
def ObjVisitor.__get_value_from_attribute(self, node: ast.Attribute) -> str:
None
@staticmethod
def ObjVisitor.__get_value_from_unary(node: ast.UnaryOp) -> str:
None
def ObjVisitor.__get_value_from_list(self, node: ast.List) -> str:
None
def ObjVisitor.__get_value_from_subscript(self, node: ast.Subscript) -> str:
None
@logger_ast
def ObjVisitor.__get_value_from_node(self, node: Union[ast.Name, ast.Constant, ast.NameConstant, ast.Num, ast.Str, ast.Attribute, ast.Subscript, ast.UnaryOp, ast.List]) -> str:
None
@logger_ast
def ObjVisitor.visit_Module(self, node: ast.Module) -> None:
Visit a module. This function is automatically called by AST mechanism when the current node is a module and add a ModuleDef obj in self.node_lst. Args: node (ast.AST): current node Returns: None
def ObjVisitor.__mod_get_docstring(self, node: ast.Module) -> str:
None
@logger_ast
def ObjVisitor.visit_ClassDef(self, node: ast.ClassDef) -> None:
Visit a Class. This function is automatically called by AST mechanism when the current node is a class and add a NodeDef obj in self.node_lst. Args: node (ast.ClassDef): current node Returns: None
@logger_ast
def ObjVisitor.__cla_get_title(self, node: ast.ClassDef) -> str:
None
@logger_ast
def ObjVisitor.__cla_get_def(self, node: ast.ClassDef) -> str:
None
@logger_ast
def ObjVisitor.__cla_get_inheritance(self, node: ast.ClassDef) -> str:
None
@logger_ast
def ObjVisitor.__cla_get_docstring(self, node: ast.ClassDef) -> str:
None
@logger_ast
def ObjVisitor.visit_FunctionDef(self, node: ast.FunctionDef) -> None:
Visit Function. This function is automatically called by AST mechanism when the current node is a function and add a NodeDef obj in self.node_lst. Args: node (ast.FunctionDef): current node Returns: None
@logger_ast
def ObjVisitor.__func_valid_name(self, node: ast.FunctionDef) -> bool:
None
@logger_ast
def ObjVisitor.__func_get_title(self, node: ast.FunctionDef) -> str:
None
@logger_ast
def ObjVisitor.__func_get_def(self, node: ast.FunctionDef) -> str:
None
@logger_ast
def ObjVisitor.__func_get_args(self, node: ast.FunctionDef) -> str:
None
@logger_ast
def ObjVisitor.__func_get_args_annotation(self, node: ast.arg) -> str:
None
@logger_ast
def ObjVisitor.__func_get_args_default(self, node: ast.FunctionDef) -> list[str]:
None
@logger_ast
def ObjVisitor.__func_get_decorator(self, node: ast.FunctionDef) -> list[str]:
None
@logger_ast
def ObjVisitor.__func_get_decorator_args(self, node: ast.Call) -> str:
None
@logger_ast
def ObjVisitor.__func_get_return(self, node: ast.FunctionDef) -> str:
None
@logger_ast
def ObjVisitor.__func_get_docstring(self, node: ast.FunctionDef) -> str:
None
def check_python() -> bool:
Check python version. This function check Python version, log the result and return a status True/False. Returns: True if successful, False otherwise.
def get_argparser() -> argparse.ArgumentParser:
Define the argument parser. This function define the argument parser and return it. Returns: ArgumentParser
Examples:
>>> a = get_argparser()
>>> type(a)
<class 'argparse.ArgumentParser'>
def run() -> ExitStatus:
Manage options and analyse modules. Called by the CLI runner, manage options to analyse the module. It exits 0 on success, and >0 if an error occurs. Returns: int: status return EX_OK: 0 -> success return EX_CONFIG: 78 -> config error return EX_OSFILE: 72 -> Module not found return EX_CANTCREAT: 73 -> can't create the file return EX_IOERR: 74 -> write error
class ConvMD():
Prepare MD string.
@staticmethod
def ConvMD.repl_str(old_string: str, new_string: str) -> Callable[[F], F]:
Search & replace a string by another string. Args: old_string (str): string to search new_string (str): new string Returns: Callable[[F], F]
Examples:
>>> from docstring2md.convmd import ConvMD
>>> @ConvMD.repl_str("docstring", "is ok !")
... def return_test() -> str:
... return "my function docstring"
>>> print(return_test())
my function is ok !
def ConvMD.repl_str.tags_decorator(func: F) -> F:
Decorate.
@wraps(func)
def ConvMD.repl_str.tags_decorator.func_wrapper(*args: Any, **kwargs: Any) -> Any:
Wrapp.
@staticmethod
def ConvMD.repl_beg_end(begin_regexp: str, end_regexp: str, begin_tag: str, end_tag: str) -> Callable[[F], F]:
Replace the beginning and the end. Args: begin_regexp (str) end_regexp (str) begin_tag (str) end_tag (str) Returns: decorated function
Examples:
>>> # All new lines must be provided with a specific tag
>>> # > 'Line' <br />
>>> from docstring2md.convmd import ConvMD
>>> @ConvMD.repl_beg_end("^", "$", ">", "<br />")
... def return_test() -> str:
... return "my function docstring"
>>> print(return_test())
>my function docstring<br />
def ConvMD.repl_beg_end.tags_decorator(func: F) -> F:
Decorate.
@wraps(func)
def ConvMD.repl_beg_end.tags_decorator.func_wrapper(*args: Any, **kwargs: Any) -> Any:
Wrapp.
@staticmethod
def ConvMD.add_tag(begin_tag: str, end_tag: str) -> Callable[[F], F]:
Add a tag in a string. Args: begin_tag (str) end_tag (str) Returns: decorated function
Examples:
>>> # ('__', '__') => __ TXT __
>>> from docstring2md.convmd import ConvMD
>>> @ConvMD.add_tag("__", "__")
... def return_test() -> str:
... return "test"
>>> print(return_test())
__test__
def ConvMD.add_tag.tags_decorator(func: F) -> F:
Decorate.
@wraps(func)
def ConvMD.add_tag.tags_decorator.func_wrapper(*args: Any, **kwargs: Any) -> Any:
Wrapp.
@staticmethod
def ConvMD.html_escape() -> Callable[[F], F]:
Escape the HTML Tag. Returns: decorated function
def ConvMD.html_escape.tags_decorator(func: F) -> F:
Decorate.
@wraps(func)
def ConvMD.html_escape.tags_decorator.func_wrapper(*args: Any, **kwargs: Any) -> Any:
Wrapp.
@staticmethod
def ConvMD.colorize_examples() -> Callable[[F], F]:
Colorize python example. Returns: decorated function
def ConvMD.colorize_examples.tags_decorator(func: F) -> F:
Decorate.
@wraps(func)
def ConvMD.colorize_examples.tags_decorator.func_wrapper(*args: Any, **kwargs: Any) -> Any:
Wrapp.
@staticmethod
def ConvMD.dedent() -> Callable[[F], F]:
Deindent text. Returns: decorated function
def ConvMD.dedent.tags_decorator(func: F) -> F:
Decorate.
@wraps(func)
def ConvMD.dedent.tags_decorator.func_wrapper(*args: Any, **kwargs: Any) -> Any:
Wrapp.
class DocString2MDOptions(NamedTuple):
Define the DocString2MD options. Attributes: toml (MyFile): MyFile.set_path(/path/to/toml/file.toml) uml (MyFile): MyFile.set_path(/path/to/mermaid/file.mmd) todo (MyFile): MyFile.set_path(/path/to/todo/file.md) output (MyFile): MyFile.set_path(/path/to/output/file) (README.md) toc (bool): True -> get a table of content private_def (bool): True -> get private function
class DocString2MD():
Export Google docstring to MD File.
Examples:
>>> options: DocString2MDOptions = DocString2MDOptions(
... toml=MyFile.set_path(None),
... uml=MyFile.set_path(None),
... output=MyFile.set_path(None),
... todo=MyFile.set_path(None),
... toc=False,
... private_def=False)
>>> doc = DocString2MD("oups", options)
>>> doc.import_module()
<ExitStatus.EX_OSFILE: 72>
>>> doc = DocString2MD("docstring2md", options)
>>> doc.import_module()
<ExitStatus.EX_OK: 0>
>>> result = doc.get_doc()
>>> result = result.split("\n")
>>> result[0]
'# docstring2md:'
def DocString2MD.__init__(self, module_name: str, options: DocString2MDOptions) -> None:
Init the obj. This function define default attributes. Args: module_name (str): /path/to/module/ or
def DocString2MD.import_module(self) -> ExitStatus:
Import the module. It exits 0 on success, and >0 if an error occurs. Returns: int: status return EX_OK: 0 -> success return EX_OSFILE: 72 -> Module not found
def DocString2MD.get_doc(self) -> str:
Return the documentation. Returns: str: doc
def DocString2MD.writedoc(self) -> ExitStatus:
Write the doc - screen or files. It exits 0 on success, and >0 if an error occurs. args: None Returns: int: status return EX_OK: 0 -> success return EX_CANTCREAT: 73 -> can't create the file return EX_IOERR: 74 -> write error
class MyFile(NamedTuple):
Describe a file with a NamedTuple. @classmethod is used to init the objects correctly. Notes: The objective is to define a file with only one NamedTuple. The NamedTuple will be created by the set_path function to define the path.
Examples:
>>> data_file = MyFile.set_path("lorem")
>>> data_file.status
<ExitStatus.EX_OSFILE: 72>
>>> fstab = MyFile.set_path("/etc/fstab")
>>> fstab.path.stem
'fstab'
>>> fstab
MyFile(path=PosixPath(...), exists=False, status=72)
>>> fstab.absolute()
'/etc/fstab'
>>> # pathlib to run the test everywhere
>>> import pathlib
>>> path = str(pathlib.Path(__file__).resolve().parent) + "/"
>>> lic = MyFile.set_path(f"{path}../../LICENSE")
>>> lic.path.stem
'LICENSE'
>>> lic.exists
True
>>> result = lic.read()
>>> result = result.split("\n")
>>> result[0]
' GNU GENERAL PUBLIC LICENSE'
@classmethod
def MyFile.set_path(cls, path: Optional[str]) -> MyFile:
Set path and create the object. if path is None -> status = ExitStatus.EX_CANTCREAT if path exists -> status = ExitStatus.EX_OK If path does not exist -> status = ExitStatus.EX_OSFILE Args: path: The file's path. Returns: MyFile or None
def MyFile.__repr__(self) -> str:
Get the repr.
def MyFile.read(self) -> str:
Read the file. Returns: str: Text if successful else ""
def MyFile.write(self, data: str) -> ExitStatus:
Write data in the file. Returns: int: status return EX_OK: 0 -> success return EX_CANTCREAT: 73 -> can't create the file return EX_IOERR: 74 -> write error
def MyFile.resolve(self) -> str:
Get the resolved path. Returns: str
def MyFile.absolute(self) -> str:
Get the absolute path. Returns: str
def define_logfile(path: str) -> None:
Define the logfile. This function set up the log to push log events in the report file. Args: path:str /path/to/logfile Returns: None
class PytMod():
Manage module analysis. Object in order to extract Python functions, class....
Examples:
>>> mod = PytMod("oups...")
>>> mod.read()
Traceback (most recent call last):
...
ModuleNotFoundError: No module named 'oups'
>>> mod = PytMod("json")
>>> mod.read()
>>> print(mod.node_lst[0].definition)
def dump(obj, fp, **kw):
>>> mod = PytMod(__file__)
>>> mod.read()
>>> print(mod.node_lst[0].docstring)
Docstring2md: mod.
...
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>>> mod = PytMod('docstring2md')
>>> mod.read()
>>> print(mod.node_lst[0].definition)
class Const(Enum):
def PytMod.__init__(self, module_name: str, private_def: bool = False) -> None:
Init the object. Args: module_name (str): module name private_def (bool): extract private def
@property
def PytMod.module(self) -> str:
Get the module name. module name (str): modulename /path/to/the/mod ./path/to/the/mod
@property
def PytMod.node_lst(self) -> NodeListType:
Get the docstrings. Returns: str: Docstring
@property
def PytMod.pkg_main_docstring(self) -> NodeListType:
Get the main docstring. Returns: str: Main docstring
def PytMod.ismodule(self) -> bool:
Check the module. If module name is a module file => True Else if the module name is a package => False Returns: bool: It exits True on success, and False otherwise.
def PytMod.read(self) -> None:
Read the module. Reads all files and store the result. Returns: None
def PytMod.__get_doc_from_module(self, module: str, module_docstring: bool = False) -> NodeListType:
None
def PytMod.__get_module_list(self, package: str) -> list[str]:
None
def PytMod.__get_doc_from_pkg(self, package: str) -> NodeListType:
None