Skip to content

Markup mit HAML

Websites bestehen - hoffentlich - in der Regel aus (wenigen) Templates, die dann mit (vielen verschiedenen) Inhalten gefüllt werden. So arbeiten Blogs und CMS, so arbeitet auch ein static site generator. Die Templates können dabei HTML-Dateien sein - müssen es aber nicht, wie ich schon anno 2015 beschrieb.

"Markup mit HAML" vollständig lesen

Serendipity und das Markdown-Plugin

Bereits seit dem Relaunch meines Blogs anno 2014 nutze ich - wie schon berichtet - Markdown zur Eingabe meiner Blogbeiträge. Ich entwerfe sie in der Regel in einem externen Editor (MarkdownPad auf meinen Rechnern oder online mit Draft, wenn ich unterwegs bin) und kopiere sie dann in das Backend von Serendipity, getrennt in “Eintrag” und “erweiterter Eintrag”. Dabei nutze ich seit einigen Monaten “Eintrag” nur noch als Teaser, mit der Folge, dass die Beiträge auf der Startseite und bei Suchergebnissen auch nur noch “angeteasert” werden; bringt mehr Übersicht und eine handlichere Startseite, erfordert andererseits aber für jeden Beitrag einen weiteren Klick, um ihn zu lesen, ermöglicht es also nicht ohne weiteres, sich “an einem Stück” durch das Blogarchiv zu lesen.

"Serendipity und das Markdown-Plugin" vollständig lesen

Markup-Formate konvertieren

In meiner Reihe “Webdesign anno 2015” habe ich versucht, einen Überblick über Techniken und Tools zu geben, die letztlich jedermann die Gestaltung moderner, gut aussehender Webseiten ermöglichen. Das hatte natürlich einen konkreten Anlass: ich bin dabei, allmählich und sehr langsam - im Rahmen der mir bleibenden zeitlichen Möglichkeiten - verschiedene ältere Webpräsenzen zu überarbeiten und inhaltlich wie optisch und technisch auf den heutigen Stand zu bringen.

Eine große Erleichterung ist dabei die automatische Konvertierung von “klassischem” HTML in HAML und/oder Markdown. Ein machtvolles Werkzeug für solche Konvertierungsaufgaben ist pandoc; es geht aber oft auch eine Nummer kleiner, ganz simpel per cut & paste online:

Wenn nur eine Handvoll Seiten - oder Teile einer Seite - zu konvertieren sind, reicht (mir) das vollständig aus.

Generatoren für statische Websites

Ganz früher bestand eine Homepage, bestanden Webseiten allgemein im wesentlichen aus HTML-Dokumenten. Auf dem Weg zum Web 2.0 kamen zunächst CGI-Scripts für bestimmte Anwendungen auf; insbesondere aber mit der Verbreitung von PHP wurden Webseiten deutlich interaktiver. Blogs, Gästebücher, Kontaktformulare wären anders auch kaum vorstellbar. Nicht immer aber ist Interaktivität wirklich erforderlich. Manche eigentlich statische Seite wird nur deshalb dynamisch via PHP - oder auf vergleichbare Weise - erzeugt, weil es so bequem ist, die Erstellung einer Navigation und der Grundstruktur der Seiten zu automatisieren und Änderungen nur an einer Stelle vornehmen zu müssen. Das kann durch Installation eines CMS - oder eines dafür “zweckentfremdeten” Blogs oder Wikis - erfolgen; man kann auch wie ich schlicht die bisherigen HTML-Dokumente durch PHP-Scripts ersetzen, die im wesentlichen nichts anderes tun als vorgefertigte Funktionen für die Generierung des Seitengerüsts und der Navigation aufzurufen und ansonsten praktisch nur aus HTML bestehen. Meistens wäre es aber eigentlich gar nicht erforderlich, die Webseiten für jeden Aufruf neu zu generieren, weil sie sich nicht oder doch nur selten ändern. Ausreichend wäre es vielmehr, die Erstellung der an und für sich statischen Seiten aus Vorlagen - Templates - zu automatisieren und dabei ggf. auch automatisch die nötige Navigation zu erstellen.

Das leisten - in verschiedensten Variationen - static site generators, also Scripts oder Programmpakete, die man mit Schablonen (Templates) und Inhalten füttert und die daraus - ergänzt um eigene Programmschnipsel - die fertige Website erstellen. Vorteilhaft daran ist, dass die Webpräsenz im wesentlichen aus statischen HTML-Seiten bestehen kann, nur dort durch Scripts ergänzt, wo das auch tatsächlich für Interaktivität notwendig ist. Auf dem Webserver wird die Last deutlich verringert, weil nicht für jeden Seitenaufruf ein PHP-Interpreter gestartet werden muss; auch bestehen weniger Angriffsmöglichkeiten, weil kein ausführbarer Code mehr “live” auf dem Webserver laufen muss. Eine gewisse Interaktivität lässt sich auch durch tägliche, halbtägliche oder sogar stündliche Neuerzeugung der Webseiten erreichen; das macht für ein Forum oder auch ein Blog mit Kommentaren sicher wenig Sinn, aber wenn “nur” ein RSS-Feed oder die aktuellsten Tweets eingeblendet werden sollen, reicht das oft aus. Zudem lassen sich bspw. Kommentare auch durch externe Systeme wie Disqus vermittels Javascript einbinden.

Das Angebot an solchen Generatoren ist - wie bei Blogs, Wikis, CMS, Bugtrackern usw. - einigermaßen unüberschaubar geworden, wie man einer beliebigen Liste von Static Site Generators entnehmen kann. Gute Erfahrungen habe ich mit nanoc gemacht, mit dem auch der CCCS seine Website generiert; Jekyll wird bspw. bei GitHub genutzt, um dort Webseiten - direkt aus Git heraus - zu generieren. Der einzige Nachteil bei beiden ist ggf., dass sie in Ruby geschrieben sind und daher eigene Scripts und Erweiterungen sinnvollerweise ebenfalls in dieser Sprache zu halten sind. :-)

Das Grundprinzip ist bei allen Generatoren immer dasselbe: Es wird ein Grundgerüst für die Seiten in Form eines oder mehrerer Templates aufgebaut, gerne in HTML 5 und “responsive”, die dabei Platzhalter oder sogar entsprechend fortgeschrittenere Funktionen enthalten. Das Design erfolgt über CSS, wobei auch CSS-Präprozessoren wie LESS oder SASS zur Anwendung kommen können. Die einzelnen Webseiten schließlich können als HTML-Dokumente, aber besser noch in einfacheren Auszeichnungssprachen wie MarkDown, Textile, Asciidoc usw. angelegt werden. Dann gibt es in der Regel noch eine Konfigurationsdatei, aus der sich ergibt, wie die einzelnen Bausteine - Templates, CSS, Seiteninhalte - “bearbeitet” und zusammengefügt werden sollen. Aus diesen Anweisungen und Bausteinen generiert der Site Generator dann statische HTML-Dokumente (oder auch PHP-Scripts, oder Dokumente, die Javascript enthalten, oder …). In der Regel sind dabei eine Vielzahl von Filtern zur Interpretation von Markdown, LESS und Co. bereits enthalten; die eigenen Seiten und Designs lassen sich daher quasi aus einem Baukasten zusammensetzen, zumal als Basis für das Grundgerüst der Seiten auf Systeme wie Bootstrap oder HTML5 Boilerplate zurückgegriffen werden kann, die eigene Schriftarten, Icons und/oder Javascript direkt mitbringen oder zumindest entsprechende Anregungen enthalten. Mit verhältnismäßig wenig Aufwand lassen sich so die eigenen Inhalte hübsch, technisch modern und auf den verschiedensten Geräten vom Smartphone über das Tablet bis zum Laptop oder großen Desktopbildschirm ansehnlich darstellen.

Wenn man möchte, kann man auch die Quelldokumente in einem Versionsverwaltungssystem wie Git verwalten und bei jeder Änderung daraus automatisch eine neue Version der Webseiten erzeugen. Auf diese Weise ist ein Blogbeitrag, aber auch eine neue Seite der eigenen Homepage schnell in Markdown geschrieben, mit einem Vorspann - mit den notwendigen Informationen wie Titel, Autor, Erstellungsdatum, Typ pp., bspw. in YAML - versehen und im Git-Repository gespeichert; daraus erzeugt dann der Generator automatisch die neue Seite und passt - gleichfalls automatisch - alle davon betroffenen anderen Seiten (Inhaltsverzeichnis/Sitemap, Navigation, RSS-Feed, …) an und erzeugt sie, soweit nötig, neu.

Ich finde das sehr praktisch für alle Anwendungsfälle, die keine “Webapplikation” darstellen, sondern im wesentlichen statische Inhalte enthalten, die sich nicht minütlich oder stündlich, sondern eher täglich, wöchentlich oder auch nur alle Jubeljahre einmal ändern. Durchaus lässt sich aber auch ein Blog so betreiben, wenn man denn die interaktiven Elemente wie Kommentare pp. “outsourced”, bspw. an Anbieter wie Disqus. Mit ausreichend Zeit - ja, genau da liegt der Knackpunkt … :-) - plane ich, zumindest einige der von mir betreuten Webseiten in der Zukunft entsprechend umzustellen.

MarkdownPad

Über Markdown habe ich in diesem Blog schon mehrfach geschrieben. Ich nutze diese simple Auszeichnungssprache nicht nur für meine Blogbeiträge, sondern auch für FAQs, die sowohl als einfacher Text - bspw. für Postings im Usenet - als auch als HTML - bspw. im Web - veröffentlicht werden sollen, als Quelle für daraus generierte Webseiten oder bei Anbietern, die gleichfalls auf diese Auszeichnungssprache setzen, wie bspw. Github.

Bislang habe ich Markdown in meinem Standardeditor Sublime Edit 2 verfasst (oder ggf. in Notetab Pro), schließlich handelt es sich letztlich um einfachen Klartext, und den Text dann veröffentlicht und notfalls einmal nachbearbeitet. Wenn ich einmal wirklich eine Vorschau sehen wollte, habe ich einen der im Web vorhandenen Online-Konverter wie Markdown Live Preview benutzt, bei dem man links in ein Fenster seinen Text einfügen kann und der rechts daneben dann live die Umsetzung in HTML darstellt. Wenn man allerdings mit einer langsamen Internetanbindung irgendwo an der Küste sitzt - oder gar offline arbeiten möchte -, ist das kein optimaler Workflow. :-)

Daher bin ich jetzt - nach kurzer Suche über Google - auf den Markdown-Editor MarkdownPad 2 gestoßen, der einem im Prinzip das, was Markdown Live Preview online kann, offline bietet: links der Text in Markdown, rechts daneben das gerenderte HTML. Außerdem gibt es die bereits sattsam aus Web-Editoren wie in Wikis oder Blogs bekannten Buttons, mit denen man das entsprechende Markup generieren kann - eigentlich nicht nötig, weil das schöne an Markdown ja gerade ist, dass man es ganz natürlich tippen kann, aber mal ganz praktisch, wenn man nach einer Schaffenspause mal wieder ein spezielleres Markup vergessen hat und sich den Ausflug zu einer Syntaxübersicht sparen möchte. Außerdem kann man auf einfache Weise das generierte HTML direkt exportieren, wenn man das möchte.

MarkdownPad ist kostenlos; die 15 Dollar teure “Professional”-Version beherrscht u.a. Tabellen in Markdown Extra und den Export in ein PDF. Ich finde das sehr praktisch und werde dieses Tool zukünftig für meine Markdown-Texte verwenden.

Blogs und Editoren

Wer ein Blog betreibt, kennt vermutlich die Frage danach, welcher Editor für die Einträge am sinnvollsten verwendet werden sollte.

Meine erste Blogengine, sunlog, bot meiner Erinnerung nach bloß ein Eingabefeld, in das man entweder HTML eingeben oder darauf setzen konnte, dass der ansonsten nicht weiter bearbeitete Text schon irgendwie ausgegeben werden würde.

Nach dem Umstieg auf Serendipity habe ich auch erst einmal den Standard-Editor verwendet, wozu braucht man schließlich WYSIWYG, wenn man HTML beherrscht? Das war auf die Dauer dann aber doch eher anstrengend: um jeden Absatz herum <p>...</p> schreiben, Hervorhebungen korrekt mit <strong>...</strong> einbauen, Links von Hand setzen … Das macht keinen wirklichen Spaß. Und der Einbau von Bildern ist von Hand auch eher eine Strafe als ein Vergnügen.

Also bin ich später auf den WYSIWYG-Editor von Serendipity gewechselt; ich glaube, ich habe sogar nacheinander verschiedene solche benutzt. So richtig zufrieden war ich damit aber auch nicht; das daraus generierte HTML erschien teilweise suboptimal, zwischendurch hatte das Gerät aufgrund irgendeiner (vermutlich von mir irrtümlich getroffenen) Einstellung die Neigung, alle Texte per <font>-Tag mit weißem Hintergrund zu hinterlegen und Spielereien dieser Art mehr. Außerdem war es so mit nicht unerheblichem Aufwand verbunden, Einträge in einem Texteditor vorzubereiten und später per copy & paste ins Blog zu übernehmen, bedurfte es dann doch eines zweiten Schrittes, in dem Formatierungen und Links hinzugefügt wurden, wie auch lx4r in einem vergleichbaren Blogbeitrag berichtet. Wenn ich stattdessen direkt im Editor schrieb, ereilte mich gerne ein Missgeschick wie “langen Blogeintrag geschrieben, abgeschickt, mittlerweile aber ausgeloggt” (worauf Serendipity den Beitrag üblicherweise hungrig verspeist und man ihn neu schreiben darf) oder, noch schlimmer, ich komme an eine Tastenkombination, die eine Browseraktion auslöst und dann den Browser den Text verschlucken lässt. Gut, dagegen hilft Lazarus, aber der wahre Jakob ist das trotzdem nicht, ganz abgesehen davon, dass man eben so nicht sinnvoll offline arbeiten (oder auch nur die Annehmlichkeiten eines guten Texteditors nutzen) kann.

Mit dem Relaunch des Blogs habe ich auch dafür eine Lösung gefunden: ich verwende den simplen Standardeditor von Serenditpity zusammen mit dem Markdown-Plugin. Wieder eine für mich sehr hilfreiche Anwendung von Markdown. Jetzt kann ich flüssig Texte schreiben, sie ggf. per copy & paste ins Blog übernehmen und muss mich nie wieder um seltsame Formatierungen kümmern. Passt. Das ist ein Workflow, der Spaß macht.

(Um zu verhindern, dass ältere Einträge durch das Markdown-Plugin zerhackt werden, kann man dieses Plugin für die älteren Einträge - jeweils einzeln pro Eintrag - deaktivieren. Jedenfalls dann, wenn man das Plugin “erweiterte Eigenschaften für Artikel” [serendipity_event_entryproperties] installiert hat. :-))

Markdown: HTML aus Text erzeugen

Der erste längere (Erläuterungs-)Text, den ich zur Veröffentlichung im Netz verfasst habe, war im September 1998 die Header-FAQ, deren erster Entwurf am 18.09.1998 in der Newsgroup de.admin.net-abuse.mail veröffentlicht wurde und die dann seit dem 15.10.1998 unter dem Titel “E-Mail-Header lesen und verstehen” dort über viele Jahre lang monatlich erschien.

Text- und HTML-Version

Natürlich sollte es zu der monatlich geposteten FAQ auch eine Web-Version geben, die bereits im Oktober entstanden war und deren URL im November 1998 das erste Mal in der FAQ genannt wurde. Und natürlich sollte diese Version auch mit allem Annehmlichkeiten, die HTML für Optik und Funktion bietet, also namentlich Formatierungen und Verlinkungen, ausgestattet sein. Das bedeutete dann umgekehrt aber auch, dass zwei völlig getrennte Versionen desselben Textes zu pflegen waren; insbesondere bei größeren Änderungen und Ergänzung keine wirklich gute Idee. Es musste also eine andere Lösung her: die eine Fassung sollte aus der anderen Fassung generiert werden, oder ggf. beide Fassungen aus demselben Rohtext.

HTML-Dokumente aus Textdokumenten erzeugen

Da mir das Usenet als Publikationsmedium (damals) deutlich näher lag, hatte ich zuerst den Gedanken, die Webseite - also das HTML-Dokument - zumindest im wesentlichen aus dem Textdokument der geposteten FAQ zu erzeugen. Bei entsprechenden Recherchen stieß ich dann auch auf das Tool AscToHTM, das genau diesem Zweck diente und sich auch insbesondere an FAQ-Autoren richtete. Eine Zeit lang habe ich damit auch gearbeitet (und das erzeuge HTML-Dokument dann quasi mit Header und Footer versehen, um es optisch und organisatorisch - Navigation! - in meine damalige Webseitenstruktur einzubinden), aber so wirklich überzeugend war das nicht. Es bedurfte einiger Kompromisse im Layout des geposteten Textes, um die HTML-Generierung überzeugend hinzubekommen, und der Aufwand war doch vergleichsweise groß.

Textdokumente aus HTML-Dokumenten erzeugen

Daher habe ich mich - theoretisch im übrigen völlig richtig - in der Folge davon überzeugen lassen, dass die Vorgehensweise, aus (letztlich) unstrukturiertem Text strukturierten Text (mit Markup) zu erzeugen, bereits gedanklich verfehlt ist und keinen dauerhaften Erfolg haben könne: HTML enthält gegenüber text/plain zusätzlichen Informationsgehalt, Struktur, Markup eben, und aus der Gestaltung des Rohtextes das Markup zu “erraten”, ist keine brauchbare Lösung. Daher bin ich danach dann eben den umgekehrten Weg gegangen und habe beschlossen, dass nunmehr die Webversion der FAQ das “Master-Dokument” (oder die Quelle) sein sollte und ich den geposteten Text daraus erzeuge. Information und optische Gestaltung zu kürzen sollte ja vergleichsweise trivial sein. — Ganz so war es dann erwartungsgemäß doch nicht, denn auch der gepostete “reine” Text sollte ja einigermaßen apart formatiert sein, mit dem was, man an “Formatierungen” in E-Mail und Usenet so gewohnt ist: Zitate eingeleitet mit “|” am Zeilenfang, Hervorhebungen und Betonungen durch *Sternchen* o.ä. und dieser Dinge mehr. Für den Anfang half dazu html2text, damals in C++ geschrieben, mittlerweile durch den verstorbenen Aaron Swartz auch in PYthon reimplementiert, aber ganz zufrieden war ich mit dem Output noch nicht.

Einiges Experimentieren führte dann zu dem folgenden Workflow:

  1. wget http://th-h.de/faq/$1 -O output.html
  2. html2text -nobs -width 70 -rcfile html2text.rc output.html > output.txt
  3. ./wrap.pl < output.txt > wrapped.txt

Und wrap.pl, das (daher der Name) vor allem für den Umbruch auf 70 Zeichen pro Zeile unter Beachtung von (nicht zu umbrechenden Zitaten) zuständig war, sah folgendermaßen aus:

  1. #!/usr/bin/perl
  2.  
  3. use Text::Wrap qw(&wrap $columns);
  4. $columns = 70;
  5.  
  6. while (<>) {
  7.  if (/[-\/]$/) {
  8.   ($zeile, $rest) = /(.+\s)(\S+)$/;
  9.   print "$zeile\n";
  10.   JOINLOOP: while (<>) {
  11.    $rest .= $_;
  12.    last JOINLOOP if (/^$/);
  13.   }
  14.   $rest =~ s/\n/ /g;
  15.   $_ = wrap(, , $rest)."\n";
  16.  };
  17. print $_;
  18.  if (/^[|>:]/) {
  19.   QUOTELOOP: while (<>) {
  20.    chomp;
  21.    if (/^$/) {
  22.     print "\n";
  23.     last QUOTELOOP;
  24.    } elsif (/^[|>:]/) {
  25.     print "\n$_";
  26.    } else {
  27.     print $_;
  28.    }
  29.   };
  30.  };
  31.  print "\n";
  32. };

Das ließ sich jetzt durchaus automatisieren; andererseits gefiel es mir nicht wirklich, dass die Quelle des Textes nun ein HTML-Dokument war und ich erst längere Konversionsprozesse laufen lassen musste, um zu überprüfen, ob auch die (aus meiner Sicht immer noch primäre) Textfassung ordentlich aussah. Und HTML schreiben ist auch deutlich aufwendiger als “Klartext”, selbst wenn man sich durch geeignete Editoren beim Einfügen der passenden Tags (und deren Schließen!) unterstützen lässt.

Die Lösung?

Am Ende habe ich, glaube ich, einfach wieder beide Texte getrennt gepflegt oder, wahrscheinlicher, die FAQ (erst einige Zeit nicht mehr richtig aktualisiert und dann) gar nicht mehr gepostet; sowohl das Spam-Problem (jedenfalls der Wunsch, Spam nachzuverfolgen und zu melden) als auch das Usenet waren dabei, in die Bedeutungslosigkeit abzurutschen.

"Markdown: HTML aus Text erzeugen" vollständig lesen

markdown: Text in HTML verwandeln

Auf dem Umweg über ikiwiki - was vielleicht zukünftig einmal einen eigenen Beitrag wert ist - bin ich letzte Woche auf markdown gestoßen - ein Perl-Script, das einen strukturierten Klartext in (X)HTML verwandelt. Das ist, wie ich finde, eine tolle Sache, weil auf diese Weise der Quellcode der HTML-Seite für sich als Text lesbar bleibt. Es ist sogar möglich, auf diese Weise eine Text- und HTML-Version eines Dokuments parallel zu nutzen (um den Preis, daß Links in der Textversion etwas eigenartig wirken, und der HTML-Version eine interne Navigation fehlt).

Beispielsweise habe ich den Einführungstext in die Newsgroup de.etc.notfallrettung, der regelmäßig in die Gruppe gepostet werden soll, auf diese Weise verfaßt. Der Text - der in genau dieser Fassung auch gepostet wird - ist gut lesbar, und markdown erstellt daraus ohne weiteren Aufwand die HTML-Version. (Das erfolgt automatisch durch ein Script, das die entsprechende Fassung des Textes aus dem Git-Repository auscheckt, durch markdown laufen läßt und dann an den richtigen Ort auf meinem Webserver verschiebt.)

tweetbackcheck