premailer 1.10.2 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 74e7a6a6abc466e9c0e113d5231d4e4a85d84cb2
4
- data.tar.gz: 4c59b4febdbcc9f24bb02a1e97f4daac68417b35
2
+ SHA256:
3
+ metadata.gz: 6d3e8552d269ddef67b722b192f58c2afe242f6a824a07e4e7fd4e5bbc3f57f2
4
+ data.tar.gz: 6c6b611237ffe68b655654c75c21c7a8f17bc73ca9502e06891f26ab5b1bb583
5
5
  SHA512:
6
- metadata.gz: 20aa057a4fb25ab0bae43093b9ba32e1dc8c64f5e37bb9b9666f57c854b971516bf2a84e2e0402d85c1ccf698a89213b3461ebab5bdfed4bd7bc68a881ed1366
7
- data.tar.gz: 60ef76babcda83da01f605c2188e15bb611b0c89b1a1de66ab01212dd2567c283fcf2328fe538215883c12670483c3f107a4625a9cf4956faf489b8294164997
6
+ metadata.gz: 1c963172a6abcb9e71824c07e54a80ea89c58fda395349d68ea0567a5fa06cf160663bd1e8a169a81532f5ad3b7c97d8ed0ad2c09a4182c3d281982a878348da
7
+ data.tar.gz: 758dae24fbd064a1ee44fe4ab6f0537c191826474dc045a8af5354f28a17e4d20e8a56e93d2ea3ebab83ab4c9c9b2376aa0b53467ff50338773e78e815b8ccbe
data/README.md CHANGED
@@ -12,7 +12,7 @@ script is my solution.
12
12
  - Checks links in `href`, `src` and CSS `url('')`
13
13
  * CSS properties are checked against e-mail client capabilities
14
14
  - Based on the Email Standards Project's guides
15
- * A plain text version is created (optional)
15
+ * A [plain text version](https://premailer.github.io/premailer/HtmlToPlainText.html) is created (optional)
16
16
 
17
17
  ## Installation
18
18
 
@@ -80,6 +80,7 @@ Premailer looks for a few CSS attributes that make working with tables a bit eas
80
80
  | -premailer-height | Available on `table`, `tr`, `th` and `td` elements |
81
81
  | -premailer-cellpadding | Available on `table` elements |
82
82
  | -premailer-cellspacing | Available on `table` elements |
83
+ | -premailer-align | Available on `table` elements |
83
84
  | data-premailer="ignore" | Available on `link` and `style` elements. Premailer will ignore these elements entirely. |
84
85
 
85
86
  Each of these CSS declarations will be copied to appropriate element's attribute.
@@ -94,7 +94,7 @@ class Premailer
94
94
  el['style'] = merged.declarations_to_s
95
95
  end
96
96
 
97
- doc = write_unmergable_css_rules(doc, @unmergable_rules)
97
+ doc = write_unmergable_css_rules(doc, @unmergable_rules) unless @options[:drop_unmergeable_css_rules]
98
98
 
99
99
  if @options[:remove_classes] or @options[:remove_comments]
100
100
  doc.traverse do |el|
@@ -149,11 +149,17 @@ class Premailer
149
149
  def write_unmergable_css_rules(doc, unmergable_rules) # :nodoc:
150
150
  styles = unmergable_rules.to_s
151
151
  unless styles.empty?
152
- style_tag = doc.create_element "style", "#{styles}"
153
- head = doc.at_css('head')
154
- head ||= doc.root.first_element_child.add_previous_sibling(doc.create_element "head") if doc.root && doc.root.first_element_child
155
- head ||= doc.add_child(doc.create_element "head")
156
- head << style_tag
152
+ if @options[:html_fragment]
153
+ style_tag = ::Nokogiri::XML::Node.new("style", doc)
154
+ style_tag.content = styles
155
+ doc.add_child(style_tag)
156
+ else
157
+ style_tag = doc.create_element "style", "#{styles}"
158
+ head = doc.at_css('head')
159
+ head ||= doc.root.first_element_child.add_previous_sibling(doc.create_element "head") if doc.root && doc.root.first_element_child
160
+ head ||= doc.add_child(doc.create_element "head")
161
+ head << style_tag
162
+ end
157
163
  end
158
164
  doc
159
165
  end
@@ -216,12 +222,16 @@ class Premailer
216
222
  end
217
223
  # Default encoding is ASCII-8BIT (binary) per http://groups.google.com/group/nokogiri-talk/msg/0b81ef0dc180dc74
218
224
  # However, we really don't want to hardcode this. ASCII-8BIT should be the default, but not the only option.
219
- if thing.is_a?(String) and RUBY_VERSION =~ /1.9/
225
+ encoding = if thing.is_a?(String) and RUBY_VERSION =~ /1.9/
220
226
  thing = thing.force_encoding(@options[:input_encoding]).encode!
221
- doc = ::Nokogiri::HTML(thing, nil, @options[:input_encoding]) { |c| c.recover }
227
+ @options[:input_encoding]
228
+ else
229
+ @options[:input_encoding] || (RUBY_PLATFORM == 'java' ? nil : 'BINARY')
230
+ end
231
+ doc = if @options[:html_fragment]
232
+ ::Nokogiri::HTML.fragment(thing, encoding)
222
233
  else
223
- default_encoding = RUBY_PLATFORM == 'java' ? nil : 'BINARY'
224
- doc = ::Nokogiri::HTML(thing, nil, @options[:input_encoding] || default_encoding) { |c| c.recover }
234
+ ::Nokogiri::HTML(thing, nil, encoding) { |c| c.recover }
225
235
  end
226
236
 
227
237
  # Fix for removing any CDATA tags from both style and script tags inserted per
@@ -96,7 +96,7 @@ class Premailer
96
96
  el['style'] = merged.declarations_to_s
97
97
  end
98
98
 
99
- doc = write_unmergable_css_rules(doc, @unmergable_rules)
99
+ doc = write_unmergable_css_rules(doc, @unmergable_rules) unless @options[:drop_unmergeable_css_rules]
100
100
 
101
101
  if @options[:remove_classes] or @options[:remove_comments]
102
102
  doc.traverse do |el|
@@ -150,12 +150,19 @@ class Premailer
150
150
  # @return [::Nokogiri::XML] a document.
151
151
  def write_unmergable_css_rules(doc, unmergable_rules) # :nodoc:
152
152
  styles = unmergable_rules.to_s
153
- return doc if styles.empty?
154
- style_tag = doc.create_element "style", styles
155
- head = doc.at_css('head')
156
- head ||= doc.root.first_element_child.add_previous_sibling(doc.create_element "head") if doc.root && doc.root.first_element_child
157
- head ||= doc.add_child(doc.create_element "head")
158
- head << style_tag
153
+ unless styles.empty?
154
+ if @options[:html_fragment]
155
+ style_tag = ::Nokogiri::XML::Node.new("style", doc)
156
+ style_tag.content = styles
157
+ doc.add_child(style_tag)
158
+ else
159
+ style_tag = doc.create_element "style", styles
160
+ head = doc.at_css('head')
161
+ head ||= doc.root.first_element_child.add_previous_sibling(doc.create_element "head") if doc.root && doc.root.first_element_child
162
+ head ||= doc.add_child(doc.create_element "head")
163
+ head << style_tag
164
+ end
165
+ end
159
166
  doc
160
167
  end
161
168
 
@@ -217,12 +224,16 @@ class Premailer
217
224
  end
218
225
  # Default encoding is ASCII-8BIT (binary) per http://groups.google.com/group/nokogiri-talk/msg/0b81ef0dc180dc74
219
226
  # However, we really don't want to hardcode this. ASCII-8BIT should be the default, but not the only option.
220
- if thing.is_a?(String) and RUBY_VERSION =~ /1.9/
227
+ encoding = if thing.is_a?(String) and RUBY_VERSION =~ /1.9/
221
228
  thing = thing.force_encoding(@options[:input_encoding]).encode!
222
- doc = ::Nokogiri::HTML(thing, nil, @options[:input_encoding]) { |c| c.recover }
229
+ @options[:input_encoding]
230
+ else
231
+ @options[:input_encoding] || (RUBY_PLATFORM == 'java' ? nil : 'BINARY')
232
+ end
233
+ doc = if @options[:html_fragment]
234
+ ::Nokogiri::HTML.fragment(thing, encoding)
223
235
  else
224
- default_encoding = RUBY_PLATFORM == 'java' ? nil : 'BINARY'
225
- doc = ::Nokogiri::HTML(thing, nil, @options[:input_encoding] || default_encoding) { |c| c.recover }
236
+ ::Nokogiri::HTML(thing, nil, encoding) { |c| c.recover }
226
237
  end
227
238
 
228
239
  # Fix for removing any CDATA tags from both style and script tags inserted per
@@ -94,7 +94,7 @@ class Premailer
94
94
  el['style'] = merged.declarations_to_s
95
95
  end
96
96
 
97
- doc = write_unmergable_css_rules(doc, @unmergable_rules)
97
+ doc = write_unmergable_css_rules(doc, @unmergable_rules) unless @options[:drop_unmergeable_css_rules]
98
98
 
99
99
  if @options[:remove_classes] or @options[:remove_comments]
100
100
  doc.traverse do |el|
@@ -148,12 +148,19 @@ class Premailer
148
148
  # @return [::Nokogiri::XML] a document.
149
149
  def write_unmergable_css_rules(doc, unmergable_rules) # :nodoc:
150
150
  styles = unmergable_rules.to_s
151
- return doc if styles.empty?
152
- style_tag = doc.create_element "style", styles
153
- head = doc.at_css('head')
154
- head ||= doc.root.first_element_child.add_previous_sibling(doc.create_element "head") if doc.root && doc.root.first_element_child
155
- head ||= doc.add_child(doc.create_element "head")
156
- head << style_tag
151
+ unless styles.empty?
152
+ if @options[:html_fragment]
153
+ style_tag = ::Nokogiri::XML::Node.new("style", doc)
154
+ style_tag.content = styles
155
+ doc.add_child(style_tag)
156
+ else
157
+ style_tag = doc.create_element "style", styles
158
+ head = doc.at_css('head')
159
+ head ||= doc.root.first_element_child.add_previous_sibling(doc.create_element "head") if doc.root && doc.root.first_element_child
160
+ head ||= doc.add_child(doc.create_element "head")
161
+ head << style_tag
162
+ end
163
+ end
157
164
  doc
158
165
  end
159
166
 
@@ -217,10 +224,11 @@ class Premailer
217
224
  # However, we really don't want to hardcode this. ASCII-8BIT should be the default, but not the only option.
218
225
  if thing.is_a?(String) and RUBY_VERSION =~ /1.9/
219
226
  thing = thing.force_encoding(@options[:input_encoding]).encode!
220
- doc = ::Nokogiri::HTML5(thing)
227
+ end
228
+ doc = if @options[:html_fragment]
229
+ ::Nokogiri::HTML5.fragment(thing)
221
230
  else
222
- default_encoding = RUBY_PLATFORM == 'java' ? nil : 'BINARY'
223
- doc = ::Nokogiri::HTML5(thing)
231
+ ::Nokogiri::HTML5(thing)
224
232
  end
225
233
 
226
234
  # Fix for removing any CDATA tags from both style and script tags inserted per
@@ -5,6 +5,11 @@ require 'htmlentities'
5
5
  module HtmlToPlainText
6
6
 
7
7
  # Returns the text in UTF-8 format with all HTML tags removed
8
+ #
9
+ # HTML content can be omitted from the output by surrounding it in the following comments:
10
+ #
11
+ # <!-- start text/html -->
12
+ # <!-- end text/html -->
8
13
  #
9
14
  # TODO: add support for DL, OL
10
15
  def convert_to_text(html, line_length = 65, from_charset = 'UTF-8')
@@ -30,8 +35,22 @@ module HtmlToPlainText
30
35
  # <img alt=''>
31
36
  txt.gsub!(/<img.+?alt=\'([^\']*)\'[^>]*\>/i, '\1')
32
37
 
33
- # links
34
- txt.gsub!(/<a\s.*?href=["'](mailto:)?([^"']*)["'][^>]*>((.|\s)*?)<\/a>/i) do |s|
38
+ # remove script tags and content
39
+ txt.gsub!(/<script.*\/script>/m, '')
40
+
41
+ # links with double quotes
42
+ txt.gsub!(/<a\s[^\n]*?href=["'](mailto:)?([^"]*)["][^>]*>(.*?)<\/a>/im) do |s|
43
+ if $3.empty?
44
+ ''
45
+ elsif $3.strip.downcase == $2.strip.downcase
46
+ $3.strip
47
+ else
48
+ $3.strip + ' ( ' + $2.strip + ' )'
49
+ end
50
+ end
51
+
52
+ # links with single quotes
53
+ txt.gsub!(/<a\s[^\n]*?href=["'](mailto:)?([^']*)['][^>]*>(.*?)<\/a>/im) do |s|
35
54
  if $3.empty?
36
55
  ''
37
56
  elsif $3.strip.downcase == $2.strip.downcase
@@ -86,9 +105,7 @@ module HtmlToPlainText
86
105
  he = HTMLEntities.new
87
106
  txt = he.decode(txt)
88
107
 
89
- # no more than two consecutive spaces
90
- txt.gsub!(/ {2,}/, " ")
91
-
108
+ # word wrap
92
109
  txt = word_wrap(txt, line_length)
93
110
 
94
111
  # remove linefeeds (\r\n and \r -> \n)
@@ -151,14 +151,14 @@ class Premailer
151
151
  #
152
152
  # @param [Hash] options the options to handle html with.
153
153
  # @option options [Fixnum] :line_length Line length used by to_plain_text. Default is 65.
154
- # @option options [Fixnum] :warn_level What level of CSS compatibility warnings to show (see {Premailer::Warnings}).
154
+ # @option options [Fixnum] :warn_level What level of CSS compatibility warnings to show (see {Premailer::Warnings}, default is Warnings::SAFE).
155
155
  # @option options [String] :link_query_string A string to append to every <tt>a href=""</tt> link. Do not include the initial <tt>?</tt>.
156
156
  # @option options [String] :base_url Used to calculate absolute URLs for local files.
157
157
  # @option options [Array(String)] :css Manually specify CSS stylesheets.
158
- # @option options [Boolean] :css_to_attributes Copy related CSS attributes into HTML attributes (e.g. background-color to bgcolor)
158
+ # @option options [Boolean] :css_to_attributes Copy related CSS attributes into HTML attributes (e.g. background-color to bgcolor). Default is true.
159
159
  # @option options [Boolean] :preserve_style_attribute Preserve original style attribute
160
160
  # @option options [String] :css_string Pass CSS as a string
161
- # @option options [Boolean] :rgb_to_hex_attributes Convert RBG to Hex colors, default false
161
+ # @option options [Boolean] :rgb_to_hex_attributes Convert RBG to Hex colors. Default is false.
162
162
  # @option options [Boolean] :remove_ids Remove ID attributes whenever possible and convert IDs used as anchors to hashed to avoid collisions in webmail programs. Default is false.
163
163
  # @option options [Boolean] :remove_classes Remove class attributes. Default is false.
164
164
  # @option options [Boolean] :remove_comments Remove html comments. Default is false.
@@ -177,6 +177,8 @@ class Premailer
177
177
  # @option options [Symbol] :adapter Which HTML parser to use, <tt>:nokogiri</tt>, <tt>:nokogiri_fast</tt> or <tt>:nokogumbo</tt>. Default is <tt>:nokogiri</tt>.
178
178
  # @option options [String] :output_encoding Output encoding option for Nokogiri adapter. Should be set to "US-ASCII" to output HTML entities instead of Unicode characters.
179
179
  # @option options [Boolean] :create_shorthands Combine several properties into a shorthand one, e.g. font: style weight size. Default is true.
180
+ # @option options [Boolean] :html_fragment Handle HTML fragment without any HTML content wrappers. Default is false.
181
+ # @option options [Boolean] :drop_unmergeable_css_rules Do not include unmergeable css rules in a <tt><style><tt> tag. Default is false.
180
182
  def initialize(html, options = {})
181
183
  @options = {:warn_level => Warnings::SAFE,
182
184
  :line_length => 65,
@@ -206,7 +208,9 @@ class Premailer
206
208
  :escape_url_attributes => true,
207
209
  :unescaped_ampersand => false,
208
210
  :create_shorthands => true,
211
+ :html_fragment => false,
209
212
  :adapter => Adapter.use,
213
+ :drop_unmergeable_css_rules => false
210
214
  }.merge(options)
211
215
 
212
216
  @html_file = html
@@ -234,7 +238,7 @@ class Premailer
234
238
 
235
239
  @adapter_class = Adapter.find @options[:adapter]
236
240
 
237
- self.class.send(:include, @adapter_class)
241
+ self.extend(@adapter_class)
238
242
 
239
243
  @doc = load_html(@html_file)
240
244
 
@@ -400,7 +404,7 @@ public
400
404
 
401
405
  # Check for an XHTML doctype
402
406
  def is_xhtml?
403
- intro = @doc.to_html.strip.split("\n")[0..2].join(' ')
407
+ intro = @doc.to_xhtml.strip.split("\n")[0..2].join(' ')
404
408
  is_xhtml = !!(intro =~ /w3c\/\/[\s]*dtd[\s]+xhtml/i)
405
409
  $stderr.puts "Is XHTML? #{is_xhtml.inspect}\nChecked:\n#{intro}" if @options[:debug]
406
410
  is_xhtml
@@ -464,11 +468,6 @@ public
464
468
  media_types && media_types.any?{|mt| mt.to_s.count('()') >= 2 }
465
469
  end
466
470
 
467
- # @private
468
- def self.escape_string(str) # :nodoc:
469
- str.gsub(/"/ , "'")
470
- end
471
-
472
471
  # @private
473
472
  def self.resolve_link(path, base_path) # :nodoc:
474
473
  path.strip!
@@ -492,9 +491,7 @@ public
492
491
  #
493
492
  # IO objects return true, as do strings that look like URLs.
494
493
  def self.local_data?(data)
495
- return true if data.is_a?(IO) || data.is_a?(StringIO)
496
- return true if data =~ /\Afile:\/\//i
497
- return false if data =~ /\A(?:(https?|ftp):)\/\//i
494
+ return false if data.kind_of?(String) && data =~ /\A(?:(https?|ftp):)\/\//i
498
495
  true
499
496
  end
500
497
 
@@ -1,4 +1,4 @@
1
1
  class Premailer
2
2
  # Premailer version.
3
- VERSION = '1.10.2'.freeze
3
+ VERSION = '1.12.0'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: premailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.2
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Dunae
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-10 00:00:00.000000000 Z
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.4.10
19
+ version: 1.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.4.10
26
+ version: 1.6.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: htmlentities
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -92,28 +92,14 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '1.7'
95
+ version: 1.8.2
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '1.7'
103
- - !ruby/object:Gem::Dependency
104
- name: yard
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
102
+ version: 1.8.2
117
103
  - !ruby/object:Gem::Dependency
118
104
  name: redcarpet
119
105
  requirement: !ruby/object:Gem::Requirement
@@ -184,6 +170,20 @@ dependencies:
184
170
  - - ">="
185
171
  - !ruby/object:Gem::Version
186
172
  version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: bump
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
187
  description: Improve the rendering of HTML emails by making CSS inline, converting
188
188
  links and warning about unsupported code.
189
189
  email: akzhan.abdulin@gmail.com
@@ -218,15 +218,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
218
  requirements:
219
219
  - - ">="
220
220
  - !ruby/object:Gem::Version
221
- version: 2.1.0
221
+ version: 2.3.0
222
222
  required_rubygems_version: !ruby/object:Gem::Requirement
223
223
  requirements:
224
224
  - - ">="
225
225
  - !ruby/object:Gem::Version
226
226
  version: '0'
227
227
  requirements: []
228
- rubyforge_project:
229
- rubygems_version: 2.6.8
228
+ rubygems_version: 3.1.3
230
229
  signing_key:
231
230
  specification_version: 4
232
231
  summary: Preflight for HTML e-mail.