Sphinx ****** `Sphinx `_ est un outil écrit en python permettant la génération de documentation à partir de source écrit en RestructuredText. le format de sortie peut être: * latex * html * html help windows * ebook / epub * text * doctest * man Installation / Premier pas ========================== Pour installer sphinx il faut: * `python `_ * `setuptools `_ puis lancer la commande :: easy_install -U Sphinx Sous Debian il suffit d'installer pip .. code-block:: bash apt-get install python-pip pip install sphinx Pour créer un nouveau projet rien de plus simple, créer un dossier contenant votre futur projet. Dans ce dossier lancer la commande suivante :: sphinx-quickstart cela va créer: - arborescence nécessaire au projet - le fichier de configuration conf.py - un buildeur du type **make.bat** pour transformer vos sources en html rien de plus simple :: make.bat html ou :: sphinx-build -b html sourcedir builddir Themes et Plugins ================= Sphinx accepte de nombreux themes et plugins que vous retrouver respectivement dans le répertoire themes et ext. les plugins ou extensions très utiles sont: * sphinx.ext.todo * sphinx.ext.graphviz * sphinx.ext.dotplus * sphinx.ext.sphinxgooglechart * sphinxcontrib.aafig Pour le plugins sphinxcontrib.aafig il faut pour l'installer .. code-block:: bash pip install sphinxcontrib-aafig puis dans son fichier conf.py rajouter l'extension .. code-block:: python extensions = ['sphinxcontrib.aafig'] et enfin si besoin modifier le fichier sphinxcontrib/aafig.py en ajoutant .. code-block:: python from docutils.parsers.rst import directives #ADD BY FAO from docutils.parsers.rst.directives import images #END ADD BY FAO ce plugin permet de générer des schéma via une description ASCII :: premier exemple .. aafig:: :textual: +-------+ +-----------+ | Hello +-------->+ aafigure! | +-------+ +-----------+ deuxième exemple .. aafig:: :textual: +---------+ +---------+ +---------+ | Shape | | Line | | Point | +---------+ +---------+ 2 +---------+ | draw +<--------+ start +----O+ x | | move +<-+ | end | | y | +---------+ \ +---------+ +---------+ \ \ +---------+ +--+ Circle | +---------+ | center | | radius | +---------+ .. note:: si vous souhaitez avec aafigure générer des images png ou jpg il faut installer PIL via .. code-block:: bash pip uninstall pil pil install Pillow un excellent thème est https://github.com/snide/sphinx_rtd_theme On peut ajouter dans le fichier breadcrumbs.html de ce theme sous le bloc display_bitbucket les éléments suivant .. code-block:: html {% elif show_source and has_source and sourcename %} {% endif %} au lieu de .. code-block:: html {% elif show_source and has_source and sourcename %} Edit {% endif %} Utilisation de flasksphinx ========================== Il est possible d'utiliser le module perso flask-sphinx qui permet de maintenir un site sphinx via un navigateur. Installation ------------ l'installation du minimum .. code-block:: bash apt-get install python-pip pip install flask pip install flask-login pip install flasksphinx ln -s /usr/local/lib/python2.7/dist-packages/flasksphinx/themes/rtdflask /usr/local/lib/python2.7/dist-packages/sphinx/themes/rtdflask on génère des dossiers pour notre application .. code-block:: bash mkdir /var/www/mysite mkdir /var/www/mydoc cd /var/www/mydoc sphinx-quickstart .. code-block:: bash Welcome to the Sphinx 1.3b1 quickstart utility. Please enter values for the following settings (just press Enter to accept a default value, if one is given in brackets). Enter the root path for documentation. > Root path for the documentation [.]: You have two options for placing the build directory for Sphinx output. Either, you use a directory "_build" within the root path, or you separate "source" and "build" directories within the root path. > Separate source and build directories (y/n) [n]: y Inside the root directory, two more directories will be created; "_templates" for custom HTML templates and "_static" for custom stylesheets and other static files. You can enter another prefix (such as ".") to replace the underscore. > Name prefix for templates and static dir [_]: The project name will occur in several places in the built documentation. > Project name: mydoc > Author name(s): Frédéric Aoustin Sphinx has the notion of a "version" and a "release" for the software. Each version can have multiple releases. For example, for Python the version is something like 2.5 or 3.0, while the release is something like 2.5.1 or 3.0a1. If you don't need this dual structure, just set both to the same value. > Project version: 1 > Project release [1]: 0 If the documents are to be written in a language other than English, you can select a language here by its language code. Sphinx will then translate text that it generates into that language. For a list of supported codes, see http://sphinx-doc.org/config.html#confval-language. > Project language [en]: fr The file name suffix for source files. Commonly, this is either ".txt" or ".rst". Only files with this suffix are considered documents. > Source file suffix [.rst]: One document is special in that it is considered the top node of the "contents tree", that is, it is the root of the hierarchical structure of the documents. Normally, this is "index", but if your "index" document is a custom template, you can also set this to another filename. > Name of your master document (without suffix) [index]: Sphinx can also add configuration for epub output: > Do you want to use the epub builder (y/n) [n]: Please indicate if you want to use one of the following Sphinx extensions: > autodoc: automatically insert docstrings from modules (y/n) [n]: > doctest: automatically test code snippets in doctest blocks (y/n) [n]: > intersphinx: link between Sphinx documentation of different projects (y/n) [n]: > todo: write "todo" entries that can be shown or hidden on build (y/n) [n]: > coverage: checks for documentation coverage (y/n) [n]: > pngmath: include math, rendered as PNG images (y/n) [n]: > mathjax: include math, rendered in the browser by MathJax (y/n) [n]: > ifconfig: conditional inclusion of content based on config values (y/n) [n]: > viewcode: include links to the source code of documented Python objects (y/n) [n]: A Makefile and a Windows command file can be generated for you so that you only have to run e.g. `make html' instead of invoking sphinx-build directly. > Create Makefile? (y/n) [y]: > Create Windows command file? (y/n) [y]: n Creating file ./source/conf.py. Creating file ./source/index.rst. Creating file ./Makefile. Finished: An initial directory structure has been created. You should now populate your master file ./source/index.rst and create other documentation source files. Use the Makefile to build the docs, like so: make builder where "builder" is one of the supported builders, e.g. html, latex or linkcheck.cd .. code-block:: bash mkdir /var/www/mydoc/build mkdir /var/www/mydoc/source/data vi /var/www/mydoc/source/conf.py .. code-block:: python extensions = ['sphinxcontrib.aafig','flasksphinx.todo'] # html_theme = "default" html_theme = "rtdflask" .. code-block:: bash chmod -r 777 /var/www/mydoc sphinx-build -b html /var/www/mydoc/source/ /var/www/mydoc/build/html/ mkdir /var/www/mydoc/wsgi-scripts vi /var/www/mydoc/wsgi-scripts/myapp.wsgi .. code-block:: python #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import os, os.path import logging, logging.handlers from flask import Flask import flasksphinx app = Flask(__name__) app.config.from_pyfile(os.path.splitext(__file__)[0]+'.cfg') flasksphinx.init(app) #for mod wsgi application = app if __name__ == "__main__": handler = logging.StreamHandler() handler.setLevel(app.config['LEVEL']) app.logger.addHandler(handler) handler = logging.handlers.RotatingFileHandler(os.path.splitext(__file__)[0]+'.log', maxBytes=2000000, backupCount=5) handler.setLevel(app.config['LEVEL']) app.logger.addHandler(handler) app.run(host = app.config['HOST'], port = app.config['PORT']) .. code-block:: bash chmod +x /var/www/mydoc/wsgi-scripts/myapp.wsgi vi /var/www/mydoc/wsgi-scripts/myapp.conf .. code-block:: python #!/usr/bin/env python # -*- coding: utf-8 -*- import os import logging DEBUG = True SPHINX_BUILD_DIR = '/var/www/mydoc/build' SPHINX_CONF_DIR = '/var/www/mydoc/source' UPLOAD_FOLDER = '/var/www/mydoc/source/data' PORT = 5001 HOST = '0.0.0.0' LEVEL = logging.DEBUG SECRET_KEY = 'secret_key' USERS = [ { 'id' : 1, 'username' : 'admin', 'password' : 'keyadmin' } ] En ajoutant l'extension flasksphinx.todo il est possible de faire des listes à cocher .. code-block:: rst :x:`todo check` :o:`todo no check` Utilisation StandAlone ---------------------- L'utilisation standAlone est assez simple .. code-block:: bash cd /var/www/mydoc/wsgi-scripts/ python myapp.wsgi On a maintenant accès à notre application via http://localhost:5001/ Il est aussi possible de transformer notre application flask en service linux Pour cela .. code-block:: bash cp /etc/init.d/skeleton /etc/init.d/mydoc chmod +x /etc/init.d/mydoc vi /etc/init.d/mydoc .. code-block:: bash ... PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="flasksphinx for mydoc" NAME=myapp.wsgi DAEMON=/var/www/mydoc/wsgi-scripts/$NAME DAEMON_ARGS="" PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME ... do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } ... do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } ... on lance notre service .. code-block:: bash /etc/init.d/mydoc start on a maintenant accès à notre application via le http://127.0.0.1:5001/ on peut installer notre service pour qu'il démarre automatiquement .. code-block:: bash update-rc.d mydoc defaults 99 Intégration dans Apache avec mod_python --------------------------------------- On ajoute à l'installation minimum .. code-block:: bash apt-get install apache2 libapache2-mod-wsgi python-dev mkdir /var/www/mysite cd /var/www/mysite echo "hello mysite" > index.html et on edit le fichier conf du site dans /etc/apache2/site-enabled .. code-block:: bash ServerAdmin webmaster@localhost DocumentRoot /var/www/mysite Options FollowSymLinks AllowOverride None Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all # permet d optimiser les performances Alias /mydoc/_static /var/www/mydoc/build/html/_static Alias /mydoc/_static /var/www/mydoc/build/html/_images Alias /mydoc/_static /var/www/mydoc/build/html/_sources Alias /mydoc/_static /var/www/mydoc/build/html/_download ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all # WSGIScriptAlias /myapp "/var/www/myapp/wsgi-scripts/myapp.wsgi" # # Order allow,deny # Allow from all # WSGIScriptAlias /mydoc "/var/www/mydoc/wsgi-scripts/myapp.wsgi" Order allow,deny Allow from all ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined On redémarre Apache .. code-block:: bash /etc/init.d/apache2 restart On a maintenant accès à notre application via http://localhost/mydoc .. note:: on peut sur un même site ajouter plusieurs application, accessible par exemple par http://127.0.0.1/mydoc et http://127.0.0.1/myapp comme dans notre exemple .. note:: il est possible d'augmenter les performances de l'application en laissant à apache de gérer différentes partie du site (alors non protégé par l'appli). Cela est réalisé par les "Alias" dans le fichier conf d'apache Intégration dans Apache en mode proxy ------------------------------------- Il faut dabord comme en mode StandAlone créer un service pour démarrer automatiquement notre application On ajoute à l'installation minimum .. code-block:: bash apt-get install apache2 cd /var/www/mysite echo "hello mysite" > index.html On active le mode proxy .. code-block:: bash a2enmod proxy proxy_http /etc/init.d/apache2 restart On paramètre pour que toutes les requêtes sur le port 80 soit redirigé vers notre application et on edit le fichier conf du site dans /etc/apache2/site-enabled .. code-block:: bash ServerAdmin webmaster@localhost DocumentRoot /var/www/mysite Options FollowSymLinks AllowOverride None Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all ProxyPass / http://localhost:5001/ ProxyPassReverse / http://localhost:5001/ ProxyPreserveHost On ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined On redémarre tout les services .. code-block:: bash /etc/init.d/mydoc stop /etc/init.d/apache2 stop /etc/init.d/mydoc start /etc/init.d/apache2 start On a maintenant accès à notre application via http://localhost/ .. note:: Aujourd'hui il n'est pas possible de faire un proxy de http://localhost/mydoc vers notre application soucis dans la redirection de flasksphinx et dans le template lui même .. warning:: - et on ne gère pas le upload et doc en ligne - installer aafigure et voir avec eux pour ajout couleur - voir comment aller plus vite sur la production de sphinx (notament copie _download) - voir gestion des todos rst2pdf ======= `rst2pdf `_ est un outil qui permet à partir de fichier rst de générer un fichier pdf. Il peut être utilisé comme une extension de sphinx. Pour installer rst2pdf il suffit de faire :: easy_install rst2pdf Pour l'intégrer dans un projet sphinx il faut: 1. modifier conf.py pour ajouter l'extensions rst2pdf :: extensions = ['sphinx.ext.autodoc','rst2pdf.pdfbuilder'] 2. ajouter dans conf.py les options de sortie pdf :: # -- Options for PDF output -------------------------------------------------- # Grouping the document tree into PDF files. List of tuples # (source start file, target name, title, author, options). # # If there is more than one author, separate them with \\. # For example: r'Guido van Rossum\\Fred L. Drake, Jr., editor' # # The options element is a dictionary that lets you override # this config per-document. # For example, # ('index', u'MyProject', u'My Project', u'Author Name', # dict(pdf_compressed = True)) # would mean that specific document would be compressed # regardless of the global pdf_compressed setting. pdf_documents = [ ('index', u'MyProject', u'My Project', u'Author Name'), ] # A comma-separated list of custom stylesheets. Example: pdf_stylesheets = ['sphinx','kerning','a4'] # Create a compressed PDF # Use True/False or 1/0 # Example: compressed=True #pdf_compressed = False # A colon-separated list of folders to search for fonts. Example: # pdf_font_path = ['/usr/share/fonts', '/usr/share/texmf-dist/fonts/'] # Language to be used for hyphenation support #pdf_language = "en_US" # Mode for literal blocks wider than the frame. Can be # overflow, shrink or truncate #pdf_fit_mode = "shrink" # Section level that forces a break page. # For example: 1 means top-level sections start in a new page # 0 means disabled #pdf_break_level = 0 # When a section starts in a new page, force it to be 'even', 'odd', # or just use 'any' #pdf_breakside = 'any' # Insert footnotes where they are defined instead of # at the end. #pdf_inline_footnotes = True # verbosity level. 0 1 or 2 #pdf_verbosity = 0 # If false, no index is generated. #pdf_use_index = True # If false, no modindex is generated. #pdf_use_modindex = True # If false, no coverpage is generated. #pdf_use_coverpage = True # Name of the cover page template to use #pdf_cover_template = 'sphinxcover.tmpl' # Documents to append as an appendix to all manuals. #pdf_appendices = [] # Enable experimental feature to split table cells. Use it # if you get "DelayedTable too big" errors #pdf_splittables = False # Set the default DPI for images #pdf_default_dpi = 72 # Enable rst2pdf extension modules (default is empty list) # you need vectorpdf for better sphinx's graphviz support #pdf_extensions = ['vectorpdf'] # Page template name for "regular" pages #pdf_page_template = 'cutePage' 3. modifier vos builders, sous windows :: if "%1" == "pdf" ( %SPHINXBUILD% -b pdf %ALLSPHINXOPTS% %BUILDDIR%/pdf echo. echo.Build finished. The PDF files are in %BUILDDIR%/pdf goto end ) sous unix :: pdf: $(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) _build/pdf @echo @echo "Build finished. The PDF files are in _build/pdf." et voilà .. note:: on utilise la feuille de style sphinx qu'on peut modifier Vous pouvez trouver la doc `ici `_ .. note:: afin de gérer les images il faut installer PIL :: easy_install PIL .. warning:: pour que graphviz fonctionne il faut modifier le fichier rst2pdf/sphinxnodes.py rechercher HandleSphinxGraphviz et remplacer if hasattr(VectorPdf,'load_xobj') par if hasattr(VectorPdf,'load_xobj') and 1==0 pour forcer le passage par png Vous pouvez trouver un exemple complet :download:`ici ` la commande utilisée est:: C:\Python27\Scripts\rst2pdf.exe sampler.txt -s sampler.style -o sampler.pdf il est aussi possible de rajouter dans son fichier rst :: .. footer:: Page ###Page###/###Total### .. header:: ###Title### - ###Section### Un autre exemple complet :: rst2pdf -o test.pdf -s style.style --footer "###Page###/###Total###" --header "###Title### - ###Section###" emile.rst et la fiche de style est :: pageSetup: size: A4 width: null height: null margin-top: 1cm margin-bottom: 1cm margin-left: 1cm margin-right: 1cm margin-gutter: 0cm spacing-header: 5mm spacing-footer: 5mm firstTemplate: coverPage defaultFooter : ###Page###/###Total### defaultHeader : ###Section### pageTemplates: coverPage: frames: [] [0cm, 0cm, 100%, 100%] showHeader : false showFooter : false background : mascarille.pdf styles: footer: parent: normal alignment: TA_CENTER styles: admonition: parent: normal spaceBefore: 12 spaceAfter: 6 borderPadding: [4,4,4,4] backColor: null borderColor: null borderWidth: 0 borderRadius : 5 commands:[] [VALIGN, [ 0, 0 ], [ -1, -1 ], TOP ] styles: note: parent: admonition backColor: #EFF8FB borderColor: #EFF8FB styles: attention: parent: admonition backColor: #FBEFEF borderColor: #FBEFEF styles: warning: parent: admonition backColor: #FBF8EF borderColor: #FBF8EF styles: admonition-title: parent: normal styles: code: parent: literal leftIndent: 0 spaceBefore: 8 spaceAfter: 8 backColor: null borderColor: darkgray borderWidth: 0.5 borderPadding: 6 Il est possible de modifier le fonctionnement des *admonitions* en ajoutant l'extension fred dans le repertoire python de rst2pdf Il est même possible via une extension de générer des presentions type powerpoint (ppt) en pdf ... dans ce cas il faut avoir des pdfs de page de taille A4. Vous pouvez trouver cette extention :download:`ici `. Il faudra pour utiliser cette extension lancer la commande :: rst2pdf -o out.pdf -e fred in.rst Vous pouvez trouver un exemple complet :download:`ici `