Benutzer:Dirk Huenniger/wb2pdf/template

Aus Wikibooks

Ein paar Erklärungen zum Template Prozessor. Es geht darum zu verstehen wie Mediawikivorlagen nach Latex umgesetzt werden können.

In mediawiki haben die Vorlage in einem Anwendungsbeispiel

{{MyVorlage|text=Mein Text}}

Wir Wollen diese nach Latex übertragen und folgenden Latex Code erhalten.

\myLaTeXVorlage{Mein Text}

Im Quellcode der Template Prozessors müssen wir also in etwa scheiben:

templateProcessor(templatename,templateparameters) {
  if (templatename=="MyVorlage") {
    return "\\myLaTeXVorlage{"+templateparameters["text"]+"}";
  }
  if (templatename=="MyAndereVorlage") {
    return ...
  }
...
}

Schauen wir uns diesen Quelltextabschnitt etwas genauer an: Ein Programm dessen genauen Arbeitsablauf wir (zum Glück) nicht genau verstehen müssen analysiert die Vorlage im MediaWikiformat. Es erzeugt daraus zwei Variablen. Die erste heißt templatename und enthält den Namen des Templates. In unserem Falle also MyVorlage. Die zweite ist ein Array. Jedoch kein so wirklich gewöhnliches Array. Bei einem Normalen Array verwendet man Zahlen als Index. Und beliebige Datentypen als werte. In unserem Speziellen Array müssen wir jedoch werte Strings als Indextyp verwenden. Genugenommen verwenden wir den String text. Der Aufruf templateparameters["text"] gibt uns den Wert der zum Index Text gehört zurück. Dieser ist ebenfalls ein String und zwar genau genommen der String Mein Text. Der Operator plus verbindet zwei strings zu einem neuen String. Zum Beispiel ergibt "ab+"cd" den Rückgabe-Wert abcd. Weiterhin fällt auf das wir den Backslash \ am Anfang verdoppelt haben. Dies ist ein escaping was notwendig wird weil der Backslash auch zum einleiten von Sonderzeichen benutzt wird.

Nun kommen wir zu eine Besonderheit der Funktionalen Programmierung. Die if Konstruktionen von oben können wir auch wie folgt schreiben.

templateProcessor("MyVorlage",templateparameters) {
    return "\\myLaTeXVorlage{"+templateparameters["text"]+"}";
}
templateProcessor("MyAndereVorlage",templateparameters) {
    return ...
}
...

Wir haben also die Funktion templateProcessor zweifach definiert. Jedoch haben wir in der Definition angegeben für welchen konkreten Wert von templatename (des ersten Parameters) unsere Definition Gültigkeit haben soll. Hierdurch ist unsere Definition immer noch eindeutig. Unsere if Konstruktion sieht jedoch etwas anders aus und erinnert etwas an eine case Konstruktion. Wir wählen nun noch eine kürzere Schreibweise die sich daraus ergibt, dass wir klammern, Kommata und return weglassen und anstelle der öffnenden Geschwungenen klammer ein Gleichheitszeichen schreiben. Ferner ersetzen wir das einfache Plus-Zeichen durch ein doppeltes.

templateProcessor "MyVorlage" templateparameters = "\\myLaTeXVorlage{"++templateparameters["text"]++"}"
templateProcessor "MyAndereVorlage" templateparameters = ...
}
...

Nun fügen wir noch ein paar zusätzliche Klammern und die Variable st ein und benennen templateparameter in ll um:

templateProcessor st ("MyVorlage",ll) = (st,"\\myLaTeXVorlage{"++ll["text"]++"}")
templateProcessor st ("MyAndereVorlage",ll) = (st, ...)
...

Nun benennen wir ll in x um und fügen am ende eine weitere Zeile ein.

templateProcessor st ("MyVorlage",x) = (st,"\\myLaTeXVorlage{"++x["text"]++"}")
  x=ensure ["text"] ll
templateProcessor st ("MyAndereVorlage",ll) = (st, ...)
...

Die letzte Zeile bewirkt, dass zum Index "text" auf alle fälle ein werte existiert, wenn gleicht dieser schlimmstenfalls der leere String ist. Nun schreiben wir das auslesen aus x noch etwas um

templateProcessor st ("MyVorlage",x) = (st,"\\myLaTeXVorlage{"++(getValueForKey "text" x)++"}")
  x=ensure ["text"] ll
templateProcessor st ("MyAndereVorlage",ll) = (st, ...)
...

Nun ist aber der Wert den das Array zurück liefert kein String sondern eine Art XML Dokument was dem Inhalt des Templates und insbesondere seiner Formatierungen entspricht. Daher muss es noch in einen String umgewandelt werden.

templateProcessor st ("MyVorlage",x) = (st,"\\myLaTeXVorlage{"++(treeToLaTeX (getValueForKey "text" x))++"}")
  x=ensure ["text"] ll
templateProcessor st ("MyAndereVorlage",ll) = (st, ...)
...

und so sieht es aus wenn es fertig ist.

templateProcessor st ("Fortran:Vorlage: Pre4",ll)=(st,   
    "{\\bf Fortran 2003-Code} \\newline"++
    "{\\tt {\\scriptsize "++
     (treeToLaTeX (getValueForKey "1" x) st) ++
     "}}\n")
    where 
      x=ensure ["1"] ll