Beispiel #1
0
def caps_doc(tenv, caps_dir, ext='rst', caps_literals=None, output_dir=None, 
             dry_run=False, overwrite=False, 
             allowed_exts=['rst', 'inc', 'txt', '']):
    """Generate documentation from caps files in ``caps_dir``.
    
    Caps files are files such as INSTALL, COPYING, README, which contain 
    documentation worthy content outside docs directory.
    
    :param caps_dir: Directory where caps files reside.
    :param dst_dir: Destination directory where caps files are *copied*.
    :param ext: Enforce all caps files to be in this extension.
    :param caps_literals: Caps files that are treated as literal files.
    :param output_dir: Output directory of generated documents.
    :param dry_run: Dry run only, no copying or other harmful changes.
    :param overwrite: Overwrite the existing file? Defaults to :const:`False`.
    :param allowed_ext: List of allowed extensions.
    
    :returns: List of generated document paths. 
    
    """
    caps_literals = caps_literals or []
    caps_files = []
    
    dir_contents = os.listdir(caps_dir)
    output_dir = output_dir or os.path.abspath(".")
    
    caps_matcher = multi_matcher(caps_literals)
    
    for filename in dir_contents:
        if re.match(r"^[A-Z]{3,}(\.[A-Za-z]+)?$", filename):
            
            # Gather information about the file
            _root, _ext = os.path.splitext(filename)
            f_base = os.path.basename(_root)
            f_ext = _ext.lower()[1:]
            
            # If not allowed extension, skip
            if not any(f_ext == allowed_ext for allowed_ext in allowed_exts):
                continue
            
            output_filename = f_base + "." + ext
            
            filepath = os.path.join(caps_dir, filename)
            output_filepath = os.path.join(output_dir, output_filename)
            
            if not dry_run:
                if overwrite or not os.path.exists(output_filepath):
                    shutil.copy(filepath, output_filepath)
                    log.info("Caps %s copied to %s" % (filepath, output_filepath))
                    
            if caps_matcher(f_base):        
                caps_literal(tenv, output_filepath)
            else:
                caps(tenv, output_filepath)
            
            caps_files.append(output_filepath)
    
    return caps_files
Beispiel #2
0
def builder_inited(app):
    """Sphinx builder-inited callback handler.
    
    :param app: Sphinx app.
    
    """
    conf = app.config
    
    truncate_path_rst = lambda p: truncate_path(p, directory=app.srcdir, 
                                                extension='rst')
    tenv = templating_environment()
    caps_files = []
    docs_files = []
    
    # Gather configuration directories
    docs_dir = conf.sphinkydoc_docs_dir
    caps_dir = conf.sphinkydoc_caps_dir
    module_dir = directory_slash_suffix(conf.sphinkydoc_modules_dir)
    script_dir = directory_slash_suffix(conf.sphinkydoc_scripts_dir)
    
    # Create relative pathed script and module dirs
    try:
        os.makedirs(os.path.join(app.srcdir, module_dir))
    except os.error:
        pass
    
    try:
        os.makedirs(os.path.join(app.srcdir, script_dir))
    except os.error:
        pass
    
    # Convert paths to abspaths if they are not already
    if docs_dir:
        docs_dir = os.path.abspath(docs_dir)
        
    if caps_dir:
        caps_dir = os.path.abspath(caps_dir)
    
    categorized = {}
    # Order of the items in category matchers, one could put this in the list of
    # matchers as tuples but then redefining the order becomes cumbersome.
    category_order = ('included', 'about', 'topic')
    
    category_matchers_caps = {
        'included': multi_matcher(conf.sphinkydoc_caps_included),
        'about': multi_matcher(conf.sphinkydoc_caps_about),
        'topic': multi_matcher(conf.sphinkydoc_caps_topic),
    }
    
    category_matchers = {
        'included': multi_matcher(conf.sphinkydoc_included),
        'about': multi_matcher(conf.sphinkydoc_about),
        'topic': multi_matcher(conf.sphinkydoc_topic),
    }
    
    # Additional docs copier
    if docs_dir and os.path.abspath(app.srcdir) != docs_dir:
        _files = copy_tree(docs_dir, app.srcdir, skip_dirs=['html', '_temp'])
        docs_files = filter(lambda p: not p.endswith('.rst'), 
                            map(truncate_path_rst, _files))    
    # Caps files generation
    if caps_dir:
        _files = caps_doc(tenv, caps_dir, ext="rst", 
                          caps_literals=conf.sphinkydoc_caps_literals, 
                          output_dir=app.srcdir)
        caps_files = filter(lambda p: not p.endswith('.rst'), 
                            map(truncate_path_rst, _files))
        
    # Should we generate HTML shortcut file to caps directory?
    if conf.sphinkydoc_readme_html and caps_dir:
        generate.readme_html_doc(tenv, "docs/html/index.html", 
                                 output_dir=caps_dir)
        
    # Notice that following generates nothing, if the lists are empty:
    _module_files, _script_files = \
        generate.all_doc(tenv, conf.sphinkydoc_modules, conf.sphinkydoc_scripts,
                         module_output_dir=module_dir, 
                         module_overwrite=conf.sphinkydoc_modules_overwrite,
                         script_output_dir=script_dir,
                         script_overwrite=conf.sphinkydoc_scripts_overwrite,
                         source_dir=os.path.abspath(app.srcdir))
        
    module_files = map(truncate_path_rst, _module_files)
    script_files = map(truncate_path_rst, _script_files)
    
    module_files = map(path_to_posix, module_files)
    script_files = map(path_to_posix, script_files)    
    docs_files = map(path_to_posix, docs_files)
    caps_files = map(path_to_posix, caps_files)
    
    for s in set(script_files + module_files).intersection(set(docs_files)):
        docs_files.remove(s)
    
    def categorize(_files, category_matchers):
        # Categorizes the items to dictionary (always to first matching category) 
        for n in _files:
            for cat in category_order:
                if category_matchers[cat](n):
                    categorized.setdefault("%s_files" % cat, []).append(n)
                    break
                
    categorize(caps_files, category_matchers_caps)
    categorize(docs_files, category_matchers)
            
    # Included docs should have different extension
    for inc in categorized.get('included_files', []):
        generate.included_doc(tenv, inc, app.srcdir)
    
    # Index generation
    if conf.sphinkydoc_index:
        tcontext = {
            'caps_files' : caps_files,
            'docs_files' : docs_files,
            'modules_dir' : module_dir,
            'scripts_dir' : script_dir,
            'scripts' : conf.sphinkydoc_scripts,
            'modules' : conf.sphinkydoc_modules,
        }
        tcontext.update(categorized)
        
        generate.index_doc(tenv, tcontext, output_dir=app.srcdir)