Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Zeile für Zeile

Syntax-Highlighter

Zeile für Zeile

Wer als Webworker für Online-Magazine oder sein eigenes Blog schreibt, wird früher oder später auch Code-Beispiele bringen. Der Quelltext ließe sich schlicht mit code und pre auszeichnen. Heutzutage darf sich ein Autor aber durchaus die Mühe machen, seinen Code etwas sinnvoller zu präsentieren – zum Beispiel mit Syntax Highlighting.

Als wir hier auf webkrauts.de die ersten Artikel veröffentlicht haben, sahen die Code-Beispiele im Quellcode noch so aus:

  1. <p class="bsp">
  2.   <code><br />
  3.   <span style="color: #a00">&lt;div id="wrap"></span><br />
  4.   &nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="identitaet">...&lt;/div><br />
  5.   <span style="color: #a00">&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="hauptbereich"></span><br />
  6.   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="inhalt">...&lt;/div><br />
  7.   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="navigation">...&lt;/div><br />
  8.   <span style="color: #a00">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div></span><br />
  9.   &nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="extra">...&lt;/div><br />
  10.   &nbsp;&nbsp;&nbsp;&nbsp;&lt;div id="rechtliches">...&lt;/div><br />
  11.   <span style="color: #a00">&lt;/div></span><br />
  12.   </code>
  13. </p>

Offensichtlich haben wir damals <pre> nicht genutzt, sondern die Zeilen per &nbsp; eingerückt. Wichtige Stellen wurden per <span style="color: #a00"> eingefärbt (weil ein Autor Inline-Styles benutzen, aber nicht am CSS rumwerkeln durfte). Und natürlich mussten wir ein <div> als &lt;div&gt; oder zumindest &lt;div> schreiben, damit es richtig als Code dargestellt wurde. Das können wir heute belächeln oder den Kopf schütteln – aber hey, es war 2005.

Code-Beispiele auf anderen Websites

Acht Jahre später sieht die Sache schon anders aus. Sowohl Autoren als auch Leser können mehr von Code-Beispielen erwarten. Das beginnt mit einem passenden Syntax Highlighting. Dabei werden bestimmte Elemente eines Codes anders dargestellt – eben die Syntax hervorgehoben. In dem Beispiel oben sind etwa die HTML-Tags fett dargestellt, Werte für die Attribute erscheinen in rot, HTML-Entitäten in ocker. Das ist meist hilfreich, um die einzelnen Elemente einer Sprache schneller zu erfassen. Was noch möglich ist, zeigt ein Blick auf die Code-Beispiele von anderen Websites.

Syntax Highlighting mit JavaScript

Syntax Highlighting auf Smashing Magazine mit Prism
Syntax Highlighting auf Smashing Magazine mit Prism

Beim Smashing Magazine ist für das Syntax Highlighting die JavaScript-Bibliothek Prism von Lea Verou zuständig, die zum Beispiel auch A List Apart oder webplatform.org nutzen. Längere Code-Zeilen werden hier einfach umbrochen. Ohne JavaScript fällt das Highlighting weg, das Beispiel sieht dann so aus:

Das Beispiel von Smashing Magazine ohne JavaScript
Das Beispiel von Smashing Magazine ohne JavaScript

Zeilennummern

Die Website A Beginner’s Guide to HTML & CSS bietet Einsteiger-Kurse für HTML und CSS. Ein orangener Hinweis oben rechts zeigt deutlich das Thema an. Der Hinweis wird per CSS ausgeblendet, sobald ein Benutzer mit der Maus über dem Code hovert. Zusätzlich gibt es hier eine Zeilennummerierung. Das ist für Code-Beispiele recht hilfreich, weil sich der Autor bei längeren Beispielen einfach im Artikel auf eine Zeile beziehen kann.

Syntax Highlighting auf A Beginner’s Guide to HTML
Syntax Highlighting auf A Beginner’s Guide to HTML

Im Einsatz ist hier eine aufgehübschte Version von Prettify, einer weiteren JavaScript-Bibliothek. Ohne JavaScript sieht der Code so aus:

Das Beispiel von A Beginner’s Guide to HTML ohne JavaScript
Das Beispiel von A Beginner’s Guide to HTML ohne JavaScript

Kleiner Exkurs: Welches HTML-Konstrukt ist sinnvoll, um die Zeilennummern hinzuzufügen?

Am einfachsten wäre es, einfach eine Zahl an den Anfang jeder Zeile zu schreiben. Das hat den Nachteil, dass die Zahlen in jedem Fall bei Copy & Paste mitkopiert werden. Das ist wenig benutzerfreundlich, weil der Nutzer die Zeilennummern per Hand wieder entfernen müsste.

Auf jquery.com wird eine Tabelle um den Code gebaut. Eine Tabellenzelle (td) trägt alle Zeilennummern, die nächste Tabellenzelle den kompletten Code. Per Copy & Paste wird hier nur der Code kopiert. Allerdings würden einem Screenreader auch alle x Zeilennummern hintereinander vorgelesen, das kann nicht sinnvoll sein.

Die meisten Syntax Highlighter bauen eine nummerierte Liste um den Code. Damit lässt sich grundsätzlich arbeiten. Ein Copy & Paste in einen üblichen Texteditor wie Sublime Text kopiert auch hier nur den reinen Text.

Erfahrene Webworker werden sicher einen professionellen Editor bevorzugen. Bei Anfängern muss das nicht unbedingt der Fall sein. Falls jemand auf die Idee käme, sein HTML mit Word oder Open Office zu schreiben, würden bei Copy & Paste jede Mege unerwünschter Zusatzinfos kopiert. Das betrifft nicht nur die Zeilennummern, sondern auch Schriftfarben und andere Auszeichnungen.

Hervorgehobene Stellen

Auf HTML Dog wiederum gibt es zwar keine Zeilennummern, dafür sind wichtige Stellen im Code hervorgehoben.

Syntax Highlighting bei HTML Dog
Syntax Highlighting bei HTML Dog

In diesem Beispiel kommt dazu ein <em> zum Einsatz. Aus HTML5-Sicht wäre <mark> besser geeignet. Mit passendem CSS bleiben die hervorgehobenen Stellen so auch erhalten, wenn JavaScript ausgeschaltet ist:

Syntax Highlighting bei HTML Dog ohne JavaScript
Syntax Highlighting bei HTML Dog ohne JavaScript

Zu lange Zeilen

Was tun mit zu langen Codezeilen? In einem Editor gibt es keine Probleme mit zu langen Zeilen. Diese werden in der Regel automatisch sinnvoll umbrochen. In einem Artikel auf einer Webseite funktioniert das leider nicht so leicht. Genau genommen gibt es keine einzige gute Lösung. Es kommen einige Spielarten in Frage, die alle ihre Nachteile haben:

  • Ein overflow: hidden kommt nicht Frage; der komplette Code muss schließlich sichtbar sein.
  • Auf Smashing Magazine werden zu lange Zeilen per CSS mit word-wrap: break-word; umbrochen. Das sieht zunächst hübscher aus, hat aber den Nachteil, dass wichtige Elemente wie Attribute oder Eigenschaften mitten im Wort getrennt werden könnten.
  • Hier auf webkrauts.de nutzen wir overflow: auto;, was für einen Scrollbalken sorgt. Wörter werden zwar nicht irgendwo getrennt, dafür kann ein Leser nun ggf. nicht mehr alles auf einen Blick erfassen.
  • Möglich wäre, zu lange Zeilen künstlich in mehrere aufzuteilen. Aber wo genau endet eine Zeile? Bei einem fixen Layout mit Monospace-Schrift für den Code lässt sich vielleicht eine maximale Buchstabenanzahl pro Zeile festlegen. Aber bei einem responsive Design wird das nicht mehr funktionieren.

Einige Seiten wie zum Beispiel lullabot.com arbeiten mit einem Codeblock, der sich horizontal aufklappt, wenn ein Leser mit der Maus über den Block fährt. Das macht die Seite allerdings recht unruhig, und der Scrollbalken kommt trotzdem zum Einsatz.

Auf lullabot.com klappt die Code-Box bei einem Hover nach rechts aus
Auf lullabot.com klappt die Code-Box bei einem Hover nach rechts aus

Externe Dienste

Eine ganz andere Lösung wäre, die Code-Beispiele direkt auszulagern. Christian Heilmann macht das zum Beispiel in diesem Artikel, bei dem alle Beispiele direkt über jsFiddle eingebunden sind. Sieht hübsch aus und hat den klaren Vorteil, dass der Leser sofort selbst mit dem Code herumspielen könnte. Auf der anderen Seite: Sollte jsFiddle seine Dienste einmal einstellen, wären alle Beispiele weg. Das muss also jeder Autor für sich selbst abwägen. Falls der Dienst erst in ein paar Jahren webgbrechen sollte, ist es vielleicht egal, weil diese alten Artikel dann ohnehin nicht mehr auf dem aktuellen Stand der Technik wären.

Anforderungen und Wunschliste

All die Effekte und Auszeichnungen könnte ein Autor selbst in seinen Quellcode schreiben. Das bietet zwar die größtmögliche Kontrolle, ist aber nicht effektiv. Zum einen macht es viel mehr Arbeit, seine Code-Beispiele sinnvoll umzuwandeln. Zum anderen verändert sich das Web nun einmal. Ein paar Jahre später ist es vielleicht besser, seinen Code etwas anders auszuzeichnen. Und wer arbeitet daraufhin schon all seine alten Beispiele nach?

Es läuft daher auf eine Bibliothek hinaus, die den Quellcode im Hintergrund aufbereitet. Das kann auf zwei Arten passieren. Entweder wird der Code bereits auf dem Server vorbereitet oder per JavaScript im Browser umgewandelt. Soll es nicht noch dynamische Effekte geben, dürfte eine Vorbereitung auf dem Server effektiver sein: Der Webworker spart ein wenig JavaScript, der Code erscheint auch ohne JavaScript hübsch aufbereitet und lässt sich aus dem Cache des CMS bereits komplett ausliefern.

Je nach persönlichen Vorlieben kommen diese Anforderungen in Frage:

  • Die Bibliothek sollte alle benötigten Sprachen verstehen und highlighten können. Das sind für Webworker erst einmal HTML, CSS und JavaScript. Je nach Themengebiet des Autors kommen Sprachen wie XML, PHP, Ruby, Java, C++ etc. hinzu.
  • Das Tool sollte von den Machern weiterentwickelt werden. Für ein reines Highlighting reichen auch ältere Bibliotheken von 2008, aber auf Dauer will ein Autor sicherstellen, dass neuere Sprachen und Formate wie etwa SASS, LESS oder JSON auch vernünftig dargestellt werden.
  • Das Highlighting passiert ordentlich über Klassen und nicht über Inline-Styles.
  • Zeilen sollten optional nummeriert werden können. Es bietet sich an, den Code als nummerierte Liste darzustellen. Der generierte Code sollte in jedem Fall auch für Screenreader sinnvoll zu lesen sein.
  • Zeilen sollten per Klasse angesprochen werden können. Sinnvoll ist eine alternierende Klasse, um gerade und ungerade Zeilen farblich zu unterscheiden. Letzteres lässt sich bei modernen Browsern natürlich auch über den Pseudo-Selektor :nth-child() regeln.
  • Zusätzlich wäre vielleicht eine Syntax wünschenswert, mit der sich bestimmte Teile zusätzlich markieren lassen. Es müsste dann eine Syntax geben, die wahlweise per <mark> Code nochmals optisch hervorhebt oder aber <mark> als Text ausgibt, weil das HTML-Element selbst im Code-Beispiel vorkommt.
    Aber zum einen ist diese Option vielleicht etwas viel verlangt, zum anderen mögen Syntax Highlighting plus <mark> zusammen optisch zu unruhig wirken.
  • Nett wäre weiterhin die Option, eine Überschrift oder Unterzeile angeben zu können. Etwa »Listing 4: Das komplette Beispiel«. Das klappt aber auch mit einem entsprechend gestalteten Absatz vor oder nach dem Codeblock.
  • Und vorzugsweise generiert die Bibliothek validen Quellcode (siehe unten).

Mögliche Highlighter

Welcher Syntax Highlighter kommt nun in Frage? Das hängt von den eigenen Vorlieben ab: JS- oder PHP-Lösung? Unterstützte Sprachen? Vorhandene Themes? Alle Varianten sollte ein Webworker fix selbst einbauen können. In Kombination mit einem Content-Management-System macht man es sich meistens einfacher und nutzt die Bibliothek, die bereits als Modul/Plugin für das CMS vorhanden ist.

PHP

GeSHi - Generic Syntax Highlighter
Der Filter unterstützt stolze 112 Sprachen und Formate. Darunter natürlich HTML, CSS, JavaScript und PHP. Aber auch LaTeX, Perl, Python, Smarty, Ruby, Ruby on Rails, robots.txt und XML. Er bietet Zeilennummern an. Darüber hinaus lassen sich eingebaute Keywords direkt verlinken, um weitere Informationen zu erhalten. So würde etwa <span> auf december.com verlinken. Diese Seite ist in der aktuellen Form natürlich wenig hilfreich, aber die Idee ist gut.

Da der GeShi-Filter aktuell auf webkrauts.de über ein Drupal-Modul im Einsatz ist, zwei Tipps dazu:

  1. In der Grundeinstellung setzt GeShi einen <pre>-Wrapper um den Quellcode. Mit Zeilennummerierung erzeugt das ein <ol> innerhalb eines <pre>. Das ist laut Validator aber nicht erlaubt. In der Konfiguration lässt sich alternativ auch ein <div> als Wrapper oder kein Wrapper-Element einstellen – beide Optionen liefern validen Code.
  2. Damit der Filter zum Einsatz kommt, packt der Autor seinen Quellcode in einen Container. Dieser kann die Syntax <foo> ... </foo>, [foo] ... [/foo] oder [foo]] ... [[/foo]] haben. Statt »foo« wird die Sprache eingesetzt, etwa html, css, javascript oder php.
    Nutzt vorzugsweise nicht die Schreibweise <foo> ... </foo>. Das führt zu Problemen, wenn ihr mal ein <html> im Quellcode benutzen wollt, denn das feuert ja den Filter neu.

JavaScript

Prism
Der besagte Highlighter von Lea Verou, der unter anderem beim Smashing Magazin, A List Apart, WebPlatform.org und dem Mozilla Developer Network eingesetzt wird. Diese Namen reichen den meisten schon, um direkt diese Bibliothek zu wählen. Die Bibliothek kennt zunächst 21 Sprachen (darunter Markup, CoffeScript, SASS und SQL). Dabei werden auch ineinander verschachtelte Sprachen richtig ausgezeichnet (CSS in HTML, JavaScript in HTML). Wer will, kann selbst weitere Sprachen hinzufügen. Mit einem Plugin werden auch automatische Zeilennummer möglich. Unterstützt werden IE9+, Firefox, Chrome, Safari, Opera, sowie die meisten mobilen Browser.
highlight.js
Auch highlight.js hat einiges zu bieten. Es unterstützt 67 Sprachen – darunter auch JSON, SQL, XML, ActionScript, SCSS, Haml, Handlebars, Smalltalk. Dazu kommen stolze 32 Themes. Das Tool kann die Sprache automatisch ermitteln und highlighted auch verschiedene Sprachen im Code. Nach der Demo und den kurzen Doku zu urteilen, gibt es hier aber keine Zeilennummern. Außerdem fehlt eine Info zu den unterstützen Browsern.

Im Netz sind viele weitere JS-Highlighter zu finden. Zum Beispiel SyntaxHighlighter, Prettify, SHJS, Lighter oder Rainbow. Die meisten sind im Vergleich zu den beiden genannten nicht besonders gut dokumentiert, bieten deutlich weniger Funktionen und/oder wurden seit Jahren nicht aktualisiert.

Wer also auf der Suche nach einem Highlighter ist, dürfte mit einer der drei Bibliotheken – GeShi, Prism oder highlight.js – gut bedient sein.

Fazit

Vielleicht findet der ein oder andere hier die Inspiration, seine eigenen Code-Beispiele etwas aufzupeppen. Schließlich ist es nicht so schwer, eine der vorhandenen Bibliotheken einzubinden. Auch hier auf webkrauts.de können wir noch dieses oder jenes verbessern: Schriftart und -farben des Codes sehen auf anderen Seiten deutlich ansehnlicher aus. Und das Ocker ist auch nicht wirklich gut lesbar (schon gar nicht im Sinne der Barrierefreiheit). Da werden wir beizeiten nachbessern müssen.

Kommentare

Chris Jung
am 17.12.2013 - 08:42

Crayon kommt hier gar nicht zur Sprache, den sehe ich auch oft.

Permanenter Link

Gunnar Bittersmann
am 17.12.2013 - 10:01

Muss es denn Bespielcode sein, an dem man sich kein Beispiel nehmen sollte? target="_blank"? Nö … Sowas sollte nicht propagiert werden; Klassitis auch nicht.

Zeilen sollten per Klasse angesprochen werden können. Sinnvoll ist eine alternierende Klasse, um gerade und ungerade Zeilen farblich zu unterscheiden.

Sollten sie? Wozu? Solche Klassen sind nicht sinnvoll, sondern völlig überflüssig, denn …

Letzteres lässt sich bei modernen Browsern natürlich auch über den Pseudo-Selektor :nth-child() regeln.

Eben. Die Nutzung von :nth-child() nicht verstehenden Browsern zum Lesen von Artikeln dürfte innerhalb der Zielgruppe gleich null sein.

Nett wäre weiterhin die Option, eine Überschrift oder Unterzeile angeben zu können.

Ja. Und die passende Auszeichnung dafür ist mit figure- und figcaption-Elementen:

  1. <figure>
  2.   <pre><code class="language-html" lang="zxx">&lt;!DOCTYPE html&gt;
  3. &lt;html&gt;
  4. &lt;/html&gt;</code></pre>
  5.   <figcaption>Listing 4: Das komplette Beispiel</figcaption>
  6. <figure>

(class="language-html" wird von der HTML-Spec empfohlen. Zu lang="zxx" siehe Kennzeichnung von Text mit keiner Sprache.)

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Autor)
am 17.12.2013 - 10:46

target="_blank"? Nö … Sowas sollte nicht propagiert werden;

Dazu habe ich mich im letzten Jahr hier schon einmal geäußert. Früher war ich da auch wesentlich strenger. Ein target="_blank" toleriere ich heutzutage eher, teilweise ist es sogar nützlich.

Sowas sollte nicht propagiert werden; Klassitis auch nicht.

Es gibt in den Screenshots nur eine Klasse. Aus dem Beispiel geht der Kontext nicht hervor. Die Klasse gehört vermutlich zu einem Icon Font.

Und wer regelmäßig mit CMS arbeitet, entwickelt ohnehin eine neue Ruhe gegenüber zu vielen Klassen und divs.

Sollten sie? Wozu? Solche Klassen sind nicht sinnvoll, sondern völlig überflüssig, denn …

Richtig. Es sei denn, man will den IE8 noch unterstützen. Was aktuell noch oft genug vorkommt.

Permanenter Link

Gunnar Bittersmann
am 17.12.2013 - 11:15

Ein target="_blank" toleriere ich heutzutage eher, teilweise ist es sogar nützlich.

Nützlich für wen? Der Betreiber der Website mag es für nützlich erachten, aber tut das der Nutzer?

Und wenn es schon ein anderes Tab/Fenster sein muss, dann doch bitte nicht jedesmal ein neues, wie ich unlängst schon zwitscherte.

Es gibt in den Screenshots nur eine Klasse.

new-window-icon – eins. twitter-icon – zwei.

Es sei denn, man will den IE8 noch unterstützen. Was aktuell noch oft genug vorkommt.

Hier kommt es nicht vor. Hier will man den IE8 nicht unterstützen. Wozu denn auch? Syntax-Highlighting kommt zum Einsatz, wenn Code dargestellt wird. Die Zielgruppe für Code sind Entwickler. Welcher Entwickler verwendet IE8 zum Lesen von Artikeln?

Dass man bei anderen Artikeln/Websites IE8 natürlich noch unterstützt, ist hier irrelevant. Ich hätte betonen sollen, dass die Nutzung von :nth-child() nicht verstehenden Browsern zum Lesen von Artikeln nicht allgemein null ist, sondern dass dies für die Zielgruppe gilt. Oh, das tat ich ja. ;-)

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Autor)
am 17.12.2013 - 12:18

Nützlich für wen? Der Betreiber der Website mag es für nützlich erachten, aber tut das der Nutzer?

Yepp. Und zwar z.B. dann, wenn man ein Formular ausfüllt und ein Link zu Tipps führt, die beim Ausfüllen helfen können. Dann sollen bereits eingetragene Daten im Formular erhalten bleiben.

Hier kommt es nicht vor. Hier will man den IE8 nicht unterstützen. Wozu denn auch?

Die Vorgabe für webkrauts.de ist derzeit noch, dass die Seite im IE8 funktionieren muss. »Funktionieren« heißt natürlich, dass wir im IE8 auch einfach auf :nth-child() verzichten könnten.

Und andere Webseiten könnten sich speziell an Anfänger richten. Die kommen vielleicht tatsächlich mit älteren Browsern auf das Angebot.

Eigentlich ist die Diskussion hier aber auch unnötig. Es geht um die Bibliotheken. Die bringen entweder die Klassen dafür mit oder nicht. An der Stelle wird kaum jemand auf die Idee kommen, das Tool umzuprogrammieren.

Permanenter Link

nikosch
am 17.12.2013 - 16:56

Am einfachsten wäre es, einfach eine Zahl an den Anfang jeder Zeile zu schreiben. Das hat den Nachteil, dass die Zahlen in jedem Fall bei Copy & Paste mitkopiert werden.
Im einfachsten Fall so, oder? http://jsfiddle.net/FK2z2/

Permanenter Link
Nicolai Schwarz

Nicolai Schwarz (Autor)
am 19.12.2013 - 11:05

Schau an. user-select: none; kannte ich noch nicht. Das müsste grundsätzlich auch funktionieren. Zumindest solange man den IE8 oder IE9 nicht unterstützen muss. Wobei die nummerierte Liste für Screenreader besser sein dürfte.

Ansonsten gilt, was ich oben sagte: Wir können uns zwar schöne HTML-Konstrukte dafür ausdenken, aber wir werden doch damit leben »müssen«, was die Bibliotheken liefern – wenn wir nicht einen eigenen Syntax Highlighter programmieren wollen.

Permanenter Link

Horst ebert
am 17.12.2013 - 18:51

Liebe Frau Schwarz,

vielen Dank für diesen interessanten Artikel, der für mich sehr hilfreich war.

Beste Grüße

Ihr Herr Ebert

Permanenter Link

Die Kommentare sind geschlossen.