Entdecken Sie eBooks
Kategorien
Entdecken Sie Hörbücher
Kategorien
Entdecken Sie Zeitschriften
Kategorien
Entdecken Sie Dokumente
Kategorien
Fakultt Informatik Referent: Prof. Dr. Oliver Braun Korreferent: Dipl. Math. Michael Otto eingereicht von: David Hahn Matr.-Nr. 280346 Martin-Luther-Ring 38 98574 Schmalkalden Schmalkalden, den 22. August 2012
Inhaltsverzeichnis
1 Einleitung 1.1 Zielsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Statische Webseiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Grundlagen 2.1 Haskell . . . . . . . . . . . . . 2.2 Pandoc . . . . . . . . . . . . . 2.3 Markdown . . . . . . . . . . . 2.3.1 Kopfzeilen . . . . . . . 2.3.2 Zitate . . . . . . . . . 2.3.3 Betonung . . . . . . . 2.3.4 Listen . . . . . . . . . 2.3.5 Links . . . . . . . . . . 2.3.6 Bilder . . . . . . . . . 2.3.7 Code . . . . . . . . . . 2.3.8 Inline-HTML . . . . . 2.3.9 Backslash-Maskierung 3 Vorbetrachtung 4 Implementierung 4.1 Datentypen . . . . . . . . 4.2 Main-Funktion . . . . . . 4.3 Create-Funktion . . . . . . 4.4 getSiteCong-Funktion . . 4.5 getPageCong-Funktion . 4.6 renderHtmlPage-Funktion 4.7 buildSite-Funktion . . . . 4.8 Navigation . . . . . . . . . 1 1 2 3 3 3 6 6 7 7 8 9 10 10 11 11 13 16 16 17 18 20 21 22 23 24 26 26 26 27 28 29 30
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
5 Anleitung zur Generierung von Webseiten 5.1 Installation . . . . . . . . . . . . . . . 5.2 Erstellung der Ordnerstruktur . . . . . 5.3 Verfgbare Templates . . . . . . . . . . 5.4 Inhalte hinzufgen . . . . . . . . . . . 5.5 HTML-Dateien erstellen . . . . . . . . 6 Zusammenfassung und Ausblick
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
David Hahn
II
David Hahn
III
1 Einleitung
Das Internet ist heutzutage nicht mehr wegzudenken. Es existieren mehrere hundert Millionen Webseiten im Internet. Tglich kommen neue Seiten hinzu oder verschwinden aus dem Internet. Der allgemeine Trend geht aber in die Richtung, dass immer mehr Webseiten im Internet abgerufen werden knnen.1 Durch die zahlreichen Anbieter und den geringen Kosten, hat nahezu jeder die Mglichkeit sich im Internet zu prsentieren. Aber nicht jeder hat die Kenntnisse eine solche Seite selber zu erstellen. Daher soll im Rahmen dieser Bachelorarbeit ein Generator programmiert werden, mit welchem ein Anwender mit wenig Vorkenntnissen schnell und einfach eine statische Webseite erstellen kann.
Abbildung 1.1: Anzahl der Webseiten von August 1995 bis August 20122
1.1 Zielsetzung
Es soll ein Generator entstehen mit welchem es mglich ist, einfach und schnell statische Webseiten zu erstellen. Dabei sollen keine HTML-Vorkenntnisse bentigt werden. Die Inhalte der Webseite werden mit Markdown beschrieben. Gespeichert werden diese in Textdateien, welche mit einem beliebigen Texteditor verndert werden knnen. Der Generator bernimmt mit Hilfe von Pandoc das bersetzten in
1 2
David Hahn
Seite 1 von 35
1. Einleitung
HTML. Auerdem sollen verschiedene Templates zur Verfgung stehen. ber die Kommandozeilen werden die Webseiten erstellt und die HTML-Dateien erzeugt.
Mit einem CMS knnen die Inhalte einer Webseite mittels einer benutzerfreundlichen Oberche gepegt werden. Es ermglicht die Pege und Aktualisierung der Inhalte durch verschiedene Personen
David Hahn
Seite 2 von 35
2 Grundlagen
In dem Kapitel Grundlagen werden die Themengebiete die in dieser Bachelorarbeit behandelt wurden nher beschrieben. Dabei wird auf Haskell, Pandoc und Markdown eingegangen.
2.1 Haskell
Haskell ist eine rein funktionale Programmiersprache, welche zu einer Untergruppe der deklarativen Sprachen gehrt. Bei funktionalen Programmiersprachen handelt es sich um Programme, die ausschlielich aus Funktionen bestehen. Dadurch knnen Nebenwirkungen, wie sie aus imperativen Programmiersprachen bekannt sind, vermieden werden. Eine Nebenwirkung von imperativen Programmiersprachen, dazu zhlen zum Beispiel C++ und Java, ist der Seiteneekt. Haskell hat aber noch weitere Vorteile: So knnen Funktionen hherer Ordnung verwendet werden, was eine starke Wiederverwendung von Programmteilen ermglicht. Die Abwesenheit von Seiteneekten fhrt zur Reinheit der Sprache. Dadurch wird das Beweisen ber Programmeigenschaften erleichtert. Auerdem bietet Haskell ein starkes Typsystem, wodurch viele Fehler bereits durch den Compiler erkannt werden.1
2.2 Pandoc
Pandoc ist ein Programm zur Konvertierung von Dokumenten. Damit lassen sich Textdateien, die in einer Auszeichnungssprache2 geschrieben sind, in ein anderes Format umwandeln. Pandoc versteht eine Reihe von verschiedenen Sprachen zur Eingabe, wie zum Beispiel Markdown, HTML oder LaTeX. Zur Ausgabe stehen viele weitere Formate zur Verfgung (siehe Tabelle 2.1). Dadurch ist es mglich einen Text, der in der Auszeichnungssprache Markdown geschrieben wurde, als Blog in HTML zu verentlichen, einen Wikipedia-Artikel zu erstellen und den Text in ein Word-Dokument umzuwandeln. Dies geschieht alles mit wenigen Befehlen.
1 2
Vgl. http://www.infosun.m.uni-passau.de/cl/lehre/funcprog05/wasistfp.html Eine Auszeichnungssprache (englisch: Markup Language) dient zur Beschreibung des Inhalts eines Dokumentenformates. Durch eine Auszeichnungssprache knnen beliebigen Textelementen auf deklarative Weise Eigenschaften zugewiesen werden, wodurch deren Bedeutung ausgedrckt werden kann.
David Hahn
Seite 3 von 35
2. Grundlagen Formatname markdown reStructuredText Textile HTML LaTeX HTML5 ConTeXt Word docx DocBook Gro man RTF OpenDocument XML ODT Texinfo Org-mode EPUB Slidy S5 dzslides Beamer AsciiDoc MediaWiki
Tabelle 2.1: Von Pandoc untersttzte Formate Da Pandoc in Haskell geschrieben wurde, steht es als Haskell-Bibliothek zu Verfgung. Dadurch ist es mglich, mit wenigen Befehlen aus einem Haskell-Programm ein Dokument umzuwandeln. Das Befehlszeilenprogramm ist fr Windows, Mac OS X und Linux verfgbar. Das folgende Beispiel zeigt eine Konvertierung von Markdown (Listing 2.2) zu HTML (Listing 2.3). Dies geschieht mit dem folgenden Befehl ber das Befehlszeilenprogramm: pandoc -f markdown pandoc.text -t html -o pandoc.html Die Option -f gibt dabei das Input-Format an. Danach folgt die Datei, welche konvertiert werden soll. Mit -t wird das Ausgabeformat festgelegt und mit -o die Ausgabedatei. Ein Haskell-Programm, welches diese Datei umwandelt, knnte folgendermaen aussehen:
David Hahn
Seite 4 von 35
2. Grundlagen
Listing 2.1: Haskell-Programm zum umwandeln mit Pandoc module Main where import Text.Pandoc markdownToHTML :: String String markdownToHTML string = let markdown = readMarkdown defaultParserState string writeHtmlString defaultWriterOptions markdown konvertiere :: FilePath IO () konvertiere datei = do text readFile datei let convertedText = markdownToHTML text writeFile "output.html" convertedText
Der Funktion konvertiere wird der Pfad zu Datei bergeben, welche in HTML umgewandelt soll. Zuerst wird dann der Inhalt der Datei eingelesen und mittels der Funktion markdownToHTML von Markdown in HTML konvertiert. Zuletzt wird dann der konvertierte Text in die Datei output.html geschrieben. Listing 2.2: Ausgangsform Markdown # Pandoc ## Was ist Pandoc Pandoc ist ein Programm zur Konvertierung von Dokumenten. Damit lassen sich Textdateien, die in einer Auszeichnungssprache geschrieben sind, in ein anderes Format umwandeln. Pandoc wurde in [Haskell] geschrieben. [Haskell]: http://haskell.org
Listing 2.3: Konvertiert in HTML <h1 id="pandoc">Pandoc</h1> <h2 id="was-ist-pandoc">Was ist Pandoc</h2> <p>Pandoc ist ein Programm zur Konvertierung von Dokumenten. Damit lassen sich Textdateien, die in einer Auszeichnungssprache geschrieben sind, in ein anderes Format umwandeln. Pandoc wurde in <a href="http://haskell.org">Haskell</a> geschrieben.</p>
David Hahn
Seite 5 von 35
2. Grundlagen
2.3 Markdown
Markdown ist eine vereinfachte Auszeichnungssprache die leicht lesbar und schreibbar ist. Um dies zu gewhrleisten besteht die Syntax von Markdown nur aus Zeichen, die ihrem Aussehen ihrer Bedeutung entsprechen. So sehen Listen in Markdown wie Listen aus oder Zitate-Blcke wie zitierte Textpassagen, wie sie aus E-Mails bekannt sind. E-Mails waren daher auch die grte Inspirationsquelle fr die Entwicklung des Markdowns Syntax. Im Folgenden werden die verschiedenen Mglichkeiten beschrieben mit Markdown Text auszuzeichnen. Auerdem wird der dazugehrige HTML-Code gezeigt.
2.3.1 Kopfzeilen
In Markdown gibt es zwei Arten Kopfzeilen zu denieren. So knnen berschriften mit Gleichheitszeichen (erste Ebene) und Bindestrichen (zweite Ebene) unterstrichen werden. Listing 2.4: berschriften in Markdown Methode 1 Dies ist ein H1 == == == == == == == = Dies ist ein H2 --------------Listing 2.5: berschriften Methode 1 in HTML <h1>Dies ist ein H1</h1> <h2>Dies ist ein H2</h2>
Mit der zweiten Mglichkeit sind bis zu sechs Ebenen mglich. Dazu werden 1-6 Rauten-Zeichen vor die berschrift gesetzt, wobei die Anzahl der Rauten-Zeichen die Ebene entspricht. Listing 2.6: berschriften in Markdown Methode 1 # Dies ist ein H1 ## Dies ist ein H2 ###### Dies ist ein H6
David Hahn
Seite 6 von 35
2. Grundlagen
Listing 2.7: berschriften Methode 2 in HTML <h1>Dies ist ein H1</h1> <h2>Dies ist ein H2</h2> <h6>Dies ist ein H2</h6>
2.3.2 Zitate
Zitate werden in Markdown mit dem Zeichen > gekennzeichnet, wie es auch aus E-Mails bekannt ist. Dabei knnen Zitate verschachtelt werden. Auerdem ist es mglich Kopfzeilen, Listen und Code-Blcke in Zitat-Blcken unterzubringen. Listing 2.8: Zitate in Markdown > # Dies ist die erste Zitat-Ebene. > > > Dies ist ein verschachteltes Zitat. > > 1. Dies ist der erste Listenpunkt. > 2. Dies ist der zweite Listenpunkt. Listing 2.9: Zitate in HTML <blockquote> <h1>Dies ist die erste Zitat-Ebene.</h1> <blockquote> <p>Dies ist ein verschachteltes Zitat.</p> </blockquote> <ol style="list-style-type: decimal"> <li>Dies ist der erste Listenpunkt.</li> <li>Dies ist der zweite Listenpunkt.</li> </ol> </blockquote>
2.3.3 Betonung
Um in Markdown einen Text fett oder kursiv zu schreiben, stehen die beiden Zeichen Sternchen (*) und Unterstrich (_) zur Verfgung. Wird der Text mit einem Sternchen oder Unterstrich umschlossen, wird der Text Kursiv geschrieben. Bei zwei Zeichen Fett und bei drei Zeichen Fett und Kursiv. Listing 2.10: Betonungen in Markdown Einige dieser Worte sind kursiv geschrieben Einige dieser Worte sind _ebenfalls kursiv geschrieben_ Einige dieser Worte sind fett geschrieben
David Hahn
Seite 7 von 35
2. Grundlagen
Einige dieser Worte sind __ebenfalls fett geschrieben__ Einige dieser Worte sind fett und kursiv geschrieben Einige dieser Worte sind ___ebenfalls fett und kursiv geschrieben___ Listing 2.11: Betonungen in HTML <p>Einige dieser Worte sind <em>kursiv geschrieben</em> </p> <p>Einige dieser Worte sind <strong>fett geschrieben</strong> </p> <p>Einige dieser Worte sind <strong> <em>fett und kursiv geschrieben</ em> </strong> </p>
2.3.4 Listen
Markdown untersttzt sortierte (nummerierte) und unsortierte (Aufzhlungen) Listen. Fr unsortierte Listen knnen die Zeichen Sternchen (*), Plus (+) und Bindestrich (-) verwendet werden. Alle drei Zeichen stellen die gleiche Liste dar. Die einzelnen Zeichen knnen sogar kombiniert werden. Listing 2.12: Unsortierte Listen in Markdown + + + Schwarz Rot Gold Schwarz Rot Gold Schwarz Rot Gold Listing 2.13: Unsortierte Listen in HTML <ul> <li>Schwarz</li> <li>Rot</li> <li>Gold</li> </ul>
Um sortierte Listen darzustellen, werden Zahlen verwendet. Dabei gibt die erste Zahl die Startzahl an, alle anderen Zahlen haben keine Auswirkung. Listing 2.14: Sortierte Listen in Markdown 1. 2. 3. Schwarz Rot Gold
David Hahn
Seite 8 von 35
2. Grundlagen
5. 2. 9.
Listing 2.15: Sortierte Listen in HTML <ol style="list-style-type: decimal"> <li>Schwarz</li> <li>Rot</li> <li>Gold</li> </ol> <ol start="5" style="list-style-type: decimal"> <li>Schwarz</li> <li>Rot</li> <li>Gold</li> </ol>
2.3.5 Links
Markdown untersttzt zwei Arten von Links: Inline und Referenzen. In beiden Arten werden eckigen Klammern benutzt, um den Link-Text zu markieren. Bei Inline-Links folgt hinter der schlieenden eckigen Klammer die URL in normalen runden Klammern. Optional kann innerhalb der runden Klammern noch ein Titel fr den Link deniert werden. Dieser wird in Anfhrungszeichen gesetzt. Listing 2.16: Inline-Links in Markdown Dies ist ein [Beispiel](http://beispiel.com/). Dies ist ein [Beispiel](http://beispiel.com/ "Optionaler Titel"). Listing 2.17: Inline-Links in HTML <p>Dies ist ein <a href="http://beispiel.com/">Beispiel</a>. Dies ist ein <a href="http://beispiel.com/" title="Optionaler Titel"> Beispiel</a>.</p>
Bei Referenz-Links wird statt der URL in runden Klammern, ein beliebiger Bezeichner in eckigen Klammern geschrieben. Irgendwo im Dokument wird dann der Link deniert. Diese Variante ist vorteilhaft, wenn der Link mehrmals im Dokument benutzt wird. Listing 2.18: Referenz-Links in Markdown Dies ist ein [Beispiel][bsp]. Die URLs werden irgendwo im [Dokument][doc] definiert.
David Hahn
Seite 9 von 35
Listing 2.19: Referenz-Links in HTML <p>Dies ist ein <a href="http://beispiel.com/" title="Optionaler Titel">Beispiel</a>. Die URLs werden irgendwo im <a href="http:// document.com/">Dokument</a> definiert.</p>
2.3.6 Bilder
Die Syntax fr Bilder ist der fr Links ziemlich hnlich. Es wird lediglich ein Ausfhrungszeichen vorangestellt. Listing 2.20: Bilder in Markdown   ![Alternativer Text][bild] [bild]: /pfad/zum/bild.jpg "Optionaler Titel" Listing 2.21: Bilder in HTML <p> <img src="/pfad/zum/bild.jpg" alt="Alternativer Text" /> </p> <p> <img src="/pfad/zum/bild.jpg" title="Optionaler Titel" alt=" Alternativer Text" /> </p> <p> <img src="/pfad/zum/bild.jpg" title="Optionaler Titel" alt=" Alternativer Text" /> </p>
2.3.7 Code
Um einen Code-Bereich zu markieren, wird er mit Backtick-Zeichen (` umschlos) sen. In Code-Bereichen werden das kaufmnnische Und so wie spitze Klammern als HTML-Entitiy kodiert. Listing 2.22: Code in Markdown In Markdown wird Code mit dem Backtick-Zeichen definiert. Listing 2.23: Code in HTML <p>In Markdown wird <code>Code</code> mit dem Backtick-Zeichen definiert.</p>
David Hahn
Seite 10 von 35
2. Grundlagen
2.3.8 Inline-HTML
Da nicht jede Formatierung in Markdown machbar ist, kann einfach HTML verwendet werden. Dabei ist es nicht ntig HTML zu markieren. Es kann einfach in den Text geschrieben werden. Um zum Beispiel eine Tabelle in einen Markdown-Text einzubauen, werden einfach die HTML-Tags benutzt: Listing 2.24: Inline-Html in Markdown Dies ist ein normaler Absatz. <table> <tr> <td>Foo</td> </tr> </table> Dies ist noch ein normaler Absatz.
Dabei ist zu beachten, das bei Block-Elemente wie z.B. <div>, <table>, <pre> usw. der umgebende Inhalt durch leere Zeilen getrennt ist. Auerdem wird die Markdown Syntax innerhalb dieser Elemente nicht interpretiert. Anders sieht das bei Inline-HTML-Tags wie z.B. <span> oder <cite> aus. Diese knnen berall in einem Markdown Text verwendet werden. Im Gegensatz zu BlockTags wird die Markdown Syntax innerhalb von Inline-Tags interpretiert.
2.3.9 Backslash-Maskierung
Um Zeichen zu schreiben die sonst eine bestimmte Bedeutung in der Markdown Syntax haben, gibt es die Mglichkeit der Backslash-Maskierung. Um ein Wort mit Sternchen zu umgeben, statt es kursiv zu schreiben, werden Backslashes vor die Sternchen gestellt. Listing 2.25: Beispiel Backslash-Maskierung in Markdown \Von Sternchen umgeben\
Markdown bietet diese Mglichkeit fr folgende Zeichen: Listing 2.26: Backslash-Maskierung in Markdown \ _ {} Backslash Backtick Sternchen Unterstrich Geschweifte Klammern
David Hahn
Seite 11 von 35
David Hahn
Seite 12 von 35
3 Vorbetrachtung
Da eine Webseite nicht nur aus dem Inhalt besteht, sondern auch aus anderen Bereichen wie einem Header, der Navigation, einer Fuzeile, sowie einem Template, mssen diese Bereiche auch von Benutzer deniert werden knnen. So wird es eine allgemeine Kongurationsdatei geben, in welcher folgende Metainformationen1 hinterlegt werden knnen: author year website_title website_slogan description keywords
Anhand von Platzhaltern sollen die hinterlegten Metainformationen author, year, website_title und website_slogan in das Template eingefgt werden (Abb. 3.1). Die Metainformationen description und keywords sind dagegen keine sichtbaren Informationen. Listing 3.1: Beispiel fr die allgemeine Kongurationsdatei author: David Hahn date: 2012 website_title: Beispielseite website_slogan: Generiert mit StatiGen description: Eine Beispielseite die mit StatiGen generiert wurde. keywords: statigen, david, hahn, fh schmalkalden, fh, schmalkalden
Der Inhalt jeder einzelnen Seite wird in eine extra Datei gespeichert. Dieser wird dann bei den Platzhalter {content:} eingefgt (Abb. 3.1). Zustzlich hat jede dieser Datei eine eigene Kongurationsdatei, in welcher folgende Metainformationen hinterlegt werden: title in_menu order
1
Metainformationen sind strukturierte Daten, die Informationen ber andere Daten enthalten. Diese sind maschinell lesbar und auswertbar. Metainformationen bei einer technischen Zeichnung sind zum Beispiel: Name des Konstrukteurs, Bauteilnummer, Zeichnungsnummer, Versionsnummer, Datum.
David Hahn
Seite 13 von 35
3. Vorbetrachtung
Die Metainformation title legt den Titel der Seite fest. Dieser taucht dann in der Navigation auf. Mit true oder false kann bei in_menu festgelegt werden, ob diese Seite berhaupt in der Navigation angezeigt werden soll. Bei order wird angegeben, an welcher Position die Seite in der Navigation angezeigt werden soll. Listing 3.2: Beispiel fr die Kongurationsdatei einer Seite title: About in_menu: true order: 3
Die folgende Abbildung zeigt die Platzhalter, welche fr den einzelnen Metainformationen und dem Inhalt genutzt werden. Die Platzierung kann von Template zu Template unterschiedlich sein. Das Template einer Webseite wird in keiner Kongurationsdatei hinterlegt, sondern beim Erstellen einer neuen Webseite vom Benutzer angegeben.
Abbildung 3.1: Platzhalter fr Metainformationen und Inahlt Jedes Webseiten-Projekt besteht aus einer bestimmten Ordner- und Dateistruktur (Abb. 3.2). Das Stammverzeichnis jedes Projektes bekommt den Namen, welcher beim Erstellen der Webseite angegeben wird. Dieses Verzeichnis enthlt neben den
David Hahn
Seite 14 von 35
3. Vorbetrachtung
beiden Ordnern output und src, auch die allgemeine Kongurationsdatei cong.conf. In dem Ordner output werden nach dem die Webseite fertig ist, die HTML-Dateien und alle erforderlichen Bilder gespeichert. Im Ordner src benden sich mit den beiden Dateien default.template und default.css das ausgewhlte Template. Auerdem werden hier auch die einzelnen Seiten mit ihren Kongurationsdateien gespeichert. Die Dateien mit der Endung .page enthalten den Inahlt der einzelnen Seiten und die mit der Endung .conf sind die Kongurationsdateien. Im Ordner images werden alle bentigten Bilder abgespeichert.
David Hahn
Seite 15 von 35
4 Implementierung
In diesem Kapitel werden ausgewhlte Funktionen nher beschrieben. Der komplette Code ist auf GitHub1 verfgbar.
4.1 Datentypen
Fr den Generator wurden die drei Datentypen Site, Page und NavEntry angelegt. In Haskell werden eigene Datentypen mit dem Schlsselwort data deniert. Hinter dem Schlsselwort wird der Name des neuen Typs angegeben. Danach folgen die Konstruktoren, wobei diese auf verschiedene Arten angegeben werden knnen. In der hier angewandten Variante wird fr jeden Feldtyp ein Name angegeben. Dadurch werden automatisch Funktionen erzeugt, um auf ein Feld in dem Datentyp zuzugreifen. Listing 4.1: Datentyp Site data Site = Site { siteAuthor , siteDate , siteTitle , siteSlogan , siteDescription , siteKeywords } deriving (Show) :: :: :: :: :: :: String String String String String String
Der Datentyp Site beinhaltet die sechs Felder siteAuthor, siteDate, siteTitle, siteSlogan, siteDescription und siteKeywords, welche alle vom Typ String sind. Der Datentyp stellt quasi das Grundgerst der Webseite dar, denn hier werden alle Informationen der cong.conf -Datei gespeichert. Listing 4.2: Datentyp Page data Page = Page { , pageTitle :: , pageInMenu :: , pageNav :: , pageContent :: } deriving (Show)
1
https://github.com/pads-fhs/hawebgen
David Hahn
Seite 16 von 35
4. Implementierung
In dem Feld pageTitle wird der Titel der Seite als String gespeichert. Ob die Seite in der Navigation angezeigt werden soll, wird mit true oder false in dem Feld pageInMenu hinterlegt. Das Feld pageNav enthlt weiter Informationen ber den Eintrag in der Navigation und in pageContent wird der Pfad zur Datei gespeichert, welche den Inhalt enthlt, der auf der Seite angezeigt werden soll. Listing 4.3: Datentyp NavEntry data NavEntry = NavEntry { navOrder :: Integer , navTitle :: String , navUrl :: String } deriving (Show, Eq, Ord) Der letzte eigene Datentyp ist NavEntry. In navOrder wird die Zahl gespeichert, an welche Position der Eintrag in der Navigation auftauchen soll. navTitle beinhaltet den Titel, der in der Navigation angezeigt wird und navUrl die Seite, auf welche verlinkt werden soll.
4.2 Main-Funktion
Das Programm wird mit dem Befehl StatiGen ber die Kommandozeile aufgerufen. Dabei knnen verschiedene Parameter angegeben werden, wodurch das Programm unterschiedliche Funktionen aufruft. Zur Verfgung stehen create, settemplate, addpage und build. Wird StatiGen ohne Parameter aufgerufen, wird die gleiche Funktion wie mit build gestartet. Das Listing 4.4 zeigt den Quellcode der Funktion main, welcher weiter unten beschrieben wird. Listing 4.4: Main-Funktion main :: IO () main = do args getArgs case args of ["create",site] ExitSuccess ["create",site,template] ExitSuccess ["settemplate",template] ExitSuccess ["addpage",name] ExitSuccess ["build"] []
create site "default" exitWith create site template exitWith setTemplate template exitWith addPage name exitWith buildSite exitWith ExitSuccess buildSite exitWith ExitSuccess
Die Paramater create, settemplate und addpage erwarten dabei noch weitere Para-
David Hahn
Seite 17 von 35
4. Implementierung
meter. create kann mit einem oder zwei zustzlichen Parametern aufgerufen werden. Der erste zustzliche Parameter ist der Name der neuen Webseite. Wird kein zweiter Parameter mit angegeben wird das Default-Template fr die neue Webseite genutzt. Optional kann der Name des Templates angegeben werden, welches genutzt werden soll. Sobald eine Funktion durchgelaufen ist, wird das Programm erfolgreich beendet.
4.3 Create-Funktion
Die Create-Funktion erstellt die Ordnerstruktur und alle notwendigen Dateien. Dabei erwartet die Funktion zwei Parameter. Der erste Paramater ist der Name der Webseite. Mit diesem Namen wird ein neuer Ordner erstellt, in welchem alle Daten fr die Webseite gespeichert werden. Der zweite Parameter ist der Name des Templates, was fr die neue Webseite genutzt werden soll. Die Funktion berprft zuerst ob es bereits einen Ordner mit dem bergebenen Namen gibt. Ist dies der Fall, wird die Funktion mit einer Fehlermeldung beendet. Im zweiten Schritt wird berprft, ob es ein Template mit dem bergebenen Name fr das Template gibt. Gibt es ein solches Template nicht, wird die Funktion mit einer Fehlermeldung beendet. Als nchstes werden alle erforderlichen Ordner erstellt und das Template in den src Ordner kopiert. Auerdem wird noch eine Beispielseite in diesen Ordner kopiert. Zum Schluss wird die cong.conf -Datei geschrieben und mit Beispieldaten gefllt.
David Hahn
Seite 18 von 35
4. Implementierung
Das Listing 4.5 zeigt den Quellcode der Funktion create, welcher weiter unten beschrieben wird. Listing 4.5: Main-Funktion create :: FilePath String IO () create site template = do existsDir doesDirectoryExist site when existsDir $ do hPutStrLn stderr $ "Eine Webite mit dem Namen " + site + " + + existiert bereits." exitWith $ ExitFailure 2 templateDir getDataFileName "templates" existsTemplate doesDirectoryExist (templateDir </> template) when (existsTemplate == False) $ do hPutStrLn stderr $ "Eine Template mit dem Namen " + template + + + " existiert nicht." exitWith $ ExitFailure 3 createDirectoryIfMissing True site createDirectoryIfMissing True (site</>"output") templateContent liftM (filter (/=".") . map (makeRelative ( templateDir </> template))) $ getDirectoryContentsRecursive ( templateDir </> template) forM_ templateContent $ \file do let dest = site </> "src" </> file createDirectoryIfMissing True $ takeDirectory dest copyFile ((templateDir </> template) </> file) dest emptyPage liftM (filter (/=".") . map (makeRelative (templateDir </> "emptyPage"))) $ getDirectoryContentsRecursive ( templateDir </> "emptyPage") forM_ emptyPage $ \file do let dest = site </> "src" </> file createDirectoryIfMissing True $ takeDirectory dest copyFile ((templateDir </> "emptyPage") </> file) dest writeFile (site</>"config.conf") "author: Dein Name\nyear: 2012\ nwebsite_title: Titel der Webseite\nwebsite_slogan: Slogan der Webseite\ndescription: Beschreibung\nkeywords: Keyw"orter" Als erstes wird mit doesDirectoryExist berprft, ob es bereits einen Ordner mit dem bergebenen Namen gibt. Gibt es einen solchen Ordner wird True in die Variable existsDir geschrieben, ansonsten False. Existiert bereits ein Ordner mit dem Namen, die Variable existsDir ist also True, wird eine Fehlermeldung ausgegeben und die Funktion beendet. Als nchstes wird der Dateipfad zu dem Speicherort der Templates eingelesen. Dies geschieht mit der Funktion getDataFileName. Danach wird berprft ob auch ein
David Hahn
Seite 19 von 35
4. Implementierung
Template mit dem Namen existiert. Dies geschieht wieder mit der Funktion doesDirectoryExist. Sollte das Template nicht vorhanden sein, wird eine Fehlermeldung ausgegeben und die Funktion beendet. Waren beide Abfragen erfolgreich wird das Stammverzeichnis angelegt und in diesem der output-Ordner erstellt. Dabei legt die Funktion createDirectoryIfMissing alle berordner an, falls diese noch nicht existieren. Sind alle Ordner erstellt wird das Template kopiert. Zunchst wird mit der Funktion getDirectoryContentsRecursive alle Dateien, die sich in dem ausgewhlten TemplateOrdner benden ausgelesen. Dabei werden auch die Dateien bercksichtigt, die in einem Unterordner liegen. Anschlieend werden die relativen Dateipfade in einer Liste in die Variable templateContent gespeichert. Mit der Funktion forM_ wird nun jeder einzelner Eintrag dieser Liste durchgegangen, wobei der Eintrag in die temporre Variable le geschrieben wird. copyFile kopiert jede Datei in den src Ordner der neuen Webseite. Die Funktion forM_ ist hnlich der Foreach-Anweisung aus anderen Programmiersprachen. Danach wird mit dem gleichem Muster die Beispielseite in den src Ordner kopiert. Mit der Funktion writeFile wird zum Schluss die Datei cong.conf in dem Stammverzeichnis erzeugt und mit Beispieldaten gefllt.
4.4 getSiteCong-Funktion
Die Funktion getSiteCong liest die in der Datei cong.conf hinterlegten Informationen ein und speichert sie in den Datentyp Site. Um die Daten aus der Datei auszulesen wurde die Bibliothek Data.CongFile benutzt. Die Funktion erwartet als Parameter den Namen der Kongurationsdatei. Das Listing 4.6 zeigt den Quellcode der Funktion getSiteCong, welcher weiter unten beschrieben wird. Listing 4.6: getSiteCong-Funktion getSiteConfig :: FilePath IO Site getSiteConfig conf = do existsConfig doesFileExist conf when (existsConfig == False) $ do hPutStrLn stderr $ "Die Seite konnte nicht gebaut werden, da keine Config.conf Datei vorhanden ist!" exitWith $ ExitFailure 3 contents readFile conf let site = do c readstring emptyCP contents author get c "DEFAULT" "author" date get c "DEFAULT" "year" title get c "DEFAULT" "website_title" slogan get c "DEFAULT" "website_slogan" description get c "DEFAULT" "description"
David Hahn
Seite 20 von 35
4. Implementierung
keywords get c "DEFAULT" "keywords" return Site { siteAuthor = author , siteDate = date , siteTitle = title , siteSlogan = slogan , siteDescription = description , siteKeywords = keywords } case site of Left cperr error $ show cperr Right site return site
Zuerst wird mit doesFileExist berprft ob es die Datei cong.conf berhaupt gibt. Ist dies nicht der Fall, wird die Funktion mit einer Fehlermeldung abgebrochen. Existiert die Datei, wird sie mit readFile eingelesen und deren Inhalt in die Variable contents gespeichert. Nun kommt die Bibliothek Data.CongFile zum Einsatz. Die einzelnen Informationen werden zunchst ausgelesen und in temporren Variablen zwischengespeichert. Im Anschluss werden alle Variablen in den Datentyp Site gespeichert und zurck gegeben.
4.5 getPageCong-Funktion
Die getPageCong-Funktion ist dafr da, die Kongurationsdateien der einzelnen Seiten einzulesen und in den Datentyp Page zu speichern. Auch hier kommt die Bibliothek Data.CongFile zum Einsatz. Die Funktion erwartet als Parameter den Namen der Kongurationsdatei. Das Listing 4.7 zeigt den Quellcode der Funktion getPageCong, welcher weiter unten beschrieben wird. Listing 4.7: getPageCong-Funktion getPageConfig :: FilePath IO Page getPageConfig conf = do content getFirstElement $ split "." conf contents readFile ("src" </> conf) let page = do c readstring emptyCP contents title get c "DEFAULT" "title" inMenu get c "DEFAULT" "in_menu" order get c "DEFAULT" "order" let nav = NavEntry { navOrder = order , navTitle = title , navUrl = content+ +".html" } return Page { pageTitle = title , pageInMenu = inMenu , pageNav = nav
David Hahn
Seite 21 von 35
4. Implementierung
case page of Left cperr error $ show cperr Right page return page Zunchst wird der Name der .conf-Datei bei dem Punkt getrennt und der erste Teil ausgelesen und in die Variable content gespeichert. Dies entspricht dann nur dem Namen der Kongurationsdateien ohne die Dateiendung, Dies ist notwendig um damit spter auf die zugehrige .page-Datei zugreifen zu knnen. Im Anschluss wird die .conf-Datei eingelesen und in die Variable contents gespeichert. Nun wird mit Hilfe der Bibliothek Data.CongFile die Metainformationen ausgelesen und in temporren Variablen zwischengespeichert. Zustzlich wird ein NavEntry erzeugt, welches alle relevanten Informationen fr den Navigationseintrag beinhaltet. Im Anschluss werden alle Variablen in den Datentyp Page gespeichert und zurck gegeben.
4.6 renderHtmlPage-Funktion
Die Funktion renderHtmlPage-Funktion ersetzt im Template die Platzhalter mit den richtigen Daten und erzeugt daraus eine HTML-Datei. bergeben wird der Funktion vier Parameter. Der erste Parameter ist vom Datentyp Site, welche die Informationen der allgemeinen Kongurationsdatei enthlt. Im zweiten Parameter bendet sich das Template als String. Die Navigation ist im dritten Parameter enthalten und der vierte Parameter enthlt die Seite, welche umgewandelt werden soll. Das Listing 4.8 zeigt den Quellcode der Funktion renderHtmlPage, welcher weiter unten beschrieben wird. Listing 4.8: renderHtmlPage-Funktion renderHtmlPage :: Site [Char] [Char] Page IO () renderHtmlPage site template navigation page = do content readFile ("src" </> (pageContent page)) let contentHtml = markdownToHTML content let siteWithContent = replace template "{content:}" contentHtml let siteWithPageTitle = replace siteWithContent "{title:}" ( pageTitle page) let siteWithSiteDescription = replace siteWithPageTitle "{ description:}" (siteDescription site) let siteWithSitesiteKeywords = replace siteWithSiteDescription "{ keywords:}" (siteKeywords site) let siteWithSiteTitle = replace siteWithSitesiteKeywords "{ website_title:}" (siteTitle site) let siteWithSlogan = replace siteWithSiteTitle "{website_slogan:}" (siteSlogan site) let siteWithDate = replace siteWithSlogan "{year:}" (siteDate site) let siteWithAuthor = replace siteWithDate "{author:}" (siteAuthor site)
David Hahn
Seite 22 von 35
4. Implementierung
let completeSite = replace siteWithAuthor "{menu:}" $ setCurrentSiteInNavigation navigation page let path = navUrl $ pageNav page writeFile ("output" </> path) completeSite
Zuerst wird die zugehrige .page-Datei eingelesen und anschlieend mit der Funktion markdownToHTML in HTML umgewandelt. Im Anschluss wird mit der Funktion replace Schritt fr Schritt alle Platzhalter im Template mit den richtigen Daten gefllt. Und zum Schluss wird die fertige HTML-Seite mit der Funktion writeFile in dem Ordner output gespeichert.
4.7 buildSite-Funktion
Die buildSite-Funktion sorgt dafr, dass alle HTML-Seiten erstellt werden und im output Ordner gespeichert werden. Das Listing 4.9 zeigt den Quellcode der Funktion buildSite, welcher weiter unten beschrieben wird. Listing 4.9: buildSite-Funktion buildSite :: IO () buildSite = do existsWebsite checkWebsite when (existsWebsite == False) $ do hPutStrLn stderr $ "Es konnte keine Website gefunden werden!" exitWith $ ExitFailure 1 config getSiteConfig "config.conf" template getTemplate content getDirectoryContents "src" let content = filter (\f let ext = takeExtension f in ext == ". conf") $ filter (notElem ["..","."]) content pages mapM getPageConfig content navigation getNavigation pages forM_ pages $ \page do renderHtmlPage config template navigation page existsCss doesFileExist ("src" </> "default.css") when existsCss $ do copyFile ("src" </> "default.css") ("output" </> "default.css") existsImages doesDirectoryExist ("src" </> "images") when existsCss $ do templateContent liftM (filter (/=".") . map (makeRelative (" src" </> "images"))) $ getDirectoryContentsRecursive ("src" < /> "images") forM_ templateContent $ \file do let dest = "output" </> "images" </> file
David Hahn
Seite 23 von 35
4. Implementierung
createDirectoryIfMissing True $ takeDirectory dest copyFile ("src" </> "images" </> file) dest
Zunchst wird mit der Funktion checkWebsite berprft, ob sich der Benutzer auch in einem Stammverzeichnis einer Webseite bendet. Dabei wird geprft ob es die Datei cong.conf und den Ordner src gibt. Ist dies nicht der Fall wird die Funktion mit einer Fehlermeldung abgebrochen. Danach wird mit getSiteCong die Kongurationsdatei und mit getTemplate das Template eingelesen. Im Anschluss werden alle Dateien in dem Ordner src ermittelt und nach den Dateien mit der Endung .conf geltert. Jede dieser Dateien wird mit der Funktion getPageCong eingelesen und in den Datentyp Page gespeichert. Sind alle Dateien eingelesen wird mittels getNavigation die Navigation erstellt. Die Funktion gibt einen String zurck, welcher einer HTML-Liste mit den Navigationseintrgen entspricht. Danach wird mit der Funktion renderHtmlPage fr jede .conf-Datei eine HTML-Datei erzeugt und im Ordner output gespeichert. Sind alle HTML-Dateien erstellt, werden die restlichen bentigten Dateien aus dem Order src kopiert. Dazu zhlen eine .css-Datei, wenn sie vorhanden ist, und der komplette Ordner images.
4.8 Navigation
Die Navigation der Webseite wird mit den drei Funktionen getNavigation, getNavEntries und buildNavigation erstellt. Zum Schluss wird eine HTML-Liste zurckgegeben, wobei jeder Listeneintrag einem Eintrag in der Navigation entspricht. Das Listing 4.10 zeigt den Quellcode der Funktion getNavigation, welcher weiter unten beschrieben wird. Listing 4.10: getNavigation-Funktion getNavigation :: Monad m [Page] m [Char] getNavigation pages = do navEntries mapM getNavEntries $ filter (\page pageInMenu page == True) pages let navEntriesWithOrder = quickSort navEntries navi mapM buildNavigation navEntriesWithOrder return (concat navi)
Zunchst werden aus den bergebenen Seiten alle Seiten rausgeltert, die in der Navigation angezeigt werden sollen. Im Anschluss wird von diesen Seiten der NavEntry Eintrag ausgelesen. Diese werden dann sortiert und der Funktion buildNavigation bergeben. Das Listing 4.11 zeigt den Quellcode der Funktion getNavEntries, welcher weiter unten beschrieben wird.
David Hahn
Seite 24 von 35
4. Implementierung
Listing 4.11: getNavEntries-Funktion getNavEntries :: Monad m Page m NavEntry getNavEntries page = do let nav = pageNav page return nav
Die Funktion getNavEntries liest mit Hilfe der Funktion pageNav den NavEntry Eintrag der bergebenen Seite aus und gibt diesen zurck. Das Listing 4.12 zeigt den Quellcode der Funktion buildNavigation, welcher weiter unten beschrieben wird. Listing 4.12: buildNavigation-Funktion buildNavigation :: Monad m NavEntry m [Char] buildNavigation entry = do let entryHtml = "<li> href=\""+ <a +(navUrl entry)+ +"\">"+ +(navTitle entry)+ +"</a> </li>" return entryHtml
Mit der Funktion buildNavigation wird der Listeneintrag der Seite fr die Navigation erstellt. Dazu wird mit der Funktion navUrl die URL aus dem bergebenen NavEntry ausgelesen, zu welcher Seite dieser Eintrag verlinken soll. Und mit der Funktion navTitle wird der Titel ausgelesen, welcher in der Navigation angezeigt wird.
David Hahn
Seite 25 von 35
5.1 Installation
StatiGen kann mit den folgenden Befehlen installiert werden: Listing 5.1: Installation von StatiGen runhaskell Setup configure --user runhaskell Setup build runhaskell Setuo install
Das Template der Webseite kann im Nachhinein mit dem Befehl StatiGen settemplate template_name gendert werden. Listing 5.3: ndern des Templates $ StatiGen settemplate andreas08
David Hahn
Seite 26 von 35
David Hahn
Seite 27 von 35
David Hahn
Seite 28 von 35
Auerdem sollte in der allgemeine Kongurationsdatei cong.conf die Metainformationen author, year, website_title, website_slogan, description und keywords angepasst werden.
David Hahn
Seite 29 von 35
David Hahn
Seite 30 von 35
Abbildungsverzeichnis
1.1 3.1 3.2 4.1 5.1 5.2 5.3 5.4 Anzahl der Webseiten von August 1995 bis August 2012 . . . . . . . 1 Platzhalter fr Metainformationen und Inahlt . . . . . . . . . . . . . 14 Ordnerstruktur eines Webseiten-Projektes . . . . . . . . . . . . . . . 15 Programmablaufplan Create-Funktion . . . . . . . . . . . . . . . . . . 18 Layout: Layout: Layout: Layout: default . . andreas00 . andreas01 . andreas08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 27 28 28
David Hahn
31
Tabellenverzeichnis
2.1 Von Pandoc untersttzte Formate . . . . . . . . . . . . . . . . . . . . 4
David Hahn
32
Listings
2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 3.1 3.2 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 Haskell-Programm zum umwandeln mit Pandoc Ausgangsform Markdown . . . . . . . . . . . . . Konvertiert in HTML . . . . . . . . . . . . . . . berschriften in Markdown Methode 1 . . . . . berschriften Methode 1 in HTML . . . . . . . berschriften in Markdown Methode 1 . . . . . berschriften Methode 2 in HTML . . . . . . . Zitate in Markdown . . . . . . . . . . . . . . . . Zitate in HTML . . . . . . . . . . . . . . . . . . Betonungen in Markdown . . . . . . . . . . . . Betonungen in HTML . . . . . . . . . . . . . . Unsortierte Listen in Markdown . . . . . . . . . Unsortierte Listen in HTML . . . . . . . . . . . Sortierte Listen in Markdown . . . . . . . . . . Sortierte Listen in HTML . . . . . . . . . . . . Inline-Links in Markdown . . . . . . . . . . . . Inline-Links in HTML . . . . . . . . . . . . . . Referenz-Links in Markdown . . . . . . . . . . . Referenz-Links in HTML . . . . . . . . . . . . . Bilder in Markdown . . . . . . . . . . . . . . . . Bilder in HTML . . . . . . . . . . . . . . . . . . Code in Markdown . . . . . . . . . . . . . . . . Code in HTML . . . . . . . . . . . . . . . . . . Inline-Html in Markdown . . . . . . . . . . . . Beispiel Backslash-Maskierung in Markdown . . Backslash-Maskierung in Markdown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 5 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 10 10 10 10 10 11 11 11
Beispiel fr die allgemeine Kongurationsdatei . . . . . . . . . . . . . 13 Beispiel fr die Kongurationsdatei einer Seite . . . . . . . . . . . . . 14 Datentyp Site . . . . . . . Datentyp Page . . . . . . Datentyp NavEntry . . . . Main-Funktion . . . . . . Main-Funktion . . . . . . getSiteCong-Funktion . . getPageCong-Funktion . renderHtmlPage-Funktion buildSite-Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 16 17 17 19 20 21 22 23
David Hahn
33
Listings
4.10 getNavigation-Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . 24 4.11 getNavEntries-Funktion . . . . . . . . . . . . . . . . . . . . . . . . . 25 4.12 buildNavigation-Funktion . . . . . . . . . . . . . . . . . . . . . . . . 25 5.1 5.2 5.3 5.4 5.5 Installation von StatiGen . . . Erstellung der Ordnerstruktur ndern des Templates . . . . Neue Seite hinzufgen . . . . HTML-Dateien erstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 26 26 28 29
David Hahn
34
Eidesstattliche Erklrung
Ich versichere an Eides Statt durch meine eigenhndige Unterschrift, dass ich die vorliegende Arbeit selbststndig und ohne fremde Hilfe angefertigt habe. Alle Stellen, die wrtlich oder dem Sinn nach auf Publikationen oder Vortrgen anderer Autoren beruhen, sind als solche kenntlich gemacht. Ich versichere auerdem, dass ich keine andere als die angegebene Literatur verwendet habe. Diese Versicherung bezieht sich auch auf alle in der Arbeit enthaltenen Zeichnungen, Skizzen, bildlichen Darstellungen und dergleichen. Die Arbeit wurde bisher keiner anderen Prfungsbehrde vorgelegt und auch noch nicht verentlicht.
David Hahn
35