thogar-computer/docstring-to-markdown

Export Google DocString to Markdown

★ 0Forks 0GitHub ↗Compare

README

docstring2md

Description:

This package Export Google DocString to Markdown from Python module.

Why ?:

We can find a lot of tools to generate docs from code but we want something quick and easy to setup. This tool can be used on python file or python package.

Setup:

$ git clone https://github.com/francois-le-ko4la/docstring-to-markdown.git
$ cd docstring-to-markdown
$ make install

Test:

This module has been tested and validated on Ubuntu 17.10/18.04.

$ make test

Use:

Use the script:

$ export_docstring2md.py -h
usage: main.py [-h] [-v] -i INPUT [-o FILE] [-t FILE] [-r FILE] [-uml FILE]
               [--toc | --no-toc] [--private-def | --no-private-def]

This script is provided by docstring2md package.
It exports google docstrings from python module to a Markdown file in order to
generate README.

optional arguments:
  --toc                 Enable the table of contents (DEFAULT)
  --no-toc              Disable the table of contents
  --private-def         Show private objects
  --no-private-def      Don't show private objects

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit

required arguments:
  -i INPUT, --input INPUT
                        Input file name

optional arguments:
  -o FILE, --output FILE
                        Output file
  -t FILE, --runtime FILE
                        Runtime file
  -r FILE, --requirements FILE
                        requirements.txt file
  -uml FILE, --uml-diagramm FILE
                        UML file (PNG)

Enjoy...

Project structure

.
├── bin
│   └── export_docstring2md.py
├── docstring2md
│   ├── __about__.py
│   ├── ast_engine.py
│   ├── __config__.py
│   ├── convmd.py
│   ├── doc2md.py
│   ├── file.py
│   ├── __init__.py
│   ├── main.py
│   └── mod.py
├── last_check.log
├── LICENSE
├── Makefile
├── MANIFEST.in
├── pictures
│   ├── classes_docstring2md.png
│   └── packages_docstring2md.png
├── README.md
├── requirements.txt
├── runtime.txt
├── setup.cfg
├── setup.py
└── tests
    ├── test_docstring2md.py
    ├── test_doctest.py
    └── test_pycodestyle.py

Todo:

  • 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

License

This package is distributed under the GPLv3 license

Runtime

python-3.6.x

Requirements

setuptools>=36.2.7
pycodestyle>=2.3.1

UML Diagram

alt text

Objects

ObjVisitor()
ObjVisitor.get_tree()
ObjVisitor.visit_Module()
ObjVisitor.visit_ClassDef()
ObjVisitor.visit_FunctionDef()
ConvMD()
ConvMD.repl_str()
ConvMD.repl_str.tags_decorator()
ConvMD.repl_beg_end()
ConvMD.repl_beg_end.tags_decorator()
ConvMD.add_tag()
ConvMD.add_tag.tags_decorator()
DocString2MD()
DocString2MD.import_module()
DocString2MD.get_doc()
PytFile()
@Property PytFile.filename
PytFile.exists()
PytFile.read()
PytLog()
PytLog.debug()
PytLog.warning()
PytLog.info()
PytLog.error()
PytLog.set_level()
PytLog.set_debug()
run()
PytMod()
@Property PytMod.module
@Property PytMod.docstring
@Property PytMod.pkg_main_docstring
@Property PytMod.toc
PytMod.ismodule()
PytMod.read()

ObjVisitor()

class ObjVisitor():
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.

Use:
    >>> from docstring2md.file import PytFile
    >>> import pathlib
    >>> module = str(pathlib.Path(__file__).resolve())
    >>> source = PytFile(module)
    >>> # init
    >>> doc = ObjVisitor(module_docstring=False)
    >>> # provide source, generate the tree and use visit mechanisme
    >>> doc.visit(doc.get_tree(source.read()))
    >>> result = doc.output
    >>> result = result.split("\n")
    >>> result[0]
    '#### ObjVisitor()'
    >>> result = doc.toc
    >>> result = result.split("\n")
    >>> result[0]
    '[ObjVisitor()](#objvisitor)<br />'
ObjVisitor.get_tree()
def ObjVisitor.get_tree(self, source):

This function allow us to parse the source and build the
tree.
We put this function to group all AST function in this
module.

Args:
                source (str): source code

Returns:
                AST tree

ObjVisitor.visit_Module()
def ObjVisitor.visit_Module(self, node):

This function is automatically called by AST mechanisme
when the current node is a module.
We update self.output.

Args:
                node (ast): current node

Returns:
                None.

ObjVisitor.visit_ClassDef()
def ObjVisitor.visit_ClassDef(self, node):

This function is automatically called by AST mechanisme
when the current node is a class.
We update self.output.

Args:
                node (ast): current node

Returns:
                None.

ObjVisitor.visit_FunctionDef()
def ObjVisitor.visit_FunctionDef(self, node):

This function is automatically called by AST mechanisme
when the current node is a function.
We update self.output.

Args:
                node (ast): current node

Returns:
                None.

ConvMD()

class ConvMD(object):
Prepare MD string
ConvMD.repl_str()
def ConvMD.repl_str(old_string, new_string):

Decorator - search & replace a string by another string
Example : replace space by a HTML tag.

Args:
                old_string (str): string to search
                new_string (str): new string

Returns:
                decorated function

ConvMD.repl_str.tags_decorator()
def ConvMD.repl_str.tags_decorator(func):

decorator

ConvMD.repl_beg_end()
def ConvMD.repl_beg_end(begin_regexp, end_regexp, begin_tag, end_tag):

Decorator - replace the beggining and the end

Example:
                All new lines must be provided with a specific tag
                > 'Line'


Args:
                begin_regexp (str)
                end_regexp (str)
                begin_tag (str)
                end_tag (str)

Returns:
                decorated function

ConvMD.repl_beg_end.tags_decorator()
def ConvMD.repl_beg_end.tags_decorator(func):

decorator

ConvMD.add_tag()
def ConvMD.add_tag(begin_tag, end_tag):

Decorator - add a tag

Example:
                ('__', '__') => __ TXT __

Args:
                beg_tag (str)
                end_tag (str)

Returns:
                decorated function

ConvMD.add_tag.tags_decorator()
def ConvMD.add_tag.tags_decorator(func):

decorator

DocString2MD()

class DocString2MD(object):
Class DocString2MD : export Google docstring to MD File.

Use:
    >>> doc = DocString2MD("oups")
    >>> doc.import_module()
    False
    >>> doc = DocString2MD("docstring2md")
    >>> doc.import_module()
    True
    >>> result = doc.get_doc()
    >>> result = result.split("\n")
    >>> print(result[0])
    # docstring2md
DocString2MD.import_module()
def DocString2MD.import_module(self):

import all infos

DocString2MD.get_doc()
def DocString2MD.get_doc(self):

Extract the doc
Returns self.__output or self.__writedoc

Args:
                None

Returns:
                str: self.__output

PytFile()

class PytFile(object):
>>> data_file = PytFile("lorem")
Traceback (most recent call last):
...
OSError: File not found !
>>> data_file = PytFile(None)
>>> data_file.exists()
False
>>> fstab = PytFile("/etc/fstab")
>>> fstab.filename.stem
'fstab'
>>> fstab
/etc/fstab
>>> # pathlib to run the test everywhere
>>> import pathlib
>>> path = str(pathlib.Path(__file__).resolve().parent) + "/"
>>> license = PytFile(path + "../LICENSE")
>>> license.filename.stem
'LICENSE'
>>> license.exists()
True
>>> result = license.read()
>>> result = result.split("\n")
>>> result[0]
'                    GNU GENERAL PUBLIC LICENSE'
@Property PytFile.filename
@property
def PytFile.filename(self):

path to the module

PytFile.exists()
def PytFile.exists(self):

file exists

PytFile.read()
def PytFile.read(self):

read the text

PytLog()

class PytLog(object):
None
PytLog.debug()
def PytLog.debug(self, msg):

                               

PytLog.warning()
def PytLog.warning(self, msg):

                               

PytLog.info()
def PytLog.info(self, msg):

                               

PytLog.error()
def PytLog.error(self, msg):

                               

PytLog.set_level()
def PytLog.set_level(self, sev):

None

PytLog.set_debug()
def PytLog.set_debug(self):

None

run()

def run():

This function is called by the CLI runner and manage options.

Args:
                None.

Returns:
                print screen|file

PytMod()

class PytMod(object):
Object in order to extract Python functions, class....

Use:
    >>> mod = PytMod("oups...")
    >>> mod.read()
    Traceback (most recent call last):
    ...
    ModuleNotFoundError: No module named 'oups'
    >>> mod = PytMod("json")
    >>> mod.read()
    >>> # print(mod.pkg_main_docstring)
    >>> # print(mod.docstring)
@Property PytMod.module
@property
def PytMod.module(self):

module name (str):
                modulename
                /path/to/the/mod
                ./path/to/the/mod

@Property PytMod.docstring
@property
def PytMod.docstring(self):

returns all the docstrings.

@Property PytMod.pkg_main_docstring
@property
def PytMod.pkg_main_docstring(self):

PKG only.
Returns the main docstring.

@Property PytMod.toc
@property
def PytMod.toc(self):

Returns the TOC

PytMod.ismodule()
def PytMod.ismodule(self):

If module name is a module file => True
Else if the module name is a package => False

PytMod.read()
def PytMod.read(self):

Reads all files and store the result.

Contributors

francois-le-ko4la

Issues