<s> """<STR_LIT>""" <EOL> import os <EOL> import re <EOL> class ApiDocWriter ( object ) : <EOL> '''<STR_LIT>''' <EOL> rst_section_levels = [ '<STR_LIT:*>' , '<STR_LIT:=>' , '<STR_LIT:->' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self , <EOL> package_name , <EOL> rst_extension = '<STR_LIT>' , <EOL> package_skip_patterns = None , <EOL> module_skip_patterns = None , <EOL> ) : <EOL> '''<STR_LIT>''' <EOL> if package_skip_patterns is None : <EOL> package_skip_patterns = [ '<STR_LIT>' ] <EOL> if module_skip_patterns is None : <EOL> module_skip_patterns = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> self . package_name = package_name <EOL> self . rst_extension = rst_extension <EOL> self . package_skip_patterns = package_skip_patterns <EOL> self . module_skip_patterns = module_skip_patterns <EOL> def get_package_name ( self ) : <EOL> return self . _package_name <EOL> def set_package_name ( self , package_name ) : <EOL> '''<STR_LIT>''' <EOL> self . _package_name = package_name <EOL> self . root_module = __import__ ( package_name ) <EOL> self . root_path = self . root_module . __path__ [ <NUM_LIT:0> ] <EOL> self . written_modules = None <EOL> package_name = property ( get_package_name , set_package_name , None , <EOL> '<STR_LIT>' ) <EOL> def _get_object_name ( self , line ) : <EOL> '''<STR_LIT>''' <EOL> name = line . split ( ) [ <NUM_LIT:1> ] . split ( '<STR_LIT:(>' ) [ <NUM_LIT:0> ] . strip ( ) <EOL> return name . rstrip ( '<STR_LIT::>' ) <EOL> def _uri2path ( self , uri ) : <EOL> '''<STR_LIT>''' <EOL> if uri == self . package_name : <EOL> return os . path . join ( self . root_path , '<STR_LIT>' ) <EOL> path = uri . replace ( '<STR_LIT:.>' , os . path . sep ) <EOL> path = path . replace ( self . package_name + os . path . sep , '<STR_LIT>' ) <EOL> path = os . path . join ( self . root_path , path ) <EOL> if os . path . exists ( path + '<STR_LIT>' ) : <EOL> path += '<STR_LIT>' <EOL> elif os . path . exists ( os . path . join ( path , '<STR_LIT>' ) ) : <EOL> path = os . path . join ( path , '<STR_LIT>' ) <EOL> else : <EOL> return None <EOL> return path <EOL> def _path2uri ( self , dirpath ) : <EOL> '''<STR_LIT>''' <EOL> relpath = dirpath . replace ( self . root_path , self . package_name ) <EOL> if relpath . startswith ( os . path . sep ) : <EOL> relpath = relpath [ <NUM_LIT:1> : ] <EOL> return relpath . replace ( os . path . sep , '<STR_LIT:.>' ) <EOL> def _parse_module ( self , uri ) : <EOL> '''<STR_LIT>''' <EOL> filename = self . _uri2path ( uri ) <EOL> if filename is None : <EOL> return ( [ ] , [ ] ) <EOL> f = open ( filename , '<STR_LIT>' ) <EOL> functions , classes = self . _parse_lines ( f ) <EOL> f . close ( ) <EOL> return functions , classes <EOL> def _parse_lines ( self , linesource ) : <EOL> '''<STR_LIT>''' <EOL> functions = [ ] <EOL> classes = [ ] <EOL> for line in linesource : <EOL> if line . startswith ( '<STR_LIT>' ) and line . count ( '<STR_LIT:(>' ) : <EOL> name = self . _get_object_name ( line ) <EOL> if not name . startswith ( '<STR_LIT:_>' ) : <EOL> functions . append ( name ) <EOL> elif line . startswith ( '<STR_LIT>' ) : <EOL> name = self . _get_object_name ( line ) <EOL> if not name . startswith ( '<STR_LIT:_>' ) : <EOL> classes . append ( name ) <EOL> else : <EOL> pass <EOL> functions . sort ( ) <EOL> classes . sort ( ) <EOL> return functions , classes <EOL> def generate_api_doc ( self , uri ) : <EOL> '''<STR_LIT>''' <EOL> functions , classes = self . _parse_module ( uri ) <EOL> if not len ( functions ) and not len ( classes ) : <EOL> print '<STR_LIT>' , uri <EOL> return '<STR_LIT>' <EOL> uri_short = re . sub ( r'<STR_LIT>' % self . package_name , '<STR_LIT>' , uri ) <EOL> ad = '<STR_LIT>' <EOL> chap_title = uri_short <EOL> ad += ( chap_title + '<STR_LIT:\n>' + self . rst_section_levels [ <NUM_LIT:1> ] * len ( chap_title ) <EOL> + '<STR_LIT>' ) <EOL> if '<STR_LIT:.>' in uri : <EOL> title = '<STR_LIT>' + uri_short + '<STR_LIT>' <EOL> else : <EOL> title = '<STR_LIT>' + uri_short + '<STR_LIT>' <EOL> ad += title + '<STR_LIT:\n>' + self . rst_section_levels [ <NUM_LIT:2> ] * len ( title ) <EOL> if len ( classes ) : <EOL> ad += '<STR_LIT>' % uri <EOL> ad += '<STR_LIT>' % uri <EOL> ad += '<STR_LIT>' <EOL> ad += '<STR_LIT>' + uri + '<STR_LIT:\n>' <EOL> ad += '<STR_LIT>' + uri + '<STR_LIT:\n>' <EOL> multi_class = len ( classes ) > <NUM_LIT:1> <EOL> multi_fx = len ( functions ) > <NUM_LIT:1> <EOL> if multi_class : <EOL> ad += '<STR_LIT:\n>' + '<STR_LIT>' + '<STR_LIT:\n>' + self . rst_section_levels [ <NUM_LIT:2> ] * <NUM_LIT:7> + '<STR_LIT:\n>' <EOL> elif len ( classes ) and multi_fx : <EOL> ad += '<STR_LIT:\n>' + '<STR_LIT>' + '<STR_LIT:\n>' + self . rst_section_levels [ <NUM_LIT:2> ] * <NUM_LIT:5> + '<STR_LIT:\n>' <EOL> for c in classes : <EOL> ad += '<STR_LIT>' + c + '<STR_LIT>' + self . rst_section_levels [ multi_class + <NUM_LIT:2> ] * ( len ( c ) + <NUM_LIT:9> ) + '<STR_LIT>' <EOL> ad += '<STR_LIT>' + c + '<STR_LIT:\n>' <EOL> ad += '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' '<STR_LIT:\n>' '<STR_LIT>' <EOL> if multi_fx : <EOL> ad += '<STR_LIT:\n>' + '<STR_LIT>' + '<STR_LIT:\n>' + self . rst_section_levels [ <NUM_LIT:2> ] * <NUM_LIT:9> + '<STR_LIT>' <EOL> elif len ( functions ) and multi_class : <EOL> ad += '<STR_LIT:\n>' + '<STR_LIT>' + '<STR_LIT:\n>' + self . rst_section_levels [ <NUM_LIT:2> ] * <NUM_LIT:8> + '<STR_LIT>' <EOL> for f in functions : <EOL> ad += '<STR_LIT>' + uri + '<STR_LIT:.>' + f + '<STR_LIT>' <EOL> return ad <EOL> def _survives_exclude ( self , matchstr , match_type ) : <EOL> '''<STR_LIT>''' <EOL> if match_type == '<STR_LIT>' : <EOL> patterns = self . module_skip_patterns <EOL> elif match_type == '<STR_LIT>' : <EOL> patterns = self . package_skip_patterns <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' <EOL> % match_type ) <EOL> L = len ( self . package_name ) <EOL> if matchstr [ : L ] == self . package_name : <EOL> matchstr = matchstr [ L : ] <EOL> for pat in patterns : <EOL> try : <EOL> pat . search <EOL> except AttributeError : <EOL> pat = re . compile ( pat ) <EOL> if pat . search ( matchstr ) : <EOL> return False <EOL> return True <EOL> def discover_modules ( self ) : <EOL> '''<STR_LIT>''' <EOL> modules = [ self . package_name ] <EOL> for dirpath , dirnames , filenames in os . walk ( self . root_path ) : <EOL> root_uri = self . _path2uri ( os . path . join ( self . root_path , <EOL> dirpath ) ) <EOL> for dirname in dirnames [ : ] : <EOL> package_uri = '<STR_LIT:.>' . join ( ( root_uri , dirname ) ) <EOL> if ( self . _uri2path ( package_uri ) and <EOL> self . _survives_exclude ( package_uri , '<STR_LIT>' ) ) : <EOL> modules . append ( package_uri ) <EOL> else : <EOL> dirnames . remove ( dirname ) <EOL> for filename in filenames : <EOL> module_name = filename [ : - <NUM_LIT:3> ] <EOL> module_uri = '<STR_LIT:.>' . join ( ( root_uri , module_name ) ) <EOL> if ( self . _uri2path ( module_uri ) and <EOL> self . _survives_exclude ( module_uri , '<STR_LIT>' ) ) : <EOL> modules . append ( module_uri ) <EOL> return sorted ( modules ) <EOL> def write_modules_api ( self , modules , outdir ) : <EOL> written_modules = [ ] <EOL> for m in modules : <EOL> api_str = self . generate_api_doc ( m ) <EOL> if not api_str : <EOL> continue <EOL> outfile = os . path . join ( outdir , <EOL> m + self . rst_extension ) <EOL> fileobj = open ( outfile , '<STR_LIT>' ) <EOL> fileobj . write ( api_str ) <EOL> fileobj . close ( ) <EOL> written_modules . append ( m ) <EOL> self . written_modules = written_modules <EOL> def write_api_docs ( self , outdir ) : <EOL> """<STR_LIT>""" <EOL> if not os . path . exists ( outdir ) : <EOL> os . mkdir ( outdir ) <EOL> modules = self . discover_modules ( ) <EOL> self . write_modules_api ( modules , outdir ) <EOL> def write_index ( self , outdir , froot = '<STR_LIT>' , relative_to = None ) : <EOL> """<STR_LIT>""" <EOL> if self . written_modules is None : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> path = os . path . join ( outdir , froot + self . rst_extension ) <EOL> if relative_to is not None : <EOL> relpath = outdir . replace ( relative_to + os . path . sep , '<STR_LIT>' ) <EOL> else : <EOL> relpath = outdir <EOL> idx = open ( path , '<STR_LIT>' ) <EOL> w = idx . write <EOL> w ( '<STR_LIT>' ) <EOL> w ( '<STR_LIT>' ) <EOL> for f in self . written_modules : <EOL> w ( '<STR_LIT>' % os . path . join ( relpath , f ) ) <EOL> idx . close ( ) </s>
