2013-02-21 9 views
6

Ich möchte mehrere Versionen einer Dokumentation, die sich in den Abschnitten, die enthalten sind, unterscheiden. Um dies zu erreichen, verwende ich normalerweise entweder die only Direktive oder die ifconfig Erweiterung. Allerdings kann ich keines davon in Kombination mit der toctree Direktive verwenden.Bedingte Toctree in Sphinx

Was ich im Grunde wollen, ist so etwas wie dieses:

.. toctree:: 
    :maxdepth: 2 

    intro 
    strings 
    datatypes 
    numeric 
    .. only:: university 
     complex 

Gibt es eine Möglichkeit, das zu tun?

+0

Diese Antwort könnte helfen: http://stackoverflow.com/a/22024580/407651 – mzjn

Antwort

3

Soweit ich weiß gibt es keine Möglichkeit zu tun, was Sie möchten. Ich habe mit dem gleichen Problem gekämpft, siehe https://github.com/sphinx-doc/sphinx/issues/1717.

Der Grund ist, dass Sphinx alle in einem Baumknoten enthaltenen Zeilen als reinen Text verarbeitet.

Ich sehe zwei Alternativen:

  1. Sie Ihre eigene toctree Richtlinie schreiben kann;
  2. können Sie die toctree einschließlich einer Option erweitern, die die Expression

    .. toctree: 
        :condition: expression 
    
        file1 
    

und passen Sie die doctree Entschlossenheit Ereignis ausgewertet werden soll, enthält.

  1. Sie können Textsubstitutionen für den Rohtext verwenden, der Ihre eigenen Tags definiert. Sie können einen Event-Handler für das source-read -Ereignis implementieren. Zum Beispiel $$condition$$ könnte die Bedingung enthalten, um zu bewerten, während $$$ das Ende des Blocks, das heißt

    .. toctree: 
    
        file1 
        $$mycondition$$ 
        file2 
        $$$ 
    

Je nach mycondition, können Sie die folgenden Blockzeilen entfernen.

Nummer 3 ist ziemlich einfach, während für mich die Nummer 2 die eleganteste ist.

1

Meine Lösung ist, den bedingten Inhalt in einem separaten Verzeichnis 'intern' zu platzieren und ein Tag 'intern' zu verwenden.

In conf.py Ich habe die Linien

if tags.has('internal'): 
    exclude_patters = ['_build'] 
else: 
    exclude_patterns = ['_build', 'intern*'] 

Nun, wenn ich die ‚interne‘ auf der Kommandozeile übergeben ich alles bekommen, sonst alles außer dem Inhalt im internen Verzeichnis.

Das Tag intern kann nur in Kombination verwendet werden.

Die ToC enthält Verweise auf intern/somedoc und sie sind enthalten oder übersprungen wie erforderlich. Ich bekomme eine Reihe von Warnungen über fehlende Seiten, aber diese können zum Schweigen gebracht werden.

1

Eine sehr einfache Lösung besteht darin, zwei separate Indexdateien unter verschiedenen Namen zu verwalten. Sie können angeben, welche Indexdatei standardmäßig in conf.py verwendet werden soll, und sie für einen speziellen Build überschreiben, indem Sie -D master_doc=alternate-index in der Befehlszeile sphinx-build verwenden.

1

Meine vorherige Antwort schlägt fehl, wenn Sie Hierarchien des Inhaltsverzeichnisses haben, also schrieb ich eine einfache toctree-filt Direktive, die Einträge basierend auf einem Präfix zum Eintrag filtern kann. Zum Beispiel, da eine toctree-filt Direktive wie

.. toctree-filt:: 
    :maxdepth: 1 

    user-manual 
    :internal:supervisor-api 
    :draft:new-feature 
    :erik:erik-maths 
    api 

und die Ausschlussliste ['draft','erik'] Einstellung wird in einem wirksamen toctree führen, wie

.. toctree-filt:: 
    :maxdepth: 1 

    user-manual 
    supervisor-api 
    api 

Fügen Sie die folgenden Zeilen zu Ihrer conf.py aussieht:

sys.path.append(os.path.abspath('../sphinx-ext/')) 
extensions = ['toctree_filter'] 
toc_filter_exclude = ['draft','erik'] 

Geben Sie den folgenden Code in /sphinx_ext neben Ihrer /source Verzeichnis:

import re 
from sphinx.directives.other import TocTree 


def setup(app): 
    app.add_config_value('toc_filter_exclude', [], 'html') 
    app.add_directive('toctree-filt', TocTreeFilt) 
    return {'version': '1.0.0'} 

class TocTreeFilt(TocTree): 
    """ 
    Directive to notify Sphinx about the hierarchical structure of the docs, 
    and to include a table-of-contents like tree in the current document. This 
    version filters the entries based on a list of prefixes. We simply filter 
    the content of the directive and call the super's version of run. The 
    list of exclusions is stored in the **toc_filter_exclusion** list. Any 
    table of content entry prefixed by one of these strings will be excluded. 
    If `toc_filter_exclusion=['secret','draft']` then all toc entries of the 
    form `:secret:ultra-api` or `:draft:new-features` will be excuded from 
    the final table of contents. Entries without a prefix are always included. 
    """ 
    hasPat = re.compile('^\s*:(.+):(.+)$') 

    # Remove any entries in the content that we dont want and strip 
    # out any filter prefixes that we want but obviously don't want the 
    # prefix to mess up the file name. 
    def filter_entries(self, entries): 
     excl = self.state.document.settings.env.config.toc_filter_exclude 
     filtered = [] 
     for e in entries: 
      m = self.hasPat.match(e) 
      if m != None: 
       if not m.groups()[0] in excl: 
        filtered.append(m.groups()[1]) 
      else: 
       filtered.append(e) 
     return filtered 

    def run(self): 
     # Remove all TOC entries that should not be on display 
     self.content = self.filter_entries(self.content) 
     return super().run() 

Jetzt brauchen Sie nur Ihre vorhandenen toctree Richtlinien toctree-filt ändern und Sie sind gut zu rollen. Beachten Sie, dass Sphinx Fehler meldet, weil es Dateien findet, die nicht im Dokument enthalten sind. Nicht sicher, wie das zu beheben ist.

Verwandte Themen