def _get_package_header_code(self): ''' Evaluates HTML code for the header of the package documentation. Returns: The header HTML code, embedded in a string, related to this package. ''' my_package_dirpath = self._package_dirpath.replace('../', '') my_parent_package_path = os.path.dirname(my_package_dirpath) my_parent_package_id = Utils.path_to_id(my_parent_package_path) my_html_code = Utils.html_indent( self._html_indent, '<div class="package_container" id="{:s}">\n'.format( Utils.path_to_id(my_package_dirpath))) if my_parent_package_id == '': my_html_code += Utils.html_indent( self._html_indent + 1, '<p class="package_def">package <b><span class="package_def">{:s}</span></b></p>\n\n' .format(self._root_package_name)) else: my_html_code += Utils.html_indent( self._html_indent + 1, '<p class="package_def">package <b><a class="package_def" href="#{:s}">{:s}</a><span class="package_def">{:s}{:s}</span></b></p>\n\n' .format(my_parent_package_id, my_parent_package_path, '/' if my_parent_package_path != '' else '', self._root_package_name)) return my_html_code
def __init__(self, package_descr, html_indent_level=0): ''' Evaluates HTML code for the documentation of a specified package. Once instantiated, Package objects can be applied their method get_html_code(). Args: package_descr: DirectoryDescr A reference to the descriptor of this package - which is also a directory on disk. html_indent_level: int The level of indentation in the HTML code for this package. Defaults to 0. Raises: AssertError: the passed argument 'package_descr' is not an instance of class DirectoryDescr. ''' assert isinstance(package_descr, DirectoryDescr) self._package_descr = package_descr self._package_dirpath = Utils.replace_backslash(package_descr.root) self._root_package_name = Utils.replace_backslash( os.path.basename(package_descr.root)) self._html_indent = html_indent_level
def _insert_decorators(self): ''' Returns: The HTML code related to the decorators applied to this class. ''' my_str = Utils.get_decorators_str( self._class_descr['class_descr'].class_node.decorator_list, self._parsed_module.module_lines) if my_str: return Utils.html_indent(self._indent_level + 1, '{:s}\n'.format(my_str)) else: return ''
def _list_assigns(self): ''' Evaluates the HTML code for all the assignments defined in this module. Returns: The HTML code associated with the list of all assignments defined in this module. ''' K_MAX_LINES = Utils.K_MAX_ASSIGNS_LINES if len(self._parsed_module.module_descr.assigns_list) == 0: return '' my_html_code = Utils.html_indent(self._indent_level + 1, '<div class="classes_list">\n') my_html_code += Utils.html_indent( self._indent_level + 2, '<p class="imports-def"><b>List of data</b> defined in module <b><span class="module-color">{:s}</span></b></p>\n' .format(self._module_name)) my_html_code += Utils.html_indent(self._indent_level + 2, '<pre class="modules-data-list">\n') max_lineno = max([ assign_descr.assign_node.lineno for assign_descr in self._parsed_module.module_descr.assigns_list ]) my_format_str = "<i>line {:%d}</i> | {:s}\n" % len(str(max_lineno)) for assign_descr in self._parsed_module.module_descr.assigns_list: my_start_line = assign_descr.assign_node.lineno - 1 my_end_line = assign_descr.assign_node.value.lineno if my_end_line - my_start_line <= K_MAX_LINES: for line_no in range(my_start_line, my_end_line): my_html_code += Utils.html_indent( 1, my_format_str.format( line_no, self._parsed_module.module_lines[line_no])) else: for line_no in range(my_start_line, my_start_line + K_MAX_LINES): my_html_code += Utils.html_indent( 1, my_format_str.format( line_no, self._parsed_module.module_lines[line_no])) my_more_lines = my_end_line - my_start_line - K_MAX_LINES my_html_code += ' ' * ( len(my_format_str.format(my_start_line, '')) - 5 ) #Utils.html_indent( 1, ' '*(len(my_format_str.format(my_start_line, ''))-5) ) my_html_code += Utils.html_indent( 1, '... (<i>{:d} more line{:s}</i>)'.format( my_more_lines, 's' if my_more_lines > 1 else '')) my_html_code = my_html_code.rstrip() my_html_code += Utils.html_indent(self._indent_level + 2, '</pre>\n') my_html_code += Utils.html_indent(self._indent_level + 1, '</div>\n\n') return my_html_code
def _empty_module(self): ''' Sets the HTML code for stating that this module contains no definition or even nothing at all. ''' if len(self._parsed_module.module_content) == 0: return Utils.html_indent( self._indent_level + 1, '<p class="modules-comments"><i>This is an empty module.</i></p>\n' ) else: return Utils.html_indent( self._indent_level+1, '<p class="modules-comments"><i>This module contains no class ' + \ 'and no function definitions, no data and no import declarations.</i></p>\n' )
def _insert_assigns(self): ''' Returns: The HTML code related to the assignments of class data. ''' K_MAX_LINES = Utils.K_MAX_ASSIGNS_LINES my_assigns_list = self._parsed_module.module_descr.classes_dict[ self._class_name]['assigns_descrs'] if len(my_assigns_list) == 0: return '' my_html_code = Utils.html_indent(self._indent_level + 1, '<div class="imports-list">\n') my_html_code += Utils.html_indent( self._indent_level + 2, '<p class="imports-def"><b>List of data</b> for class <b><span class="blue">{:s}</span></b></p>\n<pre>\n' .format(self._class_name)) max_lineno = max([ assign_descr.assign_node.lineno for assign_descr in my_assigns_list ]) my_format_str = "<i>line {:%d}</i> | {:s}\n" % len(str(max_lineno)) for assign_descr in my_assigns_list: my_start_line = assign_descr.assign_node.lineno - 1 my_end_line = assign_descr.assign_node.value.lineno if my_end_line - my_start_line <= K_MAX_LINES: for line_no in range(my_start_line, my_end_line): my_html_code += Utils.html_indent( 1, my_format_str.format( line_no, self._parsed_module.module_lines[line_no])) else: for line_no in range(my_start_line, my_start_line + K_MAX_LINES): my_html_code += Utils.html_indent( 1, my_format_str.format( line_no, self._parsed_module.module_lines[line_no])) my_more_lines = my_end_line - my_start_line - K_MAX_LINES my_html_code += Utils.html_indent( 1, ' ' * (len(my_format_str.format(my_start_line, '')) - 5)) my_html_code += Utils.html_indent( 1, '... (<i>{:d} more line{:s}</i>)'.format( my_more_lines, 's' if my_more_lines > 1 else '')) my_html_code = my_html_code.rstrip() my_html_code += Utils.html_indent(self._indent_level + 2, '</pre>\n') my_html_code += Utils.html_indent(self._indent_level + 1, '</div>\n') return my_html_code
def _insert_docstring(self): ''' Inserts docstring for this module. ''' my_html_code = Utils.html_indent(self._indent_level + 1, '<pre>\n') if self._parsed_module.docstring: try: my_html_code += Utils.html_indent( 1, self._parsed_module.docstring.strip()) #my_html_code += Utils.html_indent( 1, self._parsed_module.docstring.replace('<', '<').replace('>', '>').strip() ) except: my_html_code += '<unknown error detected in docstring - maybe string encoding/decoding failure>' my_html_code += '</pre>\n' return my_html_code
def get_html_id(self): ''' Gets an HTML identifier associated with a module and its embedding package. Returns: A string containing the CSS id associated with the specified module. ''' return '_'.join( (Utils.path_to_id(self._package_name), self._module_name))
def _insert_docstring(self): ''' Returns: The HTML code related to the docstring associated with this class. ''' my_html_code = Utils.html_indent(self._indent_level + 1, '<pre>\n') if self._class_descr['class_descr'].docstring: try: my_html_code += Utils.html_indent( 1, self._class_descr['class_descr'].docstring.strip()) #my_html_code += Utils.html_indent( 1, self._class_descr['class_descr'].docstring.replace('<', '<').replace('>', '>').strip() ) except: my_html_code += '<unknown error detected in docstring - maybe string encoding/decoding failure>' my_html_code += '</pre>\n' return my_html_code
def _get_module_footer_code(self): ''' Evaluates HTML code for the footer of the module documentation. Returns: The HTML code, embedded in a string, related to this module. ''' package_path = self._package_path.replace('../', '') my_html_code = Utils.html_indent( self._indent_level + 1, '<p>back to package <a class="package_end" href="#{:s}">{:s}</a></p>\n' .format(Utils.path_to_id(package_path), package_path)) my_html_code += Utils.html_indent( self._indent_level, '</div> <!-- end of module {:s} -->\n\n'.format( self.get_html_id())) return my_html_code
def _get_module_header_code(self): ''' Evaluates HTML code for the header of the module documentation. Returns: The header HTML code, embedded in a string, related to this module. ''' #self._root_package_name = Utils.replace_backslash( self._package_path ) self._root_package_name = Utils.replace_backslash( self._package_name).replace('../', '') my_html_code = Utils.html_indent( self._indent_level, '<div class="module_container" id="{:s}">\n'.format( Utils.path_to_id(self.get_html_id()))) my_html_code += Utils.html_indent( self._indent_level + 1, '<p class="module_def">module <b>{:s}</b></p>\n\n'.format( self._module_name)) return my_html_code
def _get_function_body_code(self): ''' Evaluates the HTML code for the body of this function documentation. Returns: The header HTML code, embedded in a string, related to this function. ''' if self._function_descr.docstring: my_html_code = Utils.html_indent(self._indent_level, '<pre>') if self._function_descr.docstring[0] != '\n': my_html_code += Utils.html_indent(2, ' ') my_html_code += self._function_descr.docstring.rstrip(' \n') my_html_code += Utils.html_indent(self._indent_level, '\n</pre>\n\n') return my_html_code else: return ''
def _list_modules(self): ''' Evaluates HTML code for the list of modules contained within this package. Returns: The HTML code, embedded in a string, related to this package. ''' if len(self._package_descr.files) == 0: return ' <p class="modules-comments"><i>this package contains no modules.</i></p>\n' my_html_code = Utils.html_indent(self._html_indent + 1, '<div class="modules-list">\n') my_html_code += Utils.html_indent( self._html_indent + 2, '<p><b>List of modules for package {:s}</b></p>\n'.format( self._root_package_name)) my_html_code += Utils.html_indent(self._html_indent + 2, '<p class="modules-names">\n') for module_name in sorted(self._package_descr.files): my_sub_module_name = HtmlModule( self._package_dirpath, self._root_package_name, module_name, self._html_indent + 1).get_html_id() my_html_code += Utils.html_indent( self._html_indent + 3, '<a href="#{:s}">{:s}</a><br />\n'.format( my_sub_module_name, module_name)) my_html_code += Utils.html_indent(self._html_indent + 2, '</p>\n') my_html_code += Utils.html_indent(self._html_indent + 1, '</div>\n\n') return my_html_code
def _list_classes(self): ''' Evaluates the HTML code for all the classes defined in this module. Returns: The HTML code associated with the list of all classes defined in this module. ''' if len(self._parsed_module.module_descr.classes_dict) == 0: return '' my_html_code = Utils.html_indent(self._indent_level + 1, '<div class="classes_list">\n') my_html_code += Utils.html_indent( self._indent_level + 2, '<p class="imports-def"><b>List of classes</b> for module <b><span class="module-color">{:s}</span></b></p>\n' .format(self._module_name)) my_html_code += Utils.html_indent(self._indent_level + 2, '<p class="modules-names">\n') for class_name in sorted( self._parsed_module.module_descr.classes_dict.keys()): my_class_id = HtmlClass.get_class_id(self.get_html_id(), class_name) my_html_code += Utils.html_indent( self._indent_level + 3, 'class <a href="#{:s}">{:s}</a><br />\n'.format( my_class_id, class_name)) my_html_code += Utils.html_indent(self._indent_level + 2, '</p>\n') my_html_code += Utils.html_indent(self._indent_level + 1, '</div>\n\n') return my_html_code
def _list_imports(self): ''' Evaluates HTML code for listing all the 'import' and 'from ... import' instructions inf this module ''' if len(self._parsed_module.module_descr.imports_list) == 0: if self._module_name == '__init__.py': return '' else: return Utils.html_indent( self._indent_level + 1, '<p class="modules-comments"><i>no imports.</i></p>\n') my_html_code = Utils.html_indent(self._indent_level + 1, '<div class="imports-list">\n') my_html_code += Utils.html_indent( self._indent_level + 2, '<p class="imports-def"><b>Imports</b></p>\n<pre>\n') for import_descr in self._parsed_module.module_descr.imports_list: my_line_no = import_descr.import_node.lineno my_import_code = self._parsed_module.module_lines[my_line_no - 1].lstrip() my_colored_keywords = ['from ', 'import ', ' as '] for kw in my_colored_keywords: my_import_code = my_import_code.replace( kw, '<span class="keyword">{:s}</span>'.format(kw)) my_html_code += Utils.html_indent(self._indent_level, '{:s}\n'.format(my_import_code)) my_html_code += Utils.html_indent(self._indent_level + 2, '</pre>\n') my_html_code += Utils.html_indent(self._indent_level + 1, '</div>\n') return my_html_code
def _get_class_footer_code(self): ''' Evaluates the HTML code for the footer of this class documentation. Returns: The header HTML code, embedded in a string, related to this class. ''' my_html_code = Utils.html_indent( self._indent_level + 1, '<p>up to class <a class="class_end" href="#{:s}">{:s}</a><br />\n' .format(self.get_html_id(), self._class_name)) my_html_code += Utils.html_indent( self._indent_level + 1, 'back to module <a class="module_end" href="#{:s}">{:s}</a></p>\n'. format(self._module_ref.get_html_id(), self._module_ref._module_name)) my_html_code += Utils.html_indent( self._indent_level, '</div> <!-- end of class {:s} -->\n\n'.format(self._class_name)) return my_html_code
def _get_package_footer_code(self): ''' Evaluates HTML code for the footer of the package documentation. Returns: The HTML code, embedded in a string, related to this package. ''' my_parent_package_path = os.path.dirname( self._package_dirpath).replace('../', '') return Utils.html_indent( self._html_indent+1, ('<p class="package_end">end of package <b><a class="package_end" href="#{:s}">' + \ '{:s}</a>{:s} <a class="package_end" href="#{:s}">{:s}</a></b></p>\n').format( Utils.path_to_id( my_parent_package_path ), my_parent_package_path , '/' if my_parent_package_path != '' else '', Utils.path_to_id( self._package_dirpath.replace('../','') ) , self._root_package_name ) ) + \ Utils.html_indent( self._html_indent, '</div> <!-- end of package container {:s} -->\n\n'.format( Utils.path_to_id( self._package_dirpath ) ) )
def _get_function_header_code(self): ''' Evaluates the HTML code for the header of this function documentation. Returns: The header HTML code, embedded in a string, related to this function. ''' my_args_count = len(self._function_descr.function_node.args.args) my_html_code = '' start_lineno = self._function_descr.function_node.lineno if my_args_count > 0: end_lineno = self._function_descr.function_node.args.args[ -1].lineno else: end_lineno = start_lineno while 'def ' not in self._parsed_module.module_lines[end_lineno - 1]: end_lineno += 1 for lineno in range(start_lineno - 1, end_lineno): my_substring = self._parsed_module.module_lines[lineno].strip() my_substring = my_substring.replace(' ', '').replace(',', ', ') my_html_code += my_substring + ' ' my_html_code = my_html_code[:-1] last_par_index = my_html_code.rfind(')') if last_par_index != -1: my_substring = my_html_code[last_par_index:].replace(' ', '') if my_substring[-1] != ':': my_html_code += ')' else: my_html_code += ')' my_html_code = my_html_code.rstrip(':').replace('->', ' -> ') my_html_split_code = my_html_code.split(self._function_name, 1) my_html_code = Utils.html_indent( self._indent_level, '<p class="function_def">{:s} <b>{:s}</b> {:s}</p>\n'.format( my_html_split_code[0], self._function_name, my_html_split_code[1])) return my_html_code
def _list_sub_packages(self): ''' Evaluates HTML code for the list of sub_packages contained within this package. Returns: The HTML code, embedded in a string, related to this package. ''' my_html_code = '' if len(self._package_descr.dirs) > 0: # sub-packages are embedded in current package package_dirpath = self._package_dirpath.replace('../', '') my_html_code += Utils.html_indent(self._html_indent + 1, '<div class="packages-list">\n') my_html_code += Utils.html_indent( self._html_indent + 2, '<p><b>List of sub-packages for package {:s}</b></p>\n'.format( package_dirpath)) my_html_code += Utils.html_indent(self._html_indent + 2, '<p class="packages-names">\n') for sub_package_name in sorted(self._package_descr.dirs): my_sub_package_name = '/'.join( (package_dirpath, sub_package_name)) my_html_code += Utils.html_indent( self._html_indent + 3, '<a href="#{:s}">{:s}</a><br />\n'.format( Utils.path_to_id(my_sub_package_name), my_sub_package_name)) my_html_code += Utils.html_indent(self._html_indent + 2, '</p>\n') my_html_code += Utils.html_indent(self._html_indent + 1, '</div>\n\n') return my_html_code
def _get_class_header_code(self): ''' Evaluates the HTML code for the header of this class documentation. Returns: The header HTML code, embedded in a string, related to this class. ''' #--------------------------------------------------------------------- def _my_list_bases(ast_node): html_code = '' for ast_base in ast_node.bases: try: # is this an ast.Name? html_code += ast_base.id + ', ' except: try: # is this an ast.Attribute? html_code += '.'.join( (ast_base.value.id, ast_base.attr)) + ', ' except: # this is an unprocessed type of ast.Node pass return html_code #--------------------------------------------------------------------- my_html_code = Utils.html_indent( self._indent_level, '<div class="class_container" id="{:s}">\n'.format( self.get_html_id())) my_html_code += Utils.html_indent( self._indent_level + 1, '<p class="class_def">class <b>{:s}</b>'.format(self._class_name)) my_ast_node = self._class_descr['class_descr'].class_node my_text_inserted = False try: if len(my_ast_node.bases) > 0 or len(my_ast_node.keywords) > 0: my_html_code += ' ( {:s}'.format( _my_list_bases(my_ast_node)) my_text_inserted = True if len(my_ast_node.keywords) > 0: if len(my_ast_node.bases) > 0: my_html_code += ', ' for ast_keyword in my_ast_node.keywords: my_html_code += '{:s}={:s}, '.format( ast_keyword.arg, ast_keyword.value.id) except Exception as _e: # Python 2.x - no 'keywords' attribute pass if my_text_inserted: my_html_code = my_html_code[:-2] + ' )' my_html_decorators = self._insert_decorators() if my_html_decorators: my_html_code += '<br />\n' + my_html_decorators return my_html_code + Utils.html_indent(self._indent_level + 1, '</p>\n')