Ticket #6495: trac_6495-part3-the-remaining-vs-5.7.beta4.patch

File trac_6495-part3-the-remaining-vs-5.7.beta4.patch, 32.1 KB (added by jhpalmieri, 6 years ago)
  • doc/common/builder.py

    # HG changeset patch
    # User Florent Hivert <Florent.Hivert@univ-rouen.fr>
    # Date 1336416039 -7200
    # Node ID 98bd7e5987cd1965752561a09e68e9acbcfec9c5
    # Parent  b1eb53b45672567c86a69cf52a10b8a6a7f23673
    #6495: Build the reference manual incrementally
    - Add a builder for generating object.inv and pickle files.
    - Add an extension multidocs which merge the various indexes.
    
    diff --git a/doc/common/builder.py b/doc/common/builder.py
    a b  
    6464##########################################
    6565#      Parallel Building Ref Manual      #
    6666##########################################
    67 
    68 def build_ref_doc(doc, lang, format, output_dir, *args, **kwds):
    69     # Build the reference manual for doc
    70     static_dir = os.path.join(output_dir, 'reference', '_static')
    71     bad_static = os.path.join(output_dir, doc, '_static')
    72     # We need to remove the link to "_static" before generating the
    73     # documentation, because the html doc builder writes to the
    74     # _static directory.
    75     if (os.path.isdir(static_dir) and os.path.isdir(bad_static)
    76         and os.path.islink(bad_static)):
    77         os.remove(bad_static)
     67def build_ref_doc(doc, lang, format, *args, **kwds):
    7868    getattr(ReferenceSubBuilder(doc, lang), format)(*args, **kwds)
    79     # The standard Sphinx html build puts a copy of the "static"
    80     # directory in reference/doc/_static.  For the reference manual,
    81     # these are all identical to reference/_static, so delete the
    82     # directory reference/doc/_static and replace it with a link to
    83     # reference/_static.  This saves hundreds of megabytes of disk
    84     # space.
    85     if (os.path.isdir(static_dir) and os.path.isdir(bad_static)
    86         and not os.path.islink(bad_static)):
    87         shutil.rmtree(bad_static)
    88     if os.path.isdir(static_dir):
    89         os.symlink(static_dir, bad_static)
    9069
    9170##########################################
    9271#             Builders                   #
    9372##########################################
     73
    9474def builder_helper(type):
    9575    """
    9676    Returns a function which builds the documentation for
     
    156136            sage: b._output_dir('html')
    157137            '.../devel/sage/doc/output/html/en/tutorial'
    158138        """
     139        if type == "inventory": # put inventories in the html tree
     140            type = "html"
    159141        d = os.path.join(SAGE_DOC, "output", type, self.lang, self.name)
    160142        mkdir(d)
    161143        return d
     
    186168            sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    187169            sage: b = builder.DocBuilder('tutorial')
    188170            sage: b._output_formats()
    189             ['changes', 'html', 'htmlhelp', 'json', 'latex', 'linkcheck', 'pickle', 'web']
     171            ['changes', 'html', 'htmlhelp', 'inventory', 'json', 'latex', 'linkcheck', 'pickle', 'web']
    190172
    191173        """
    192174        #Go through all the attributes of self and check to
     
    238220    latex = builder_helper('latex')
    239221    changes = builder_helper('changes')
    240222    linkcheck = builder_helper('linkcheck')
     223    # import the customized builder for object.inv files
     224    inventory = builder_helper('inventory')
     225
     226##########################################
     227#      Parallel Building Ref Manual      #
     228##########################################
     229def build_other_doc(document, name, *args, **kwds):
     230    logger.warning("\nBuilding %s.\n" % document)
     231    getattr(get_builder(document), name)(*args, **kwds)
    241232
    242233
    243234class AllBuilder(object):
     
    259250        This is the function which goes through all of the documents
    260251        and does the actual building.
    261252        """
     253        import time
     254        start = time.time()
    262255        docs = self.get_all_documents()
    263256        refs = [x for x in docs if x.endswith('reference')]
    264257        others = [x for x in docs if not x.endswith('reference')]
    265         for document in others:
    266             logger.warning("\nBuilding %s.\n" % document)
    267             getattr(get_builder(document), name)(*args, **kwds)
    268         # Build the reference manual twice to resolve references.
    269         # That is, build once to construct the intersphinx inventory
    270         # files, and then build the second time for real.  So the
    271         # first build should be as fast as possible; thus do an html
    272         # build first.
     258        # Build the reference manual twice to resolve references.  That is,
     259        # build once with the inventory builder to construct the intersphinx
     260        # inventory files, and then build the second time for real.  So the
     261        # first build should be as fast as possible;
    273262        logger.warning("\nBuilding reference manual, first pass.\n")
    274263        global ALLSPHINXOPTS
    275         ALLSPHINXOPTS += ' -Q '
     264        #ALLSPHINXOPTS += ' -Q -D multidoc_first_pass=1'
     265        ALLSPHINXOPTS += ' -D multidoc_first_pass=1'
    276266        for document in refs:
    277             getattr(get_builder(document), 'html')(*args, **kwds)
     267            getattr(get_builder(document), 'inventory')(*args, **kwds)
    278268        logger.warning("Building reference manual, second pass.\n")
     269        ALLSPHINXOPTS = ALLSPHINXOPTS.replace(
     270            'multidoc_first_pass=1', 'multidoc_first_pass=0')
    279271        ALLSPHINXOPTS = ALLSPHINXOPTS.replace('-Q', '-q') + ' '
    280272        for document in refs:
    281273            getattr(get_builder(document), name)(*args, **kwds)
    282274
     275        # build the other documents in parallel
     276        from multiprocessing import Pool, cpu_count
     277        pool = Pool(int(os.environ.get('SAGE_NUM_THREADS', 1)))
     278        for document in others:
     279            pool.apply_async(build_other_doc,
     280                             (document, name)+args, kwds)
     281        pool.close()
     282        pool.join()
     283        logger.warning("Elapsed time = %s."%(time.time()-start))
     284        logger.warning("Done compiling the doc !")
     285
    283286    def get_all_documents(self):
    284287        """
    285288        Returns a list of all of the documents. A document is a directory within one of
     
    377380            sage: b._output_dir('html')
    378381            '.../devel/sage/doc/output/html/en/reference'
    379382        """
     383        if type == "inventory": # put inventories in the html tree
     384            type = "html"
    380385        return mkdir(os.path.join(SAGE_DOC, "output", type, lang, self.name))
    381386
    382387    def _wrapper(self, format, *args, **kwds):
     
    388393            refdir = os.path.join(SAGE_DOC, lang, self.name)
    389394            if not os.path.exists(refdir):
    390395                continue
    391 
    392396            output_dir = self._output_dir(format, lang)
    393             getattr(DocBuilder(self.name, lang), format)(*args, **kwds)
    394 
    395397            from multiprocessing import Pool, cpu_count
    396398            # Determine the number of threads from the environment variable
    397399            # SAGE_NUM_THREADS.
    398400            pool = Pool(int(os.environ.get('SAGE_NUM_THREADS', 1)))
     401
    399402            for doc in self.get_all_documents(refdir):
    400403                pool.apply_async(build_ref_doc,
    401                                  (doc, lang, format,
    402                                   os.path.split(output_dir)[0]) + args, kwds)
     404                                 (doc, lang, format) + args, kwds)
    403405            pool.close()
    404406            pool.join()
    405             if format == 'html':
    406                 # html build: combine the todo lists from the
    407                 # different modules.
    408                 todofile = os.path.join(output_dir, 'todolist', 'index.html')
    409                 old = open(todofile).read()
    410                 note = "The combined to do list is only available in the html version of the reference manual."
    411                 preamble = old.find(note)
    412                 postamble = preamble + len(note)
    413                 if preamble != -1:
    414                     old_todofile = os.path.join(output_dir, 'todolist', 'index-old.html')
    415                     shutil.move(todofile, old_todofile)
    416                     new = open(todofile, 'w')
    417                     new.write(old[:preamble])
    418                     for f in os.listdir(output_dir):
    419                         index = os.path.join(output_dir, f, 'index.html')
    420                         if (f != 'todolist' and os.path.exists(index)):
    421                             html = open(index).read()
    422                             start = html.find('<div class="admonition-todo')
    423                             end = html.find('<div class="section" id="indices-and-tables">')
    424                             if start != -1:
    425                                 html = html[start:end].replace('sage/%s' %f,
    426                                                                '../%s/sage/%s' % (f, f))
    427                                 new.write(html)
    428                     new.write(old[postamble:])
    429                     new.close()
     407            # The html refman must be build at the end to ensure correct
     408            # merging of indexes and inventories.
     409            getattr(DocBuilder(self.name, lang), format)(*args, **kwds)
    430410
    431                 logger.warning('''
    432 Build finished.  The Sage reference manual can be found in
    433 
    434   %s
    435 ''' % (os.path.join(output_dir, 'index.html')))
    436411            # PDF: we need to build master index file which lists all
    437412            # of the PDF file.  So we create an html file, based on
    438413            # the file index.html from the "website" target.
     
    532507        Returns a list of all reference manual components to build.
    533508        We add a component name if it's a subdirectory of the manual's
    534509        directory and contains a file named 'index.rst'.
     510
     511        EXAMPLES::
     512
     513            sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
     514            sage: b = builder.ReferenceBuilder('reference')
     515            sage: refdir = os.path.join(os.environ['SAGE_DOC'], 'en', b.name)
     516            sage: b.get_all_documents(refdir)
    535517        """
    536518        documents = []
    537519
    538520        for doc in os.listdir(refdir):
    539521            if os.path.exists(os.path.join(refdir, doc, 'index.rst')):
    540522                documents.append(os.path.join(self.name, doc))
    541        
    542         return documents
     523
     524        return sorted(documents)
    543525
    544526
    545527class ReferenceSubBuilder(DocBuilder):
     
    674656        except IOError as err:
    675657            logger.debug("Failed to open Sphinx environment: %s", err)
    676658            pass
    677                                            
     659
    678660    def update_mtimes(self):
    679661        """
    680662        Updates the modification times for ReST files in the Sphinx
     
    843825
    844826            sage: import os, sys; sys.path.append(os.environ['SAGE_DOC']+'/common/'); import builder
    845827            sage: import builder
    846             sage: builder.ReferenceBuilder("reference").auto_rest_filename("sage.combinat.partition")
     828            sage: builder.ReferenceSubBuilder("reference").auto_rest_filename("sage.combinat.partition")
    847829            '.../devel/sage/doc/en/reference/sage/combinat/partition.rst'
    848830        """
    849831        return self.dir + os.path.sep + module_name.replace('.',os.path.sep) + '.rst'
  • doc/common/conf.py

    diff --git a/doc/common/conf.py b/doc/common/conf.py
    a b  
    1919
    2020# Add any Sphinx extension module names here, as strings. They can be extensions
    2121# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
    22 extensions = ['sage_autodoc',  'sphinx.ext.graphviz',
     22extensions = ['inventory_builder', 'multidocs',
     23              'sage_autodoc',  'sphinx.ext.graphviz',
    2324              'sphinx.ext.inheritance_diagram', 'sphinx.ext.todo',
    2425              'sphinx.ext.extlinks']
    2526# We do *not* fully initialize intersphinx since we call it by hand
     
    213214# If false, no module index is generated.
    214215#html_use_modindex = True
    215216
     217# A list of prefixes that are ignored for sorting the Python module index ( if
     218# this is set to ['foo.'], then foo.bar is shown under B, not F). Works only
     219# for the HTML builder currently.
     220modindex_common_prefix = ['sage.']
     221
    216222# If false, no index is generated.
    217223#html_use_index = True
    218224
  • new file doc/common/inventory_builder.py

    diff --git a/doc/common/inventory_builder.py b/doc/common/inventory_builder.py
    new file mode 100644
    - +  
     1# -*- coding: utf-8 -*-
     2"""
     3    inventory builder
     4    ~~~~~~~~~~~~~~~~~
     5
     6    A customized HTML builder which only generate intersphinx "object.inv"
     7    inventory files and pickle files. The documentation files are not writen.
     8"""
     9from sphinx.builders.html import StandaloneHTMLBuilder
     10from sphinx.util.console import bold
     11
     12class InventoryBuilder(StandaloneHTMLBuilder):
     13    """
     14    A customized HTML builder which only generate intersphinx "object.inv"
     15    inventory files and pickle files. The documentation files are not writen.
     16    """
     17    name = "inventory"
     18
     19    def write_doc(self, docname, doctree):
     20        """
     21        Don't write any doc
     22        """
     23
     24    def finish(self):
     25        """
     26        Only write the inventory files.
     27        """
     28        self.write_buildinfo()
     29        self.dump_inventory()
     30
     31    def removed_method_error(self):
     32        """
     33        Raise an error if this method is called.
     34
     35        This is just for making sure that some writer methods are indeed
     36        deactivated.
     37        """
     38        raise RuntimeError, "This function souldn't be called in \"%s\" builder"%(self.name)
     39
     40    copy_image_files = removed_method_error
     41    copy_download_files = removed_method_error
     42    copy_static_files = removed_method_error
     43    handle_finish = removed_method_error
     44
     45def setup(app):
     46    app.add_builder(InventoryBuilder)
     47
  • new file doc/common/multidocs.py

    diff --git a/doc/common/multidocs.py b/doc/common/multidocs.py
    new file mode 100644
    - +  
     1# -*- coding: utf-8 -*-
     2"""
     3    multi documentations in Sphinx
     4    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     5
     6    The goal of this extension is to manage a multi documentation in Sphinx.
     7    To be able to compile Sage huge documentation in parallel, the
     8    documentation is cut in a bunch of independent documentations called a
     9    "subdoc", which are compiled separately. There is a master document which
     10    points to all the subdocs. The intersphinx extension ensure that the
     11    cross-link between the subdocs are correctly resolved. However some work
     12    is needed to build a global index. This is the goal of multidocs.
     13
     14    More precisely this extension ensure the correct merging of
     15    - the todo list if this extension is activated;
     16    - the python indexes;
     17    - the list of python modules;
     18    - the javascript index;
     19    - the citations.
     20"""
     21import cPickle, os, sys
     22import sphinx
     23from sphinx.util.console import bold
     24
     25
     26CITE_FILENAME = 'citations.pickle'
     27
     28
     29def merge_environment(app, env):
     30    """
     31    Merges the following attributes of the sub-docs environment into the main
     32    environment:
     33    - todo_all_todos              # ToDo's
     34    - indexentries                # global python index
     35    - all_docs                    # needed by the js index
     36    - citations                   # citations
     37
     38    - domaindata['py']['modules'] # list of python modules
     39    """
     40    app.info(bold('Merging environment/index files...'))
     41    for curdoc in app.env.config.multidocs_subdoc_list:
     42        app.info("    %s:"%curdoc, nonl=1)
     43        docenv = get_env(app, curdoc)
     44        if docenv is not None:
     45            fixpath = lambda path: os.path.join(curdoc, path)
     46            app.info(" %s todos, %s index, %s citations"%(
     47                    len(docenv.todo_all_todos),
     48                    len(docenv.indexentries),
     49                    len(docenv.citations)
     50                    ), nonl=1)
     51
     52            # merge the todo links
     53            for dct in docenv.todo_all_todos:
     54                dct['docname']=fixpath(dct['docname'])
     55            env.todo_all_todos += docenv.todo_all_todos
     56            # merge the html index links
     57            newindex = {}
     58            for ind in docenv.indexentries:
     59                if ind.startswith('sage/'):
     60                    newind = fixpath(ind)
     61                    newindex[newind] = docenv.indexentries[ind]
     62                else:
     63                    newindex[ind] = docenv.indexentries[ind]
     64            env.indexentries.update(newindex)
     65            # merge the all_docs links, needed by the js index
     66            newalldoc = {}
     67            for ind in docenv.all_docs:
     68                newalldoc[fixpath(ind)]=docenv.all_docs[ind]
     69            env.all_docs.update(newalldoc)
     70            # needed by env.check_consistency (sphinx.environement, line 1734)
     71            for ind in newalldoc:
     72                env.metadata[ind] = {}
     73            # merge the citations
     74            newcite = {}
     75            for ind, (path, tag) in docenv.citations.iteritems():
     76                # TODO: Warn on conflicts
     77                newcite[ind]=(fixpath(path), tag)
     78            env.citations.update(newcite)
     79            # merge the py:module indexes
     80            newmodules = {}
     81            for ind,(modpath,v1,v2,v3) in (
     82                docenv.domaindata['py']['modules'].iteritems()):
     83                newmodules[ind] = (fixpath(modpath),v1,v2,v3)
     84            env.domaindata['py']['modules'].update(newmodules)
     85            app.info(", %s modules"%(len(newmodules)))
     86    app.info('... done (%s todos, %s index, %s citations, %s modules)'%(
     87            len(env.todo_all_todos),
     88            len(env.indexentries),
     89            len(env.citations),
     90            len(env.domaindata['py']['modules'])))
     91    write_citations(app, env.citations)
     92
     93def get_env(app, curdoc):
     94    """
     95    Get the environement of a sub-doc from the pickle
     96    """
     97    from sphinx.application import ENV_PICKLE_FILENAME
     98    filename = os.path.join(
     99        app.env.doctreedir, curdoc, ENV_PICKLE_FILENAME)
     100    try:
     101        f = open(filename, 'rb')
     102    except IOError:
     103        app.info("")
     104        app.warn("Unable to fetch %s "%filename)
     105        return None
     106    docenv = cPickle.load(f)
     107    f.close()
     108    return docenv
     109
     110def merge_js_index(app):
     111    """
     112    Merge the JS indexes of the sub-docs into the main JS index
     113    """
     114    app.info('')
     115    app.info(bold('Merging js index files...'))
     116    mapping = app.builder.indexer._mapping
     117    for curdoc in app.env.config.multidocs_subdoc_list:
     118        app.info("    %s:"%curdoc, nonl=1)
     119        fixpath = lambda path: os.path.join(curdoc, path)
     120        index = get_js_index(app, curdoc)
     121        if index is not None:
     122            # merge the mappings
     123            app.info(" %s js index entries"%(len(index._mapping)))
     124            for (ref, locs) in index._mapping.iteritems():
     125                newmapping = set(map(fixpath, locs))
     126                if ref in mapping:
     127                    newmapping = mapping[ref] | newmapping
     128                mapping[unicode(ref)] = newmapping
     129            # merge the titles
     130            titles = app.builder.indexer._titles
     131            for (res, title) in index._titles.iteritems():
     132                titles[fixpath(res)] = title
     133            # TODO: merge indexer._objtypes, indexer._objnames as well
     134
     135            # Setup source symbolic links
     136            dest = os.path.join(app.outdir, "_sources", curdoc)
     137            if not os.path.exists(dest):
     138                os.symlink(os.path.join("..", curdoc, "_sources"), dest)
     139    app.info('... done (%s js index entries)'%(len(mapping)))
     140    app.info(bold('Writing js search indexes...'), nonl=1)
     141    return [] # no extra page to setup
     142
     143def get_js_index(app, curdoc):
     144    """
     145    Get the JS index of a sub-doc from the file
     146    """
     147    from sphinx.search import IndexBuilder, languages
     148    # FIXME: find the correct lang
     149    indexer = IndexBuilder(app.env, 'en',
     150                           app.config.html_search_options)
     151    indexfile = os.path.join(app.outdir, curdoc, 'searchindex.js')
     152    try:
     153        f = open(indexfile, 'rb')
     154    except IOError:
     155        app.info("")
     156        app.warn("Unable to fetch %s "%indexfile)
     157        return None
     158    indexer.load(f, sphinx.search.js_index)
     159    f.close()
     160    return indexer
     161
     162
     163mustbefixed = ['search', 'genindex', 'genindex-all'
     164               'py-modindex', 'searchindex.js']
     165def fix_path_html(app, pagename, templatename, ctx, event_arg):
     166    """
     167    Fixes the context so that the files
     168    - search.html
     169    - genindex.html
     170    - py-modindex.html
     171    points to the right place, that is in
     172        reference/
     173    instead of
     174        reference/subdocument
     175    """
     176    # sphinx/builder/html.py line 702
     177    # def pathto(otheruri, resource=False,
     178    #            baseuri=self.get_target_uri(pagename)):
     179    old_pathto = ctx['pathto']
     180    def sage_pathto(otheruri, *args, **opts):
     181        if otheruri in mustbefixed:
     182            otheruri = os.path.join("..", otheruri)
     183        return old_pathto(otheruri, *args, **opts)
     184    ctx['pathto'] = sage_pathto
     185
     186
     187def write_citations(app, citations):
     188    """
     189    Pickle the citation in a file
     190    """
     191    import cPickle
     192    file = open(os.path.join(app.outdir, CITE_FILENAME), 'wb')
     193    cPickle.dump(citations, file)
     194    file.close()
     195    app.info("Saved pickle file: %s"%CITE_FILENAME)
     196
     197
     198def fetch_citation(app, env):
     199    """
     200    Fetch the global citation index from the refman to allows for cross
     201    references.
     202    """
     203    app.builder.info(bold('loading cross citations... '), nonl=1)
     204    filename = os.path.join(app.outdir, '..', CITE_FILENAME)
     205    if not os.path.exists(filename):
     206        return
     207    import cPickle
     208    file = open(filename, 'rb')
     209    try:
     210        cache = cPickle.load(file)
     211    except:
     212        app.warn("Cache file '%s' is corrupted; ignoring it..."% filename)
     213        return
     214    else:
     215        app.builder.info("done (%s citations)."%len(cache))
     216    finally:
     217        file.close()
     218    cite = env.citations
     219    for ind, (path, tag) in cache.iteritems():
     220        if ind not in cite: # don't override local citation
     221            cite[ind]=(os.path.join("..", path), tag)
     222
     223def init_subdoc(app):
     224    """
     225    Init the merger depending on if we are compiling a subdoc or the master
     226    doc itself.
     227    """
     228    if app.config.multidocs_is_master:
     229        app.info(bold("Compiling the master document"))
     230        app.connect('env-updated', merge_environment)
     231        app.connect('html-collect-pages', merge_js_index)
     232    else:
     233        app.info(bold("Compiling a sub-document"))
     234        app.connect('env-updated', fetch_citation)
     235        app.connect('html-page-context', fix_path_html)
     236
     237        # Monkey patch copy_static_files to make a symlink to "../"
     238        def link_static_files():
     239            """
     240            Instead of copying static files, make a link to the master static file.
     241            See sphinx/builder/html.py line 536::
     242
     243                class StandaloneHTMLBuilder(Builder):
     244                [...]
     245                    def copy_static_files(self):
     246                    [...]
     247            """
     248            app.builder.info(bold('linking _static directory.'))
     249            static_dir = os.path.join(app.builder.outdir, '_static')
     250            master_static_dir = os.path.join('..', '_static')
     251            if not os.path.isdir(static_dir):
     252                os.symlink(master_static_dir, static_dir)
     253
     254        app.builder.copy_static_files = link_static_files
     255
     256    if app.config.multidoc_first_pass == 1:
     257        app.config.intersphinx_mapping = {}
     258
     259
     260def setup(app):
     261    app.add_config_value('multidocs_is_master', True, True)
     262    app.add_config_value('multidocs_subdoc_list', [], True)
     263    app.add_config_value('multidoc_first_pass', 0, False)   # 1 = deactivate the loading of the inventory
     264    app.connect('builder-inited', init_subdoc)
  • doc/en/reference/conf.py

    diff --git a/doc/en/reference/conf.py b/doc/en/reference/conf.py
    a b  
    6161#Ignore all .rst in the _sage subdirectory
    6262exclude_trees = exclude_trees + ['_sage']
    6363
    64 # List of directories, relative to source directory, that shouldn't be
    65 # searched for source files.
    66 exclude_trees = exclude_trees + [
     64multidocs_is_master = True
     65
     66# List of subdocs
     67multidocs_subdoc_list = [
    6768    'algebras',
    6869    'arithgroup',
    6970    'calculus',
     
    101102    'notebook',
    102103    'number_fields',
    103104    'numerical',
    104     'options',
    105105    'padics',
    106106    'parallel',
    107107    'plane_curves',
     
    115115    'rings',
    116116    'rings_numerical',
    117117    'rings_standard',
    118     'sage',
    119     'sagenb',
    120118    'schemes',
    121119    'semirings',
    122120    'stats',
    123121    'structure',
    124     'tensor',
    125     'todolist'
     122    'tensor'
    126123    ]
     124
     125# List of directories, relative to source directory, that shouldn't be
     126# searched for source files.
     127exclude_trees += multidocs_subdoc_list + [
     128    'sage', 'sagenb', 'options'
     129    ]
  • doc/en/reference/conf_sub.py

    diff --git a/doc/en/reference/conf_sub.py b/doc/en/reference/conf_sub.py
    a b  
    6969
    7070#Ignore all .rst in the _sage subdirectory
    7171exclude_trees = exclude_trees + ['_sage']
     72
     73multidocs_is_master = False
  • doc/en/reference/footer.txt

    diff --git a/doc/en/reference/footer.txt b/doc/en/reference/footer.txt
    a b  
    1 
    2 .. todolist::
    3 
    41Indices and Tables
    52==================
    63
    7 .. toctree::
    8    :maxdepth: 1
    9 
    10 * :ref:`genindex`
    11 * :ref:`modindex`
    12 * :ref:`search`
     4* `Index <../genindex.html>`_
     5* `Module Index <../py-modindex.html>`_
     6* `Search Page <../search.html>`_
  • doc/en/reference/index.rst

    diff --git a/doc/en/reference/index.rst b/doc/en/reference/index.rst
    a b  
    1414Sage, and should produce exactly the same output as in this manual,
    1515except for line breaks.
    1616
    17 The Sage command line is briefly described in `The Sage Command Line
    18 <cmd/index.html>`_, which lists the command line options. For more
     17The Sage command line is briefly described in :doc:`The Sage Command Line
     18<cmd/index>`, which lists the command line options. For more
    1919details about the command line, see the Sage tutorial.
    2020
    21 The Sage graphical user interface is described in `The Sage Notebook
    22 <notebook/index.html>`_. This graphical user interface is unusual in
     21The Sage graphical user interface is described in :doc:`The Sage Notebook
     22<notebook/index>`. This graphical user interface is unusual in
    2323that it operates via your web browser. It provides you with Sage
    2424worksheets that you can edit and evaluate, which contain scalable
    2525typeset mathematics and beautiful antialiased images.
     
    3434Table of Contents
    3535=================
    3636
    37    * `The Sage Command Line <cmd/index.html>`_
    38    * `The Sage Notebook <notebook/index.html>`_
    39  
     37* :doc:`The Sage Command Line <cmd/index>`
     38* :doc:`The Sage Notebook <notebook/index>`
     39
    4040Calculus, Plotting
    4141------------------
    42  
    43    * `Symbolic Calculus <calculus/index.html>`_
    44    * `Constants <constants/index.html>`_
    45    * `Functions <functions/index.html>`_
    46    * `2D Graphics <plotting/index.html>`_
    47    * `3D Graphics <plot3d/index.html>`_
    48  
     42
     43* :doc:`Symbolic Calculus <calculus/index>`
     44* :doc:`Constants <constants/index>`
     45* :doc:`Functions <functions/index>`
     46* :doc:`2D Graphics <plotting/index>`
     47* :doc:`3D Graphics <plot3d/index>`
     48
    4949Combinatorics, Discrete Mathematics
    5050-----------------------------------
    51  
    52    * `Combinatorics <combinat/index.html>`_
    53    * `Graph Theory <graphs/index.html>`_
    54  
     51
     52* :doc:`Combinatorics <combinat/index>`
     53* :doc:`Graph Theory <graphs/index>`
     54
    5555Structures, Coercion, Categories
    5656--------------------------------
    57  
    58    * `Basic Structures <structure/index.html>`_
    59    * `Coercion <coercion/index.html>`_
    60    * `Category Theory and Categories <categories/index.html>`_
    61  
     57
     58* :doc:`Basic Structures <structure/index>`
     59* :doc:`Coercion <coercion/index>`
     60* :doc:`Category Theory and Categories <categories/index>`
     61
    6262Rings, Fields, Algebras
    6363-----------------------
    64  
    65    * `General Rings, Ideals, and Morphisms <rings/index.html>`_
    66    * `Standard Commutative Rings <rings_standard/index.html>`_
    67    * `Fixed and Arbitrary Precision Numerical Fields <rings_numerical/index.html>`_
    68    * `Finite Rings <finite_rings/index.html>`_
    69    * `Algebraic Number Fields <number_fields/index.html>`_
    70    * `Function Fields <function_fields/index.html>`_
    71    * `p-Adics <padics/index.html>`_
    72    * `Polynomial Rings <polynomial_rings/index.html>`_
    73    * `Power Series Rings <power_series/index.html>`_
    74    * `Standard Semirings <semirings/index.html>`_
    75    * `Algebras <algebras/index.html>`_
    76    * `Quaternion Algebras <quat_algebras/index.html>`_
    77  
     64
     65* :doc:`General Rings, Ideals, and Morphisms <rings/index>`
     66* :doc:`Standard Commutative Rings <rings_standard/index>`
     67* :doc:`Fixed and Arbitrary Precision Numerical Fields <rings_numerical/index>`
     68* :doc:`Finite Rings <finite_rings/index>`
     69* :doc:`Algebraic Number Fields <number_fields/index>`
     70* :doc:`Function Fields <function_fields/index>`
     71* :doc:`p-Adics <padics/index>`
     72* :doc:`Polynomial Rings <polynomial_rings/index>`
     73* :doc:`Power Series Rings <power_series/index>`
     74* :doc:`Standard Semirings <semirings/index>`
     75* :doc:`Algebras <algebras/index>`
     76* :doc:`Quaternion Algebras <quat_algebras/index>`
     77
    7878Groups, Monoids, Matrices, Modules
    7979----------------------------------
    80  
    81    * `Groups <groups/index.html>`_
    82    * `Monoids <monoids/index.html>`_
    83    * `Matrices and Spaces of Matrices <matrices/index.html>`_
    84    * `Modules <modules/index.html>`_
     80
     81* :doc:`Groups <groups/index>`
     82* :doc:`Monoids <monoids/index>`
     83* :doc:`Matrices and Spaces of Matrices <matrices/index>`
     84* :doc:`Modules <modules/index>`
    8585
    8686Geometry and Topology
    8787---------------------
    8888
    89    * `Combinatorial Geometry <geometry/index.html>`_
    90    * `Cell Complexes and their Homology <homology/index.html>`_
    91    * `Differential Forms <tensor/index.html>`_
     89* :doc:`Combinatorial Geometry <geometry/index>`
     90* :doc:`Cell Complexes and their Homology <homology/index>`
     91* :doc:`Differential Forms <tensor/index>`
    9292
    9393Number Theory, Algebraic Geometry
    9494---------------------------------
    9595
    96    * `Quadratic Forms <quadratic_forms/index.html>`_
    97    * `L-Functions <lfunctions/index.html>`_
    98    * `Schemes <schemes/index.html>`_
    99    * `Elliptic, Plane, and Hyperelliptic Curves <plane_curves/index.html>`_
    100    * `Arithmetic Subgroups of SL_2(Z) <arithgroup/index.html>`_
    101    * `General Hecke Algebras and Hecke Modules <hecke/index.html>`_
    102    * `Modular Symbols <modsym/index.html>`_
    103    * `Modular Forms <modfrm/index.html>`_
    104    * `Modular Abelian Varieties <modabvar/index.html>`_
    105    * `Miscellaneous Modular-Form-Related Modules <modmisc/index.html>`_
     96* :doc:`Quadratic Forms <quadratic_forms/index>`
     97* :doc:`L-Functions <lfunctions/index>`
     98* :doc:`Schemes <schemes/index>`
     99* :doc:`Elliptic, Plane, and Hyperelliptic Curves <plane_curves/index>`
     100* :doc:`Arithmetic Subgroups of SL_2(Z) <arithgroup/index>`
     101* :doc:`General Hecke Algebras and Hecke Modules <hecke/index>`
     102* :doc:`Modular Symbols <modsym/index>`
     103* :doc:`Modular Forms <modfrm/index>`
     104* :doc:`Modular Abelian Varieties <modabvar/index>`
     105* :doc:`Miscellaneous Modular-Form-Related Modules <modmisc/index>`
    106106
    107107Miscellaneous Mathematics
    108108-------------------------
    109109
    110    * `Games <games/index.html>`_
    111    * `Symbolic Logic <logic/index.html>`_
    112    * `SAT solvers <sat/index.html>`_
    113    * `Cryptography <cryptography/index.html>`_
    114    * `Numerical Optimization <numerical/index.html>`_
    115    * `Probability <probability/index.html>`_
    116    * `Statistics <stats/index.html>`_
    117    * `Quantitative Finance <finance/index.html>`_
    118    * `Coding Theory <coding/index.html>`_
     110* :doc:`Games <games/index>`
     111* :doc:`Symbolic Logic <logic/index>`
     112* :doc:`SAT solvers <sat/index>`
     113* :doc:`Cryptography <cryptography/index>`
     114* :doc:`Numerical Optimization <numerical/index>`
     115* :doc:`Probability <probability/index>`
     116* :doc:`Statistics <stats/index>`
     117* :doc:`Quantitative Finance <finance/index>`
     118* :doc:`Coding Theory <coding/index>`
    119119
    120120Interfaces, Databases, Miscellany
    121121---------------------------------
    122122
    123    * `Interpreter Interfaces <interfaces/index.html>`_
    124    * `C/C++ Library Interfaces <libs/index.html>`_
    125    * `Databases <databases/index.html>`_
    126    * `Parallel Computing <parallel/index.html>`_
    127    * `Miscellaneous <misc/index.html>`_
     123* :doc:`Interpreter Interfaces <interfaces/index>`
     124* :doc:`C/C++ Library Interfaces <libs/index>`
     125* :doc:`Databases <databases/index>`
     126* :doc:`Parallel Computing <parallel/index>`
     127* :doc:`Miscellaneous <misc/index>`
    128128
    129129Other
    130130-----
    131131
    132    * `Sage's To Do List <todolist/index.html>`_
    133    * `History and License <history_and_license/index.html>`_
     132.. toctree::
     133   :maxdepth: 2
    134134
    135 .. include:: footer.txt
     135   todolist
     136
     137* :doc:`History and License <history_and_license/index>`
     138
     139Indices and Tables
     140------------------
     141
     142* :ref:`genindex`
     143* :ref:`modindex`
     144* :ref:`search`