Shiki Highlighting in Elixir: Code im Virtual Classroom
Syntax Highlighting ist ein essentieller Bestandteil technischer Dokumentation und Schulungsmaterialien. Als wir bei workshops.de nach einer modernen Lösung für unseren Virtual Classroom suchten, stießen wir auf Shiki – und haben es erfolgreich in unser Elixir/Phoenix-System integriert. In diesem Artikel zeigen wir, wie wir das gemacht haben und welche Vorteile es für unsere Online-Schulungen bringt.
Warum Shiki?
Shiki ist ein Syntax Highlighter, der die gleiche Engine wie VS Code verwendet – TextMate Grammars. Das bedeutet:
- Präzise Syntax-Erkennung: Die gleiche Qualität, die Entwickler:innen aus ihrem Editor kennen
- Umfangreiche Sprachunterstützung: Über 200 Programmiersprachen und Frameworks
- Moderne Themes: Inklusive Dark Mode Support
- Zero Runtime: Das Highlighting passiert beim Rendern, nicht im Browser
Die Herausforderung: Node.js in Elixir
Shiki ist ein Node.js-Paket. Elixir/Phoenix ist… nun ja, nicht Node.js. Die Lösung? Das nodejs Elixir-Package, das eine Bridge zwischen beiden Welten schlägt.
Installation
Zuerst fügen wir die Dependencies hinzu:
# mix.exs
defp deps do
[
{:nodejs, "~> 3.1"},
# ... andere deps
]
end
Dann installieren wir Shiki via npm:
cd assets
npm install shiki
Die Bridge: ShikiHighlighter Module
Wir haben ein dediziertes Modul erstellt, das die Kommunikation mit Node.js übernimmt:
defmodule PlatformWeb.Helpers.ShikiHighlighter do
@moduledoc """
Highlights code blocks using Shiki via Node.js
"""
def highlight(html) when is_binary(html) do
html
|> highlight_code_blocks()
|> highlight_inline_code()
end
defp highlight_code_blocks(html) do
Regex.replace(
~r/<pre><code(?:\s+class="(\w+)")?>(.*?)<\/code><\/pre>/s,
html,
fn full_match, lang, code ->
highlight_code_block(code, lang, full_match, false)
end
)
end
end
Transformers: Die Superkräfte von Shiki
Shiki bietet sogenannte “Transformers” – Plugins, die das Highlighting erweitern. Wir nutzen drei davon:
1. Line Highlighting
Bestimmte Zeilen hervorheben:
function hello() {
console.log("Diese Zeile ist highlighted");
console.log("Normal");
console.log("Zeilen 4-6");
console.log("sind auch");
console.log("highlighted");
}
2. Diff Highlighting
Änderungen visualisieren – perfekt für Refactoring-Beispiele:
function greet(name) {
console.log("Hello " + name);
console.log(`Hello ${name}`);
console.log("Focus on this");
console.log("Warning here");
}
3. Focus/Blur
Unwichtige Code-Teile ausblenden:
export function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
// Dieser Code ist "geblurred"
Inline Code Highlighting – Der Game Changer
Eine unserer coolsten Features: Syntax-Highlighting auch für Inline-Code! Statt langweiligem console.log("test") bekommen wir farblich hervorgehobenen Code direkt im Fließtext.
Die Syntax ist einfach:
Verwende `const items = [];{:js}` für Arrays oder `<button className="primary">{:html}` für React-Komponenten.
Das wird zu schön gefärbtem Inline-Code mit der richtigen Syntax-Erkennung!
Integration in den Content-Pipeline
Die Integration in unseren bestehenden Markdown-zu-HTML-Pipeline war überraschend einfach:
def calculate_content_html(%Ecto.Changeset{} = changeset) do
if content = get_change(changeset, :content) do
html =
content
|> Earmark.as_html!() # Markdown → HTML
|> ShikiHighlighter.highlight() # Shiki Magic ✨
put_change(changeset, :content_html, html)
else
changeset
end
end
Das funktioniert für alle Bereiche unseres Virtual Classroom:
- Blog Posts: Artikel wie dieser hier
- Course Tasks: Übungsaufgaben in unseren Schulungen
- Course Materials: Schulungsunterlagen und Slides
- Live-Sessions: Code-Beispiele während der Schulung
Performance: Der Trick mit dem Caching
Shiki-Highlighting ist nicht kostenlos – jeder Aufruf zu Node.js kostet Zeit. Unsere Lösung:
Pre-Rendering beim Speichern: Wir highlighten den Code einmal beim Speichern und cachen das Ergebnis in der Datenbank. Der User bekommt instant gerenderten, schön gefärbten Code – ohne Wartezeit.
# Beim Speichern
changeset
|> calculate_content_html() # Einmal highlighten
|> Repo.update() # HTML in DB speichern
# Beim Anzeigen
post.content_html # Direkt aus DB, instant! 🚀
Dark Mode Support
Shiki unterstützt CSS Variables für Themes. Wir nutzen das für automatischen Dark Mode:
.shiki {
background-color: var(--shiki-light-bg);
color: var(--shiki-light);
}
@media (prefers-color-scheme: dark) {
.shiki {
background-color: var(--shiki-dark-bg);
color: var(--shiki-dark);
}
}
Jedes Token bekommt beide Farben:
<span style="color:#24292E;--shiki-dark:#E1E4E8">const</span>
Unser Virtual Classroom: Moderne Lernumgebung
Unser Virtual Classroom ist mehr als nur eine Videokonferenz-Plattform. Es ist eine vollständige Lernumgebung, die speziell für technische Schulungen entwickelt wurde:
- Interaktive Übungsaufgaben: Teilnehmer:innen arbeiten direkt an praktischen Aufgaben
- Live-Code-Beispiele: Trainer:innen zeigen Code in Echtzeit
- Materialien on-demand: Alle Slides, Code-Snippets und Dokumentation an einem Ort
- Progress Tracking: Teilnehmer:innen sehen ihren Fortschritt durch die Schulung
Für all diese Bereiche brauchten wir professionelles Syntax-Highlighting – und genau hier kommt Shiki ins Spiel.
Vorteile für unseren Virtual Classroom
Die Shiki-Integration hat unseren Virtual Classroom und die Schulungsmaterialien auf ein neues Level gehoben:
1. Professionellere Darstellung
Code sieht aus wie in VS Code – vertraut und professionell.
2. Bessere Lesbarkeit
Syntax-Highlighting macht Code-Beispiele deutlich verständlicher. Teilnehmer:innen erfassen Strukturen schneller.
3. Diff-Highlighting für Refactorings
Wir können Vorher/Nachher-Vergleiche direkt im Code zeigen – perfekt für Best Practices und Code Reviews.
4. Inline-Code im Fließtext
Technische Begriffe im Text bekommen Syntax-Highlighting – das erhöht die Klarheit enorm.
5. Konsistenz über alle Materialien
Egal ob Blog, Slides oder Übungsaufgaben – überall im Virtual Classroom die gleiche, hochwertige Code-Darstellung.
6. Nahtlose Integration in den Lernprozess
Unser Virtual Classroom bietet eine moderne Lernumgebung. Mit Shiki sehen Code-Beispiele genauso aus wie im Editor der Teilnehmer:innen – das reduziert kognitive Reibung und beschleunigt das Lernen.
Lessons Learned
Was gut funktioniert hat:
- nodejs Package: Stabile Bridge zwischen Elixir und Node.js
- Pre-Rendering: Caching macht die Performance exzellent
- Transformers: Die Shiki-Plugins sind mächtig und gut dokumentiert
Herausforderungen:
-
Regex-Komplexität: Inline-Code mit HTML-Tags im Code (z.B.
</code>) war tricky - Timeout-Handling: Bei großen Batches mussten wir Timeouts erhöhen
- Error Handling: Node.js-Crashes müssen sauber abgefangen werden
Code-Beispiele aus der Praxis
Hier ein echtes Beispiel aus unserer Angular-Schulung:
@Component({
selector: 'app-book-list',
template: `
<div *ngFor="let book of books">
{{ book.title }}
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class BookListComponent {
books = signal<Book[]>([]);
}
Mit Line-Highlighting und Focus können wir genau zeigen, worauf es ankommt!
Fazit
Die Integration von Shiki in unser Elixir/Phoenix-System war eine der besten technischen Entscheidungen für unseren Virtual Classroom. Die Kombination aus:
- Präzisem Syntax-Highlighting
- Modernen Transformers
- Inline-Code-Support
- Dark Mode
…macht unsere Materialien deutlich professioneller und verständlicher.
Der Aufwand? Überschaubar. Der Nutzen? Enorm.
Weiterführende Links
Interessiert an modernen Web-Technologien? Erlebe unseren Virtual Classroom selbst und schau dir unsere Schulungen an – mit Code-Highlighting und interaktiven Übungen! 😉
