Trix Editor Syntax Highlight
Created: 2025/05/05, Updated: 2026/06/08,10:05:34Subpages Menu
Als Entwickler kommt irgendwann der Zeitpunkt, an dem wir uns mit Syntaxhervorhebung (Code Highlighting | Syntax Highlighting) befassen müssen.
Ganz gleich, ob wir einen Blog, ein CMS, eine Dokumentationswebseite oder eine andere Rails-Anwendung erstellen, das Hinzufügen von Syntaxhervorhebung zu Code-Blöcken ist eine unverzichtbare Funktion.
In diesem Artikel lernen wir, wie man Syntax-Hervorhebung zu Rails-Anwendungen hinzufügt, indem wir verschiedene Möglichkeiten dazu und ein paar nützliche Tricks zur Verbesserung der Benutzererfahrung vorstellen.
Ganz gleich, ob wir einen Blog, ein CMS, eine Dokumentationswebseite oder eine andere Rails-Anwendung erstellen, das Hinzufügen von Syntaxhervorhebung zu Code-Blöcken ist eine unverzichtbare Funktion.
In diesem Artikel lernen wir, wie man Syntax-Hervorhebung zu Rails-Anwendungen hinzufügt, indem wir verschiedene Möglichkeiten dazu und ein paar nützliche Tricks zur Verbesserung der Benutzererfahrung vorstellen.
Rouge Helper Modul CodeHighlight
Es gibt einige Optionen um die Syntax eines Quelltextes (Syntax Highlight) etwas ansprechender zu gestalten.
- Ruby Gem Rouge - Serverseitig (Ruby interpreter erzeugt den "highlight Quelltext" )
- Ruby Gem Coderay - Serverseitig (Ruby interpreter erzeugt den "highlight Quelltext" )
- Javascript highlight.js - Klientseitig (Browser erzeugt den "highlight Quelltext" )
Ich bevorzuge gerne eine Serverseitige Variante, da es etwas mehr Kontrolle für die erzeugte Ausgabe ermöglicht.
Die Entscheidung war nicht einfach, aber dennoch habe ich mich für das Ruby Gem Rouge entschieden. Es ist ein großartiges Ruby-Gem, das uns diesen Vorgang erheblich erleichtert.
Was ist Rouge?
Die Entscheidung war nicht einfach, aber dennoch habe ich mich für das Ruby Gem Rouge entschieden. Es ist ein großartiges Ruby-Gem, das uns diesen Vorgang erheblich erleichtert.
Was ist Rouge?
Rouge ist ein rein in Ruby geschriebener Syntax-Highlighter. Er kann über 60 Sprachen hervorheben und die Ausgabe als HTML oder ANSI-Text mit 256 Farben liefern. Seine HTML-Ausgabe ist mit Stylesheets kompatibel, die für Pygments entwickelt wurden.
# ....
gem "rouge" # currently (2026.05.05) 5.0.0
...
Danach einfach
bundle install
Jetzt erstellen wir ein Helper Modul für Rouge. Da das hervorheben des Quelltextes (Syntax Highlight) im Standard Trix Editor für Ruby on Rails steuerbar sein soll, war der ursprüngliche Plan, eine "DropDown" in die Trix Editor Toolbar zu integrieren. Die Anpassung war mir dann doch etwas zu umfangreich, so dass ich mich entschieden habe die Steuerung der einfacher zu gestalten.
Es wird einfach der existierende Code Button des Editors verwendet, welcher den Text mit <pre> ... </pre> Tags versieht.
Die Steuerung ob der Quelltext mit Syntax Highlight gerendert werden soll und welche Programmiersprache als Basis verwendet wird, kann einfach mittels eines Schlüsselwortes in der 1. Zeile angegeben werden.
Die Schlüssel könnten zum Beispiel so angegeben werden: #css#, #html#, #erb#, #ruby#.
Das folgende Modul CodeHighlightHelper sucht in der 1. Zeile nach diesen Schlüsseln, entfernt diesen und verwendet die entsprechende Sprache zwischen den Hash Tags #lang# als Basis. Die beiden require Methoden für nokogiri und rouge sind nicht zwingend notwendig, da beide schon im Gemfile existieren und somit in Ruby on Rails verfügbar sind.
Sollte eines dieser Gems nicht vorhanden sein, dann wird somit eine Exeption schon beim Start vom Rails Server erzeugt.
Datei: app/helpers/code_highlight_helper.rb mit folgenden Inhalt:
# frozen_string_literal: true
# Module CodeHighlightHelper for Syntax highlight of supported programming languages.
module CodeHighlightHelper
require "nokogiri"
require "rouge"
# Parse the HTML string using Nokogiri, and for every “pre” tag found, attempt to apply syntax highlighting
# using Rouge::Formatters.
#
# Syntax highlighting is only applied if the first line at the beginning of the string specifies the programming language
# like #ruby#, #css, #html#, etc..
#
# Example:
# #css#
# pre code-lang {
# position: absolute;
# top: 0;
# width: 100px;
# }
#
def pre_code_highlight(body_text, line_numbers = true)
body = Nokogiri::HTML5.fragment(body_text.to_s)
body.css("pre").each do |node|
lang = nil
remove = nil
# logger.debug "=== node.text: #{node.text} === END node.text"
# match language between #lang# on beginning of string
if (match = node.text.match(/^#([a-z]{1,10}?)#\n/))
remove = match[0] # contains the matched string
lang = match[1] # contains the language string
end
if remove && lang
code_text = node.text.sub(/^#{remove}/, "")
highlight_code = syntax_highlight(code_text, get_language(lang), line_numbers)
node.replace(highlight_code) # or `.swap(new_node)`
else
node.text
end
end
body
end
# find supported code highlight languages.
# If nothing compatible found, then return ruby.
def get_language(lang)
Rouge::Lexer.all.map(&:tag).sort.include?(lang) ? lang : "ruby"
end
# Do the syntax highlight
def syntax_highlight(text, language, line_numbers)
formatter = Rouge::Formatters::HTML.new
if line_numbers
formatter = Rouge::Formatters::HTMLLinewise.new(formatter, class: "line-%i")
end
lexer = Rouge::Lexer.find(language)
"<div class=\"auto-scroll-x\"><pre class=\"highlight\"><code class=\"#{language}\">#{formatter.format(lexer.lex(text))}</code></pre></div>"
end
def theme(theme)
# Get some CSS
# Rouge::Themes::Base16.mode(:light).render(scope: '.highlight')
# Or use Theme#find with string input
# Rouge::Theme.find('base16.light').render(scope: '.highlight')
Rouge::Theme.find(theme).render(scope: ".highlight")
end
end
Rouge Helper Modul in den Render Prozess integrieren
In Arbeit ...
Stylesheets für den Syntax Highlight Code
Damit der Quellltext ansprechend und passend zu Layout gestaltet werden kann muss natürlich auch eine entsprechende Stylesheet Datei erzeugt und integriert werden.
Selbst die Nummerierung der Zeilen kann mit CSS bzw. SCSS realisiert werden. Das Gem Rouge bring diverse Stylesheets mit.
Hierfür existieren 2 Methoden als Beispiel:
Selbst die Nummerierung der Zeilen kann mit CSS bzw. SCSS realisiert werden. Das Gem Rouge bring diverse Stylesheets mit.
Hierfür existieren 2 Methoden als Beispiel:
- Rouge::Themes::Base16.mode(:light).render(scope: '.highlight') - Hiermit kann das gewünschte Thema als Symbol übergeben werden.
- Rouge::Theme.find('base16.light').render(scope: '.highlight') - Hiermit kann das gewünschte Thema als String übergeben werden.
In Arbeit ..