webficient-rack-coderay 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = CodeRay Syntax Highlighter for Rack
2
+
3
+ Rack::Coderay parses text/html markup and replaces code with output
4
+ from the CodeRay gem (http://coderay.rubychan.de/), producing syntax highlighting.
5
+ By default, this component looks for <pre lang="xxxx">...</pre>
6
+ blocks, where 'xxxx' is any of the languages supported by CodeRay (e.g. 'ruby').
7
+ See http://coderay.rubychan.de/doc/classes/CodeRay/Scanners.html
8
+
9
+ For more information about the Rack specification, check out http://rack.rubyforge.org
10
+
11
+ == Installation
12
+
13
+ Prerequisites:
14
+
15
+ -Rack gem (sudo gem install rack)
16
+ -CodeRay gem (sudo gem install coderay)
17
+
18
+ From Gem:
19
+
20
+ $ sudo gem install webficient-rack-coderay
21
+
22
+ With a local working copy:
23
+
24
+ $ git clone git://github.com/webficient/rack-coderay.git
25
+ $ rake build && sudo rake install
26
+
27
+ == Usage
28
+
29
+ Basic Usage
30
+ -----------
31
+
32
+ Rack::Coderay is implemented as a piece of Rack middleware and can be used with
33
+ any Rack-based application. If your application includes a rackup (`.ru`) file
34
+ or uses Rack::Builder to construct the application pipeline, simply require
35
+ and use as follows:
36
+
37
+ require 'rack/coderay'
38
+
39
+ use Rack::Coderay
40
+ run app
41
+
42
+ Using with Rails
43
+ ----------------
44
+
45
+ Add this to your `config/environment.rb`:
46
+
47
+ # above Rails::Initializer block
48
+ require 'rack/coderay'
49
+
50
+ # inside Rails::Initializer block
51
+ config.middleware.use Rack::Coderay
52
+
53
+ You should now see `Rack::Coderay` listed in the middleware pipeline:
54
+
55
+ rake middleware
56
+
57
+ Configuration Options
58
+ ---------------------
59
+
60
+ To override the default markup trigger (<pre lang="xxxx">), you
61
+ can pass in a css or xpath selector as the second argument:
62
+
63
+ # Rails example
64
+ config.middleware.use Rack::Coderay, "//div[@lang]"
65
+
66
+ To set additional CodeRay gem options, pass a hash as the third argument:
67
+
68
+ # Rails example
69
+ config.middleware.use Rack::Coderay,
70
+ "//pre[@lang]",
71
+ :line_numbers => :table
72
+
73
+ Stylesheet
74
+ ----------
75
+ You can grab the latest CSS from the CodeRay site at http://coderay.rubychan.de/stylesheets/coderay.css.
76
+
77
+ A copy has been embedded in the Rack::Coderay gem under the /resources directory for your convenience.
78
+
79
+ == Copyright
80
+
81
+ Copyright (c) 2009 Phil Misiowiec, Webficient LLC. See MIT-LICENSE for details.
@@ -0,0 +1,61 @@
1
+ require 'coderay'
2
+ require 'hpricot'
3
+
4
+ module Rack::Coderay
5
+ # This class is the interface between Rack and the CodeRay gem
6
+ class Parser
7
+
8
+ # Defaults for the Coderay gem config
9
+ DEFAULT_CODERAY_OPTS = {
10
+ :css => :class
11
+ }
12
+
13
+ # Coderay gem options for HTML encoder,
14
+ # see http://coderay.rubychan.de/doc/classes/CodeRay/Encoders/HTML.html
15
+ attr_accessor :coderay_options
16
+
17
+ def initialize(app, markup_trigger, options = {})
18
+ @app = app
19
+ @markup_trigger = markup_trigger
20
+ self.coderay_options = DEFAULT_CODERAY_OPTS.merge(options)
21
+ raise "Markup trigger must include a 'lang' attribute" if !markup_trigger.include?('lang')
22
+ end
23
+
24
+ # method required by Rack interface
25
+ def call(env)
26
+ call! env
27
+ end
28
+
29
+ # thread safe version using shallow copy of env
30
+ def call!(env)
31
+ @env = env.dup
32
+ status, headers, response = @app.call(@env)
33
+ if headers["Content-Type"] && headers["Content-Type"].include?("text/html")
34
+ headers.delete('Content-Length')
35
+ response = Rack::Response.new(
36
+ response = parse_and_replace(response.respond_to?(:body) ? response.body : response),
37
+ status,
38
+ headers
39
+ )
40
+ response.finish
41
+ response.to_a
42
+ else
43
+ [status, headers, response]
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def parse_and_replace(content) #:nodoc:
50
+ doc = Hpricot(content.is_a?(Array) ? content[0] : content)
51
+ doc.search(@markup_trigger).each do |node|
52
+ node.swap(coderay_render(node.inner_html, node['lang']))
53
+ end
54
+ doc.to_original_html
55
+ end
56
+
57
+ def coderay_render(text, language) #:nodoc:
58
+ ::CodeRay.scan(text, language.to_sym).div(self.coderay_options)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,46 @@
1
+ require 'rack'
2
+
3
+ # = CodeRay Syntax Highlighter Rack Appliance
4
+ #
5
+ # Rack::Coderay parses text/html markup and replaces code with output
6
+ # from the CodeRay gem (http://coderay.rubychan.de/), producing syntax highlighting.
7
+ # By default, this component looks for <pre lang="xxxx">...</pre>
8
+ # blocks, where 'xxxx' is any of the languages supported by CodeRay (e.g. 'ruby').
9
+ # See http://coderay.rubychan.de/doc/classes/CodeRay/Scanners.html
10
+ #
11
+ # You can re-configure Rack::Coderay to look for a different trigger
12
+ # but it needs to have a 'lang' attribute.
13
+ #
14
+ # === Usage
15
+ #
16
+ # Within a rackup file (or with Rack::Builder):
17
+ # require 'rack/coderay'
18
+ # use Rack::Coderay
19
+ # run app
20
+ #
21
+ # Rails example:
22
+ # # above Rails::Initializer block
23
+ # require 'rack/coderay'
24
+ #
25
+ # # inside Rails::Initializer block
26
+ # config.middleware.use Rack::Coderay
27
+ #
28
+ # To override the default markup trigger (<pre lang="xxxx">), you
29
+ # can pass in a css or xpath selector as the second argument:
30
+ #
31
+ # config.middleware.use Rack::Coderay, "//div[@lang]"
32
+ #
33
+ # To set additional CodeRay gem options, pass a hash as the third argument:
34
+ #
35
+ # config.middleware.use Rack::Coderay,
36
+ # "//pre[@lang]",
37
+ # :line_numbers => :table
38
+ module Rack::Coderay
39
+ autoload :Parser, 'rack/coderay/parser'
40
+
41
+ # Create a new Rack::Coderay middleware component that automatically
42
+ # highlights syntax using the CodeRay gem.
43
+ def self.new(backend, markup_trigger = "//pre[@lang]", options = {})
44
+ Parser.new(backend, markup_trigger, options)
45
+ end
46
+ end
@@ -0,0 +1,130 @@
1
+ .CodeRay {
2
+ background-color: #f8f8f8;
3
+ border: 1px solid silver;
4
+ font-family: 'Courier New', 'Terminal', monospace;
5
+ color: #000;
6
+ }
7
+ .CodeRay pre { margin: 0px }
8
+
9
+ div.CodeRay { }
10
+
11
+ span.CodeRay { white-space: pre; border: 0px; padding: 2px }
12
+
13
+ table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px }
14
+ table.CodeRay td { padding: 2px 4px; vertical-align: top }
15
+
16
+ .CodeRay .line_numbers, .CodeRay .no {
17
+ background-color: #def;
18
+ color: gray;
19
+ text-align: right;
20
+ }
21
+ .CodeRay .line_numbers tt { font-weight: bold }
22
+ .CodeRay .line_numbers .highlighted { color: red }
23
+ .CodeRay .no { padding: 0px 4px }
24
+ .CodeRay .code { width: 100% }
25
+
26
+ ol.CodeRay { font-size: 10pt }
27
+ ol.CodeRay li { white-space: pre }
28
+
29
+ .CodeRay .code pre { overflow: auto }
30
+
31
+ .CodeRay .debug { color:white ! important; background:blue ! important; }
32
+
33
+ .CodeRay .af { color:#00C }
34
+ .CodeRay .an { color:#007 }
35
+ .CodeRay .at { color:#f08 }
36
+ .CodeRay .av { color:#700 }
37
+ .CodeRay .aw { color:#C00 }
38
+ .CodeRay .bi { color:#509; font-weight:bold }
39
+ .CodeRay .c { color:#888; }
40
+
41
+ .CodeRay .ch { color:#04D }
42
+ .CodeRay .ch .k { color:#04D }
43
+ .CodeRay .ch .dl { color:#039 }
44
+
45
+ .CodeRay .cl { color:#B06; font-weight:bold }
46
+ .CodeRay .cm { color:#A08; font-weight:bold }
47
+ .CodeRay .co { color:#036; font-weight:bold }
48
+ .CodeRay .cr { color:#0A0 }
49
+ .CodeRay .cv { color:#369 }
50
+ .CodeRay .de { color:#B0B; }
51
+ .CodeRay .df { color:#099; font-weight:bold }
52
+ .CodeRay .di { color:#088; font-weight:bold }
53
+ .CodeRay .dl { color:black }
54
+ .CodeRay .do { color:#970 }
55
+ .CodeRay .dt { color:#34b }
56
+ .CodeRay .ds { color:#D42; font-weight:bold }
57
+ .CodeRay .e { color:#666; font-weight:bold }
58
+ .CodeRay .en { color:#800; font-weight:bold }
59
+ .CodeRay .er { color:#F00; background-color:#FAA }
60
+ .CodeRay .ex { color:#F00; font-weight:bold }
61
+ .CodeRay .fl { color:#60E; font-weight:bold }
62
+ .CodeRay .fu { color:#06B; font-weight:bold }
63
+ .CodeRay .gv { color:#d70; font-weight:bold }
64
+ .CodeRay .hx { color:#058; font-weight:bold }
65
+ .CodeRay .i { color:#00D; font-weight:bold }
66
+ .CodeRay .ic { color:#B44; font-weight:bold }
67
+
68
+ .CodeRay .il { background: #ddd; color: black }
69
+ .CodeRay .il .il { background: #ccc }
70
+ .CodeRay .il .il .il { background: #bbb }
71
+ .CodeRay .il .idl { background: #ddd; font-weight: bold; color: #666 }
72
+ .CodeRay .idl { background-color: #bbb; font-weight: bold; color: #666; }
73
+
74
+ .CodeRay .im { color:#f00; }
75
+ .CodeRay .in { color:#B2B; font-weight:bold }
76
+ .CodeRay .iv { color:#33B }
77
+ .CodeRay .la { color:#970; font-weight:bold }
78
+ .CodeRay .lv { color:#963 }
79
+ .CodeRay .oc { color:#40E; font-weight:bold }
80
+ .CodeRay .of { color:#000; font-weight:bold }
81
+ .CodeRay .op { }
82
+ .CodeRay .pc { color:#038; font-weight:bold }
83
+ .CodeRay .pd { color:#369; font-weight:bold }
84
+ .CodeRay .pp { color:#579; }
85
+ .CodeRay .ps { color:#00C; font-weight: bold; }
86
+ .CodeRay .pt { color:#349; font-weight:bold }
87
+ .CodeRay .r, .kw { color:#080; font-weight:bold }
88
+
89
+ .CodeRay .ke { color: #808; }
90
+ .CodeRay .ke .dl { color: #606; }
91
+ .CodeRay .ke .ch { color: #80f; }
92
+ .CodeRay .vl { color: #088; }
93
+
94
+ .CodeRay .rx { background-color:#fff0ff }
95
+ .CodeRay .rx .k { color:#808 }
96
+ .CodeRay .rx .dl { color:#404 }
97
+ .CodeRay .rx .mod { color:#C2C }
98
+ .CodeRay .rx .fu { color:#404; font-weight: bold }
99
+
100
+ .CodeRay .s { background-color:#fff0f0; color: #D20; }
101
+ .CodeRay .s .s { background-color:#ffe0e0 }
102
+ .CodeRay .s .s .s { background-color:#ffd0d0 }
103
+ .CodeRay .s .k { }
104
+ .CodeRay .s .ch { color: #b0b; }
105
+ .CodeRay .s .dl { color: #710; }
106
+
107
+ .CodeRay .sh { background-color:#f0fff0; color:#2B2 }
108
+ .CodeRay .sh .k { }
109
+ .CodeRay .sh .dl { color:#161 }
110
+
111
+ .CodeRay .sy { color:#A60 }
112
+ .CodeRay .sy .k { color:#A60 }
113
+ .CodeRay .sy .dl { color:#630 }
114
+
115
+ .CodeRay .ta { color:#070 }
116
+ .CodeRay .tf { color:#070; font-weight:bold }
117
+ .CodeRay .ts { color:#D70; font-weight:bold }
118
+ .CodeRay .ty { color:#339; font-weight:bold }
119
+ .CodeRay .v { color:#036 }
120
+ .CodeRay .xt { color:#444 }
121
+
122
+ .CodeRay .ins { background: #afa; }
123
+ .CodeRay .del { background: #faa; }
124
+ .CodeRay .chg { color: #aaf; background: #007; }
125
+ .CodeRay .head { color: #f8f; background: #505 }
126
+
127
+ .CodeRay .ins .ins { color: #080; font-weight:bold }
128
+ .CodeRay .del .del { color: #800; font-weight:bold }
129
+ .CodeRay .chg .chg { color: #66f; }
130
+ .CodeRay .head .head { color: #f4f; }
@@ -0,0 +1,106 @@
1
+ require 'test_helper'
2
+
3
+ class RackCoderayTest < Test::Unit::TestCase
4
+
5
+ def get_response(path, body, markup_trigger = "//pre[@lang]", options = {})
6
+ app = Rack::Builder.new do
7
+ use Rack::Coderay, markup_trigger, options
8
+ run lambda { |env| [200, {'Content-Type' => 'text/html'}, [body] ] }
9
+ end
10
+ Rack::MockRequest.new(app).get(path)
11
+ end
12
+
13
+ context "Rack::Coderay" do
14
+ context "with default options" do
15
+ setup do
16
+ @response = get_response('/', %Q{
17
+ <pre lang="ruby">
18
+ class Foo
19
+ def bar
20
+ end
21
+ end
22
+ </pre>})
23
+ end
24
+ should "replace markup with CodeRay formatting" do
25
+ assert @response.body.include?(%Q{<div class="CodeRay">})
26
+ end
27
+ end
28
+
29
+ context "with markup trigger set to a non-matching tag" do
30
+ setup do
31
+ @response = get_response('/', %Q{
32
+ <pre lang="ruby">
33
+ class Foo
34
+ def bar
35
+ end
36
+ end
37
+ </pre>}, '//div[@lang]')
38
+ end
39
+ should "not replace markup with CodeRay formatting" do
40
+ assert @response.body.include?(%Q{<pre lang="ruby">})
41
+ end
42
+ end
43
+
44
+ context "with markup trigger set to //div[@lang]" do
45
+ setup do
46
+ @response = get_response('/', %Q{
47
+ <div lang="ruby">
48
+ class Foo
49
+ def bar
50
+ end
51
+ end
52
+ </div>}, '//div[@lang]')
53
+ end
54
+ should "replace markup with CodeRay formatting" do
55
+ assert @response.body.include?(%Q{<div class="CodeRay">})
56
+ end
57
+ end
58
+
59
+ context "with :css property set to :style" do
60
+ setup do
61
+ @response = get_response('/', %Q{
62
+ <pre lang="ruby">
63
+ class Foo
64
+ def bar
65
+ end
66
+ end
67
+ </pre>}, "//pre[@lang]", :css => :style)
68
+ end
69
+ should "replace markup with CodeRay formatting and use embedded styles" do
70
+ assert @response.body.include?(%Q{<span style="color:#080;font-weight:bold">})
71
+ end
72
+ end
73
+
74
+ context "with different order of attributes in markup trigger" do
75
+ setup do
76
+ @response = get_response('/', %Q{
77
+ <pre class="blah" lang="json">
78
+ { "just": "an", "example": 42 }
79
+ </pre>})
80
+ end
81
+ should "replace markup with CodeRay formatting" do
82
+ assert @response.body.include?(%Q{<div class="CodeRay">})
83
+ end
84
+ end
85
+
86
+ context "with lang set to json" do
87
+ setup do
88
+ @response = get_response('/', %Q{
89
+ <pre lang="json">
90
+ { "just": "an", "example": 42 }
91
+ </pre>})
92
+ end
93
+ should "replace markup with CodeRay formatting" do
94
+ assert @response.body.include?(%Q{<div class="CodeRay">})
95
+ end
96
+ end
97
+
98
+ context "when markup trigger is missing 'lang' attribute" do
99
+ should "raise a RuntimeError exception " do
100
+ assert_raise(RuntimeError) {
101
+ @response = get_response('/', 'blah', '//pre')
102
+ }
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,10 @@
1
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+ require 'rack/coderay'
7
+ require 'rack/mock'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webficient-rack-coderay
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Phil Misiowiec
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-28 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: coderay
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hpricot
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: This Rack middleware component uses the CodeRay gem to automatically format code syntax by detecting a specific container in the final rendered markup.
36
+ email: phil@webficient.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - lib/rack/coderay.rb
45
+ - lib/rack/coderay/parser.rb
46
+ - resources/coderay.css
47
+ - README.rdoc
48
+ has_rdoc: false
49
+ homepage: http://github.com/webficient/rack-coderay
50
+ licenses:
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --charset=UTF-8
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project:
71
+ rubygems_version: 1.3.5
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Rack middleware that automatically formats code syntax using CodeRay gem
75
+ test_files:
76
+ - test/rack_coderay_test.rb
77
+ - test/test_helper.rb