Dank Github Pages, war es noch nie so leicht wie heute eine Webseite für seine Dokumentation zu erstellen. Einfach ein neuen git branch gh-pages oder einen Ordner docs erstellen, eine index.html Datei reinziehen, und fertig ist die Webseite.
Einfach oder? Ja definitiv, aber auch effizient? Nicht wirklich. Eine Webseite lässt sich zwar schnell aufziehen, Bootstrap drauf und fertig, jedoch wird diese immer unübersichtlicher, je größer das Projekt wird. Deswegen gibt es spezielle Tools, um die Dokumenation seiner Programme effizient zu gestalten. Eines davon, besonders für Python, ist Sphinx. Aber wie benutzt man Sphinx mit GitHub Pages?
Sphinx
Mit Sphinx lassen sich ganz einfach Dokumentation erstellen. Die einzelnen Seiten werden in reStructuredText (reST) geschrieben. Dies ist eine Markup Sprache. Alternativ gibt es auch ein Plugin names recommonmark, welches auch das bekanntere Markdown nativ einbindet.
Sphinx selbst ist ein Python Modul und kann über pip installiert werden. Ebenso sind die meisten Plugins über pip installierbar.
Beispiel
Der Start einer jeden Sphinx-Dokumentation ist die index.rst Datei. Hier ein Beispiel einer einfachen Dokumentation mit drei Unterseiten:
H1 Headline *********** Eine Beschreibung .. toctree:: :caption: Contents module about/changelog about/License.md H2 Headline =========== .. include:: ../README.md Generierte Indizes ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search`
.. _module: ********************* Module ********************* :mod:`transfer` =============== .. automodule:: transfer :members: :undoc-members:
.. _changelog: Changelog ********* = 0.4 --- - Added better documentation - Added public function descriptions 0.3 --- - Added (CLI) option to change size, contrast and sharpness - Added size to ouput name - Resize goal image automatically to size of base - Updated Sphinx docs
# License BSD 3-Clause License Copyright (c) 2020, Arne Rantzen All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Kompiliert
Einführung
Überschriften
Überschriften werden eine Zeile darunter mit dem entsprechenden Zeichen markiert. Die Zeichenketten müssen mindestens so lange sein wie die Überschrift.
H1 | *** |
H2 | === |
H3 | — |
H4 | ^^^ |
H5 | “”” |
Befehle
Ein reST Befehl ist wie eine Klasse. Man erstellt das Objekt mit .., dann den Namen der Klasse, gefolgt von :: und schließlich den Argumenten für den Konstruktor. Spezielle Argumente ruft man mit :[Name]: auf.
Inhaltsverzeichnis
Ein Inhaltsverzeichnis wird durch den toctree erstellt. (toc = Table of Contents). Hierbei ist die Einrückung, wie aus Python bekannt, enorm wichtig, da es sonst zu Fehlern bei der Kompilierung kommt. Durch recommonmark kann man sowohl reST- als auch Markdown Dateien einfach nennen und sie werden automatisch verlinkt. Bei Markdown muss man jedoch die Endung mit nennen. Der toctree dienst dazu als Navigationsmenu um durch die Dokumentation zu navigieren.
Einbinden
Externe Dateien lassen sich einfach in ein Dokument einbinden. Oben in dem Beispiel wurde die GitHub typische Readme.md, welche in einem Ordner darunter liegt, mit dem include Befehl in das Dokument eingebunden. Diese wird auch automatisch mit kompiliert. Dadurch lassen sich größere Dateien praktisch teilen.
Autodoc
Durch das Plugin autodoc kann man automatisch die Kommentare und Funktionen seiner Module in eine schöne Übersicht bringen:
Verlinkung
Wie oben mit dem toctree ist es auch möglich Verlinkungen aus dem Text raus zu erstellen. Man kann mit :ref:[Name] auf eine Datei verlinken, oder auf einen speziellen Marker. Der Marker wird mit .. _[Name]: erstellt. Ein weiterer spezielle Befehl aus autodoc ist mod:[Name]. Mit ihm wird auf die Dokumentation des automodules [Name] verlinkt.
Mit Sphinx arbeiten
Um mit Sphinx zu arbeiten, muss man es erst installieren. Dazu gibt man pip install sphinx autodoc recommonmark in sein Terminal ein und erhält damit auch zwei sehr praktische Plugins dazu.
Ist Sphinx installiert, kann man in ein beliebiges Verzeichnis navigieren und sphinx-quickstart ausführen. Dies startet ein CLI Wizard der ein Grundgerüst mit Makefile aufbaut. Ich empfehle Source und Build zu trennen (erste Frage mit “y” beantworten).
Hat man nun eine fertige Installation, kann man ganz einfach mit make html das Makefile aufrufen und bekommt in seinen build Ordner eine kompilierte Webseite. Aber wie benutzt man nun Sphinx mit GitHub Pages?
Sphinx mit GitHub Pages
GitHub Pages ist eine Funktion von GitHub mit der man eine statische Webseite für sein Projekt hosten kann. Dies geschieht mit Zugriff auf Files in einem auf GitHub gehosteten Repository.
Das Problem ist, dass GitHub nicht ohne weiteres mit Sphinx kompatibel ist. Eine typische Sphinx Installation sieht wie folgt aus:
├───build
│ ├───doctrees
│ └───html
│ ├───_sources
│ └───_static
└───source
├───_static
└───_template
Mit GitHub hat man jedoch nur zwei Möglichkeiten seine Webseite zu hosten: Entweder ein index.html in dem /docs/ Ordner, oder auf dem Wurzel Level. Sphinx erstellt die index.html jedoch im /build/html/ Ordner.
Es ist natürlich möglich diesen einfach immer in den /docs/ Ordner zu kopieren, jedoch kommt hier das nächste Problem ins Spiel: GitHub benutzt Jekyll für die Bereitstellung welche alle Ordern die mit einem Unterstrich beginnen, wie _sources und _static, komplett ignoriert.
Von Sphinx aus ist es nicht möglich diese Ordner umzubenennen, jedoch gibt es die Möglichkeit bei GitHub Jekyll auszuschalten. Dazu muss man eine leere Datei mit dem Namen .nojekyll in den Wurzelordner seiner Webseite packen.
Wir haben also eine Lösung gefunden: Wir erstellen die .nojekyll Datei in den /build/html Ordner und den verschieben den Inhalt jenes Ordners nach /docs/.
Möglich, aber nicht so elegant. Besser ist es git Magie und Hooks zu benutzen!
Git Magie
Unser Ziel ist folgende Ordnerstruktur:
├───gh-pages
│ └───docs
└───master
└───src
├───docs
│ ├───build
│ │ ├───doctrees
│ │ └───html
│ │ ├───_sources
│ │ └───_static
│ └───source
│ ├───_static
│ └───_template
└───modules
Wir brauchen dafür zwei Branches: Einen Master und einen gh-pages. Auf gh-pages kommen nur die kompilierten Dateien für unsere Webseite. Der Master-Branch ist nur für die Quelldateien. So wie es sich gehört: Eine strikte Trennung zwischen Source und Build.
Repository erstellen
Im Folgenden Abschnitt wird anhand von Windows 10 und der Powershell Konsole eine funktionierende GitHub Page mit Sphinx gebaut, die dem obigen Schema entspricht.
Erstelle Stamm-Repository
Als erstes erstellen wir dazu ein neues Repository in einem neuen Projektordner. Ich nenne das Project einmal: SphinxPages. Dazu wird ein neuer Ordner master erstellt.
In diesem wird unser git initialisiert und eine erste Datei angelegt. Diese wird nun unserem git hinzugefügt und commited.
Sobald ein GitHub Repository erstellt wurde, kann dieses dann mit unserem lokalen verbunden werden. Anschließend wird unser Commit hochgeladen.
Erstelle Zweig-Repository
Nun wird zurück in den Stammordner gewechselt und dort das Repository noch einmal gecloned. Und zwar mit dem Namen gh-pages. Dorthin wird gewechselt und der neue Zweig gh-pages wird erstellt. Anschließend wird ein link erzeugt, damit jedes mal auf diesen Zweig gewechselt wird, sobald man diesen Ordner betritt. Zuletzt wird die .git/index Datei gelöscht und der Zweig bereinigt.
Erstelle Sphinx Ordner
Die Ausgangs-Struktur steht soweit, nun können wir uns um die Quelle kümmern.
Wir erstellen den Pfad master/src/docs, wechseln dorthin und start den Sphinx Wizard.
In der ersten Entscheidung wählen wir “ja”.
Sobald man die restlichen Schritte durchgegangen ist – es ist egal für diese Anleitung was man hier wählt – hat man die fertige Sphinx Struktur. Zum Schluss müssen noch die Makefile bzw. make.bat angepasst werden, damit der html Order im master automatisch in den gp-pages Order kopiert wird.
Automatisiere
Für Windows wird die make.bat Datei erändert. Als erstes erstellen wir eine neue Variable DOCS die auf unsere gh-pages Verweist. Da wir im Order master/src/docs sind, müssen wir 3 Stufen nach unten.
Danach wird eine neue Abfrage erstellt um zu sehen, ob als Befehl “github” gegeben wurde. Falls dies geschehen ist, soll auf unsere neue Stelle verwiesen werden.
[...] set BUILDDIR=build set DOCS=../../../gh-pages if "%1" == "" goto help if "%1" == "github" goto github [...] :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :github rmdir /S /Q "%BUILDDIR%" %SPHINXBUILD% -M html %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% copy /Y "%BUILDDIR%/html" "%DOCS%" echo. 2>"%DOCS%/.nojekyll" goto end :end popd
Diese neue Stelle wird anschließend Implementiert.
Hierbei wird erst der Build Order gelöscht, damit keine alten Artefakte übrig bleiben, dann wird der normale Sphinx-Build Prozess gestartet, mit dem Argument html, und schließend das Resultat in den Order gh-pages kopiert.
Zum Schluss wird eine Datei .nojekyll in gh-pages eingefügt, damit GitHub die Seite richtig rendert.
Schlussbemerkung
Sobald nun die fertige Architektur steht, kann man einfach mit make github die Dokumentation erstellen. Diese wrid nun automatisch in den gh-pages Ordner kopiert. Man muss also nur noch beide Zweige hochladen.
Theoretisch kann man dies auch noch durch ein git hook machen, der so in etwa wie dieser aussehen muss:
echo Update documentation cd /src/docs && make github cd ../../../gh-pages while true; do read -p "Do you wish to push the updated documenation?" yn case $yn in [Yy]* ) git add *; echo Add a commit message to your updated documentation read message git commit -m "$message" git push break;; [Nn]* ) exit;; * ) echo "Please answer yes or no.";; esac done exit 0
Tl;dr
Wer keine lust hatte den Hintergrund zu verstehen und nur eine schnelle Lösung will, der ist hier genau richtig. Auf der letzen Seite stelle ich ein Skript zur Verfügung, welches die Arbeit erledigt und auch das veränderte Makefile. Dazu gibt es ein GitHub Template Repository, welches man auch einfach clonen kann.
GitHub Template
Auf der Seite SphinxPages gibt es auch ein fertiges GitHub Template welches man einfach clonen kann und mit ein paar Schritten einrichten.
Es hat eine leicht andere Struktur als in diesem Guide. So ist der gh-pages Ordner in das Stamm-Repository integriert.
Skripte
Einfach eines der folgenden Skripte ausführen um die gewollte Struktur zu erhalten:
#!/bin/bash echo Wie soll das neue Repository heissen? read name master="./$name/master" echo Erstelle Pfad mkdir -p $master && cd $master echo Erstelle ersten Eintrag git init && touch Readme.md && git add Readme.md && git commit -m "Initial commit" echo Wie lautet die GitHub Adresse? read github echo Lade Repository zu GitHub hoch git remote add origin $github && git push -u origin master echo Clone Repository cd .. && git clone $github gh-pages && cd gh-pages echo Erstelle gh-branches und automatischen Wechsel git branch gh-pages && git symbolic-ref HEAD refs/heads/gh-pages echo Raeume Zweig auf rm .git/index && git clean -fdx echo Initialisiere Sphinx cd .. && mkdir -p ./master/src/docs && cd ./master/src/docs && sphinx-quickstart exit 0
@echo off set /p name="Wie soll das neue Repository heissen? " set master=".\%name%\master" echo Erstelle Pfad mkdir %master% && cd %master% echo Erstelle ersten Eintrag git init && type nul >> Readme.md && git add Readme.md && git commit -m "Initial commit" set /p github="Wie lautet die GitHub Adresse? " echo Lade Repository zu GitHub hoch git remote add origin %github% && git push -u origin master echo Clone Repository cd .. && git clone %github% gh-pages && cd gh-pages echo Erstelle gh-branches und automatischen Wechsel git branch gh-pages && git symbolic-ref HEAD refs/heads/gh-pages echo Raeume Zweig auf del /q ".git\index" && git clean -fdx echo Initialisiere Sphinx cd .. && mkdir .\master\src\docs && cd .\master\src\docs && sphinx-quickstart exit 0
Anschließend das Makefile und make.bat im Ordner master/src/docs/ mit den folgenden beiden Dateien ersetzen.
# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = build DOCS = ../../../gh-pages # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile github: @rm -rf "$(BUILDDIR)" @make html @mv "$(BUILDDIR)/html" "$(DOCS)" @touch "$(DOCS)/.nojekyll" # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=build set DOCS=..\..\..\gh-pages if "%1" == "" goto help if "%1" == "github" goto github %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :github rmdir /S /Q "%BUILDDIR%" %SPHINXBUILD% -M html %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% copy /Y "%BUILDDIR%\html" "%DOCS%" echo. 2>"%DOCS%\.nojekyll" goto end :end popd
Ich hoffe diese Anleitung, wie man Sphinx mit GitHub Pages benutzt, hat geholfen. Lasst mir doch ein Kommentar da für euer Feedback und weitere Fragen.
0 Comments