Von Thomas Rohde auf Mittwoch, 21. April 2021
Kategorie: Application Development

Docs as Code - Dokumentation mit Asciidoctor

In diesem Artikel möchte ich am Beispiel von Asciidoctor beleuchten, wie eine Alternative zu klassischen Dokumentationswerkzeugen aussehen kann, wie diese funktioniert, und wie sich Dokumentation als Code in den Softwareentwicklungsprozess einbinden lässt. Gerade für agile Projekte kann die kontinuierliche Fortschreibung und Verbesserung der Dokumentation damit sehr effektiv und effizient gestaltet werden.

​In nahezu jedem halbwegs professionellen Projekt im Bereich der Softwareentwicklung müssen verschiedene Arten von Dokumenten erstellt, fortgeschrieben, versioniert und publiziert werden. Viele Unternehmen setzen hier zunächst auf klassische Schreibprogramme, wie z. B. Microsoft Word. Für viele Anwendungszwecke kommt man damit gut zurecht. Wenn es um technische Dokumentationen geht, zeigen sich hier jedoch schnell Grenzen:


Neben diesen Aspekten kommen in der Praxis noch viele Kleinigkeiten hinzu, die eine klassische Form der Dokumentation erschweren. Da Softwareentwickler ihre Programme in Form von Programmcode entwickeln, liegt es nahe, diesen Ansatz für die Erstellung der Dokumentation zu adaptieren. Dies führt uns zum Titel des Beitrags: Documentation as Code oder Docs-as-Code (DaC) - also Dokumentation als Quellcode. Der Ansatz ist nicht neu und wird beispielsweise in Universitäten mittels LaTex bereits seit Jahrzehnten praktiziert. Einen ähnlichen Ansatz bietet die Auszeichnungsprache AsciiDoc mit dem Textverarbeitungstool Asciidoctor. Eine alternative Implementierung von Asciidoctor für die JVM wird von AsciidoctorJ zur Verfügung gestellt. Damit lassen sich Dokumentationen ohne externe Binaries direkt im Rahmen des Build-Prozesses mit Maven oder Gradle erstellen. Und genau das wollen wir uns in diesem Artikel einmal anschauen.

AsciiDoc

AsciiDoc ist eine Auszeichnungssprache, mit der sich Texte in verschiedenen Dokumentenformaten publizieren lassen. Der Quellcode wird in normalen Textdateien mit der Dateiendung ".adoc" gespeichert und kann in verschiedene Ausgabeformate konvertiert werden, z. B. nach HTML5 oder ins DocBook-Format. Von DocBook können sie wiederum in viele andere Formate, z. B. nach PDF konvertiert werden.

Asciidoctor

Asciidoctor ist eine Neuimplementierung des ursprünglich in Python geschriebenen Textverarbeitungstoos und wurde in Ruby erstellt. Im vorliegenden Artikel kommt es allerdings nicht zum Einsatz, denn wir arbeiten hier mit AsciidoctorJ.

AsciidoctorJ

AsciidoctorJ ist eine Adaptierung für die Java Virtual Machine (JVM) und wird dort unter der Verwendung von JRuby ausgeführt. Neben dem eigentlichen Text-Processor stehen ein Maven- und ein Gradle-Plugin für die nahtlose Einbindung in den Buildprozess zur Verfügung.

AsciidoctorJ is the official library for running Asciidoctor on the JVM. Using AsciidoctorJ, you can convert AsciiDoc content or analyze the structure of a parsed AsciiDoc document from Java and other JVM languages.

https://github.com/asciidoctor/asciidoctorj

Eine Beispiel-dokumentation

Um uns mit den Prinzipien der Auszeichnungssprache und den Möglichkeiten der Konvertierung vertraut zu machen, schauen wir uns im Folgenden anhand eines DV-Konzepts eine Beispiel-Dokumentation eines Software-Projektes an. Zunächst gehen wir auf die Strukturierung des Projektes und der Dateien ein. Danach werfen wir einen Blick auf einige wichtige Syntax-Elementen von AsciiDoc. Im Anschluss folgt ein Überblick über die Erzeugung von Grafiken und Diagrammen. Zuletzt schauen wir uns die Konfiguration des Maven-Plugins und die Integration in den Build-Prozess an.

Strukturierung

​Die nebenstehende Grafik zeigt ein klassisches Java-Maven-Projekt. Unter src/main/java befindet sich der Java-Quellcode - das sollte uns vertraut vorkommen. Etwas weniger bekannt dürfte allerdings das Verzeichnis src/docs/asciidoc sein. Dort finden wir die *.adoc-Dateien wieder, die den Quellcode für unsere Dokumentation enthalten. Wie diese inhaltlich aufgebaut sind, schauen wir uns im nächsten Kapitel an. Zunächst möchte ich die Strukturierung vorstellen.

Die Datei 1_main.adoc ist das Hauptdokument, in das alle anderen Dokumente eingebunden sind. 2_preface.adoc enthält Vorwort und Einleitung und 3_overviews.adoc enthält Projektglossar, Abkürzungsverzeichnis etc. Dazwischen kommen die eigentlichen Kapitel mit den spezifischen Inhalten. Diese sind zur besseren Übersicht im Unterverzeichnis chapter abgelegt. Es gibt hier also drei Kapitel (001_demo_ditaa.adoc, 002_demo_use_case.adoc und 003_demo_sequenz.adoc).

Darüber hinaus gibt es natürlich noch die pom.xml für Maven und eine README.md.

Syntax von AsciiDoc

Schauen wir uns zunächst ein paar Syntax-Elemente von AsciiDoc an, damit wir ein Gefühl dafür bekommen, wie die Sprache aufgebaut ist.

Überschriften

Eine Überschrift wird mit einen =-Zeichen eingeleitet

= erste Ebene / Dokumententitel

Eine Überschrift mit einem =-Zeichen ist die Hauptüberschrift für das gesamte Dokument. Die weiteren Gliederungspunkte werden mit weiteren =-Zeichen erstellt:

== zweite Ebene

=== dritte Ebene

==== vierte Ebene

===== fünfte Ebene

Aufzählungen

Unsortierte Aufzählungen (Unordered List) werden mit dem *-Zeichen eingeleitet:

* erster Punkt

** zweiter Punkt

*** dritter Punkt

Sortierte Aufzählungen (Ordered List) werden mit dem .-Zeichen eingeleitet:

. erster Punkt

.. zweiter Punkt

... dritter Punkt

Tabellen

Tabellen werden ebenfalls mit einfachen Ascii-Zeichen abgebildet. Eine einfache Tabelle könnte wie folgt aussehen:

.Die beteiligten Komponenten
|===
| Browser     | Der Browser läuft auf dem Client-PC oder einem mobilen Endgerät (Tablet, Smartphone etc.)
| Frontend    | Das Frontend wird auf dem Server in der DMZ deployed und ist für das Rendering der GUI zuständig.
| Middleware  | Die Middleware enthält die Business-Logik.
| Datenbank   | Die Daten werden in der zentralen Datenbank gespeichert.
|===

Die erste Zeile mit dem führenden Punkt ist die Legende der Tabelle. Legenden können auch an anderen Stellen verwendet werden (z. B. bei Grafiken).

Mit der zweiten Zeile |=== wird die Tabelle eingeleitet. In der dritten Zeile werden die einzelnen Zellen durch das |-Symbol getrennt. In der letzten Zeile wird die Tabelle mit ===| beendet.

Textformatierungen

Einfache Formatierungen von Text können wie folgt abgebildet werden:

Dies ist ein *fettes* Wort.

Dies ist ein _kursives_ Wort.

Dieses ist ein als `Code` dargestelltes Wort.

Code-Blöcke

Quellcode wird oft nicht nur im Text, sondern als kompletter Block dargestellt. Dazu wird dieser in zwei Blöcken von .... eingeschlossen:

[source,xml]
....
<element tag="value">text</element>
....

Über dem Block wird in eckigen Klammern definiert, welchen Inhalt der folgende Block hat. In diesem Fall liegt mit source also Quellcode in xml vor.

Eine ausführliche Erläuterung mit entsprechenden Beispielen zur Syntax ist auf der offiziellen Webseite von Asciidoctor (hier) zu finden.

Diagramme

Für eine umfassende und nützliche Software-Dokumentation oder ein sinnvolles DV-Konzept werden zur Erläuterung und Veranschaulichung üblicherweise Grafiken und Diagramme einsetzt. Hier spielt Asciidoctor seine Stärken aus, indem es nativ Ditaa- und PlantUML-Diagramme unterstützt.
Ditaa

​Ditaa steht für "Diagrams Through Ascii Art" und erlaubt die Erstellung von einfachen Grafiken und Diagrammen mittels Ascii-Art. Im konkreten Demo-Projekt wird dies im Kapitel 001_demo_ditaa.adoc demonstriert:

Das Resultat sieht dann wie folgt aus:

PlantUML

Einen anderen Ansatz verfolgt PlantUML. Mit einer speziellen DSL lassen sich durch einen Beschreibungstext komplexe und anschauliche Diagramme generieren. Je nach Diagramm-Typ funktioniert das besser oder schlechter. Sequenzdiagramme sind beispielsweise sehr gut geeignet, da ein solches Diagramm einen relativ einfachen Aufbau hat, und sich daher sehr gut textuell beschreiben lässt. Ein einfaches Beispiel liefert das Kapitel 003_demo_sequenz.adoc unses Beispiel-Projekts:

Das daraus generierte Diagramm sieht dann wie folgt aus:

Ein weiteres Beispiel mit PlantUML zeigt uns das Kapitel 002_demo_use_case.adoc. Dort wird ein Use-Case-Diagramm verwendet:

​Werfen wir auch hier einen Blick auf das Ergebnis:

Maven-Plugin
 

​Nachdem wir jetzt die grundlegenden Eigenschaften und die Struktur der Beispiel-Dokumentation angeschaut haben, werfen wir nun einen Blick auf das Resultat bzw. das Maven-Plugin von AsciidoctorJ, mit welchem der Output erzeugt wird.

Zunächst wird das Plugin in den build-Block der pom.xml eingebunden:

​In den Zeilen 4-6 erfolgt die Angabe des Plugins org.asciidoctor:asciidoctor-maven-plugin:2.1.0. Anschließend folgen die für das Plugin notwendigen Abhängigkeiten:

In  den Blöcken configuration und exectutions folgen dann konkrete Anweisungen an das Plugin. Dort sehen wir auch, dass es zwei Output-Formate gibt: PDF und HTML5. Im Rahmen des Build-Prozesses werden also Dokumente im PDF-Format und HTML5-Seiten erzeugt.

Um ein Gefühl dafür zu bekommen, wie die erzeugte Dokumentation aussieht, hier ein Auszug aus dem Kapitel 2 des PDF-Dokuments:

PDF eignet sich natürlich gut dafür, eine Gesamtdokumentation zusammen mit dem Software-Paket an einen Kunden auszuliefern, oder an Stakeholder zu verschicken.

Die HTML-Variante kann sehr einfach auf einem Webserver publiziert werden. Wenn dies im Rahmen eines automatischen Build-Prozesses, z. B. im Zuge des CI/CD-Prozesses erfolgt, dann ist sichergestellt, dass immer eine aktuelle Dokumentation zur Verfügung steht. Je nach Art der Dokumentation und Applikation entweder im Intra- oder sogar im Internet.

Hier ebenfalls ein Auszug aus der erzeugten HTML-Dokumentation von Kapitel 2:

Fazit

AsciiDoc in Kombination mit Asciidoctor oder AsciidoctorJ ist eine gute Variante für die Erstellung von technischen Dokumentationen. Die einfache Erzeugung und native Einbindung von Diagrammen erlaubt eine einfache Anpassung und Weiterentwicklung der Dokumentation. Durch die Integration in ein beliebiges Java-Projekt und den entsprechenden Build-Prozess kann die Dokumentation auf Knopfdruck oder sogar vollkommen automatisch generiert werden. Durch ein Quellcodeverwaltungssystem wird die Dokumentation automatisch versioniert und kann zusammen mit dem Programmcode weiterentwickelt werden. Verschiedene Ausgabeformate erlauben ein konsumentengerechtes Format, ohne zu viel Aufwand in Layout und Formatierung investieren zu müssen.
Der Quellcode des Beispiel-Projekts kann auf GitHub heruntergeladen werden: https://github.com/trojava/asciidoctorj-ordix-blog-demo

Kommentare hinterlassen