Top

pyMez.Code.Utils.HelpUtils module

The HelpUtils module has tools for interacting with help files. It uses pdoc for auto-generated help and nbcovert to change ipynb based examples to html. There is an error when certain extensions are activated in jupyter for nbconvert that is solved by changing the imports in three modules see (https://github.com/jupyter/nbconvert/pull/370/commits/f01e44daca69f349bfdcf24aa397aa8edc7b2b53)

Help

pyMez.Code.Utils

Documentation Home | API Documentation Home | Examples Home | Index

#-----------------------------------------------------------------------------
# Name:        HelpUtils
# Purpose:    Provides general utilities for help based functions
# Author:      Aric Sanders
# Created:     3/11/2016
# License:     MIT License
#-----------------------------------------------------------------------------
""" The HelpUtils module has tools for interacting with help files. It uses pdoc for
  auto-generated help and nbcovert to change ipynb based examples to html. There is an
  error when certain extensions are activated in jupyter for nbconvert that is solved by
  changing the imports in three modules
  see (https://github.com/jupyter/nbconvert/pull/370/commits/f01e44daca69f349bfdcf24aa397aa8edc7b2b53)

  Help
---------------
<a href="./index.html">`pyMez.Code.Utils`</a>
<div>
<a href="../../../pyMez_Documentation.html">Documentation Home</a> |
<a href="../../index.html">API Documentation Home</a> |
<a href="../../../Examples/html/Examples_Home.html">Examples Home</a> |
<a href="../../../Reference_Index.html">Index</a>
</div>"""
#-----------------------------------------------------------------------------
# Standard Imports
import os
import inspect
import sys
import shutil
#-----------------------------------------------------------------------------
# Third Party Imports
sys.path.append(os.path.join(os.path.dirname( __file__ ), '..','..'))
try:
    import pdoc
except:
    print("Could not import pdoc, add it to the python path or install it. pip install pdoc")
try:
    from Code.Utils.Alias import *
    METHOD_ALIASES=1
except:
    print("The module pyMez.Code.Utils.Alias was not found")
    METHOD_ALIASES=0
    pass
try:
    from Code.Utils.Names import auto_name,change_extension
    DEFAULT_FILE_NAME=None
except:
    print("The function auto_name in pyMez.Code.Utils.Names was not found")
    print("Setting Default file name to New_Data_Table.txt")
    DEFAULT_FILE_NAME='New_Data_Table.txt'
    pass
#-----------------------------------------------------------------------------
# Module Constants
TESTS_DIRECTORY=os.path.join(os.path.dirname(os.path.realpath(__file__)),'Tests')
PYMEASURE_ROOT=os.path.join(os.path.dirname(os.path.realpath(__file__)),'..','..')
DOCUMENTATION_DIRECTORY=os.path.join(PYMEASURE_ROOT,"Documentation")
DOCUMENTATION_INDEX=os.path.join(DOCUMENTATION_DIRECTORY,"pyMez_Documentation.html")
EXAMPLES_INDEX=os.path.join(DOCUMENTATION_DIRECTORY,"Examples/html","Examples_Home.html")
API_INDEX=os.path.join(DOCUMENTATION_DIRECTORY,"pyMez","index.html")
REFERENCE_INDEX=os.path.join(DOCUMENTATION_DIRECTORY,"Reference_Index.html")

INDEX_HTML_PREFIX="""<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
    <style>
          body {
    background: #fff;
    font-family: "Source Sans Pro", "Helvetica Neueue", Helvetica, sans;
    font-weight: 300;
    font-size: 16px;
    line-height: 1.6em;
    background: #fff;
    color: #000;
  }
  li {font-family: "Ubuntu Mono", "Cousine", "DejaVu Sans Mono", monospace;}
  h1 {
    font-size: 2.5em;
    line-height: 1.1em;
    margin: 0 0 .50em 0;
    font-weight: 300;

}
    </style>
</head>
<body>
        <table style='border-style:none;'>
        <tr style="border-style:none;">
        <td style="border-style:none;">
        <a href="./pyMez_Documentation.html"><button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Documentation Home</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href="./pyMez/index.html"><button type="button" class='btn btn-primary'>
        <span style="font-size:20px">API Documentation</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href="./Examples/html/Examples_Home.html">
        <button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Examples</span></button></a>
        </td>
        </tr>
        </table>
<hr/>
<h1 class="h1">Index of All Functions and Classes in pyMez</h1>
<hr/>
"""
INDEX_HTML_POSTFIX="""</body></html>"""
IMPORT_HMTL_PREFIX="""<html>
<head>

    <style>
          body {
    background: #fff;
    font-family: "Source Sans Pro", "Helvetica Neueue", Helvetica, sans;
    font-weight: 300;
    font-size: 16px;
    line-height: 1.6em;
    background: #fff;
    color: #000;
  }
  li {font-family: "Ubuntu Mono", "Cousine", "DejaVu Sans Mono", monospace;}
  h1 {
    font-size: 2.5em;
    line-height: 1.1em;
    margin: 0 0 .50em 0;
    font-weight: 300;

}
    </style>
</head>
<body>
<h1>All Imports</h1>
<ol>"""
#-----------------------------------------------------------------------------
# Module Functions
def return_help(object):
    """Returns an html help page autogenerated by the pdoc module for any live object"""
    module=inspect.getmodule(object).__name__
    html_text=pdoc.html(module_name=module,allsubmodules=True)
    return html_text

def create_help_page(module,output_format='html',file_path=None):
    """Uses the pdoc module to create a html autogenerated help file for the specified module.
    If file_path is not specified it auto names it and saves it in the current working directory."""
    if re.search('htm',output_format,re.IGNORECASE):
        html_text=pdoc.html(module_name=module,allsubmodules=True)
        if file_path is None:
            file_path=auto_name(module.replace('.','_'),'Help',directory=None,extension='html')
        out_file=open(file_path,'w')
        out_file.write(html_text)
        out_file.close()


def create_examples_page(ipynb_path):
    """Given a jupyter notebook uses nbconvert to output an html file at the specified path."""
    os.system("jupyter nbconvert --to html %s"%ipynb_path)



#-----------------------------------------------------------------------------
# Module Classes

#-----------------------------------------------------------------------------
# Module Scripts
def test_create_help_page(module='pyMez.Code.DataHandlers.GeneralModels'):
    "Tests the create help page function, it seems pretty slow"
    os.chdir(TESTS_DIRECTORY)
    create_help_page(module)
def test_create_examples_page(ipynb_path='Development_Stack_Installation_Example_20160130_01.ipynb'):
    """Tests the create_examples_page function, really nb convert on the command line"""
    os.chdir(TESTS_DIRECTORY)
    create_examples_page(ipynb_path)

def autogenerate_api_documentation_script():
    """Autogenerates the api help files. It requires that pdoc is installed and that the pdoc script is in
    the Documentation folder under pyMez. If the folder exists it first deletes the folder and then creates a
     new one. The folder permissions must be set properly to allow the script to delete the old API help.
     Uses the mako templates found in Documentation/templates"""

    os.chdir(DOCUMENTATION_DIRECTORY)
    template_directory=os.path.join(DOCUMENTATION_DIRECTORY,"templates")
    try:
        shutil.rmtree(os.path.join(DOCUMENTATION_DIRECTORY,"pyMez"))
    except:
        print("Could not delete existing API documentation")
        pass
    os.system("python pdoc --html --overwrite --template-dir {0} pyMez".format(template_directory))

def create_index_html_script(top_directory,group=True):
    """create_index returns an html page with links to the autogenerated help page for all
    functions and classes in .py files in the directory structure. Uses the module constants INDEX_HTML_PREFIX
    and INDEX_HTML_POSTFIX to wrap the resulting html elements. Added the ability to group the functions and
    classes by sub package. """
    subpackages=["FrontEnds","InstrumentControl","Analysis","DataHandlers","Utils"]
    subpackage_descriptions=["""Function and classes for user interaction. pyMez targets three methods of
    user interaction, scripting (for example in spyder or a jupyter notebook), desktop gui (using the wx package),
    and web applications (using the django web framework).""",
                             """Functions and classes used in controlling instruments. Experiment classes integrate
                             instruments and data manipulation. Instruments are a set of control classes that
                              have static metadata, dynamic metadata (state saving and loading) and data formatting.""",
                             """Functions and classes used in Analyzing data or processes.""",
                             """Functions in classes used in data storage and format manipulation.""",
                             """Functions and classes that are base utilities for the pyMez package."""]
    classes_and_functions=[]
    class_pattern=re.compile('class (?P<name>\w+)\(')
    function_pattern=re.compile('def (?P<name>\w+)\(')
    links_dictionary={}
    group_links_dictionary={}

    link_template="<li><a href='{0}'>{1}</a></li>\n"
    for directory, dirnames, file_names in os.walk(top_directory):
        clean_directory=directory.split('..\\')[-1].replace("\\","/")
        for file_name in file_names:
            extension=file_name.split(".")[-1]
            if re.match('py',extension,re.IGNORECASE):
                try:
                    in_file=open(os.path.join(directory,file_name),'r',encoding="latin1")
                except:
                    in_file = open(os.path.join(directory, file_name), 'r') #python 2.7 compatibility
                for line in in_file:
                    if re.search(class_pattern,line):
                        reference_file="pyMez/"+change_extension(os.path.join(clean_directory,file_name),'m')+".html"
                        reference_id = reference_file.split(".")[0]
                        reference_file="./"+reference_file.replace("\\","/")
                        name=re.search(class_pattern,line).groupdict()['name']
                        reference_id = reference_id.replace("\\", "/")
                        reference_id=reference_id.replace("/", ".")+"."+name
                        reference=reference_file+"#"+reference_id
                        classes_and_functions.append(name)
                        links_dictionary[name]=link_template.format(reference,
                                                          name)
                    elif re.match(function_pattern,line):
                        reference_file="pyMez/"+change_extension(os.path.join(clean_directory,file_name),'m')+".html"
                        reference_id = reference_file.split(".")[0]
                        reference_file="./"+reference_file.replace("\\","/")
                        name=re.search(function_pattern,line).groupdict()['name']
                        classes_and_functions.append(name)
                        reference_id = reference_id.replace("\\", "/")
                        reference_id=reference_id.replace("/", ".")+"."+name
                        reference=reference_file+"#"+reference_id
                        links_dictionary[name]=link_template.format(reference,
                                                          name)

    #print("{0} is {1}".format('classes_and_functions',classes_and_functions))
    #print("{0} is {1}".format('links_string',links_string))
    # now arrange all in alphabetical order
    sorted_keys=sorted(list(links_dictionary.keys()),key=str.lower)
    links_string=""
    for key in sorted_keys:
        links_string=links_string+links_dictionary[key]
    links_string = INDEX_HTML_PREFIX +"<ol>" +links_string + "</ol>"+INDEX_HTML_POSTFIX

    # if group is true group the links and add a group title
    if group:
        links_string=""
        for subpackage_index,subpackage in enumerate(subpackages):
            links_string=links_string+"<h2>{0}</h2><p>{1}</p>".format(subpackage,
                                                                      subpackage_descriptions[subpackage_index])+"<ol>"
            group_links_dictionary[subpackage]={}
            group_keys=[]
            for key in sorted_keys:
                if re.search(subpackage,links_dictionary[key],re.IGNORECASE):
                    group_links_dictionary[subpackage][key]=links_dictionary[key]
                    group_keys.append(key)
            group_keys=sorted(group_keys,key=str.lower)
            for key in group_keys:
                links_string=links_string+links_dictionary[key]
            links_string=links_string+"</ol>"
        links_string=INDEX_HTML_PREFIX  + links_string  + INDEX_HTML_POSTFIX

    out_file=open(os.path.join(DOCUMENTATION_DIRECTORY,"Reference_Index.html"),"w")
    out_file.write(links_string)
    out_file.close()

def create_imports_html_script(top_directory,output_directory=None):
    """Reads all .py files under top directory and creates an html page that
    contains all of the imports and the file that imports them."""
    if output_directory is None:
        output_directory=top_directory
    imports=[]
    import_pattern_1=re.compile('import (?P<name>[\w|\.]+\n)')
    import_pattern_2=re.compile('from (?P<name>\[w|\.]+) import \w+\n')
    for directory, dirnames, file_names in os.walk(top_directory):
        clean_directory=directory.split('..\\')[-1].replace("\\","/")
        for file_name in file_names:
            extension=file_name.split(".")[-1]
            if re.match('py',extension,re.IGNORECASE):
                in_file=open(os.path.join(directory,file_name),'r')
                for line in in_file:
                    if re.search(import_pattern_1,line) and not re.match(import_pattern_2,line):
                        name=re.search(import_pattern_1,line).groupdict()['name']
                        imports.append("{0} in {1}".format(name,file_name))
                    elif re.match(import_pattern_2,line):
                        name=re.search(import_pattern_2,line).groupdict()['name']
                        imports.append("{0} in {1}".format(name, file_name))
    unique_imports=sorted(list(set(imports)))
    html_string=""
    for import_name in unique_imports:
        html_string=html_string+"<li>{0}</li>".format(import_name)
    html_string=IMPORT_HMTL_PREFIX+html_string+INDEX_HTML_POSTFIX
    out_file=open(os.path.join(output_directory,"pyMez_Imports.html"),"w")
    out_file.write(html_string)
    out_file.close()


def create_modules_html_script(top_directory,output_directory=None,output_name="pyMez_Modules.html"):
    """Creates an html page with all python modules under top_directory"""
    if output_directory is None:
        output_directory=top_directory
    modules=[]
    for directory, dirnames, file_names in os.walk(top_directory):
        for file_name in file_names:
            extension=file_name.split(".")[-1]
            if re.match('py(?!c)',extension,re.IGNORECASE):
                modules.append(file_name)

    html_string=""
    for module_name in modules:
        html_string=html_string+"<li>{0}</li>".format(module_name)
    html_string=IMPORT_HMTL_PREFIX.replace("All Imports","All Modules")+html_string+INDEX_HTML_POSTFIX
    out_file=open(os.path.join(output_directory,output_name),"w")
    out_file.write(html_string)
    out_file.close()

def create_examples_html_script(jupyter_examples_directory):
    """Uses nbconvert to change all .ipynb to .html then moves all files that are not .ipynb, to a
    directory at the same level called html. It deletes out any files that are generated in the original directory"""
    html_examples_directory=os.path.join(jupyter_examples_directory,"..","html")
    os.chdir(jupyter_examples_directory)
    os.system("jupyter nbconvert *.ipynb --to html")
    try:
        shutil.rmtree(html_examples_directory)
    except:
        print(("Could not remove {0}".format(html_examples_directory)))
    shutil.copytree(jupyter_examples_directory,html_examples_directory)
    os.chdir(html_examples_directory)
    file_names=os.listdir(html_examples_directory)
    # now clean out any .ipynb files in html
    for file_name in file_names:
        if re.search('.ipynb',file_name):
            try:
                os.remove(file_name)
            except:
                pass
    # now delete any generated .html files in jupyter
    os.chdir(jupyter_examples_directory)
    file_names = os.listdir(jupyter_examples_directory)
    for file_name in file_names:
        file_root=file_name.split(".")[0]
        if re.search('.html',file_name):
            ipynb_name=file_root+".ipynb"
            if ipynb_name in file_names:
                try:
                    os.remove(file_name)
                except:
                    pass


def change_links_examples_script(top_directory):
    """Changes all the links with extensions .ipynb to .html, designed to be run
    after nbconvert has changed all of the .ipynb files to .html so that the new files will
    now link to .html versions of themselves instead of .ipynb"""
    file_names=os.listdir(top_directory)
    for file_name in file_names:
        extension=file_name.split(".")[-1]
        if re.search('htm',extension,re.IGNORECASE) and os.path.isfile(os.path.join(top_directory,file_name)):
            in_file=open(os.path.join(top_directory,file_name),'r')
            content=in_file.read()
            new_content=content.replace('.ipynb','.html')
            in_file.close()
            out_file=open(os.path.join(top_directory,file_name),'w')
            out_file.write(new_content)
            out_file.close()


def add_navigation_script(top_directory, navigation_style='button', **options):
    """Adds navigation links to the body tag of all html files in top_directory,
    designed to add navigation to all files in Documentation/Examples/html"""
    defaults = {"pages": ["Documentation Home",
                          "API Documentation",
                          "Examples",
                          "Index"],
                "page_locations": [DOCUMENTATION_INDEX, API_INDEX, EXAMPLES_INDEX, REFERENCE_INDEX]}
    navigation_options = {}

    for key, value in defaults.items():
        navigation_options[key] = value
    for key, value in options.items():
        navigation_options[key] = value

    simple_navigation_html = """<a href='{Documentation Home}'>Documentation Home </a> |
        <a href='{API Documentation}'>API Documentation </a> |
        <a href='{Examples}'>Examples</a> |
        <a href='{Index}'>Index </a>"""
    button_navigation_html = """<a id="top"></a>
        <table style='border-style:none;'>
        <tr style="border-style:none;">
        <td style="border-style:none;">
        <a href='{Documentation Home}'><button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Documentation Home</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href='{API Documentation}'><button type="button" class='btn btn-primary'>
        <span style="font-size:20px">API Documentation</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href='{Examples}'>
        <button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Examples</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href='{Index}'>
        <button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Index</span></button></a>
        </td>
        </tr>
        </table>"""
    page_location_dictionary = {}
    if re.search('but|nav|bar', navigation_style, re.IGNORECASE):
        navigation_html = button_navigation_html
    else:
        navigation_html = simple_navigation_html
    file_names = os.listdir(top_directory)
    for file_name in file_names:
        extension = file_name.split(".")[-1]
        if re.search('htm', extension, re.IGNORECASE) and os.path.isfile(os.path.join(top_directory, file_name)):
            try:
                in_file = open(os.path.join(top_directory, file_name), 'r',encoding="latin1")
            except:
                in_file = open(os.path.join(top_directory, file_name), 'r')
            lines = []
            for line in in_file:
                if re.search("\<body\>", line, re.IGNORECASE):
                    for page_index, page in enumerate(navigation_options["pages"]):
                        relative_path = os.path.relpath(navigation_options["page_locations"][page_index],
                                                        top_directory)

                        page_location_dictionary[page] = relative_path.replace("\\", "/")

                    # print(page_location_dictionary)
                    navigation_html = navigation_html.format(**page_location_dictionary)
                    line = line + navigation_html
                    lines.append(line)
                else:
                    lines.append(line)
            in_file.close()
            try:
                out_file = open(os.path.join(top_directory, file_name), 'w',encoding="latin1")
            except:
                out_file = open(os.path.join(top_directory, file_name), 'w')
            out_file.writelines(lines)
            out_file.close()

def add_navigation_all_api_script(top_directory):
    """Adds a navigation script to all files under top directory. This is specifically designed to
    use after the API documentation is generated"""
    for directory, dirnames, filenames in os.walk(top_directory):
        add_navigation_script(directory)

def test_create_index_html(top_directory=PYMEASURE_ROOT):
    "Tests the create_index_html_script by applying it to pyMez itself. "
    create_index_html_script(top_directory=top_directory)
#-----------------------------------------------------------------------------
# Module Runner
if __name__ == '__main__':
    #test_create_help_page()
    #test_create_help_page('pyMez')
    #test_create_help_page('pyMez.Code.DataHandlers.NISTModels')
    #test_create_help_page('pyMez.Code.DataHandlers')
    #test_create_examples_page()
    test_create_examples_page(os.path.join(DOCUMENTATION_DIRECTORY,"pyMez_Documentation.ipynb"))
    autogenerate_api_documentation_script()
    test_create_index_html()
    #create_imports_html_script(PYMEASURE_ROOT,DOCUMENTATION_DIRECTORY)
    create_examples_html_script(os.path.join(DOCUMENTATION_DIRECTORY,"Examples","jupyter"))
    change_links_examples_script(os.path.join(DOCUMENTATION_DIRECTORY, "Examples", "html"))
    add_navigation_script(os.path.join(DOCUMENTATION_DIRECTORY, "Examples", "html"))
    add_navigation_all_api_script(os.path.join(DOCUMENTATION_DIRECTORY,"pyMez"))
    #create_modules_html_script(PYMEASURE_ROOT)

Functions

def add_navigation_all_api_script(

top_directory)

Adds a navigation script to all files under top directory. This is specifically designed to use after the API documentation is generated

def add_navigation_all_api_script(top_directory):
    """Adds a navigation script to all files under top directory. This is specifically designed to
    use after the API documentation is generated"""
    for directory, dirnames, filenames in os.walk(top_directory):
        add_navigation_script(directory)

def add_navigation_script(

top_directory, navigation_style='button', **options)

Adds navigation links to the body tag of all html files in top_directory, designed to add navigation to all files in Documentation/Examples/html

def add_navigation_script(top_directory, navigation_style='button', **options):
    """Adds navigation links to the body tag of all html files in top_directory,
    designed to add navigation to all files in Documentation/Examples/html"""
    defaults = {"pages": ["Documentation Home",
                          "API Documentation",
                          "Examples",
                          "Index"],
                "page_locations": [DOCUMENTATION_INDEX, API_INDEX, EXAMPLES_INDEX, REFERENCE_INDEX]}
    navigation_options = {}

    for key, value in defaults.items():
        navigation_options[key] = value
    for key, value in options.items():
        navigation_options[key] = value

    simple_navigation_html = """<a href='{Documentation Home}'>Documentation Home </a> |
        <a href='{API Documentation}'>API Documentation </a> |
        <a href='{Examples}'>Examples</a> |
        <a href='{Index}'>Index </a>"""
    button_navigation_html = """<a id="top"></a>
        <table style='border-style:none;'>
        <tr style="border-style:none;">
        <td style="border-style:none;">
        <a href='{Documentation Home}'><button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Documentation Home</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href='{API Documentation}'><button type="button" class='btn btn-primary'>
        <span style="font-size:20px">API Documentation</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href='{Examples}'>
        <button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Examples</span></button></a>
        </td>
        <td style="border-style:none;">
        <a href='{Index}'>
        <button type="button" class='btn btn-primary'>
        <span style="font-size:20px">Index</span></button></a>
        </td>
        </tr>
        </table>"""
    page_location_dictionary = {}
    if re.search('but|nav|bar', navigation_style, re.IGNORECASE):
        navigation_html = button_navigation_html
    else:
        navigation_html = simple_navigation_html
    file_names = os.listdir(top_directory)
    for file_name in file_names:
        extension = file_name.split(".")[-1]
        if re.search('htm', extension, re.IGNORECASE) and os.path.isfile(os.path.join(top_directory, file_name)):
            try:
                in_file = open(os.path.join(top_directory, file_name), 'r',encoding="latin1")
            except:
                in_file = open(os.path.join(top_directory, file_name), 'r')
            lines = []
            for line in in_file:
                if re.search("\<body\>", line, re.IGNORECASE):
                    for page_index, page in enumerate(navigation_options["pages"]):
                        relative_path = os.path.relpath(navigation_options["page_locations"][page_index],
                                                        top_directory)

                        page_location_dictionary[page] = relative_path.replace("\\", "/")

                    # print(page_location_dictionary)
                    navigation_html = navigation_html.format(**page_location_dictionary)
                    line = line + navigation_html
                    lines.append(line)
                else:
                    lines.append(line)
            in_file.close()
            try:
                out_file = open(os.path.join(top_directory, file_name), 'w',encoding="latin1")
            except:
                out_file = open(os.path.join(top_directory, file_name), 'w')
            out_file.writelines(lines)
            out_file.close()

def autogenerate_api_documentation_script(

)

Autogenerates the api help files. It requires that pdoc is installed and that the pdoc script is in the Documentation folder under pyMez. If the folder exists it first deletes the folder and then creates a new one. The folder permissions must be set properly to allow the script to delete the old API help. Uses the mako templates found in Documentation/templates

def autogenerate_api_documentation_script():
    """Autogenerates the api help files. It requires that pdoc is installed and that the pdoc script is in
    the Documentation folder under pyMez. If the folder exists it first deletes the folder and then creates a
     new one. The folder permissions must be set properly to allow the script to delete the old API help.
     Uses the mako templates found in Documentation/templates"""

    os.chdir(DOCUMENTATION_DIRECTORY)
    template_directory=os.path.join(DOCUMENTATION_DIRECTORY,"templates")
    try:
        shutil.rmtree(os.path.join(DOCUMENTATION_DIRECTORY,"pyMez"))
    except:
        print("Could not delete existing API documentation")
        pass
    os.system("python pdoc --html --overwrite --template-dir {0} pyMez".format(template_directory))

Changes all the links with extensions .ipynb to .html, designed to be run after nbconvert has changed all of the .ipynb files to .html so that the new files will now link to .html versions of themselves instead of .ipynb

def create_examples_html_script(

jupyter_examples_directory)

Uses nbconvert to change all .ipynb to .html then moves all files that are not .ipynb, to a directory at the same level called html. It deletes out any files that are generated in the original directory

def create_examples_html_script(jupyter_examples_directory):
    """Uses nbconvert to change all .ipynb to .html then moves all files that are not .ipynb, to a
    directory at the same level called html. It deletes out any files that are generated in the original directory"""
    html_examples_directory=os.path.join(jupyter_examples_directory,"..","html")
    os.chdir(jupyter_examples_directory)
    os.system("jupyter nbconvert *.ipynb --to html")
    try:
        shutil.rmtree(html_examples_directory)
    except:
        print(("Could not remove {0}".format(html_examples_directory)))
    shutil.copytree(jupyter_examples_directory,html_examples_directory)
    os.chdir(html_examples_directory)
    file_names=os.listdir(html_examples_directory)
    # now clean out any .ipynb files in html
    for file_name in file_names:
        if re.search('.ipynb',file_name):
            try:
                os.remove(file_name)
            except:
                pass
    # now delete any generated .html files in jupyter
    os.chdir(jupyter_examples_directory)
    file_names = os.listdir(jupyter_examples_directory)
    for file_name in file_names:
        file_root=file_name.split(".")[0]
        if re.search('.html',file_name):
            ipynb_name=file_root+".ipynb"
            if ipynb_name in file_names:
                try:
                    os.remove(file_name)
                except:
                    pass

def create_examples_page(

ipynb_path)

Given a jupyter notebook uses nbconvert to output an html file at the specified path.

def create_examples_page(ipynb_path):
    """Given a jupyter notebook uses nbconvert to output an html file at the specified path."""
    os.system("jupyter nbconvert --to html %s"%ipynb_path)

def create_help_page(

module, output_format='html', file_path=None)

Uses the pdoc module to create a html autogenerated help file for the specified module. If file_path is not specified it auto names it and saves it in the current working directory.

def create_help_page(module,output_format='html',file_path=None):
    """Uses the pdoc module to create a html autogenerated help file for the specified module.
    If file_path is not specified it auto names it and saves it in the current working directory."""
    if re.search('htm',output_format,re.IGNORECASE):
        html_text=pdoc.html(module_name=module,allsubmodules=True)
        if file_path is None:
            file_path=auto_name(module.replace('.','_'),'Help',directory=None,extension='html')
        out_file=open(file_path,'w')
        out_file.write(html_text)
        out_file.close()

def create_imports_html_script(

top_directory, output_directory=None)

Reads all .py files under top directory and creates an html page that contains all of the imports and the file that imports them.

def create_imports_html_script(top_directory,output_directory=None):
    """Reads all .py files under top directory and creates an html page that
    contains all of the imports and the file that imports them."""
    if output_directory is None:
        output_directory=top_directory
    imports=[]
    import_pattern_1=re.compile('import (?P<name>[\w|\.]+\n)')
    import_pattern_2=re.compile('from (?P<name>\[w|\.]+) import \w+\n')
    for directory, dirnames, file_names in os.walk(top_directory):
        clean_directory=directory.split('..\\')[-1].replace("\\","/")
        for file_name in file_names:
            extension=file_name.split(".")[-1]
            if re.match('py',extension,re.IGNORECASE):
                in_file=open(os.path.join(directory,file_name),'r')
                for line in in_file:
                    if re.search(import_pattern_1,line) and not re.match(import_pattern_2,line):
                        name=re.search(import_pattern_1,line).groupdict()['name']
                        imports.append("{0} in {1}".format(name,file_name))
                    elif re.match(import_pattern_2,line):
                        name=re.search(import_pattern_2,line).groupdict()['name']
                        imports.append("{0} in {1}".format(name, file_name))
    unique_imports=sorted(list(set(imports)))
    html_string=""
    for import_name in unique_imports:
        html_string=html_string+"<li>{0}</li>".format(import_name)
    html_string=IMPORT_HMTL_PREFIX+html_string+INDEX_HTML_POSTFIX
    out_file=open(os.path.join(output_directory,"pyMez_Imports.html"),"w")
    out_file.write(html_string)
    out_file.close()

def create_index_html_script(

top_directory, group=True)

create_index returns an html page with links to the autogenerated help page for all functions and classes in .py files in the directory structure. Uses the module constants INDEX_HTML_PREFIX and INDEX_HTML_POSTFIX to wrap the resulting html elements. Added the ability to group the functions and classes by sub package.

def create_index_html_script(top_directory,group=True):
    """create_index returns an html page with links to the autogenerated help page for all
    functions and classes in .py files in the directory structure. Uses the module constants INDEX_HTML_PREFIX
    and INDEX_HTML_POSTFIX to wrap the resulting html elements. Added the ability to group the functions and
    classes by sub package. """
    subpackages=["FrontEnds","InstrumentControl","Analysis","DataHandlers","Utils"]
    subpackage_descriptions=["""Function and classes for user interaction. pyMez targets three methods of
    user interaction, scripting (for example in spyder or a jupyter notebook), desktop gui (using the wx package),
    and web applications (using the django web framework).""",
                             """Functions and classes used in controlling instruments. Experiment classes integrate
                             instruments and data manipulation. Instruments are a set of control classes that
                              have static metadata, dynamic metadata (state saving and loading) and data formatting.""",
                             """Functions and classes used in Analyzing data or processes.""",
                             """Functions in classes used in data storage and format manipulation.""",
                             """Functions and classes that are base utilities for the pyMez package."""]
    classes_and_functions=[]
    class_pattern=re.compile('class (?P<name>\w+)\(')
    function_pattern=re.compile('def (?P<name>\w+)\(')
    links_dictionary={}
    group_links_dictionary={}

    link_template="<li><a href='{0}'>{1}</a></li>\n"
    for directory, dirnames, file_names in os.walk(top_directory):
        clean_directory=directory.split('..\\')[-1].replace("\\","/")
        for file_name in file_names:
            extension=file_name.split(".")[-1]
            if re.match('py',extension,re.IGNORECASE):
                try:
                    in_file=open(os.path.join(directory,file_name),'r',encoding="latin1")
                except:
                    in_file = open(os.path.join(directory, file_name), 'r') #python 2.7 compatibility
                for line in in_file:
                    if re.search(class_pattern,line):
                        reference_file="pyMez/"+change_extension(os.path.join(clean_directory,file_name),'m')+".html"
                        reference_id = reference_file.split(".")[0]
                        reference_file="./"+reference_file.replace("\\","/")
                        name=re.search(class_pattern,line).groupdict()['name']
                        reference_id = reference_id.replace("\\", "/")
                        reference_id=reference_id.replace("/", ".")+"."+name
                        reference=reference_file+"#"+reference_id
                        classes_and_functions.append(name)
                        links_dictionary[name]=link_template.format(reference,
                                                          name)
                    elif re.match(function_pattern,line):
                        reference_file="pyMez/"+change_extension(os.path.join(clean_directory,file_name),'m')+".html"
                        reference_id = reference_file.split(".")[0]
                        reference_file="./"+reference_file.replace("\\","/")
                        name=re.search(function_pattern,line).groupdict()['name']
                        classes_and_functions.append(name)
                        reference_id = reference_id.replace("\\", "/")
                        reference_id=reference_id.replace("/", ".")+"."+name
                        reference=reference_file+"#"+reference_id
                        links_dictionary[name]=link_template.format(reference,
                                                          name)

    #print("{0} is {1}".format('classes_and_functions',classes_and_functions))
    #print("{0} is {1}".format('links_string',links_string))
    # now arrange all in alphabetical order
    sorted_keys=sorted(list(links_dictionary.keys()),key=str.lower)
    links_string=""
    for key in sorted_keys:
        links_string=links_string+links_dictionary[key]
    links_string = INDEX_HTML_PREFIX +"<ol>" +links_string + "</ol>"+INDEX_HTML_POSTFIX

    # if group is true group the links and add a group title
    if group:
        links_string=""
        for subpackage_index,subpackage in enumerate(subpackages):
            links_string=links_string+"<h2>{0}</h2><p>{1}</p>".format(subpackage,
                                                                      subpackage_descriptions[subpackage_index])+"<ol>"
            group_links_dictionary[subpackage]={}
            group_keys=[]
            for key in sorted_keys:
                if re.search(subpackage,links_dictionary[key],re.IGNORECASE):
                    group_links_dictionary[subpackage][key]=links_dictionary[key]
                    group_keys.append(key)
            group_keys=sorted(group_keys,key=str.lower)
            for key in group_keys:
                links_string=links_string+links_dictionary[key]
            links_string=links_string+"</ol>"
        links_string=INDEX_HTML_PREFIX  + links_string  + INDEX_HTML_POSTFIX

    out_file=open(os.path.join(DOCUMENTATION_DIRECTORY,"Reference_Index.html"),"w")
    out_file.write(links_string)
    out_file.close()

def create_modules_html_script(

top_directory, output_directory=None, output_name='pyMez_Modules.html')

Creates an html page with all python modules under top_directory

def create_modules_html_script(top_directory,output_directory=None,output_name="pyMez_Modules.html"):
    """Creates an html page with all python modules under top_directory"""
    if output_directory is None:
        output_directory=top_directory
    modules=[]
    for directory, dirnames, file_names in os.walk(top_directory):
        for file_name in file_names:
            extension=file_name.split(".")[-1]
            if re.match('py(?!c)',extension,re.IGNORECASE):
                modules.append(file_name)

    html_string=""
    for module_name in modules:
        html_string=html_string+"<li>{0}</li>".format(module_name)
    html_string=IMPORT_HMTL_PREFIX.replace("All Imports","All Modules")+html_string+INDEX_HTML_POSTFIX
    out_file=open(os.path.join(output_directory,output_name),"w")
    out_file.write(html_string)
    out_file.close()

def return_help(

object)

Returns an html help page autogenerated by the pdoc module for any live object

def return_help(object):
    """Returns an html help page autogenerated by the pdoc module for any live object"""
    module=inspect.getmodule(object).__name__
    html_text=pdoc.html(module_name=module,allsubmodules=True)
    return html_text

def test_create_examples_page(

ipynb_path='Development_Stack_Installation_Example_20160130_01.ipynb')

Tests the create_examples_page function, really nb convert on the command line

def test_create_examples_page(ipynb_path='Development_Stack_Installation_Example_20160130_01.ipynb'):
    """Tests the create_examples_page function, really nb convert on the command line"""
    os.chdir(TESTS_DIRECTORY)
    create_examples_page(ipynb_path)

def test_create_help_page(

module='pyMez.Code.DataHandlers.GeneralModels')

Tests the create help page function, it seems pretty slow

def test_create_help_page(module='pyMez.Code.DataHandlers.GeneralModels'):
    "Tests the create help page function, it seems pretty slow"
    os.chdir(TESTS_DIRECTORY)
    create_help_page(module)

def test_create_index_html(

top_directory='C:\\ProgramData\\Anaconda2\\lib\\site-packages\\pyMez\\Code\\Utils\\..\\..')

Tests the create_index_html_script by applying it to pyMez itself.

def test_create_index_html(top_directory=PYMEASURE_ROOT):
    "Tests the create_index_html_script by applying it to pyMez itself. "
    create_index_html_script(top_directory=top_directory)

Module variables

var API_INDEX

var DEFAULT_FILE_NAME

var DOCUMENTATION_DIRECTORY

var DOCUMENTATION_INDEX

var EXAMPLES_INDEX

var IMPORT_HMTL_PREFIX

var INDEX_HTML_POSTFIX

var INDEX_HTML_PREFIX

var METHOD_ALIASES

var PYMEASURE_ROOT

var REFERENCE_INDEX

var TESTS_DIRECTORY