ActionText Highlighting with Rouge
03.30.2024
I wrote this module to process and format code blocks within a given text input that can be output through ActionText, utilizing the Rouge library for syntax highlighting.
# frozen_string_literal: true module ActionText module RougeExtension def transform_text(text) parsed_text = parse_html_fragment(text) process_code_blocks(parsed_text) parsed_text.to_html.html_safe end private def format_code_block(content, lexer) formatter = Rouge::Formatters::HTML.new formatter.format(lexer.lex(content)) end def get_lexer(language) Rouge::Lexer.find(language.downcase) || Rouge::Lexers::PlainText end def get_first_line(block) block.text.strip.lines.first.strip end def parse_html_fragment(text) Nokogiri::HTML.fragment(text) end def process_code_blocks(parsed_text) parsed_text.css("pre").each do |block| first_line = get_first_line(block) lexer = get_lexer(first_line) content = block.content.lines.drop(1).join formatted_code = format_code_block(content, lexer) block.content = formatted_code block.inner_html = formatted_code end end end end
It can be used by including the module and modifying the ActionText content partial.
# app/helpers/application_helper.rb # frozen_string_literal: true module ApplicationHelper extend ActiveSupport::Concern include ActionText::RougeExtension end
<%# app/views/layouts/action_text/contents/_content.html.erb %> <div class="trix-content"> <%= transform_text(yield) %> </div>