How do I implement Rouge syntax highlighting in Rails? -


there bunch of tutorials floating around, seem incomplete or not current or don't work me.

this have done.

gemfile:

gem 'rouge' gem 'redcarpet' 

then created config/initializer/rouge.rb:

require 'rouge/plugins/redcarpet' 

then created file called app/assets/stylesheets/rouge.css.erb

<%= rouge::themes::github.render(:scope => '.highlight') %> 

then in app/helpers/application_helper.rb, added this:

module applicationhelper   class html < redcarpet::render::html     include rouge::plugins::redcarpet      def block_code(code, language)       rouge.highlight(code, language || 'text', 'html')     end   end    def markdown(text)     render_options = {       filter_html: true,       hard_wrap: true,       link_attributes: { rel: 'nofollow' }     }     renderer = html.new(render_options)      extensions = {       autolink: true,       fenced_code_blocks: true,       lax_spacing: true,       no_intra_emphasis: true,       strikethrough: true,       superscript: true     }     redcarpet::markdown.new(renderer, extensions).render(text).html_safe   end end 

then in show.html.erb, did this:

<%= markdown(@question.body) %> 

but literally not work. outputs ruby code snippet this:

unformatted-ruby-snippet

how snippet of code formatted github? or first step being formatted @ all, how tweak formatting?

i don't see stylesheet included in source of page, don't know styles tweak want.

edit 1

or when this:

            <div class="highlight">               <%= @question.test_suite %>             </div> 

it renders this:

another-ruby-snippet

edit 2

i attempted borama's suggestion , got output looks this:

enter image description here

edit 3

i made modification borama's answer follows.

in block_code method, call highlight follows:

rouge.highlight(code, 'ruby', 'html') 

then in view this:

<%= raw rouge_markdown(<<-'eof'                 def rouge_me                   puts "this #{'test'} rouge"                 end                 eof                 ) %> 

then produces this:

enter image description here

note referring code snippet @ bottom of screenshot.

however, text @ top generated this:

          <pre class="highlight ruby">             <%= rouge_markdown(@question.body) %>           </pre> 

and rendered shown in screenshot.

edit 4

after removing <div class="highlight">, see this:

enter image description here

aka....nothing being rendered @ all.

once add raw view...aka <%= raw rouge_markdown(@question.body) %>

the view renders this:

enter image description here

edit 5

here content various @question objects:

[1] pry(#<#<class:0x007fc041b97ce8>>)> @question.body => "5.times do\r\n   puts \"herro rerl!\"\r\nend" [1] pry(#<#<class:0x007fc041b97ce8>>)> @question.body => "puts \"hello world version 9\"\r\nputs \"this comes after version 8.\"\r\nputs \"this comes after version 7.\"\r\nputs \"this comes after version 6.\"\r\nputs \"this comes after version 5.\"\r\nputs \"this comes after version 4.\"\r\nputs \"this comes after version 3.\"\r\nputs \"this comes after version 2.\"\r\nputs \"this comes after version 1.\""  [1] pry(#<#<class:0x007fc041b97ce8>>)> @question.body => "def convert_relation(invited_gender, relation)\r\n case invited_gender\r\n \twhen \"male\"\r\n  \tcase relation\r\n      when \"daughter\", \"son\" \"dad\"\r\n      when \"mom\", \"dad\" \"son\"\r\n      when \"grandfather\", \"grandmother\" \"grandson\"\r\n      when \"sister\", \"brother\" \"brother\"\r\n      when \"wife\" \"husband\"\r\n      when \"husband\" \"husband\"\r\n    end\r\n  when \"female\"\r\n  \tcase relation\r\n      when \"daughter\", \"son\" \"mom\"\r\n      when \"mom\", \"dad\" \"daughter\"\r\n      when \"grandfather\", \"grandmother\" \"granddaughter\"\r\n      when \"sister\", \"brother\" \"sister\"\r\n      when \"wife\" \"wife\"\r\n      when \"husband\" \"wife\"\r\n    end\r\n  end\r\nend\r\n\r\nputs convert_relation(\"male\", \"wife\")" 

the original question indicated (in solution attempted) markdown used in highlighted questions turned out not case. answer split 2 distinct sections, 1 highlighting pure code without markdown, other 1 markdown text code.

a) want highlight pure code (no markdown involved)

in case, , according readme, need highlight code rouge a lexer , a formatter. since highlighted text displayed on web page, need html formatter. lexer, need know language code in beforehand (or may try guessing source code not seem reliable small code snippets).

you can create simple helper method highlighting:

module rougehelper   def rouge(text, language)     formatter = rouge::formatters::html.new(css_class: 'highlight')     lexer = rouge::lexer.find(language)     formatter.format(lexer.lex(text))   end end 

then in template, call helper text highlight , language:

<%= raw rouge("def rouge_me\n  puts 'hey!'\nend", "ruby") %> 

which render:

to list of languages rouge supports , corresponding names should passed rouge helper, can use following code. code gets defined lexers rouge , shows tags (i.e. names rouge recognizes them with):

rouge::lexer.all.map(&:tag).sort # => ["actionscript", "apache", "apiblueprint", "applescript", ..., "xml", "yaml"] 

you can (and should) use list when showing users languages choose in selection box. note each lexer has title , desc methods defined give human-readable name , short description of each of them. might want use info shown user, too.

note: should rid of initializer, custom html class , div wrapped around rouge helper call (all of these have in original attempt). thing need besides code above css rules, have correctly included in web page.

b) highlighted text markdown text code blocks

a couple of changes attempt make work:

  1. the initializer not needed, can remove think (but if don't want require files later in helper, guess can leave it).

  2. remove block_code method helper class, same done including markdown plugin.

  3. remove <div class="highlight"> wrapper div template , use helper in it. rouge adds own wrapper "highlight" class , div seems confuse it.

try following helper code. btw, moved code applicationhelper separate rougehelper (but not required change):

module rougehelper   require 'redcarpet'   require 'rouge'   require 'rouge/plugins/redcarpet'    class html < redcarpet::render::html     include rouge::plugins::redcarpet   end    def rouge_markdown(text)     render_options = {         filter_html: true,         hard_wrap: true,         link_attributes: { rel: 'nofollow' }     }     renderer = html.new(render_options)      extensions = {         autolink: true,         fenced_code_blocks: true,         lax_spacing: true,         no_intra_emphasis: true,         strikethrough: true,         superscript: true     }     markdown = redcarpet::markdown.new(renderer, extensions)     markdown.render(text)   end end 

then, in template, tried highlight test ruby code:

<%= raw rouge_markdown(<<-'eof' ```ruby def rouge_me   puts "this #{'test'} rouge" end ``` eof ) %> 

note needed specify language manually, made me use 3 backticks way delimit code instead of space indentation. have no clue why code language autodetection did not work here, perhaps it's short code.

in end rendered colors me nicely: