bootstrap-email 1.0.0.alpha2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/core/bootstrap-head.scss +88 -15
  4. data/core/scss/_utilities.scss +1 -1
  5. data/core/scss/components/_grid.scss +25 -20
  6. data/core/scss/components/_stack.scss +18 -12
  7. data/core/scss/utilities/_sizing.scss +4 -0
  8. data/core/scss/utilities/_valign.scss +1 -1
  9. data/core/templates/body.html +9 -0
  10. data/core/templates/{container.html.erb → container.html} +2 -2
  11. data/core/templates/div.html +3 -0
  12. data/core/templates/table-left.html +9 -0
  13. data/core/templates/table-to-tbody.html +5 -0
  14. data/core/templates/table-to-tr.html +7 -0
  15. data/core/templates/table.html +9 -0
  16. data/core/templates/td.html +3 -0
  17. data/core/templates/{tr.html.erb → tr.html} +1 -1
  18. data/lib/bootstrap-email/bootstrap_email_cli.rb +3 -4
  19. data/lib/bootstrap-email/compiler.rb +33 -28
  20. data/lib/bootstrap-email/config.rb +50 -0
  21. data/lib/bootstrap-email/{components → converters}/alert.rb +1 -1
  22. data/lib/bootstrap-email/{components → converters}/align.rb +3 -3
  23. data/lib/bootstrap-email/{components → converters}/badge.rb +1 -1
  24. data/lib/bootstrap-email/{components → converters}/base.rb +16 -7
  25. data/lib/bootstrap-email/{components → converters}/block.rb +1 -1
  26. data/lib/bootstrap-email/{components → converters}/body.rb +1 -1
  27. data/lib/bootstrap-email/{components → converters}/button.rb +1 -1
  28. data/lib/bootstrap-email/{components → converters}/card.rb +1 -1
  29. data/lib/bootstrap-email/{components → converters}/color.rb +1 -1
  30. data/lib/bootstrap-email/{components → converters}/container.rb +1 -1
  31. data/lib/bootstrap-email/converters/force_encoding.rb +14 -0
  32. data/lib/bootstrap-email/{components → converters}/grid.rb +2 -2
  33. data/lib/bootstrap-email/{components → converters}/head_style.rb +1 -1
  34. data/lib/bootstrap-email/{components → converters}/hr.rb +1 -1
  35. data/lib/bootstrap-email/{components → converters}/margin.rb +3 -3
  36. data/lib/bootstrap-email/converters/padding.rb +16 -0
  37. data/lib/bootstrap-email/{components → converters}/paragraph.rb +1 -1
  38. data/lib/bootstrap-email/{components → converters}/preview_text.rb +1 -1
  39. data/lib/bootstrap-email/{components → converters}/spacer.rb +1 -1
  40. data/lib/bootstrap-email/{components → converters}/spacing.rb +1 -1
  41. data/lib/bootstrap-email/{components → converters}/stack.rb +7 -7
  42. data/lib/bootstrap-email/{components → converters}/table.rb +1 -1
  43. data/lib/bootstrap-email/{components → converters}/version_comment.rb +1 -1
  44. data/lib/bootstrap-email/sass_cache.rb +16 -19
  45. data/lib/bootstrap-email/setup.rb +27 -0
  46. data/lib/bootstrap-email.rb +5 -3
  47. metadata +38 -37
  48. data/core/templates/body.html.erb +0 -9
  49. data/core/templates/div.html.erb +0 -3
  50. data/core/templates/table-left.html.erb +0 -9
  51. data/core/templates/table-to-tbody.html.erb +0 -5
  52. data/core/templates/table-to-tr.html.erb +0 -7
  53. data/core/templates/table.html.erb +0 -9
  54. data/core/templates/td.html.erb +0 -3
  55. data/lib/bootstrap-email/components/force_encoding.rb +0 -16
  56. data/lib/bootstrap-email/components/padding.rb +0 -16
  57. data/lib/bootstrap-email/initialize.rb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 754525440d7ea29f8ca2fbd07a4c54af48abf49bb3a08e6be127c4b287cbb94b
4
- data.tar.gz: e6164558bc455056434601be51978b0cae979bb4581238a4325c53da493cbb4b
3
+ metadata.gz: f0363b6b03e3d4fbca8e0e52c55c2a3120671c720807fb970f96c2a711bedc60
4
+ data.tar.gz: 8462e35921bcfe274abed980d895e1ca57fc06f30d91e8c70ff15f9355175ef5
5
5
  SHA512:
6
- metadata.gz: 436b384bb50dc14c83b4d2903af0c5caeeecc3ef99e618383fb7aa05bac1ca43e0bde09619c229806ae7926adc762296ae7c70f3dfa7c7c10a79c2702a2d40e4
7
- data.tar.gz: bb4e1834510e3a833a518a559d460972637012f6e3b1771fc46238af972b8df0fcd2a1ebfbd2c5d76eedb8eaa532600e4fc9746856de670ddab4645977da8d95
6
+ metadata.gz: 50e8c9a0967f48e016b24cb8f46f92e5ff4fb3b8682b23131bea81cd73d6aec5334c6098c77ce2ecf1a811acc0f459c8feae122bfb997815fc955c2a29a4525d
7
+ data.tar.gz: 68650d469df9644d5c1c9f2ad990ee33697f297382c9f81111f5553d01a14c7071de409a82ab5353178a961397d9e496dd30aaf42b5d99b1c9e2bcb86450bbcb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0.alpha2.1
1
+ 1.0.0
@@ -8,6 +8,11 @@
8
8
  @import 'scss/selectors_for_utils';
9
9
  @import 'scss/helper_groups';
10
10
 
11
+ // Force base font in Outlook
12
+ body, table, td {
13
+ font-family: $font-family-base !important;
14
+ }
15
+
11
16
  // Forces Outlook.com to display emails at full width
12
17
  .ExternalClass {
13
18
  width: 100%;
@@ -66,18 +71,57 @@ table:not([class^=s-]) {
66
71
  /*! allow_purge_after */
67
72
 
68
73
  @media screen and (max-width: 600px) {
74
+ // Row Gap
75
+ @each $space, $value in $spacers {
76
+ .gap-#{$space}.row,
77
+ .gap-x-#{$space}.row {
78
+ margin-right: -1 * $value !important;
79
+ & > table > tbody > tr > td {
80
+ padding-right: $value !important;
81
+ }
82
+ }
83
+ .gap-#{$space}.row,
84
+ .gap-y-#{$space}.row {
85
+ margin-bottom: -1 * $value !important;
86
+ & > table > tbody > tr > td {
87
+ padding-bottom: $value !important;
88
+ }
89
+ }
90
+ }
91
+
92
+ // Stack Gap
93
+ @each $space, $value in $spacers {
94
+ table.gap-lg-#{$space}.stack-x > tbody > tr > td {
95
+ padding-right: 0 !important;
96
+ }
97
+ table.gap-lg-#{$space}.stack-y > tbody > tr > td {
98
+ padding-bottom: 0 !important;
99
+ }
100
+ }
101
+ @each $space, $value in $spacers {
102
+ table.gap-#{$space}.stack-x > tbody > tr > td {
103
+ padding-right: $value !important;
104
+ }
105
+ table.gap-#{$space}.stack-y > tbody > tr > td {
106
+ padding-bottom: $value !important;
107
+ }
108
+ }
109
+
69
110
  // Grid
70
111
  @each $key, $value in $grid-cols {
71
- table.row > tbody > tr {
72
- & > td.col-lg-#{$key},
73
- & > td.col-lg {
74
- display: block;
75
- width: 100% !important;
76
- padding-left: 0 !important;
77
- padding-right: 0 !important;
78
- }
112
+ td.col-lg-#{$key} {
113
+ display: block;
114
+ width: 100% !important;
115
+ padding-left: 0 !important;
116
+ padding-right: 0 !important;
79
117
  }
80
118
  }
119
+ td.col-lg {
120
+ display: block;
121
+ width: 100% !important;
122
+ padding-left: 0 !important;
123
+ padding-right: 0 !important;
124
+ }
81
125
 
82
126
  // Display
83
127
  @each $display in $display-type {
@@ -91,26 +135,56 @@ table:not([class^=s-]) {
91
135
  }
92
136
  }
93
137
 
94
- // Sizing
138
+ // Sizing Max Width / Height
139
+ @each $name, $property in $sizing-types {
140
+ @include sizing-util('.max-#{$name}-lg-full') {
141
+ max-#{$property}: unset !important;
142
+ #{$property}: auto !important;
143
+ }
144
+ @each $size, $value in $sizing {
145
+ @include sizing-util('.max-#{$name}-lg-#{$size}') {
146
+ max-#{$property}: unset !important;
147
+ #{$property}: auto !important;
148
+ }
149
+ }
150
+ }
151
+ @each $name, $property in $sizing-types {
152
+ @include sizing-util('.max-#{$name}-full') {
153
+ max-#{$property}: 100% !important;
154
+ #{$property}: 100% !important;
155
+ }
156
+ @each $size, $value in $sizing {
157
+ @include sizing-util('.max-#{$name}-#{$size}') {
158
+ max-#{$property}: $value !important;
159
+ #{$property}: 100% !important;
160
+ }
161
+ }
162
+ }
163
+
164
+ // Sizing Width / Height
95
165
  @each $name, $property in $sizing-types {
96
166
  @include sizing-util('.#{$name}-lg-full') {
97
- max-#{$property}: auto !important;
167
+ #{$property}: auto !important;
168
+ }
169
+ @include sizing-util('.#{$name}-lg-auto') {
98
170
  #{$property}: auto !important;
99
171
  }
100
172
  @each $size, $value in $sizing {
101
173
  @include sizing-util('.#{$name}-lg-#{$size}') {
102
- max-#{$property}: auto !important;
103
174
  #{$property}: auto !important;
104
175
  }
105
176
  }
177
+ }
178
+ @each $name, $property in $sizing-types {
106
179
  @include sizing-util('.#{$name}-full') {
107
- max-#{$property}: 100% !important;
108
180
  #{$property}: 100% !important;
109
181
  }
182
+ @include sizing-util('.#{$name}-auto') {
183
+ #{$property}: auto !important;
184
+ }
110
185
  @each $size, $value in $sizing {
111
186
  @include sizing-util('.#{$name}-#{$size}') {
112
- max-#{$property}: $value !important;
113
- #{$property}: 100% !important;
187
+ #{$property}: $value !important;
114
188
  }
115
189
  }
116
190
  }
@@ -132,7 +206,6 @@ table:not([class^=s-]) {
132
206
  line-height: 0 !important;
133
207
  height: 0 !important;
134
208
  }
135
-
136
209
  @each $size, $value in $spacers {
137
210
  @include spacer-util('.s-#{$size}') {
138
211
  font-size: $value !important;
@@ -117,9 +117,9 @@ $border-widths: (
117
117
  ) !default;
118
118
 
119
119
  $border-radiuses: (
120
+ '': 4px,
120
121
  '-none': 0px,
121
122
  '-sm': 2px,
122
- '': 4px,
123
123
  '-md': 6px,
124
124
  '-lg': 8px,
125
125
  '-xl': 12px,
@@ -1,13 +1,16 @@
1
- table.row {
2
- table-layout: fixed;
3
- -premailer-width: 100%;
4
- width: 100%;
5
- & > tbody > tr > td {
6
- min-height: 1px;
7
- font-weight: normal;
8
- padding-right: 30px;
9
- vertical-align: top;
10
- text-align: left;
1
+ .row {
2
+ margin-right: -24px;
3
+ & > table {
4
+ table-layout: fixed;
5
+ -premailer-width: 100%;
6
+ width: 100%;
7
+ & > tbody > tr > td {
8
+ min-height: 1px;
9
+ font-weight: normal;
10
+ padding-right: 24px;
11
+ vertical-align: top;
12
+ text-align: left;
13
+ }
11
14
  }
12
15
  }
13
16
 
@@ -19,19 +22,21 @@ table.row {
19
22
  }
20
23
 
21
24
  @each $space, $value in $spacers {
22
- table.row.g-#{$space},
23
- table.row.gx-#{$space},
24
- table.row.g-lg-#{$space},
25
- table.row.gx-lg-#{$space} {
26
- & > tbody > tr > td {
25
+ .row.gap-#{$space},
26
+ .row.gap-x-#{$space},
27
+ .row.gap-lg-#{$space},
28
+ .row.gap-x-lg-#{$space} {
29
+ margin-right: -1 * $value;
30
+ & > table > tbody > tr > td {
27
31
  padding-right: $value;
28
32
  }
29
33
  }
30
- table.row.g-#{$space},
31
- table.row.gy-#{$space},
32
- table.row.g-lg-#{$space},
33
- table.row.gy-lg-#{$space} {
34
- & > tbody > tr > td {
34
+ .row.gap-#{$space},
35
+ .row.gap-y-#{$space},
36
+ .row.gap-lg-#{$space},
37
+ .row.gap-y-lg-#{$space} {
38
+ margin-bottom: -1 * $value;
39
+ & > table > tbody > tr > td {
35
40
  padding-bottom: $value;
36
41
  }
37
42
  }
@@ -1,16 +1,22 @@
1
1
  @each $space, $value in $spacers {
2
- table.stack-x.gap-#{$space} > tbody > tr > td {
3
- padding-right: $value;
4
- &:last-child {
5
- padding-right: 0;
2
+ table.stack-row.gap-#{$space},
3
+ table.stack-row.gap-lg-#{$space} {
4
+ & > tbody > tr > td {
5
+ padding-right: $value;
6
+ &:last-child {
7
+ padding-right: 0;
8
+ }
6
9
  }
7
10
  }
8
- table.stack-y.gap-#{$space} > tbody > tr {
9
- & > td {
10
- padding-bottom: $value;
11
- }
12
- &:last-child > td {
13
- padding-bottom: 0;
11
+ table.stack-col.gap-#{$space},
12
+ table.stack-col.gap-lg-#{$space} {
13
+ & > tbody > tr {
14
+ & > td {
15
+ padding-bottom: $value;
16
+ }
17
+ &:last-child > td {
18
+ padding-bottom: 0;
19
+ }
14
20
  }
15
21
  }
16
22
  }
@@ -21,13 +27,13 @@
21
27
  }
22
28
 
23
29
  @each $align in $vertical-align {
24
- table.stack-valign-#{$align} > tbody > tr > td {
30
+ table.stack-ay-#{$align} > tbody > tr > td {
25
31
  vertical-align: $align;
26
32
  }
27
33
  }
28
34
 
29
35
  @each $align in $text-align {
30
- table.stack-align-#{$align} > tbody > tr > td {
36
+ table.stack-ax-#{$align} > tbody > tr > td {
31
37
  text-align: $align;
32
38
  }
33
39
  }
@@ -21,6 +21,10 @@
21
21
  -premailer-#{$property}: 100%;
22
22
  #{$property}: 100%;
23
23
  }
24
+ @include sizing-util('.#{$name}-#{$prefix}auto') {
25
+ -premailer-#{$property}: auto;
26
+ #{$property}: auto;
27
+ }
24
28
  @each $size, $value in $sizing {
25
29
  @include sizing-util('.#{$name}-#{$prefix}#{$size}') {
26
30
  -premailer-#{$property}: strip-unit($value);
@@ -1,5 +1,5 @@
1
1
  @each $align in $vertical-align {
2
- @include valign-util('.valign-#{$align}') {
2
+ @include valign-util('.ay-#{$align}') {
3
3
  vertical-align: $align !important;
4
4
  }
5
5
  }
@@ -0,0 +1,9 @@
1
+ <table class="{{ classes }}" valign="top" role="presentation">
2
+ <tbody>
3
+ <tr>
4
+ <td valign="top">
5
+ {{ contents }}
6
+ </td>
7
+ </tr>
8
+ </tbody>
9
+ </table>
@@ -1,4 +1,4 @@
1
- <table class="<%= classes %>" role="presentation">
1
+ <table class="{{ classes }}" role="presentation">
2
2
  <tbody>
3
3
  <tr>
4
4
  <td align="center">
@@ -12,7 +12,7 @@
12
12
  <tbody>
13
13
  <tr>
14
14
  <td>
15
- <%= contents %>
15
+ {{ contents }}
16
16
  </td>
17
17
  </tr>
18
18
  </tbody>
@@ -0,0 +1,3 @@
1
+ <div class="{{ classes }}">
2
+ {{ contents }}
3
+ </div>
@@ -0,0 +1,9 @@
1
+ <table class="{{ classes }}" align="left" role="presentation">
2
+ <tbody>
3
+ <tr>
4
+ <td>
5
+ {{ contents }}
6
+ </td>
7
+ </tr>
8
+ </tbody>
9
+ </table>
@@ -0,0 +1,5 @@
1
+ <table class="{{ classes }}" role="presentation">
2
+ <tbody>
3
+ {{ contents }}
4
+ </tbody>
5
+ </table>
@@ -0,0 +1,7 @@
1
+ <table class="{{ classes }}" role="presentation">
2
+ <tbody>
3
+ <tr>
4
+ {{ contents }}
5
+ </tr>
6
+ </tbody>
7
+ </table>
@@ -0,0 +1,9 @@
1
+ <table class="{{ classes }}" role="presentation">
2
+ <tbody>
3
+ <tr>
4
+ <td>
5
+ {{ contents }}
6
+ </td>
7
+ </tr>
8
+ </tbody>
9
+ </table>
@@ -0,0 +1,3 @@
1
+ <td class="{{ classes }}">
2
+ {{ contents }}
3
+ </td>
@@ -1,5 +1,5 @@
1
1
  <tr>
2
2
  <td>
3
- <%= contents %>
3
+ {{ contents }}
4
4
  </td>
5
5
  </tr>
@@ -1,6 +1,5 @@
1
1
  require_relative '../bootstrap-email'
2
2
  require 'optparse'
3
- require 'fileutils'
4
3
 
5
4
  input = nil
6
5
  options = {
@@ -37,7 +36,7 @@ parser = OptionParser.new do |opts|
37
36
  options[:destination] = v
38
37
  end
39
38
 
40
- opts.on('-c', '--config STRING', String, 'Relative path to SCSS config config file to customize Bootstrap Email.') do |v|
39
+ opts.on('-c', '--config STRING', String, 'Relative path to ruby config file to customize Bootstrap Email.') do |v|
41
40
  options[:config] = File.expand_path(v, Dir.pwd)
42
41
  end
43
42
 
@@ -82,9 +81,9 @@ if input
82
81
  end
83
82
  when :file
84
83
  path = File.expand_path(input, Dir.pwd)
85
- puts BootstrapEmail::Compiler.new(path, type: :file, options: {config_path: options[:config]}).perform_full_compile
84
+ puts BootstrapEmail::Compiler.new(path, type: :file, options: {config_path: options[:config], sass_log_enabled: false}).perform_full_compile
86
85
  when :string
87
- puts BootstrapEmail::Compiler.new(input, options: {config_path: options[:config]}).perform_full_compile
86
+ puts BootstrapEmail::Compiler.new(input, options: {config_path: options[:config], sass_log_enabled: false}).perform_full_compile
88
87
  end
89
88
  else
90
89
  puts opts
@@ -3,6 +3,7 @@ module BootstrapEmail
3
3
  attr_accessor :type, :doc, :premailer
4
4
 
5
5
  def initialize(input, type: :string, options: {})
6
+ BootstrapEmail.load_options(options)
6
7
  self.type = type
7
8
  case type
8
9
  when :rails
@@ -14,7 +15,8 @@ module BootstrapEmail
14
15
  html = File.read(input)
15
16
  end
16
17
  html = add_layout!(html)
17
- build_premailer_doc(html, options)
18
+ sass_load_paths
19
+ build_premailer_doc(html)
18
20
  end
19
21
 
20
22
  def perform_full_compile
@@ -36,42 +38,45 @@ module BootstrapEmail
36
38
  )
37
39
  end
38
40
 
39
- def build_premailer_doc(html, options)
40
- SassC.load_paths << File.expand_path('../../core', __dir__)
41
- css_string = BootstrapEmail::SassCache.compile('bootstrap-email', config_path: options[:config_path], style: :expanded)
41
+ def sass_load_paths
42
+ SassC.load_paths << BootstrapEmail.config.sass_load_paths
43
+ end
44
+
45
+ def build_premailer_doc(html)
46
+ css_string = BootstrapEmail::SassCache.compile('bootstrap-email', style: :expanded)
42
47
  self.premailer = Premailer.new(
43
48
  html,
44
49
  with_html_string: true,
45
50
  preserve_reset: false,
51
+ adapter: :nokogiri_fast,
52
+ output_encoding: 'US-ASCII',
46
53
  css_string: css_string
47
54
  )
48
55
  self.doc = premailer.doc
49
56
  end
50
57
 
51
58
  def compile_html!
52
- BootstrapEmail::Component::Block.build(doc)
53
-
54
- BootstrapEmail::Component::Button.build(doc)
55
- BootstrapEmail::Component::Badge.build(doc)
56
- BootstrapEmail::Component::Alert.build(doc)
57
- BootstrapEmail::Component::Card.build(doc)
58
- # BootstrapEmail::Component::Paragraph.build(doc) this might be too much
59
- BootstrapEmail::Component::Hr.build(doc)
60
- BootstrapEmail::Component::Container.build(doc)
61
- BootstrapEmail::Component::Grid.build(doc)
62
- BootstrapEmail::Component::Stack.build(doc)
59
+ BootstrapEmail::Converter::Body.build(doc)
60
+ BootstrapEmail::Converter::Block.build(doc)
63
61
 
64
- BootstrapEmail::Component::Spacing.build(doc)
65
- BootstrapEmail::Component::Padding.build(doc)
66
- BootstrapEmail::Component::Margin.build(doc)
67
- BootstrapEmail::Component::Spacer.build(doc)
62
+ BootstrapEmail::Converter::Button.build(doc)
63
+ BootstrapEmail::Converter::Badge.build(doc)
64
+ BootstrapEmail::Converter::Alert.build(doc)
65
+ BootstrapEmail::Converter::Card.build(doc)
66
+ BootstrapEmail::Converter::Hr.build(doc)
67
+ BootstrapEmail::Converter::Container.build(doc)
68
+ BootstrapEmail::Converter::Grid.build(doc)
69
+ BootstrapEmail::Converter::Stack.build(doc)
68
70
 
69
- BootstrapEmail::Component::Table.build(doc)
70
- BootstrapEmail::Component::Body.build(doc)
71
- BootstrapEmail::Component::Align.build(doc)
72
- BootstrapEmail::Component::Color.build(doc)
71
+ BootstrapEmail::Converter::Color.build(doc)
72
+ BootstrapEmail::Converter::Spacing.build(doc)
73
+ BootstrapEmail::Converter::Margin.build(doc)
74
+ BootstrapEmail::Converter::Spacer.build(doc)
75
+ BootstrapEmail::Converter::Align.build(doc)
76
+ BootstrapEmail::Converter::Padding.build(doc)
73
77
 
74
- BootstrapEmail::Component::PreviewText.build(doc)
78
+ BootstrapEmail::Converter::PreviewText.build(doc)
79
+ BootstrapEmail::Converter::Table.build(doc)
75
80
  end
76
81
 
77
82
  def inline_css!
@@ -79,13 +84,13 @@ module BootstrapEmail
79
84
  end
80
85
 
81
86
  def configure_html!
82
- BootstrapEmail::Component::ForceEncoding.build(doc)
83
- BootstrapEmail::Component::HeadStyle.build(doc)
84
- BootstrapEmail::Component::VersionComment.build(doc)
87
+ BootstrapEmail::Converter::HeadStyle.build(doc)
88
+ BootstrapEmail::Converter::VersionComment.build(doc)
85
89
  end
86
90
 
87
91
  def finalize_document!
88
- html = BootstrapEmail::Component::ForceEncoding.replace(doc.to_html)
92
+ html = doc.to_html(encoding: 'US-ASCII')
93
+ html = BootstrapEmail::Converter::ForceEncoding.replace(html)
89
94
  case type
90
95
  when :rails
91
96
  (@mail.html_part || @mail).body = html
@@ -0,0 +1,50 @@
1
+ module BootstrapEmail
2
+ class Config
3
+ attr_writer :sass_email_location # path to main sass file
4
+ attr_writer :sass_head_location # path to head sass file
5
+ attr_writer :sass_load_paths # array of directories for loading sass imports
6
+ attr_writer :sass_cache_location # path to tmp folder for sass cache
7
+ attr_writer :sass_log_enabled # turn on or off sass log when caching new sass
8
+
9
+ def load_options(options)
10
+ file = File.expand_path('bootstrap-email.config.rb', Dir.pwd)
11
+ if options[:config_path]
12
+ require_relative options[:config_path]
13
+ elsif File.exist?(file)
14
+ require_relative file
15
+ end
16
+ options.each { |name, value| instance_variable_set("@#{name}", value) }
17
+ end
18
+
19
+ def sass_location_for(type:)
20
+ ivar = instance_variable_get("@sass_#{type.sub('bootstrap-', '')}_location")
21
+ return ivar if ivar
22
+
23
+ lookup_locations = ["#{type}.scss", "app/assets/stylesheets/#{type}.scss"]
24
+ locations = lookup_locations.map { |location| File.expand_path(location, Dir.pwd) }.select { |location| File.exist?(location) }
25
+ locations.first if locations.any?
26
+ end
27
+
28
+ def sass_load_paths
29
+ paths_array = [SassCache::SASS_DIR]
30
+ @sass_load_paths ||= []
31
+ paths_array.concat(@sass_load_paths)
32
+ end
33
+
34
+ def sass_cache_location
35
+ @sass_cache_location ||= begin
36
+ if defined?(::Rails) && ::Rails.root
37
+ ::Rails.root.join('tmp', 'cache', 'bootstrap-email', '.sass-cache')
38
+ elsif File.writable?(Dir.pwd)
39
+ File.join(Dir.pwd, '.sass-cache', 'bootstrap-email')
40
+ else
41
+ File.join(Dir.tmpdir, '.sass-cache', 'bootstrap-email')
42
+ end
43
+ end
44
+ end
45
+
46
+ def sass_log_enabled?
47
+ defined?(@sass_log_enabled) ? @sass_log_enabled : true
48
+ end
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Alert < Base
4
4
  def build
5
5
  each_node('.alert') do |node|
@@ -1,9 +1,9 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Align < Base
4
4
  def build
5
5
  ['left', 'center', 'right'].each do |type|
6
- full_type = "align-#{type}"
6
+ full_type = "ax-#{type}"
7
7
  each_node(".#{full_type}") do |node|
8
8
  align_helper(node, full_type, type)
9
9
  end
@@ -12,7 +12,7 @@ module BootstrapEmail
12
12
 
13
13
  def align_helper(node, full_type, type)
14
14
  unless table?(node) || td?(node)
15
- node['class'] = node['class'].sub(full_type, '')
15
+ node['class'] = node['class'].sub(full_type, '').strip
16
16
  node = node.replace(template('table', classes: full_type, contents: node.to_html))[0]
17
17
  end
18
18
  node['align'] = type
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Badge < Base
4
4
  def build
5
5
  each_node('.badge') do |node|
@@ -1,9 +1,10 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Base
4
4
  attr_reader :doc
5
5
  def initialize(doc)
6
6
  @doc = doc
7
+ @cached_templates = {}
7
8
  end
8
9
 
9
10
  def self.build(doc)
@@ -13,11 +14,19 @@ module BootstrapEmail
13
14
  private
14
15
 
15
16
  def template(file, locals_hash = {})
16
- locals_hash[:classes] = locals_hash[:classes].split.join(' ') if locals_hash[:classes]
17
- BootstrapEmail::Erb.template(
18
- File.expand_path("../../../core/templates/#{file}.html.erb", __dir__),
19
- locals_hash
20
- )
17
+ locals_hash[:classes] = locals_hash[:classes].to_s.split.join(' ')
18
+ locals_hash[:content] ||= nil
19
+ if @cached_templates[file]
20
+ string = @cached_templates[file]
21
+ else
22
+ path = File.expand_path("../../../core/templates/#{file}.html", __dir__)
23
+ string = File.read(path).chop # read and remove trailing newline
24
+ @cached_templates[file] = string
25
+ end
26
+ locals_hash.each do |key, value|
27
+ string = string.sub("{{ #{key} }}", value.to_s)
28
+ end
29
+ string
21
30
  end
22
31
 
23
32
  def each_node(css_lookup, &blk)
@@ -27,7 +36,7 @@ module BootstrapEmail
27
36
 
28
37
  def add_class(node, class_name)
29
38
  node['class'] ||= ''
30
- node['class'] += class_name
39
+ node['class'] += node['class'].length.zero? ? class_name : " #{class_name}"
31
40
  end
32
41
 
33
42
  def margin?(node)
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Block < Base
4
4
  def build
5
5
  each_node('block, .to-table') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Body < Base
4
4
  def build
5
5
  body = doc.at_css('body')
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Button < Base
4
4
  def build
5
5
  each_node('.btn') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Card < Base
4
4
  def build
5
5
  each_node('.card') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Color < Base
4
4
  def build
5
5
  each_node('*[class*=bg-]') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Container < Base
4
4
  def build
5
5
  each_node('.container') do |node|
@@ -0,0 +1,14 @@
1
+ module BootstrapEmail
2
+ module Converter
3
+ class ForceEncoding < Base
4
+ def self.replace(html)
5
+ # force utf-8 character encoded in iOS Mail: https://github.com/bootstrap-email/bootstrap-email/issues/50
6
+ # this needs to be done after the document has been outputted to a ascii string so it doesn't get converted
7
+ html.sub(
8
+ '<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">',
9
+ '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,9 +1,9 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Grid < Base
4
4
  def build
5
5
  each_node('.row') do |node|
6
- node.replace(template('table-to-tr', classes: node['class'], contents: node.inner_html))
6
+ node.replace(template('div', classes: node['class'], contents: template('table-to-tr', contents: node.inner_html)))
7
7
  end
8
8
  each_node('*[class*=col]') do |node|
9
9
  node.replace(template('td', classes: node['class'], contents: node.inner_html))
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class HeadStyle < Base
4
4
  def build
5
5
  doc.at_css('head').add_child(bootstrap_email_head)
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Hr < Base
4
4
  def build
5
5
  each_node('hr') do |node|
@@ -1,11 +1,11 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Margin < Base
4
4
  def build
5
- each_node('*[class*=my-], *[class*=mt-], *[class*=mb-]') do |node|
5
+ each_node("*[class^='my-'], *[class^='mt-'], *[class^='mb-'], *[class*=' my-'], *[class*=' mt-'], *[class*=' mb-']") do |node|
6
6
  top_class = node['class'][/m[ty]{1}-(lg-)?(\d+)/]
7
7
  bottom_class = node['class'][/m[by]{1}-(lg-)?(\d+)/]
8
- node['class'] = node['class'].gsub(/(m[tby]{1}-(lg-)?\d+)/, '')
8
+ node['class'] = node['class'].gsub(/(m[tby]{1}-(lg-)?\d+)/, '').strip
9
9
  html = ''
10
10
  if top_class
11
11
  html += template('div', classes: "s-#{top_class.gsub(/m[ty]{1}-/, '')}", contents: nil)
@@ -0,0 +1,16 @@
1
+ module BootstrapEmail
2
+ module Converter
3
+ class Padding < Base
4
+ def build
5
+ each_node("*[class^=p-], *[class^=pt-], *[class^=pr-], *[class^=pb-], *[class^=pl-], *[class^=px-], *[class^=py-], *[class*=' p-'], *[class*=' pt-'], *[class*=' pr-'], *[class*=' pb-'], *[class*=' pl-'], *[class*=' px-'], *[class*=' py-']") do |node|
6
+ next if ['table', 'td', 'a'].include?(node.name)
7
+
8
+ padding_regex = /(p[trblxy]?-(lg-)?\d+)/
9
+ classes = node['class'].gsub(padding_regex).to_a.join(' ')
10
+ node['class'] = node['class'].gsub(padding_regex, '').strip
11
+ node.replace(template('table', classes: classes, contents: node.to_html))
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Paragraph < Base
4
4
  def build
5
5
  each_node('p') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class PreviewText < Base
4
4
  def build
5
5
  preview_node = doc.at_css('preview')
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Spacer < Base
4
4
  def build
5
5
  each_node('*[class*=s-]') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Spacing < Base
4
4
  def build
5
5
  each_node('*[class*=space-y-]') do |node|
@@ -1,13 +1,13 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Stack < Base
4
4
  def build
5
- stack_x
6
- stack_y
5
+ stack_row
6
+ stack_col
7
7
  end
8
8
 
9
- def stack_x
10
- each_node('.stack-x') do |node|
9
+ def stack_row
10
+ each_node('.stack-row') do |node|
11
11
  html = ''
12
12
  node.xpath('./*').each do |child|
13
13
  html += template('td', classes: 'stack-cell', contents: child.to_html)
@@ -16,8 +16,8 @@ module BootstrapEmail
16
16
  end
17
17
  end
18
18
 
19
- def stack_y
20
- each_node('.stack-y') do |node|
19
+ def stack_col
20
+ each_node('.stack-col') do |node|
21
21
  html = ''
22
22
  node.xpath('./*').each do |child|
23
23
  html += template('tr', classes: 'stack-cell', contents: child.to_html)
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class Table < Base
4
4
  def build
5
5
  each_node('table') do |node|
@@ -1,5 +1,5 @@
1
1
  module BootstrapEmail
2
- module Component
2
+ module Converter
3
3
  class VersionComment < Base
4
4
  def build
5
5
  doc.at_css('head').prepend_child(bootstrap_email_comment)
@@ -1,24 +1,27 @@
1
1
  module BootstrapEmail
2
2
  class SassCache
3
- CACHE_DIR = File.expand_path('../../.sass-cache', __dir__)
4
3
  SASS_DIR = File.expand_path('../../core', __dir__)
5
4
 
6
- def self.compile(type, config_path: nil, style: :compressed)
7
- new(type, config_path, style).compile
5
+ def self.compile(type, style: :compressed)
6
+ new(type, style).compile
8
7
  end
9
8
 
10
9
  attr_accessor :type, :style, :file_path, :config_file, :checksum
11
10
 
12
- def initialize(type, config_path, style)
11
+ def initialize(type, style)
13
12
  self.type = type
14
13
  self.style = style
15
14
  self.file_path = "#{SASS_DIR}/#{type}"
16
- self.config_file = load_config(config_path)
15
+ self.config_file = load_config
17
16
  self.checksum = checksum_files
18
17
  end
19
18
 
19
+ def cache_dir
20
+ BootstrapEmail.config.sass_cache_location
21
+ end
22
+
20
23
  def compile
21
- cache_path = "#{CACHE_DIR}/#{checksum}/#{type}.css"
24
+ cache_path = "#{cache_dir}/#{checksum}/#{type}.css"
22
25
  unless cached?(cache_path)
23
26
  compile_and_cache_scss(cache_path)
24
27
  end
@@ -27,16 +30,9 @@ module BootstrapEmail
27
30
 
28
31
  private
29
32
 
30
- def load_config(config_path)
31
- lookup_locations = ["#{type}.config.scss", "app/assets/stylesheets/#{type}.config.scss"]
32
- locations = lookup_locations.select { |location| File.exist?(File.expand_path(location, Dir.pwd)) }
33
- if config_path && File.exist?(config_path)
34
- # check if custom config was passed in
35
- replace_config(File.read(config_path))
36
- elsif locations.any?
37
- # look for common lookup locations of config
38
- replace_config(File.read(File.expand_path(locations.first, Dir.pwd)))
39
- end
33
+ def load_config
34
+ path = BootstrapEmail.config.sass_location_for(type: type)
35
+ replace_config(File.read(path)) if path
40
36
  end
41
37
 
42
38
  def replace_config(config_file)
@@ -58,10 +54,11 @@ module BootstrapEmail
58
54
  def compile_and_cache_scss(cache_path)
59
55
  file = config_file || File.read("#{file_path}.scss")
60
56
  css = SassC::Engine.new(file, style: style).render
61
- Dir.mkdir(CACHE_DIR) unless File.directory?(CACHE_DIR)
62
- Dir.mkdir("#{CACHE_DIR}/#{checksum}") unless File.directory?("#{CACHE_DIR}/#{checksum}")
57
+ FileUtils.mkdir_p("#{cache_dir}/#{checksum}") unless File.directory?("#{cache_dir}/#{checksum}")
63
58
  File.write(cache_path, css)
64
- puts "New css file cached for #{type}"
59
+ if BootstrapEmail.config.sass_log_enabled?
60
+ puts "New css file cached for #{type}"
61
+ end
65
62
  end
66
63
  end
67
64
  end
@@ -0,0 +1,27 @@
1
+ module BootstrapEmail
2
+ class << self
3
+ def config
4
+ @config ||= BootstrapEmail::Config.new
5
+ @config
6
+ end
7
+
8
+ def load_options(options)
9
+ @config ||= BootstrapEmail::Config.new
10
+ @config.load_options(options)
11
+ @config
12
+ end
13
+
14
+ def configure(&proc)
15
+ @config ||= BootstrapEmail::Config.new
16
+ yield @config
17
+ end
18
+
19
+ def reset_config!
20
+ remove_instance_variable :@config if defined?(@config)
21
+ end
22
+
23
+ def clear_sass_cache!
24
+ FileUtils.rm_rf(BootstrapEmail.config.sass_cache_location)
25
+ end
26
+ end
27
+ end
@@ -5,6 +5,7 @@ require 'premailer'
5
5
  require 'sassc'
6
6
  require 'digest/sha1'
7
7
  require 'css_parser'
8
+ require 'fileutils'
8
9
 
9
10
  begin
10
11
  require 'rails'
@@ -14,13 +15,14 @@ if defined?(Rails)
14
15
  require 'action_mailer'
15
16
  end
16
17
 
17
- require_relative 'bootstrap-email/initialize'
18
+ require_relative 'bootstrap-email/config'
19
+ require_relative 'bootstrap-email/setup'
18
20
  require_relative 'bootstrap-email/erb'
19
21
  require_relative 'bootstrap-email/compiler'
20
22
  require_relative 'bootstrap-email/sass_cache'
21
23
  require_relative 'bootstrap-email/version'
22
- require_relative 'bootstrap-email/components/base'
23
- Dir[File.join(__dir__, 'bootstrap-email/components', '*.rb')].each { |file| require_relative file }
24
+ require_relative 'bootstrap-email/converters/base'
25
+ Dir[File.join(__dir__, 'bootstrap-email/converters', '*.rb')].each { |file| require_relative file }
24
26
 
25
27
  if defined?(Rails)
26
28
  require_relative 'bootstrap-email/rails/action_mailer'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap-email
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha2.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stuart Yamartino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-17 00:00:00.000000000 Z
11
+ date: 2021-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -92,46 +92,47 @@ files:
92
92
  - core/scss/utilities/_text-decoration.scss
93
93
  - core/scss/utilities/_typography.scss
94
94
  - core/scss/utilities/_valign.scss
95
- - core/templates/body.html.erb
96
- - core/templates/container.html.erb
97
- - core/templates/div.html.erb
98
- - core/templates/table-left.html.erb
99
- - core/templates/table-to-tbody.html.erb
100
- - core/templates/table-to-tr.html.erb
101
- - core/templates/table.html.erb
102
- - core/templates/td.html.erb
103
- - core/templates/tr.html.erb
95
+ - core/templates/body.html
96
+ - core/templates/container.html
97
+ - core/templates/div.html
98
+ - core/templates/table-left.html
99
+ - core/templates/table-to-tbody.html
100
+ - core/templates/table-to-tr.html
101
+ - core/templates/table.html
102
+ - core/templates/td.html
103
+ - core/templates/tr.html
104
104
  - lib/bootstrap-email.rb
105
105
  - lib/bootstrap-email/bootstrap_email_cli.rb
106
106
  - lib/bootstrap-email/compiler.rb
107
- - lib/bootstrap-email/components/alert.rb
108
- - lib/bootstrap-email/components/align.rb
109
- - lib/bootstrap-email/components/badge.rb
110
- - lib/bootstrap-email/components/base.rb
111
- - lib/bootstrap-email/components/block.rb
112
- - lib/bootstrap-email/components/body.rb
113
- - lib/bootstrap-email/components/button.rb
114
- - lib/bootstrap-email/components/card.rb
115
- - lib/bootstrap-email/components/color.rb
116
- - lib/bootstrap-email/components/container.rb
117
- - lib/bootstrap-email/components/force_encoding.rb
118
- - lib/bootstrap-email/components/grid.rb
119
- - lib/bootstrap-email/components/head_style.rb
120
- - lib/bootstrap-email/components/hr.rb
121
- - lib/bootstrap-email/components/margin.rb
122
- - lib/bootstrap-email/components/padding.rb
123
- - lib/bootstrap-email/components/paragraph.rb
124
- - lib/bootstrap-email/components/preview_text.rb
125
- - lib/bootstrap-email/components/spacer.rb
126
- - lib/bootstrap-email/components/spacing.rb
127
- - lib/bootstrap-email/components/stack.rb
128
- - lib/bootstrap-email/components/table.rb
129
- - lib/bootstrap-email/components/version_comment.rb
107
+ - lib/bootstrap-email/config.rb
108
+ - lib/bootstrap-email/converters/alert.rb
109
+ - lib/bootstrap-email/converters/align.rb
110
+ - lib/bootstrap-email/converters/badge.rb
111
+ - lib/bootstrap-email/converters/base.rb
112
+ - lib/bootstrap-email/converters/block.rb
113
+ - lib/bootstrap-email/converters/body.rb
114
+ - lib/bootstrap-email/converters/button.rb
115
+ - lib/bootstrap-email/converters/card.rb
116
+ - lib/bootstrap-email/converters/color.rb
117
+ - lib/bootstrap-email/converters/container.rb
118
+ - lib/bootstrap-email/converters/force_encoding.rb
119
+ - lib/bootstrap-email/converters/grid.rb
120
+ - lib/bootstrap-email/converters/head_style.rb
121
+ - lib/bootstrap-email/converters/hr.rb
122
+ - lib/bootstrap-email/converters/margin.rb
123
+ - lib/bootstrap-email/converters/padding.rb
124
+ - lib/bootstrap-email/converters/paragraph.rb
125
+ - lib/bootstrap-email/converters/preview_text.rb
126
+ - lib/bootstrap-email/converters/spacer.rb
127
+ - lib/bootstrap-email/converters/spacing.rb
128
+ - lib/bootstrap-email/converters/stack.rb
129
+ - lib/bootstrap-email/converters/table.rb
130
+ - lib/bootstrap-email/converters/version_comment.rb
130
131
  - lib/bootstrap-email/erb.rb
131
- - lib/bootstrap-email/initialize.rb
132
132
  - lib/bootstrap-email/rails/action_mailer.rb
133
133
  - lib/bootstrap-email/rails/engine.rb
134
134
  - lib/bootstrap-email/sass_cache.rb
135
+ - lib/bootstrap-email/setup.rb
135
136
  - lib/bootstrap-email/version.rb
136
137
  homepage: https://bootstrapemail.com
137
138
  licenses:
@@ -148,9 +149,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
149
  version: '2.0'
149
150
  required_rubygems_version: !ruby/object:Gem::Requirement
150
151
  requirements:
151
- - - ">"
152
+ - - ">="
152
153
  - !ruby/object:Gem::Version
153
- version: 1.3.1
154
+ version: '0'
154
155
  requirements: []
155
156
  rubygems_version: 3.0.3
156
157
  signing_key:
@@ -1,9 +0,0 @@
1
- <table class="<%= classes %>" valign="top" role="presentation">
2
- <tbody>
3
- <tr>
4
- <td valign="top">
5
- <%= contents %>
6
- </td>
7
- </tr>
8
- </tbody>
9
- </table>
@@ -1,3 +0,0 @@
1
- <div class="<%= classes %>">
2
- <%= contents %>
3
- </div>
@@ -1,9 +0,0 @@
1
- <table class="<%= classes %>" align="left" role="presentation">
2
- <tbody>
3
- <tr>
4
- <td>
5
- <%= contents %>
6
- </td>
7
- </tr>
8
- </tbody>
9
- </table>
@@ -1,5 +0,0 @@
1
- <table class="<%= classes %>" role="presentation">
2
- <tbody>
3
- <%= contents %>
4
- </tbody>
5
- </table>
@@ -1,7 +0,0 @@
1
- <table class="<%= classes %>" role="presentation">
2
- <tbody>
3
- <tr>
4
- <%= contents %>
5
- </tr>
6
- </tbody>
7
- </table>
@@ -1,9 +0,0 @@
1
- <table class="<%= classes %>" role="presentation">
2
- <tbody>
3
- <tr>
4
- <td>
5
- <%= contents %>
6
- </td>
7
- </tr>
8
- </tbody>
9
- </table>
@@ -1,3 +0,0 @@
1
- <td class="<%= classes %>">
2
- <%= contents %>
3
- </td>
@@ -1,16 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class ForceEncoding < Base
4
- def build
5
- body = doc.at_css('body')
6
- body.add_child('<force-encoding></force-encoding>')
7
- end
8
-
9
- def self.replace(html)
10
- # force utf-8 character encoded in iOS Mail: https://github.com/bootstrap-email/bootstrap-email/issues/50
11
- # this needs to be done after the document has been outputted to a string so it doesn't get converted
12
- html.sub('<force-encoding></force-encoding>', '<div id="force-encoding-to-utf-8" style="display: none;">&#10175;</div>')
13
- end
14
- end
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class Padding < Base
4
- def build
5
- each_node('*[class*=p-], *[class*=pt-], *[class*=pr-], *[class*=pb-], *[class*=pl-], *[class*=px-], *[class*=py-]') do |node|
6
- next if ['table', 'td', 'a'].include?(node.name)
7
-
8
- padding_regex = /(p[trblxy]?-\d+)/
9
- classes = node['class'].scan(padding_regex).join(' ')
10
- node['class'] = node['class'].gsub(padding_regex, '')
11
- node.replace(template('table', classes: classes, contents: node.to_html))
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1 +0,0 @@
1
- Premailer::Adapter.use = :nokogiri_fast