Steuerung der Dokumentengenerierung

Steuerung der Dokumentengenerierung

Inhalt


1 Motivation und Übersicht

Topic:.XmlDocuGenCtrl.overview.

pStyle=std tableStyle=stdTable

Der Inhalt eines zu generierenden Dokumentes kann aus mehreren Quellen zusammengesetzt werden. Damit muss der Inhalt so genau wie notwendig vorgebbar sein. Die Quellen eines Dokumentes können zum Beispiel sein:

Die Input-Informationen müssen teilweise zunächst speziell nach XML konvertiert werden oder in ein passendes XML-Format transformiert werden. Danach stehen sie zum Generieren in einem großen XML-Baum aus dem Inhalt aller XML-Files zur Verfügung. Der XSL-Translator sucht die entsprechenden Informationen heraus und erzeugt das PreXhtml-File als Basis für die End-Dokumentation.

Die gesamte Steuerung für diesen Prozess ist in einem textuellem File niedergelegt, der den Aufbau des Dokumentes beschreibt. Als Beispiel dafür kann das File XmlDocu/docuSrc/XmlDocuGen.genctrl gelten. Dieses umfangreichere File enthält die Steuerung der gesamten Dokumentationsgenerierung (mehrere HTML-Files) dieses Internetauftrittes.

Über mehrere Übersetzungsschritte wird aus dem textuellen Steuerfile der Dokumentengenerierung ein XML-File für eine Ant-Steuerung der Generierung (Wikipedia:Ant) und der XSL-File für die Konvertierung des Dokumentes erzeugt. Die Dokumentengenerierung enthält noch Auflösungsschritte für Querverweise, und letzlich eine Erzeugung eines HTML-Files, und/oder eines Word-XML-Files und gegebenenfalls weitere Ausgabeformate.

Für die Generierung werden mehrere XSL-Files und ZBNF-Files benutzt, die projektspezifisch angepasst werden können aber nicht müssen. Sie liegen für Zwecke der Generierung von Dokumenten insbesondere aus UML-Quellen (XMI), Headerfiles und Texttopics hier vor. Für andere XML-Formate beispielsweise aus Datenbankabfragen ist eine Anpassung zu empfehlen.


2 Datenfluss der Dokumentengenerierung

Topic:.XmlDocuGenCtrl.DataFlow.

pStyle=std tableStyle=stdTable


Bild: Datenfluss Dokumentengenerierung Das Bild zeigt den Datenfluss der Dokumentengenerierung in einer komplexen Form. Die blauen Kästen und Pfeile sind Inhalte der Dokumentation. Quellen sind blau stark umranded: Ein oder mehrere UML-Modelle, beliebige XML-Files, Header der C-Programmierung, Topics in Textform, und weitere Inputs. Blau schwach umranded sind temporäre Files. Türkis stark umranded sind dann die Ergebnisfiles in HTML und word.xml. Der Datenfluss läuft hier von links oben nach rechts unten.

Der grün stark umrandede Kasten ist derjenige, der die Inhalte der zu erzeugenden Dokumente auswählt. Das ist die einzige Stelle, an der ein Anwender eingreifen muss, um teils mehrere Dokumente aus sehr vielfältigen Inhalten zusammenzustellen. Als Beispiel ist der Steuerfile XmlDocu/docuSrc/XmlDocuGen.genctrl für diese gesamte Xml-Dokumentationsbeschreibung hier verlinkt. Grün schwach umrandes sind dann Temporärfiles. Der Datenfluss geht hier von links unten hin zur Steuerung der Generierung in grünen Pfeilen.

Die gelb/braun stark umrandeden Kästen sind Scripts entweder in XSLT oder ZBNF, die für die Generierung grundsätzlich bestimmend sind, aber nicht für einzelne Dokumente angepasst werden müssen/sollen. Diese Files können zugeschnitten werden auf die Dokumentengenerierung in einer Abteilung insgesamt, deren Tool-Landschaft berücksichtigend.

Die gestrichelten Linien zeigen die Abhängigkeiten, in welchen Scripts welche andere Scripts bestimmt werden. Die grünen Linien gehen dabei von dem Example.genctrl aus. In diesem vom Anwender bestimmten Script wird also bestimmt, dass beispielsweise TopicXhtml.xslp verwendet wird. Dieses Script steuert die Abbildung von Text-Topics. Das ist eine Zeile im Anwenderscript, der Anwender kann möglicherweise aus mehreren alternativen Scripts für diesen Zweck wählen. Der Anwender gibt selbstverständlich die im genctrl-script die Quellen seiner Dokumentendaten an. Das sind die grünen gestrichelten Linien, die auf den blauen Kästen landen.

Die gelb/braun gestrichelten Linien gehen von dem Script DocuGenCtrl2Ant.xslp aus. In diesem Script ist festgelegt, dass DocuGenCtrl2Xsl.xslp verwendet werden soll, um das für die Dokumentengenerierung wesentliche XSL-Script zu erzeugen. Damit ist diese Auswahl fest, nicht im Anwenderscript Example.genctrl steuerbar. Der Anwender bestimmt aber mit dem Aufruf der Documentengenerierung in einem batchfile (Windows), das DocuGenCtrl2Ant.xslp verwendet werden soll, hat also mit dieser Wahl den indirekten Einflusss. Die verwendeten Scripts HeaderXml2Xmi.xsl usw. hängen von der Auswahl der Konvertierung ab, die der Anwender in seinem Example.genctrl angibt. Für eine gewählte Konvertierung ist das Konvertierungsscript bestimmt. Das gilt solange der Anwender nicht die entsprechenden Scripts anpasst. Letzteres sollte aber nie auf ein einzelnes zu generierenden Dokument bezogen erfolgen sondern als Anpassung an eine projektweit vorhandene Tool-Landschaft.

Übersicht über alle Files der Dokumentengenerier-Steuerung:

Wie kommt man von einem recht einfachen Steuerfile zu einer recht komplexen Generierung? Selbstverständlich sind dazu einige komplexe Schritte notwendig. Diese werden ANT-gesteuert ausgeführt. Der dazu notwendige anwenderspezifische und komplexe ant.xml-File wird aus dem Inhalt des genctrl-Files generiert. Was alles berücksichtigt werden muss, ist dort enthalten. Wie es berücksichtigt werden soll, wird durch das XSL-Script XmlDocu_xsl/DocuGenCtrl2Ant.xslp und durch weitere includierte Scripts geregelt. Das wie hängt nicht von der konkreten Dokumentation ab und muss daher nicht für jedes Dokument extra bearbeitet werden. Die manuelle Erstellung eines ant.xml-Files, auch mit Hilfe von grafischen Möglichkeiten, wäre sonst durchaus aufwändig.


3 Notationsmöglichkeiten und Syntax des DocuGenCtrl.genctrl

Topic:.XmlDocuGenCtrl.Syntax.

pStyle=std tableStyle=stdTable

Die Syntax ist festgelegt durch das SyntaxScript XmlDocu_xsl/DocuGenCtrl.zbnf, im Bild links unten gelb stark umranded. Dieses Script stellt die formale Syntax dar, mit semantischen Ergänzungen und Kommentierungen. Damit ist das SyntaxScript selbsterklärend. Wenn es eine Unterstützung als Eclipse-plugin gibt, dann ist auch eine einfache Bedienerführung gegeben. Dieses Plugin, generell für ZBNF, gibt es im Moment noch nicht. Damit muss ein Anwender derzeit den Text nach bestem Wissen richtig schreiben, die Konvertierung aufrufen und nach Syntaxfehlermeldungen halt korrigieren. Die beste Methode ist copy'n paste'n adaption.

Im folgenden sind Möglichkeiten der Schreibweise als Beispiel aus dem File XmlDocu/docuSrc/XmlDocuGen.genctrl angegeben:

 Beispiel des XmlDocuGen.genctrl

und die zugehörige

 ZBNF-Syntax

angegeben.


3.1 Kopf-Angaben

Topic:.XmlDocuGenCtrl.Syntax..

pStyle=std tableStyle=stdTable

Das Steuerfile kann/sollte, muss aber nicht mit einer Kopfzeile beginnen, in der unter anderem Zeichensatz deklariert ist. Das impliziert die grundsätzliche Möglichkeit, ein beispielsweise fremdsprachiges Dokument auch mit einem anderen Zeichensatz zu beschreiben:

 <?DocuGenCtrl-www.vishia.org version="1.0" encoding="ISO-8859-1" ?>

Danach muss die Angabe des eigenen Filenamens erfolgen. Dieser ist notwendig insbesondere weil die Querverweise mit Informationen aus diesem File realisiert werden:

 genCtrl: XmlDocuGen.genctrl;

Syntaktisch ist beides mit

 GenCtrl::=<?GenCtrl>
 [\<\?DocuGenCtrl-www\.vishia\.[de|org] {version=<""?@version-GenDocuCtr>|encoding=<""?@encoding>} \?\>]
 genCtrl: <*\ ;?@file> ;
 [ importXsl ( {<import> ? , } ) ; ]

am Angang der Toplevel-Syntaxvorschrift beschrieben. Die Kopfzeile ist optional, da in [...] gesetzt. In der Syntax oben ist bereits das folgende Konstrukt gezeigt, import-Statement für Xsl-Scripts. Die Sub-Syntax für <import> ist im Script nachlesbar, hier der unvollständigkeitshalber nicht dargestellt. Im Beispiel XmlDocu/docuSrc/XmlDocuGen.genctrl sieht das so aus:

 importXsl
 ( XmlDocu_xsl:TopicXhtml.xsl
 );

Damit wird das TopicXhtml.xsl aus dem Ordner XmlDocu_xsl als import-script in die Dokumentengenerierung einbezogen. Das ist notwendig, um Topics aufzulösen.


3.2 Vorübersetzungen aus verschiedenen Quellen nach XML

Topic:.XmlDocuGenCtrl.Syntax..

pStyle=std tableStyle=stdTable

Weiter geht es in der Syntax mit

 [{ target: <target>; | \$<variable>; }]                              ##some Zmake-targets

Die Syntax der <target> und <variable> sind im importiertem Script xsl/ZmakeStd.zbnf aus dem Zmake definiert. Das heißt, man hat hier die Mögichkeiten, die Zmake bietet, geerbt. Im Beispiel ist das ausgenutzt, in dem

 target: ../html/*.html := file2Html
 ( srcpath="../../ZBNF/sf/ZBNF/Xml_Toolbase"
 , XmlDocu_xsl/AsciiTopics.zbnf
 , XmlDocu_xsl/DocuGenCtrl.zbnf
 , XmlDocu_xsl/DocuGenCtrl2Ant.txt.xslp
 , XmlDocu_xsl/DocuGenCtrl2Ant.xslp
 );

gerufen wird. Damit enthält das Steuerscript der Dokumentengenerierung implizit die Generierung von Textfiles in eine html-Form, damit sie in dieser Internetseite aufrufbar sind. Andere Möglichkeiten sind Beispielsweise eine Konvertierung von Headerfiles nach XMI oder andere Vor-Übersetzungen. Im Bild des Datenflusses sind diese angedeutet.

 target: ../tmp/*.xml := TextTopic2Xml
 ( DocuGenCtrl.topic
 , DocuGenCtrl_internal.topic
 , XmlDocuGen.topic
 , XslHints.topic
 );
 //prepXml: DocuGenCtrl.topic     ->TextTopic2Xml;

Das obige Target ist essentiell für eine Dokumentengenerierung aus TextTopics, wie sie auf dieser vishia-Seite benutzt wird. Hier wird angewiesen, dass vor der eigentlichen Dokumentengenerierung diese Umsetzung erfolgen muss. Im Beispiel steht in der letzten Zeile kommentiert noch die alte Form, bevor Zmake mit der Dokumentengenerierung verbunden wurde (vor Juli 2008). Dabei waren statements solcher Art speziell für Dokumentengenerierung vorgesehen.


3.3 Dokumente mit Inhaltsbestimmung

Topic:.XmlDocuGenCtrl.Syntax..

pStyle=std tableStyle=stdTable

Die eigentlichen Dokumente folgen danach, hier an einem Beispiel gezeigt. Danach deshalb, weil das Script der Dokumentengenerierung wie auch die Zmake-Scripts in der Reihenfolge der Anweisungen die Targets ausführen. Zuerst müssen die vorbereitenden Konvertierungen genannt werden.

 Document "Dokumentationsgenerierung mit XML - Übersicht" ident=XmlDocuGen
 html="../docu/html/XmlDocuGen.html" css="../htmlstd.css"
 {
   input: XmlDocuGen.topic.txt;
   input: ./xmlDocuGenPicture.xml;
   inset: label = topic(Special/path);
   chapter "Übersicht" (id=XmlDocuGen_Overview)
   { picture("Übersicht Ablauf der Dokumentengenerierung", imgMap="XML_DocuGen_1");
     topic(XmlDocuGen/overviewNavigation/*, ulStyle="list-closely");
   }
   chapter "Motivation" (id=XmlDocuGen)
   { topic(XmlDocuGen/conceptualFormulation/*);
   }
 }

Alle unter input: aufgeführten Files werden als Inputfiles (Eingangsquellen) benutzt. Dabei wird eine vorige Aufbereitung der Eingangsquellen vorausgesetzt. Das Dokument wird nur dann neu generiert, wenn die Eingangsquellen neueren Datums sind als das zu erzeugende HTML-Dokument. Wenn die Eingangsquellen aufbereitet worden sind, damit typisch aus dem ../tmp-Verzeichnis gelesen werden, dann hat die Aufbereitung ebenfalls eine Abhängigkeit des Neuwertes berücksichtigt, Lässt man das ../tmp-Verzeichnis stehen, was bei wiederholter Generieurung zweckmäßig ist, dann wird nur das generiert, was neu ist. Ist das ../tmp-Verzeichnis jedoch gelöscht, dann wird das HTML-Dokument bereits deswegen neu generiert, weil alle Zwischen.xml-Files in das ../tmp-Verzeichnis hinein neu generiert worden sind. Das ist auch meist zweckmäßig.

Die Kapitelgliederung des Dokumentes wird hier meist direkt angegeben. Allerdings werden Unterkapitel auch gebildet, wenn ein topictree anstelle von topic verwendet wird. Anstelle von topic oder picture können auch andere Eingangselemente gewählt werden, die entweder selbst Kapitel bilden oder nur Textinhalte, oder Tabellen usw.usf. Eine genaue Übersicht liefert hier das XmlDocu_xsl/DocuGenCtrl.zbnf-Script, im Ausschnitt dargestellt:

document::=Document <""?@title> ident = <$?@ident>  ##the ident is the identification of the document for generating process. Old form, it is the file name in html/ident.html and word/ident.xml
                        [ html = <file?outHtml>  ]  ##this file with path will be produced as html-file
                        [ css  = <""?cssHtml>  ]    ##this file with path is linked as css file in the html-file
                        [ word = <file?outWord>  ]  ##this file with path will be produced as word-file
\{
[{ input: <prepXmlInput?input> ;                    ##The input files for generating the XhtmlPre, possible preprocessed, see <prepXml>
 | inputCrossRef: <prepXmlInput?inputCrossRef> ;
 | inset: <inset> ;                                 ##association between inset proxy label and associated topic
}]
[xslCrossRef: <import?xslCrossRef> ; ]
{ chapter <chapter>                                   ##at least one, or more toplevel chapters
| <content?>
| HyperlinkAssociation <HyperlinkAssociations>
}
\}
.
?topic::="topic content without sub-topics. Use /* on end of select string to get the content without the topic-title.".
?topictree::="topic with all sub-topics as sub-chapters.".
?freemindtopictree::="topic with all sub-topics as sub-chapters from freemind.mm.".
prepXmlInput::=<*;\ \r\n-?@inputfile> [ -\> <$?@translator> [ -\> <*;\ \r\n-?@outputfile>]].
##association between inset label and a topic. Just now only topic association is supported.
##in the future more as that is able, hence the <topic> is produced.
inset::=<*\ =?@label> = [<?topic> topic ( <*)\ ?@select> )| none].
chapter::= <""?title> [({ id=<*,) ?@id> ?, })]  ##the id produce a hyperlink anchor in the output document for this chapter.
\{ { [chapter <chapter>|[<content?>]]}
\}.
content::=
{ p <""?p>
   | inset <inset>
   | topic( <topic> );
   | topictree( <topic?topictree> );
   | freemindtopic( <topic?freemindtopic> );
   | freemindtopictree( <topic?freemindtopictree> );
   | freemindtable(<topic?freemindtable>);
   |<?file> file( <""?@path> [, <""?@from> \.\. [<""?@to> ]]);  ##input from a file, it is able to select a part from .. to specified text, exclusive this labels.
   | picture( <picture> );
   | umlPkg ( <umlPkg> );
   | umlClass ( <umlClass> );
   | umlIfc ( <umlClass?umlIfc> );
   | umlMethod ( <umlMethod> );
   | umlIfcMethod ( <umlMethod?umlIfcMethod> );
   | umlMethodBody ( <umlMethod?umlMethodBody> );
   | umlIfc ( <umlIfc> );
   | umlComment ( <umlComment> );
   | umlSQD ( <umlSQD> );
   | umlStateD ( <umlStateD> );
   | umlStateReport ( <umlStateReport> );
   | umlEnumeration( <umlEnumeration> );
   | umlDatatype( <umlDatatype> );
   | CLASS_C(<*)?CLASS_C/@select>);
   | dataStruct ( <umlClass> );
   | headerCClass(<*)?CLASS_C/@select>);
   | DEFINE_C(<*)?DEFINE_C/@select>);
   | crossRef( <crossRef> );
   | call <call> ;
   }
.
call::=<$?@name> ( <*,)\ ?@select> ).
##The syntax of topic is also used for ?topictree-semantic. It is the same.
topic::=<*,)\ ?@select>
[,{
  divStyle=[<$?@divStyle>|<""?@divStyle>]
| pStyle=[<$?@pStyle>|<""?@pStyle>]
| ulStyle=[<$?@ulStyle>|<""?@ulStyle>]
| olStyle=[<$?@olStyle>|<""?@olStyle>]
| dlStyle=[<$?@dlStyle>|<""?@dlStyle>]
| tableStyle=[<$?@tableStyle>|<""?@tableStyle>]
| style:<styleTransform>
? , }].

Die Syntax kann hier erweitert werden um anwenderspezifische Verarbeitungen. Sichtbar ist, dass Dokumente hier auch aus UML-Quellen (XMI) verarbeitet werden. An dieser Stelle muss auf eine zweckmäßig Entwicklung der Zukunft hingewiesen werden: Ein Eclipse-Plugin sollte das Editieren des Docu.genctrl-Files so unterstützen, dass mittels Test über das ZBNF-Script angeboten werden kann, was möglich ist. Dann sind auch Hilfetexte, die ebenfalls im ZBNF-Script stehen, als kontextsensitive Erklärung vorhanden.

Ein Dokument kann auf dem Toplevel, außerhalb von Kapiteln, topics enthalten. Der andere Inhalt, hier als content::=... definiert, darf nur in Kapiteln stehen. Das ist meist vernünftig. Kapitel können beliebig geschachtel werden.

Der Eintrag inset: weist einem Platzhalters in einem beliebigen Text des Dokumentes den Inhalt eines Topics zu. Damit ist es möglich, innerhalb von Topics oder anderen Textbestandteilen des Dokumentes nicht nur den dort stehenden Text wiederzugeben sondern ihn mit dokumentenspezifischen Inhalt zu mischen, wenn dies an entsprechenden Textstellen vorgesehen ist. Das ist eine generelle zweite Möglichkeit der Inhaltsbestimmung. Siehe auch inset-Technologie.


3.4 Querverweisangaben

Topic:.XmlDocuGenCtrl.Syntax..

pStyle=std tableStyle=stdTable

Für die Dokumente sind Querverweise essentiell. Wie in HrefInDocuGenCtrl dargestellt, sind die Querverweise nicht in den eigentlichen Texten planbar (dort ist nicht definiert, was nach der Dokumentengenerierung vorhanden ist), sondern sie sind es erst mit der Dokumentengenerierung. Das schafft nebenbei eine hohe Flexibilität. Am Beispiel XmlDocu/docuSrc/XmlDocuGen.genctrl sieht das wie folgt aus (gekürzt):

 HyperlinkAssociation
 {
   //Verweise auf andere Dokumente innerhalb der XmlDocuGen:
   //-------------------------------------------------------
   XmlDocuGen-Overview = "XmlDocuGen.html";
   WikiFormat ="WikiFormat.html";
   insetTechnology ="todo";
   HrefInDocuGenCtrl = "Hyperlink.html";
   CorrectHref = "Hyperlink.html#CorrectHref";
   ZBNF = "../../ZBNF/index.html";
   //Verweise auf andere Dokumente innerhalb vishia
   //----------------------------------------------
   JcReflection = "../../Jc/oldHtml/Reflection.html";
   Cheader2Xmi = "../../SwEng/html/headerXmi.html";
   Zmake = "../../Xml/indexZmake.html";
   //Links nach außen:
   //-----------------
   >>Java="http://www.java.sun.com";
   >>Eclipse-Ant="http://Sourceforge.net/projects/ant-eclipse";
   //Downloads sind verteilt im System, aber einheitlich mit einem Schluesselwort download:_ gekennzeichnet:
   //-------------------------------------------------------------------------------------------------------
   download:_XmlDocu_xsl = "../../Xml/XSL_Download.zip";
   //Schlüsselwort zum Auffinden von Dateien, die Schlüsselworte sollten im normalen Text dargestellt werden können:
   //---------------------------------------------------------------------------------------------------------------
   javadoc:_* = "../../Java/docuSrcJavaPublic/*.html";
   javadoc-src:_* = "../../Java/docuSrcJavaSrc/*.html";
   XmlDocu_xsl/* = "../html/XmlDocu_xsl/*.html";
   XmlDocu_batch/*.bat = "*.bat.html";
 }

Es sind also eine Menge links als direkte Schlüsselworte wie WikiFormat hier sichtbar. Eine Änderung des Zieles für alle Stellen innerhalb der hier generierten Dokumente, die in topics, in UML-Descriptions, in Headerfiles usw. mit diesem Link-Schlüsselwort gekennzeichnet sind, kann also an dieser einen Stelle erfolgen.

Die zweite Möglichkeit ist das Platzhalter-, Wildcard- oder Gieskannen-Symbol *. Alle Link-Schlüsselworte, die auf das Symbol passen, werden ersetzt. Beispielsweise alle javadoc:_packagepath/file-Angaben werden auf die javadoc-Dokumentation umgeleitet.

Syntaktisch in XmlDocu_xsl/DocuGenCtrl.zbnf sieht das so aus:

 HyperlinkAssociations::= \{ {<?Association/> <*\ =?@href> = <""?@dst> [: <$?@content>] ; } \}.

Also nur eine Zeile, die diese Syntax beschreibt.


3.5 Hinweise auf Fehler, die während der Konvertierung auffallen

Topic:.XmlDocuGenCtrl.Syntax..

pStyle=std tableStyle=stdTable

 NAME.pre.xml:
    [exec] WARNING: ERROR argument -i is obligat.

Obige ANT-Meldung weist darauf hin, dass im Document-Block kein input angegeben ist:

 Document "vishia - Object_Jc - Basis aller Daten" ident=Object_Jc
 {
   input: Object_Jc.topic.txt;

4 Beschreibung der Arbeitsweise der Konvertierung

Dieses Kapitel ist gedacht nicht für die einfache Anwendung sondern zur Darstellung

      der internen Wirkungsweise.


Bild: ../InclFiles/DocuGenCtrl_internal.png

Topic:.XmlDocuGenCtrl.internalOverview.

pStyle=std tableStyle=stdTable

.


ERROR: not found ---/root//topics:topic[@ident='XmlDocuGenCtrl']/topics:topic[@ident='DocuGenCtrl2Ant_xslp']---


ERROR: not found ---/root//topics:topic[@ident='XmlDocuGenCtrl']/topics:topic[@ident='DocuGenCtrl2Xsl_xslp']---