Rack::Codehighlighter middleware
Rack::Codehighlighter provides a thin wrapper over a bunch of code highlighters to make their usage as generic possible.
- ultraviolet
- coderay
- syntax
- prettify
- censor (a fake highlighter used in example below)
Install the gem with:
sudo gem install wbzyl-rack-codehighlighter -s http://gems.github.com
The middleware looks for code blocks to be highlighted in HTML produced by
application. For each block found it calls requested highlighter.
Below we ask coderay to highlight all pre elements:
use Rack::Codehighlighter, :coderay, :element => "pre", :pattern => /\A:::(\w+)\s*\n/
The middleware uses the pattern to learn what language the code block contains, for example
<pre>:::ruby
puts "hello world"
</pre>
Plain description what the pattern says: If the element contents begins with three colons, the text following the colons, up to the end of line, identifies the language. The text matched by the pattern is removed from the code block before processing.
The above example could be shortened to:
use Rack::Codehighlighter, :coderay
because the default options values are used.
Normalization:
- Highlighted code is always wrapped with
preelement with attributes appropriate for codehighlighter used. - Language names are taken from Ultraviolet.
Using with Rack application
Rack::Codehighlighter can be used with any Rack application, for example with a Sinatra application. If your application includes a rackup file or uses Rack::Builder to construct the application pipeline, simply require and use as follows:
gem 'coderay' # get one of supported highlighters
require 'coderay'
gem 'wbzyl-rack-codehighlighter'
require 'rack/codehighlighter'
use Rack::Codehighlighter, :coderay
run app
Remember to include in the layout an appropriate stylesheet
(look into examples/public/stylesheets directory
for sample stylesheets).
Using with Rails
In order to use include the following in a Rails application
config/environment.rb file:
require 'coderay' # get one of supported highlighters
require 'rack/codehighlighter'
Rails::Initializer.run do |config|
config.gem 'coderay'
config.gem 'wbzyl-rack-codehighlighter'
config.middleware.use Rack::Codehighlighter, :coderay
end
Check the Rack configuration:
rake middleware
Remember to include in the layout an appropriate stylesheet
(look into examples/public/stylesheets directory
for sample stylesheets).
Configuration examples
Coderay:
use Rack::Codehighlighter, :coderay,
:element => "pre", :pattern => /\A:::(\w+)\s*\n/, :logging => false
Ultraviolet:
use Rack::Codehighlighter, :ultraviolet, :theme => "dawn", :lines => false,
:element => "pre", :pattern => /\A:::(\w+)\s*\n/, :logging => false
Prettify:
use Rack::Codehighlighter, :prettify,
:element => "pre", :pattern => /\A:::(\w+)\s*\n/, :logging => false
Syntax:
use Rack::Codehighlighter, :syntax,
:element => "pre", :pattern => /\A:::(\w+)\s*\n/, :logging => false
Censor:
use Rack::Codehighlighter, :censor, :reason => "[[-- ugly code removed --]]",
:element => "pre", :pattern => /\A:::(\w+)\s*\n/, :logging => false
In the above examples, the default value of each option is used.
All highlighters use pre element to wrap highlighted code.
In Markdown, Maruku and RDiscount templates code is wrapped with pre>code.
To remove an extra nesting the :markdown option should be used:
use Rack::Codehighlighter, :coderay, :markdown => true,
:element => "pre>code", :pattern => /\A:::(\w+)\s*\n/, :logging => false
A simple example with inline template
# example.rb
require 'rubygems'
gem 'sinatra', '>=0.9.0'
require 'sinatra'
gem 'wbzyl-rack-codehighlighter', '>=0.2.0'
require 'rack/codehighlighter'
use Rack::Codehighlighter, :censor, :reason => '[[--difficult code removed--]]'
get "/" do
erb :hello
end
__END__
Run the above example with:
ruby example.rb
The results are accessible from http://localhost:4567.
Why using middleware for code highlighting is awesome?
In each piece of code inserted into html we must change:
< to <. This is annoying thing.
Each(? prettify, dp-) pure javascript highlighter has this defect.
In pre-Rack applications era possible approaches were:
- gems; conection to methods responsible for code highlighting is obtrusive, i.e. via plugin + additional markup
Analyze packages mentioned at the The Ruby Toolbox page: Syntax Highlighting
Links:
http://carboni.ca/projects/harsh/
unless HAML is used
http://redclothcoderay.rubyforge.org/
http://github.com/augustl/redcloth-with-coderay
how to use with Rails
does't degrade to html: new source tag
http://github.com/arya/tm_syntax_highlighting/
how to connect to rails/sinatra?
Ruby tips from me, your idol: I can not tell you how much time I’ve wasted trying to add in some cool feature into rails. I would dig into the rails internals, override methods, do all kinds of tricky stuff. I thought I was awesome. A month later rails comes out with some cool new feature, I update rails and everything explodes.
Conclusion: highlighting via plugins is doomed to explode sooner or later.
Supported highlighters
These currently include: Syntax (fast), Coderay (very fast), Ultraviolet (slow, but highlights almost any language).
Syntax
Languages supported by Syntax:
- xml
- ruby
Coderay
Languages supported by Coderay:
- C, CSS
- Delphi, diff
- HTML, RHTML (Rails), Nitro-XHTML
- Java, JavaScript, JSON
- Ruby
- YAML
Google Code Prettify, pure Javascript
Languages supported by Prettify:
- css, lisp, hs, lua, sql, vb, wiki,
- bsh, c, cc, cpp, cs, csh, cyc, cv, htm, html,
- java, js, m, mxml, perl, pl, pm, py, rb, sh,
- xhtml, xml, xsl
Ultraviolet
The ultraviolet gem needs oniguruma regexp library.
On Fedora install the library with:
sudo yum install oniguruma
For installation instruction from sources, see Carbonica
Now, install the gem:
sudo gem install ultraviolet
See also Ultraviolet themes gallery
Ultraviolet supports almost any language:
- actionscript, active4d, active4d_html, active4d_ini, active4d_library, ada, antlr, apache, applescript, asp, asp_vb.net
- bibtex, blog_html, blog_markdown, blog_text, blog_textile, build, bulletin_board
- c, c++, cake, camlp4, cm, coldusion, context_free, cs, css, css_experimental, csv
- d, diff, dokuwiki, dot, doxygen, dylan
- eiffel, erlang, f-script, fortran, fxscript
- greasemonkey, gri, groovy, gtd, gtdalt
- haml, haskell, html, html-asp, html_django, html_for_asp.net, html_mason, html_rails, html_tcl
- icalendar, inform, ini, installer_distribution_script, io
- java, javaproperties, javascript, javascript_+_prototype, javascript_+_prototype_bracketed, jquery_javascript, json
- languagedefinition, latex, latex_beamer, latex_log, latex_memoir, lexflex, lighttpd, lilypond, lisp, literate_haskell, logo, logtalk, lua
- m, macports_portfile, mail, makefile, man, markdown, mediawiki, mel, mips, mod_perl, modula-3, moinmoin, mootools, movable_type, multimarkdown
- objective-c, objective-c++, ocaml, ocamllex, ocamlyacc, opengl
- pascal, perl, php, plain_text, pmwiki, postscript, processing, prolog, property_list, python, python_django
- qmake_project, qt_c++, quake3_config
- r, r_console, ragel, rd_r_documentation, regexp, regular_expressions_oniguruma, regular_expressions_python, release_notes remind, restructuredtext, rez, ruby, ruby_experimental, ruby_on_rails
- s5, scheme, scilab, setext, shell-unix-generic, slate, smarty, sql, sql_rails, ssh-config, standard_ml, strings_file, subversion_commit_message, sweave, swig
- tcl, template_toolkit, tex, tex_math, textile, tsv, twiki, txt2tags
- vectorscript
- xhtml_1.0, xml, xml_strict, xsl
- yaml, yui_javascript