sundawg_premailer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Premailer styles - should not import
3
+ *
4
+ * Copyright (c) 2009 Dialect Communications Group (dialect.ca)
5
+ *
6
+ * $Package: Premailer $
7
+ * $Date: 2009-02-09 17:15:56 -0800 (Mon, 09 Feb 2009) $WCDATE$ $
8
+ * $Rev: 95 $WCREV$ $
9
+ */
10
+
11
+ body {
12
+ background: none red !important;
13
+ }
@@ -0,0 +1,102 @@
1
+ /*
2
+ * Premailer styles
3
+ *
4
+ * Copyright (c) 2009 Dialect Communications Group (dialect.ca)
5
+ *
6
+ * $Package: Premailer $
7
+ * $Date: 2009-02-09 17:15:56 -0800 (Mon, 09 Feb 2009) $WCDATE$ $
8
+ * $Rev: 95 $WCREV$ $
9
+ */
10
+
11
+ @import "noimport.css" print;
12
+
13
+
14
+ /*** structure and table cells ***/
15
+ body{font:13px/1.231 "Arial",sans-serif;color: #fff;background-color: #9EBF00;}
16
+
17
+ #wrapper { width: 100%; margin: 2em 0; background-color: #9EBF00; color: #fff; }
18
+
19
+ .container { margin: 0 auto; line-height: 130%; color: #4d4d4d; text-align: left; }
20
+
21
+ .frame { background-color: #b6d93f; font-size: 1px; line-height: 1px; }
22
+
23
+ .hairline { background-color: #9ebf00; font-size: 1px; line-height: 1px; }
24
+
25
+ .masthead, .gutter { color: #999; background-color: #fff; }
26
+
27
+ .content { line-height: 158%; color: #999; background-color: #fff; }
28
+
29
+ #webversion, #footer { margin: 0 auto; text-align: center; font-size: 85%; }
30
+
31
+
32
+ /*** general styles ***/
33
+ h1, h1 a, h2, h2 a { color: #9ebf00; }
34
+
35
+ h1 span { padding: 0 .5em; background: #fff; }
36
+
37
+ h1 {
38
+ margin: 32px 0 19px;
39
+ font: bold 85% "Verdana", sans-serif;
40
+ text-transform: uppercase;
41
+ text-align: center;
42
+ letter-spacing: .1em;
43
+ background: transparent url("dots_h.gif") repeat-x 0 55%;
44
+ }
45
+
46
+ h2 { margin: 0 0 .4em; font: normal 205%/109% "Arial", sans-serif; }
47
+
48
+ h3, h3 a { color: #808080; }
49
+
50
+ h3 { margin: 0 0 .1em; font: normal 165%/109% "Arial", sans-serif; }
51
+
52
+ table{ border-collapse:collapse;border-spacing:0; border: 0; }
53
+
54
+ caption,th,td {text-align:left;font-weight:normal; margin: 0; padding: 0; }
55
+
56
+ pre,code,kbd,samp,tt{font-family:monospace;line-height:100%;}
57
+
58
+ th, td { vertical-align: top; }
59
+
60
+ a { text-decoration: none; }
61
+
62
+ blockquote { margin: 0; padding: 5px 30px; text-align: center; }
63
+
64
+ blockquote, blockquote p { font: italic 16px/145% "Georgia", serif; }
65
+
66
+ p, blockquote { color: #999; }
67
+
68
+ p { margin: 0 0 1em; font: normal 100%/158% "Arial", sans-serif; vertical-align: top; }
69
+
70
+
71
+ .hide { text-align: center; color: red; font-size: 150%; }
72
+
73
+ /*** specific elements ***/
74
+ .content p a, .content li a { color: #8AAD09; text-decoration: underline; }
75
+
76
+ .content p.dt { margin-bottom: .8em; font: italic 95%/135% "Arial", sans-serif; }
77
+
78
+ img.right { float: right; margin: 0 0 30px 20px; }
79
+
80
+ .contact { text-align: center; background: #9EC03B url("contact_bg.png") repeat 0 0; }
81
+
82
+ .contact, .contact p, .contact a { color: #fff; text-decoration: none; }
83
+
84
+ .contact p { margin-bottom: 0; line-height: 140%; }
85
+
86
+ .contact a:hover { text-decoration: underline; }
87
+
88
+ #webversion, #webversion a {
89
+ font: bold 12px/28px "Trebuchet", "Trebuchet MS", serif;
90
+ color: #fff;
91
+ background: #9ebf00;
92
+ }
93
+
94
+ #credit { padding-bottom: 20px; }
95
+
96
+ #credit, #credit a {
97
+ color: #fff;
98
+ font: normal 10px/13px "Verdana", sans-serif;
99
+ text-align: center;
100
+ }
101
+
102
+ #contact_info { padding: 5px; }
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/premailer'
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class TestHtmlToPlainText < Test::Unit::TestCase
4
+ include HtmlToPlainText
5
+
6
+ def test_accents
7
+ assert_plaintext 'cédille garçon à ñ', 'c&eacute;dille gar&#231;on &agrave; &ntilde;'
8
+ end
9
+
10
+ def test_stripping_whitespace
11
+ assert_plaintext "text\ntext", " \ttext\ntext\n"
12
+ assert_plaintext "a\na", " \na \n a \t"
13
+ assert_plaintext "a\n\na", " \na \n\t \n \n a \t"
14
+ assert_plaintext "test text", "test text&nbsp;"
15
+ end
16
+
17
+ def test_line_breaks
18
+ assert_plaintext "Test text\nTest text", "Test text\r\nTest text"
19
+ assert_plaintext "Test text\nTest text", "Test text\rTest text"
20
+ end
21
+
22
+ def test_lists
23
+ assert_plaintext "* item 1\n* item 2", "<li class='123'>item 1</li> <li>item 2</li>\n"
24
+ assert_plaintext "* item 1\n* item 2\n* item 3", "<li>item 1</li> \t\n <li>item 2</li> <li> item 3</li>\n"
25
+ end
26
+
27
+ def test_stripping_html
28
+ assert_plaintext 'test text', "<p class=\"123'45 , att\" att=tester>test <span class='te\"st'>text</span>\n"
29
+ end
30
+
31
+ def test_paragraphs_and_breaks
32
+ assert_plaintext "Test text\n\nTest text", "<p>Test text</p><p>Test text</p>"
33
+ assert_plaintext "Test text\n\nTest text", "\n<p>Test text</p>\n\n\n\t<p>Test text</p>\n"
34
+ assert_plaintext "Test text\nTest text", "\n<p>Test text<br/>Test text</p>\n"
35
+ assert_plaintext "Test text\nTest text", "\n<p>Test text<br> \tTest text<br></p>\n"
36
+ assert_plaintext "Test text\n\nTest text", "Test text<br><BR />Test text"
37
+ end
38
+
39
+ def test_headings
40
+ assert_plaintext "****\nTest\n****", "<h1>Test</h1>"
41
+ assert_plaintext "----\nTest\n----", "<h2>Test</h2>"
42
+ assert_plaintext "Test\n----", "<h3> <span class='a'>Test </span></h3>"
43
+ end
44
+
45
+ def test_links
46
+ # basic
47
+ assert_plaintext 'Link ( http://example.com/ )', '<a href="http://example.com/">Link</a>'
48
+
49
+ # nested html
50
+ assert_plaintext 'Link ( http://example.com/ )', '<a href="http://example.com/"><span class="a">Link</span></a>'
51
+
52
+ # complex link
53
+ assert_plaintext 'Link ( http://example.com:80/~user?aaa=bb&c=d,e,f#foo )', '<a href="http://example.com:80/~user?aaa=bb&amp;c=d,e,f#foo">Link</a>'
54
+
55
+ # attributes
56
+ assert_plaintext 'Link ( http://example.com/ )', '<a title=\'title\' href="http://example.com/">Link</a>'
57
+
58
+ # spacing
59
+ assert_plaintext 'Link ( http://example.com/ )', '<a href=" http://example.com/ "> Link </a>'
60
+
61
+ # merge links
62
+ assert_plaintext 'Link ( %%LINK%% )', '<a href="%%LINK%%">Link</a>'
63
+ assert_plaintext 'Link ( [LINK] )', '<a href="[LINK]">Link</a>'
64
+ assert_plaintext 'Link ( {LINK} )', '<a href="{LINK}">Link</a>'
65
+ end
66
+
67
+ def assert_plaintext(out, raw, msg = nil)
68
+ assert_equal out, convert_to_text(raw), msg
69
+ end
70
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class TestLinkResolver < Test::Unit::TestCase
4
+ def test_resolving_urls_from_string
5
+ ['test.html', '/test.html', './test.html',
6
+ 'test/../test.html', 'test/../test/../test.html'].each do |q|
7
+ assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, 'http://example.com/'), q
8
+ end
9
+
10
+ assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', 'https://example.net:80/~basedir/')
11
+ end
12
+
13
+ def test_resolving_urls_from_uri
14
+ base_uri = URI.parse('http://example.com/')
15
+ ['test.html', '/test.html', './test.html',
16
+ 'test/../test.html', 'test/../test/../test.html'].each do |q|
17
+ assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, base_uri), q
18
+ end
19
+
20
+ base_uri = URI.parse('https://example.net:80/~basedir/')
21
+ assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', base_uri)
22
+
23
+ # base URI with a query string
24
+ base_uri = URI.parse('http://example.com/dir/index.cfm?newsletterID=16')
25
+ assert_equal 'http://example.com/dir/index.cfm?link=15', Premailer.resolve_link('?link=15', base_uri)
26
+
27
+ # URI preceded by a space
28
+ base_uri = URI.parse('http://example.com/')
29
+ assert_equal 'http://example.com/path', Premailer.resolve_link(' path', base_uri)
30
+ end
31
+
32
+ def test_resolving_urls_in_doc
33
+ base_file = File.dirname(__FILE__) + '/files/base.html'
34
+ base_url = 'https://my.example.com:8080/test-path.html'
35
+ premailer = Premailer.new(base_file, :base_url => base_url)
36
+ premailer.to_inline_css
37
+ pdoc = premailer.processed_doc
38
+ doc = premailer.doc
39
+
40
+ # unchanged links
41
+ ['#l02', '#l03', '#l05', '#l06', '#l07', '#l08',
42
+ '#l09', '#l10', '#l11', '#l12', '#l13'].each do |link_id|
43
+ assert_equal doc.at(link_id).attributes['href'], pdoc.at(link_id).attributes['href'], link_id
44
+ end
45
+
46
+ assert_equal 'https://my.example.com:8080/', pdoc.at('#l01').attributes['href']
47
+ assert_equal 'https://my.example.com:8080/images/', pdoc.at('#l04').attributes['href']
48
+ end
49
+ end
@@ -0,0 +1,119 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'webrick'
3
+
4
+ class TestPremailer < Test::Unit::TestCase
5
+ include WEBrick
6
+
7
+ def test_accents
8
+ local_setup
9
+
10
+ assert_equal 'cédille c&eacute; garçon gar&#231;on à &agrave;', @doc.at('#accents').inner_html
11
+ end
12
+
13
+ def test_escaping_strings
14
+ local_setup
15
+
16
+ str = %q{url("/images/test.png");}
17
+ assert_equal("url(\'/images/test.png\');", Premailer.escape_string(str))
18
+ end
19
+
20
+ def test_importing_local_css
21
+ flunk
22
+ local_setup
23
+
24
+ # noimport.css (print stylesheet) sets body { background } to red
25
+ assert_no_match /red/, @doc.at('body').attributes['style']
26
+
27
+ # import.css sets .hide to { display: none }
28
+ assert_match /display: none/, @doc.at('#hide01').attributes['style']
29
+ end
30
+
31
+ def test_importing_remote_css
32
+ flunk
33
+ remote_setup
34
+
35
+ # noimport.css (print stylesheet) sets body { background } to red
36
+ assert_no_match /red/, @doc.at('body').attributes['style']
37
+
38
+ # import.css sets .hide to { display: none }
39
+ assert_match /display: none/, @doc.at('#hide01').attributes['style']
40
+ end
41
+
42
+
43
+ def test_related_attributes
44
+ local_setup
45
+
46
+ # h1 { text-align: center; }
47
+ assert_equal 'center', @doc.at('h1')['align']
48
+
49
+ # td { vertical-align: top; }
50
+ assert_equal 'top', @doc.at('td')['valign']
51
+
52
+ # p { vertical-align: top; } -- not allowed
53
+ assert_nil @doc.at('p')['valign']
54
+
55
+ # no align attr is specified for <p> elements, so it should not appear
56
+ assert_nil @doc.at('p.unaligned')['align']
57
+
58
+ # .contact { background: #9EC03B url("contact_bg.png") repeat 0 0; }
59
+ assert_equal '#9EC03B', @doc.at('td.contact')['bgcolor']
60
+
61
+ # body { background-color: #9EBF00; }
62
+ assert_equal '#9EBF00', @doc.at('body')['bgcolor']
63
+ end
64
+
65
+ def test_merging_cellpadding
66
+ flunk
67
+ local_setup('cellpadding.html', {:prefer_cellpadding => true})
68
+ assert_equal '0', @doc.at('#t1')['cellpadding']
69
+ assert_match /padding\:/i, @doc.at('#t1 td')['style']
70
+
71
+ assert_equal '5', @doc.at('#t2')['cellpadding']
72
+ assert_no_match /padding\:/i, @doc.at('#t2 td')['style']
73
+
74
+ assert_nil @doc.at('#t3')['cellpadding']
75
+ assert_match /padding\:/i, @doc.at('#t3 td')['style']
76
+
77
+ assert_nil @doc.at('#t4')['cellpadding']
78
+ assert_match /padding\:/i, @doc.at('#t4a')['style']
79
+ assert_match /padding\:/i, @doc.at('#t4b')['style']
80
+ end
81
+
82
+ protected
83
+ def local_setup(f = 'base.html', opts = {})
84
+ base_file = File.dirname(__FILE__) + '/files/' + f
85
+ premailer = Premailer.new(base_file, opts)
86
+ premailer.to_inline_css
87
+ @doc = premailer.processed_doc
88
+ end
89
+
90
+ def remote_setup(opts = {})
91
+ # from http://nullref.se/blog/2006/5/17/testing-with-webrick
92
+ uri_base = 'http://localhost:12000'
93
+ www_root = File.dirname(__FILE__) + '/files/'
94
+
95
+ @server_thread = Thread.new do
96
+ s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => www_root, :Logger => Log.new(nil, BasicLog::ERROR), :AccessLog => [])
97
+ port = s.config[:Port]
98
+ begin
99
+ s.start
100
+ ensure
101
+ s.shutdown
102
+ end
103
+ end
104
+
105
+ sleep 1 # ensure the server has time to load
106
+
107
+ premailer = Premailer.new(uri_base + '/base.html', opts)
108
+ premailer.to_inline_css
109
+ @doc = premailer.processed_doc
110
+ end
111
+
112
+ def teardown
113
+ if @server_thread
114
+ @server_thread.kill
115
+ @server_thread.join(5)
116
+ @server_thread = nil
117
+ end
118
+ end
119
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sundawg_premailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Sun
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-09 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hpricot
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0.6"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: css_parser
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: text-reform
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.2.0
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: htmlentities
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 4.0.0
54
+ version:
55
+ description: Fork of premailer project to accomodate in memory HTML (http://premailer.dialect.ca/).
56
+ email: christopher.sun@gmail.com
57
+ executables:
58
+ - premailer
59
+ - trollop.rb
60
+ extensions: []
61
+
62
+ extra_rdoc_files:
63
+ - CHANGELOG.rdoc
64
+ - LICENSE.rdoc
65
+ - README.rdoc
66
+ - bin/premailer
67
+ - bin/trollop.rb
68
+ - lib/premailer.rb
69
+ - lib/premailer/html_to_plain_text.rb
70
+ - lib/premailer/premailer.rb
71
+ files:
72
+ - CHANGELOG.rdoc
73
+ - LICENSE.rdoc
74
+ - Manifest
75
+ - README.rdoc
76
+ - Rakefile
77
+ - bin/premailer
78
+ - bin/trollop.rb
79
+ - init.rb
80
+ - lib/premailer.rb
81
+ - lib/premailer/html_to_plain_text.rb
82
+ - lib/premailer/premailer.rb
83
+ - misc/client_support.yaml
84
+ - premailer.gemspec
85
+ - tests/files/base.html
86
+ - tests/files/contact_bg.png
87
+ - tests/files/dialect.png
88
+ - tests/files/dots_end.png
89
+ - tests/files/dots_h.gif
90
+ - tests/files/import.css
91
+ - tests/files/inc/2009-placeholder.png
92
+ - tests/files/noimport.css
93
+ - tests/files/styles.css
94
+ - tests/test_helper.rb
95
+ - tests/test_html_to_plain_text.rb
96
+ - tests/test_link_resolver.rb
97
+ - tests/test_premailer.rb
98
+ - sundawg_premailer.gemspec
99
+ has_rdoc: true
100
+ homepage: http://github.com/SunDawg/premailer
101
+ licenses: []
102
+
103
+ post_install_message:
104
+ rdoc_options:
105
+ - --line-numbers
106
+ - --inline-source
107
+ - --title
108
+ - Sundawg_premailer
109
+ - --main
110
+ - README.rdoc
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: "0"
118
+ version:
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: "1.2"
124
+ version:
125
+ requirements: []
126
+
127
+ rubyforge_project: sundawg_premailer
128
+ rubygems_version: 1.3.5
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: Fork of premailer project to accomodate in memory HTML (http://premailer.dialect.ca/).
132
+ test_files: []
133
+