rack-tidy 0.0.1

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.
@@ -0,0 +1,87 @@
1
+ = Tidy Markup Cleaner for Rack
2
+
3
+ Rack::Tidy cleans text/html markup by automatically
4
+ indenting and reformatting content. Best results are achieved
5
+ with valid markup, when you simply want to use this component
6
+ to produce clean (X)HTML rendered by templating systems such as ERb.
7
+
8
+ Rack::Tidy relies on the power of the Tidy gem and defaults to settings
9
+ based on convention. However, you can override these through configuration.
10
+
11
+ For more information about the Rack specification, check out
12
+
13
+ http://rack.rubyforge.org/
14
+
15
+ == Installation
16
+
17
+ Prerequisites:
18
+
19
+ -Rack gem (sudo gem install rack)
20
+ -Tidy gem (sudo gem install tidy)
21
+
22
+ From Gem:
23
+
24
+ $ sudo gem install webficient-rack-tidy
25
+
26
+ With a local working copy:
27
+
28
+ $ git clone git://github.com/webficient/rack-tidy.git
29
+ $ rake build && sudo rake install
30
+
31
+ == Usage
32
+
33
+ Basic Usage
34
+ -----------
35
+
36
+ Rack::Tidy is implemented as a piece of Rack middleware and can be used with
37
+ any Rack-based application. If your application includes a rackup (`.ru`) file
38
+ or uses Rack::Builder to construct the application pipeline, simply require
39
+ and use as follows:
40
+
41
+ require 'rack/tidy'
42
+
43
+ use Rack::Tidy
44
+ run app
45
+
46
+ Using with Rails
47
+ ----------------
48
+
49
+ Add this to your `config/environment.rb`:
50
+
51
+ # above Rails::Initializer block
52
+ require 'rack/tidy'
53
+
54
+ # inside Rails::Initializer block
55
+ config.middleware.use Rack::Tidy
56
+
57
+ You should now see `Rack::Cache` listed in the middleware pipeline:
58
+
59
+ rake middleware
60
+
61
+ Configuration Options
62
+ ---------------------
63
+
64
+ The Tidy gem requires setting an internal path variable that points to the Tidy library,
65
+ which will differ per platform. Rack::Tidy defaults to '/usr/lib/libtidy.A.dylib'
66
+ which is the default location for the Tidy gem on Mac Leopard. To override the constant,
67
+ simply define it in your application's configuration file:
68
+
69
+ TIDY_LIB = '/usr/lib/tidylib.so'
70
+
71
+ Need Rack::Tidy to ignore certain paths? In your config, pass in an optional array of paths:
72
+
73
+ # Rails example
74
+ config.middleware.use Rack::Tidy,
75
+ :ignore_paths => ['/admin', '/cms']
76
+
77
+ Rack::Tidy relies on convention with regard to Tidy's configuration (see Rack::Tidy::Cleaner for details). If you want to override/set attributes supported by the Tidy gem, declare them in your configuration as an optional hash:
78
+
79
+ # Rails example
80
+ config.middleware.use Rack::Tidy,
81
+ 'indent-spaces' => 4
82
+
83
+ See http://tidy.sourceforge.net/docs/quickref.html for Tidy gem config options
84
+
85
+ == Copyright
86
+
87
+ Copyright (c) 2009 Phil Misiowiec, Webficient LLC. See MIT-LICENSE for details.
@@ -0,0 +1,47 @@
1
+ require 'rack'
2
+
3
+ # = Tidy Markup Cleaner for Rack
4
+ #
5
+ # Rack::Tidy cleans text/html markup by automatically
6
+ # indenting and reformatting content. Best results are achieved
7
+ # with valid markup, when you simply want to use this component
8
+ # to produce clean (X)HTML rendered by templating systems such as ERb.
9
+ #
10
+ # Rack::Tidy relies on the power of the Tidy gem and defaults to settings
11
+ # based on convention. However, you can override these through configuration.
12
+ #
13
+ # === Usage
14
+ #
15
+ # Within a rackup file (or with Rack::Builder):
16
+ # require 'rack/tidy'
17
+ # use Rack::Tidy,
18
+ # :ignore_paths => ['/admin', '/cms'],
19
+ # 'indent-spaces' => 4
20
+ # run app
21
+ #
22
+ # Rails example:
23
+ # # above Rails::Initializer block
24
+ # require 'rack/tidy'
25
+ #
26
+ # # inside Rails::Initializer block
27
+ # config.middleware.use Rack::Tidy,
28
+ # :ignore_paths => ['/admin', '/cms'],
29
+ # 'indent-spaces' => 4
30
+ module Rack::Tidy
31
+ autoload :Cleaner, 'rack/tidy/cleaner'
32
+
33
+ # Specify path of Tidy library, e.g.
34
+ # "/usr/lib/libtidy.A.dylib" (Mac; also the default if not set)
35
+ # "/usr/lib/tidylib.so" (Ubuntu)
36
+ # "/usr/lib/libtidy-0.99.so.0" (Fedora/CentOS)
37
+ TIDY_LIB = defined?(::TIDY_LIB) ? ::TIDY_LIB : '/usr/lib/libtidy.A.dylib'
38
+
39
+ # Create a new Rack::Tidy middleware component that cleans text/html markup
40
+ # using the Tidy gem. The +options+ Hash can be used to specify which paths
41
+ # should be ignored during processing as well as Tidy gem configuration values.
42
+ # See Cleaner for defaults and http://tidy.sourceforge.net/docs/quickref.html
43
+ # for more options
44
+ def self.new(backend, options = {})
45
+ Cleaner.new(backend, options)
46
+ end
47
+ end
@@ -0,0 +1,63 @@
1
+ require 'tidy'
2
+
3
+ module Rack::Tidy
4
+ # This class is the interface between Rack and the Tidy gem
5
+ class Cleaner
6
+
7
+ # Defaults for the Tidy gem config
8
+ DEFAULT_TIDY_OPTS = {
9
+ 'char-encoding' => 'utf8',
10
+ 'indent' => true,
11
+ 'indent-spaces' => 2,
12
+ 'tidy-mark' => false,
13
+ 'wrap' => 0 }
14
+
15
+ # Tidy gem options, see http://tidy.sourceforge.net/docs/quickref.html
16
+ attr_accessor :tidy_options
17
+
18
+ # Paths to be ignored during Rack::Tidy processing
19
+ attr_accessor :ignore_paths
20
+
21
+ def initialize(app, options = {})
22
+ ::Tidy.path = TIDY_LIB
23
+ @app = app
24
+ self.ignore_paths = options[:ignore_paths] || []
25
+ self.tidy_options = DEFAULT_TIDY_OPTS.merge(options)
26
+ end
27
+
28
+ # method required by Rack interface
29
+ def call(env)
30
+ call! env
31
+ end
32
+
33
+ # thread safe version using shallow copy of env
34
+ def call!(env)
35
+ @env = env.dup
36
+ status, @headers, response = @app.call(@env)
37
+ if should_clean?
38
+ @headers.delete('Content-Length')
39
+ response = Rack::Response.new(
40
+ tidy_markup(response.respond_to?(:body) ? response.body : response),
41
+ status,
42
+ @headers
43
+ )
44
+ response.finish
45
+ response.to_a
46
+ else
47
+ [status, @headers, response]
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def should_clean? #:nodoc:
54
+ @headers["Content-Type"] &&
55
+ @headers["Content-Type"].include?("text/html") &&
56
+ self.ignore_paths.none? { |p| @env["PATH_INFO"].start_with?(p) }
57
+ end
58
+
59
+ def tidy_markup(content) #:nodoc:
60
+ ::Tidy.open(self.tidy_options) { |tidy| tidy.clean(content) }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,97 @@
1
+ module RackTidySampleData
2
+
3
+ DIRTY_HTML = <<-dirty
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9
+ <title>True Blood - Wikipedia, the free encyclopedia</title>
10
+ <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
11
+ </head>
12
+ <body>
13
+ <p><i><b>True Blood</b></i> is an <a href="/wiki/Television_in_the_United_States" title="Television in the United States">American</a> <a href="/wiki/Television_drama_series" title="Television drama series" class="mw-redirect">television drama series</a> created and produced by <a href="/wiki/Alan_Ball_(screenwriter)" title="Alan Ball (screenwriter)">Alan Ball</a>. It is based on the <i><a href="/wiki/The_Southern_Vampire_Mysteries" title="The Southern Vampire Mysteries">The Southern Vampire Mysteries</a></i> series of novels by <a href="/wiki/Charlaine_Harris" title="Charlaine Harris">Charlaine Harris</a>. The show is broadcast on the premium cable network <a href="/wiki/HBO" title="HBO">HBO</a> in the United States. It is produced by HBO in association with Ball's production company, Your Face Goes Here Entertainment. It premiered on September 7, 2008.</p>
14
+ <h1>Episode Guide</h1>
15
+ <ul>
16
+ <li><a href="/wiki/True_Blood_(season_1)">Season One</a></li>
17
+ <li><a href="/wiki/True_Blood_(season_2)">Season Two</a></li>
18
+ </ul>
19
+ </body>
20
+ </html>
21
+ dirty
22
+
23
+ CLEAN_HTML = <<-clean
24
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
25
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
26
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
27
+ <head>
28
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
29
+ <title>
30
+ True Blood - Wikipedia, the free encyclopedia
31
+ </title>
32
+ <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
33
+ </head>
34
+ <body>
35
+ <p>
36
+ <i><b>True Blood</b></i> is an <a href="/wiki/Television_in_the_United_States" title="Television in the United States">American</a> <a href="/wiki/Television_drama_series" title="Television drama series" class="mw-redirect">television drama series</a> created and produced by <a href="/wiki/Alan_Ball_(screenwriter)" title="Alan Ball (screenwriter)">Alan Ball</a>. It is based on the <i><a href="/wiki/The_Southern_Vampire_Mysteries" title="The Southern Vampire Mysteries">The Southern Vampire Mysteries</a></i> series of novels by <a href="/wiki/Charlaine_Harris" title="Charlaine Harris">Charlaine Harris</a>. The show is broadcast on the premium cable network <a href="/wiki/HBO" title="HBO">HBO</a> in the United States. It is produced by HBO in association with Ball's production company, Your Face Goes Here Entertainment. It premiered on September 7, 2008.
37
+ </p>
38
+ <h1>
39
+ Episode Guide
40
+ </h1>
41
+ <ul>
42
+ <li>
43
+ <a href="/wiki/True_Blood_(season_1)">Season One</a>
44
+ </li>
45
+ <li>
46
+ <a href="/wiki/True_Blood_(season_2)">Season Two</a>
47
+ </li>
48
+ </ul>
49
+ </body>
50
+ </html>
51
+ clean
52
+
53
+ CLEAN_HTML_WITH_4_SPACE_INDENTS = <<-clean_with_4
54
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
55
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
56
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
57
+ <head>
58
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
59
+ <title>
60
+ True Blood - Wikipedia, the free encyclopedia
61
+ </title>
62
+ <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
63
+ </head>
64
+ <body>
65
+ <p>
66
+ <i><b>True Blood</b></i> is an <a href="/wiki/Television_in_the_United_States" title="Television in the United States">American</a> <a href="/wiki/Television_drama_series" title="Television drama series" class="mw-redirect">television drama series</a> created and produced by <a href="/wiki/Alan_Ball_(screenwriter)" title="Alan Ball (screenwriter)">Alan Ball</a>. It is based on the <i><a href="/wiki/The_Southern_Vampire_Mysteries" title="The Southern Vampire Mysteries">The Southern Vampire Mysteries</a></i> series of novels by <a href="/wiki/Charlaine_Harris" title="Charlaine Harris">Charlaine Harris</a>. The show is broadcast on the premium cable network <a href="/wiki/HBO" title="HBO">HBO</a> in the United States. It is produced by HBO in association with Ball's production company, Your Face Goes Here Entertainment. It premiered on September 7, 2008.
67
+ </p>
68
+ <h1>
69
+ Episode Guide
70
+ </h1>
71
+ <ul>
72
+ <li>
73
+ <a href="/wiki/True_Blood_(season_1)">Season One</a>
74
+ </li>
75
+ <li>
76
+ <a href="/wiki/True_Blood_(season_2)">Season Two</a>
77
+ </li>
78
+ </ul>
79
+ </body>
80
+ </html>
81
+ clean_with_4
82
+
83
+ CSS = <<-css
84
+ body {
85
+ font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif;
86
+ font-size: 1em;
87
+ margin: 0 auto;
88
+ }
89
+ css
90
+
91
+ JS = <<-js
92
+ function(foo) {
93
+ alert('bar')
94
+ }
95
+ js
96
+
97
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+ require 'rack_tidy_sample_data'
3
+
4
+ class RackTidyTest < Test::Unit::TestCase
5
+ include RackTidySampleData
6
+
7
+ def get_response(path, body, content_type = 'text/html', options = {})
8
+ app = Rack::Builder.new do
9
+ use Rack::Tidy, options
10
+ run lambda { |env| [200, {'Content-Type' => content_type}, [body] ] }
11
+ end
12
+ Rack::MockRequest.new(app).get(path)
13
+ end
14
+
15
+ context "Rack::Tidy" do
16
+ context "with content type equal to 'text/html'" do
17
+ setup do
18
+ @response = get_response('/', DIRTY_HTML)
19
+ end
20
+ should "clean response body" do
21
+ assert_equal CLEAN_HTML, @response.body
22
+ end
23
+
24
+ context "with ignore paths containing one item that matches current path" do
25
+ setup do
26
+ @response = get_response('/cms', DIRTY_HTML, 'text/html', :ignore_paths => '/cms')
27
+ end
28
+ should "not clean response body" do
29
+ assert_equal DIRTY_HTML, @response.body
30
+ end
31
+ end
32
+
33
+ context "with ignore paths containing array of items with one matching current path" do
34
+ setup do
35
+ @response = get_response('/cms',
36
+ DIRTY_HTML,
37
+ 'text/html',
38
+ :ignore_paths => ['/admin', '/cms'])
39
+ end
40
+ should "not clean response body" do
41
+ assert_equal DIRTY_HTML, @response.body
42
+ end
43
+ end
44
+
45
+ context "with ignore paths containing array of items that don't match current path" do
46
+ setup do
47
+ @response = get_response('/',
48
+ DIRTY_HTML,
49
+ 'text/html',
50
+ :ignore_paths => ['/admin', '/cms'])
51
+ end
52
+ should "clean response body" do
53
+ assert_equal CLEAN_HTML, @response.body
54
+ end
55
+ end
56
+
57
+ context "with 'indent-spaces' set to 4" do
58
+ setup do
59
+ @response = get_response('/',
60
+ DIRTY_HTML,
61
+ 'text/html',
62
+ 'indent-spaces' => 4)
63
+ end
64
+
65
+ should "clean response body, indenting with 4 spaces" do
66
+ assert_equal CLEAN_HTML_WITH_4_SPACE_INDENTS, @response.body
67
+ end
68
+ end
69
+ end
70
+
71
+ context "with content type equal to 'text/css'" do
72
+ setup do
73
+ @response = get_response('/', CSS, 'text/css')
74
+ end
75
+ should "not clean response body" do
76
+ assert_equal CSS, @response.body
77
+ end
78
+ end
79
+
80
+ context "with content type equal to 'application/javascript'" do
81
+ setup do
82
+ @response = get_response('/', JS, 'application/javascript')
83
+ end
84
+ should "not clean response body" do
85
+ assert_equal JS, @response.body
86
+ end
87
+ end
88
+
89
+ context "with ignore path set and multiple requests" do
90
+ setup do
91
+ app = Rack::Builder.new do
92
+ use Rack::Tidy, :ignore_paths => '/cms'
93
+ run lambda { |env| [200, {'Content-Type' => 'text/html'}, [DIRTY_HTML] ] }
94
+ end
95
+ Rack::MockRequest.new(app).get('/')
96
+ @response = Rack::MockRequest.new(app).get('/cms')
97
+ end
98
+ should "not clean response body" do
99
+ assert_equal DIRTY_HTML, @response.body
100
+ end
101
+ end
102
+ end
103
+ 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/tidy'
7
+ require 'rack/mock'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-tidy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Phil Misiowiec
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-19 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
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: tidy
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: Rack middleware for automatically cleaning markup using Tidy
36
+ email: phil@webficient.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - lib/rack/tidy.rb
45
+ - lib/rack/tidy/cleaner.rb
46
+ - README.rdoc
47
+ has_rdoc: true
48
+ homepage: http://github.com/webficient/rack-tidy
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.1
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: Rack middleware for automatically cleaning markup using Tidy
73
+ test_files:
74
+ - test/rack_tidy_sample_data.rb
75
+ - test/rack_tidy_test.rb
76
+ - test/test_helper.rb