public
Last active

  • Download Gist
app.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
require 'rubygems'
require 'sinatra'
 
require 'coderay'
require 'rack-codehighlighter'
use Rack::Codehighlighter, :coderay,
:element => "pre", :pattern => /\A:::(\w+)\s*\n/
 
get "/" do
erb :index
end
 
set :public, File.dirname(__FILE__)
 
__END__
@@ layout
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="stylesheet" href="coderay.css">
<title>Rack::Codehighlighter example</title>
<body>
<%= yield %>
 
@@ index
<pre>:::ruby
def hello
puts "hello world"
end
</pre>
coderay.css
CSS
1 2 3 4
.CodeRay .s { background-color:#fff0f0; color:#d02000; }
.CodeRay .dl { color:black }
.CodeRay .r { color:#080; font-weight:bold }
.CodeRay .fu { color:#06B; font-weight:bold }
rack-codehighlighter.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
require 'rack/utils'
require 'hpricot'
module Rack
class Codehighlighter
include Rack::Utils
# for logging use
FORMAT = %{%s - [%s] [%s] "%s %s%s %s" (%s) %d %d %0.4f\n}
def initialize(app, highlighter = :censor, opts = {})
@app = app
@highlighter = highlighter
@opts = {
:element => "pre",
:pattern => /\A:::(\w+)\s*\n/,
:reason => "[[-- ugly code removed --]]", #8-)
:markdown => false
}
@opts.merge! opts
end
def call(env)
began_at = Time.now
status, headers, response = @app.call(env)
headers = HeaderHash.new(headers)
if !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
!headers['transfer-encoding'] &&
headers['content-type'] &&
headers['content-type'].include?("text/html")
content = ""
response.each { |part| content += part }
doc = Hpricot(content)
nodes = doc.search(@opts[:element])
nodes.each do |node|
s = node.inner_html || "[++where is the code?++]"
if @opts[:markdown]
node.parent.swap(send(@highlighter, s))
else
node.swap(send(@highlighter, s))
end
end
body = doc.to_html
headers['content-length'] = bytesize(body).to_s
log(env, status, headers, began_at) if @opts[:logging]
[status, headers, [body]]
else
[status, headers, response]
end
end
private
def log(env, status, headers, began_at)
# 127.0.0.1 - [ultraviolet] [10/Oct/2009 12:12:12] "GET /pastie HTTP/1.1" (text/html) 200 512 1.23
now = Time.now
logger = env['rack.errors']
logger.write FORMAT % [
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
@highlighter,
now.strftime("%d/%b/%Y %H:%M:%S"),
env["REQUEST_METHOD"],
env["PATH_INFO"],
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
env["HTTP_VERSION"],
headers["content-type"] || "unknown",
status.to_s[0..3],
headers['content-length'],
now - began_at
]
end
# simplifies testing
def censor(string)
"<pre class='censor'>#{@opts[:reason]}</pre>"
end
def syntax(string)
# allow use html instead of xml
translate = {
'html' => 'xml'
}
lang = 'unknown'
refs = @opts[:pattern].match(string) # extract language name
if refs
lang = refs[1]
convertor = ::Syntax::Convertors::HTML.for_syntax translate[lang]
convertor.convert(unescape_html(string.sub(@opts[:pattern], "")) || "[=this can'n happen=]")
else
"<pre>#{string}</pre>"
end
end
def coderay(string)
lang = 'unknown'
refs = @opts[:pattern].match(string) # extract language name
if refs
lang = refs[1]
str = unescape_html(string.sub(@opts[:pattern], ""))
"<pre class='CodeRay'>#{::CodeRay.encoder(:html).encode str, lang}</pre>"
else
"<pre class='CodeRay'>#{string}</pre>"
end
end
def ultraviolet(string)
opts = { :theme => 'dawn', :lines => false }
opts.merge! @opts
lang = 'text'
refs = @opts[:pattern].match(string) # extract language name
if refs
lang = refs[1]
str = unescape_html(string.sub(@opts[:pattern], ""))
"#{::Uv.parse(str, 'xhtml', lang, opts[:lines], opts[:theme])}"
else
"<pre class='#{opts[:theme]}'>#{string}</pre>"
end
end
def unescape_html(string)
string.to_s.gsub("&lt;", '<').gsub("&gt;", '>').gsub("&amp;", '&')
end
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.