bootstrap-email 1.0.0.alpha1.2 → 1.0.0.alpha2
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.
- checksums.yaml +4 -4
 - data/VERSION +1 -1
 - data/core/bootstrap-email.scss +2 -0
 - data/core/bootstrap-head.scss +1 -1
 - data/core/scss/_selectors_for_utils.scss +24 -0
 - data/core/scss/_utilities.scss +24 -4
 - data/core/scss/components/_grid.scss +3 -0
 - data/core/scss/components/_stack.scss +33 -0
 - data/core/scss/utilities/_sizing.scss +17 -2
 - data/core/scss/utilities/_typography.scss +4 -10
 - data/core/scss/utilities/_valign.scss +5 -0
 - data/core/templates/body.html.erb +1 -1
 - data/core/templates/container.html.erb +3 -3
 - data/core/templates/table-left.html.erb +1 -1
 - data/core/templates/table-to-tbody.html.erb +5 -0
 - data/core/templates/{row.html.erb → table-to-tr.html.erb} +1 -1
 - data/core/templates/table.html.erb +1 -1
 - data/core/templates/td.html.erb +3 -0
 - data/core/templates/tr.html.erb +5 -0
 - data/lib/{bootstrap_email.rb → bootstrap-email.rb} +1 -0
 - data/lib/bootstrap-email/bootstrap_email_cli.rb +3 -3
 - data/lib/bootstrap-email/compiler.rb +30 -50
 - data/lib/bootstrap-email/components/align.rb +7 -6
 - data/lib/bootstrap-email/components/base.rb +31 -3
 - data/lib/bootstrap-email/components/block.rb +13 -0
 - data/lib/bootstrap-email/components/body.rb +2 -14
 - data/lib/bootstrap-email/components/card.rb +2 -2
 - data/lib/bootstrap-email/components/force_encoding.rb +16 -0
 - data/lib/bootstrap-email/components/grid.rb +2 -2
 - data/lib/bootstrap-email/components/head_style.rb +33 -0
 - data/lib/bootstrap-email/components/hr.rb +1 -1
 - data/lib/bootstrap-email/components/paragraph.rb +2 -13
 - data/lib/bootstrap-email/components/preview_text.rb +18 -0
 - data/lib/bootstrap-email/components/spacing.rb +4 -5
 - data/lib/bootstrap-email/components/stack.rb +30 -0
 - data/lib/bootstrap-email/components/version_comment.rb +15 -0
 - data/lib/bootstrap-email/erb.rb +9 -0
 - data/lib/bootstrap-email/rails/action_mailer.rb +1 -0
 - data/lib/bootstrap-email/sass_cache.rb +42 -22
 - metadata +20 -9
 - data/core/templates/col.html.erb +0 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 759e1882e8d2e275343ff2d3b6c92a358f350f35319c14208c26b7641ef989de
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6fb098dd28e51f2c962aa0c774b4948e1ad0499282d66927755a18539c1aa00e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d5f19d06827848b6a1cdc3f47ed99e66f46d0465748ac7c46d49654f7815e274c3462028442518b0cf6bd6cfb58e21becbc85204eab5abd45445e1dfe962594b
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 4b9716bca2ccc400c22b30e12a6c9b7a03be72d9e595c854d99e92ffdf8d78d4b3dd8061fe914a9e60e3d3868df0e23d7383196a10f75d24514b73ed6ccaef95
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            1.0.0. 
     | 
| 
      
 1 
     | 
    
         
            +
            1.0.0.alpha2
         
     | 
    
        data/core/bootstrap-email.scss
    CHANGED
    
    | 
         @@ -16,6 +16,7 @@ 
     | 
|
| 
       16 
16 
     | 
    
         
             
            @import 'scss/components/image';
         
     | 
| 
       17 
17 
     | 
    
         
             
            @import 'scss/components/preview';
         
     | 
| 
       18 
18 
     | 
    
         
             
            @import 'scss/components/table';
         
     | 
| 
      
 19 
     | 
    
         
            +
            @import 'scss/components/stack';
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
            @import 'scss/utilities/background';
         
     | 
| 
       21 
22 
     | 
    
         
             
            @import 'scss/utilities/border';
         
     | 
| 
         @@ -26,3 +27,4 @@ 
     | 
|
| 
       26 
27 
     | 
    
         
             
            @import 'scss/utilities/spacing';
         
     | 
| 
       27 
28 
     | 
    
         
             
            @import 'scss/utilities/text-decoration';
         
     | 
| 
       28 
29 
     | 
    
         
             
            @import 'scss/utilities/typography';
         
     | 
| 
      
 30 
     | 
    
         
            +
            @import 'scss/utilities/valign';
         
     | 
    
        data/core/bootstrap-head.scss
    CHANGED
    
    
| 
         @@ -98,3 +98,27 @@ 
     | 
|
| 
       98 
98 
     | 
    
         
             
                }
         
     | 
| 
       99 
99 
     | 
    
         
             
              }
         
     | 
| 
       100 
100 
     | 
    
         
             
            }
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            //
         
     | 
| 
      
 103 
     | 
    
         
            +
            // Text align
         
     | 
| 
      
 104 
     | 
    
         
            +
            //
         
     | 
| 
      
 105 
     | 
    
         
            +
            @mixin text-align-util($class) {
         
     | 
| 
      
 106 
     | 
    
         
            +
              #{$class} {
         
     | 
| 
      
 107 
     | 
    
         
            +
                &,
         
     | 
| 
      
 108 
     | 
    
         
            +
                & > tbody > tr > td {
         
     | 
| 
      
 109 
     | 
    
         
            +
                  @content
         
     | 
| 
      
 110 
     | 
    
         
            +
                }
         
     | 
| 
      
 111 
     | 
    
         
            +
              }
         
     | 
| 
      
 112 
     | 
    
         
            +
            }
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            //
         
     | 
| 
      
 115 
     | 
    
         
            +
            // Vertical align
         
     | 
| 
      
 116 
     | 
    
         
            +
            //
         
     | 
| 
      
 117 
     | 
    
         
            +
            @mixin valign-util($class) {
         
     | 
| 
      
 118 
     | 
    
         
            +
              #{$class} {
         
     | 
| 
      
 119 
     | 
    
         
            +
                &,
         
     | 
| 
      
 120 
     | 
    
         
            +
                & > tbody > tr > td {
         
     | 
| 
      
 121 
     | 
    
         
            +
                  @content
         
     | 
| 
      
 122 
     | 
    
         
            +
                }
         
     | 
| 
      
 123 
     | 
    
         
            +
              }
         
     | 
| 
      
 124 
     | 
    
         
            +
            }
         
     | 
    
        data/core/scss/_utilities.scss
    CHANGED
    
    | 
         @@ -117,9 +117,29 @@ $border-widths: ( 
     | 
|
| 
       117 
117 
     | 
    
         
             
            ) !default;
         
     | 
| 
       118 
118 
     | 
    
         | 
| 
       119 
119 
     | 
    
         
             
            $border-radiuses: (
         
     | 
| 
       120 
     | 
    
         
            -
              '- 
     | 
| 
       121 
     | 
    
         
            -
              '':  
     | 
| 
       122 
     | 
    
         
            -
              ' 
     | 
| 
      
 120 
     | 
    
         
            +
              '-none': 0px,
         
     | 
| 
      
 121 
     | 
    
         
            +
              '-sm': 2px,
         
     | 
| 
      
 122 
     | 
    
         
            +
              '': 4px,
         
     | 
| 
      
 123 
     | 
    
         
            +
              '-md': 6px,
         
     | 
| 
      
 124 
     | 
    
         
            +
              '-lg': 8px,
         
     | 
| 
       123 
125 
     | 
    
         
             
              '-xl': 12px,
         
     | 
| 
       124 
     | 
    
         
            -
              '- 
     | 
| 
      
 126 
     | 
    
         
            +
              '-2xl': 16px,
         
     | 
| 
      
 127 
     | 
    
         
            +
              '-3xl': 24px,
         
     | 
| 
      
 128 
     | 
    
         
            +
              '-full': 9999px
         
     | 
| 
      
 129 
     | 
    
         
            +
            ) !default;
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            $vertical-align: (
         
     | 
| 
      
 132 
     | 
    
         
            +
              top,
         
     | 
| 
      
 133 
     | 
    
         
            +
              middle,
         
     | 
| 
      
 134 
     | 
    
         
            +
              bottom,
         
     | 
| 
      
 135 
     | 
    
         
            +
              baseline,
         
     | 
| 
      
 136 
     | 
    
         
            +
              text-top,
         
     | 
| 
      
 137 
     | 
    
         
            +
              text-bottom
         
     | 
| 
      
 138 
     | 
    
         
            +
            ) !default;
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
            $text-align: (
         
     | 
| 
      
 141 
     | 
    
         
            +
              left,
         
     | 
| 
      
 142 
     | 
    
         
            +
              right,
         
     | 
| 
      
 143 
     | 
    
         
            +
              center,
         
     | 
| 
      
 144 
     | 
    
         
            +
              justify
         
     | 
| 
       125 
145 
     | 
    
         
             
            ) !default;
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 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;
         
     | 
| 
      
 6 
     | 
    
         
            +
                }
         
     | 
| 
      
 7 
     | 
    
         
            +
              }
         
     | 
| 
      
 8 
     | 
    
         
            +
              table.stack-y.gap-#{$space} > tbody > tr {
         
     | 
| 
      
 9 
     | 
    
         
            +
                & > td {
         
     | 
| 
      
 10 
     | 
    
         
            +
                  padding-bottom: $value;
         
     | 
| 
      
 11 
     | 
    
         
            +
                }
         
     | 
| 
      
 12 
     | 
    
         
            +
                &:last-child > td {
         
     | 
| 
      
 13 
     | 
    
         
            +
                  padding-bottom: 0;
         
     | 
| 
      
 14 
     | 
    
         
            +
                }
         
     | 
| 
      
 15 
     | 
    
         
            +
              }
         
     | 
| 
      
 16 
     | 
    
         
            +
            }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            .stack-cell {
         
     | 
| 
      
 19 
     | 
    
         
            +
              vertical-align: top;
         
     | 
| 
      
 20 
     | 
    
         
            +
              text-align: left;
         
     | 
| 
      
 21 
     | 
    
         
            +
            }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            @each $align in $vertical-align {
         
     | 
| 
      
 24 
     | 
    
         
            +
              table.stack-valign-#{$align} > tbody > tr > td {
         
     | 
| 
      
 25 
     | 
    
         
            +
                vertical-align: $align;
         
     | 
| 
      
 26 
     | 
    
         
            +
              }
         
     | 
| 
      
 27 
     | 
    
         
            +
            }
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            @each $align in $text-align {
         
     | 
| 
      
 30 
     | 
    
         
            +
              table.stack-align-#{$align} > tbody > tr > td {
         
     | 
| 
      
 31 
     | 
    
         
            +
                text-align: $align;
         
     | 
| 
      
 32 
     | 
    
         
            +
              }
         
     | 
| 
      
 33 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            @each $prefix in $breakpoints {
         
     | 
| 
       2 
2 
     | 
    
         
             
              @each $name, $property in $sizing-types {
         
     | 
| 
       3 
     | 
    
         
            -
                @include sizing-util(' 
     | 
| 
      
 3 
     | 
    
         
            +
                @include sizing-util('.max-#{$name}-#{$prefix}full') {
         
     | 
| 
       4 
4 
     | 
    
         
             
                  max-#{$property}: 100%;
         
     | 
| 
       5 
5 
     | 
    
         
             
                  -premailer-#{$property}: 100%;
         
     | 
| 
       6 
6 
     | 
    
         
             
                  #{$property}: 100%;
         
     | 
| 
       7 
7 
     | 
    
         
             
                }
         
     | 
| 
       8 
8 
     | 
    
         
             
                @each $size, $value in $sizing {
         
     | 
| 
       9 
     | 
    
         
            -
                  @include sizing-util(' 
     | 
| 
      
 9 
     | 
    
         
            +
                  @include sizing-util('.max-#{$name}-#{$prefix}#{$size}') {
         
     | 
| 
       10 
10 
     | 
    
         
             
                    max-#{$property}: $value;
         
     | 
| 
       11 
11 
     | 
    
         
             
                    -premailer-#{$property}: strip-unit($value);
         
     | 
| 
       12 
12 
     | 
    
         
             
                    #{$property}: 100%;
         
     | 
| 
         @@ -14,3 +14,18 @@ 
     | 
|
| 
       14 
14 
     | 
    
         
             
                }
         
     | 
| 
       15 
15 
     | 
    
         
             
              }
         
     | 
| 
       16 
16 
     | 
    
         
             
            }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            @each $prefix in $breakpoints {
         
     | 
| 
      
 19 
     | 
    
         
            +
              @each $name, $property in $sizing-types {
         
     | 
| 
      
 20 
     | 
    
         
            +
                @include sizing-util('.#{$name}-#{$prefix}full') {
         
     | 
| 
      
 21 
     | 
    
         
            +
                  -premailer-#{$property}: 100%;
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #{$property}: 100%;
         
     | 
| 
      
 23 
     | 
    
         
            +
                }
         
     | 
| 
      
 24 
     | 
    
         
            +
                @each $size, $value in $sizing {
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @include sizing-util('.#{$name}-#{$prefix}#{$size}') {
         
     | 
| 
      
 26 
     | 
    
         
            +
                    -premailer-#{$property}: strip-unit($value);
         
     | 
| 
      
 27 
     | 
    
         
            +
                    #{$property}: $value;
         
     | 
| 
      
 28 
     | 
    
         
            +
                  }
         
     | 
| 
      
 29 
     | 
    
         
            +
                }
         
     | 
| 
      
 30 
     | 
    
         
            +
              }
         
     | 
| 
      
 31 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -36,16 +36,10 @@ h1, h2, h3, h4, h5, h6, 
     | 
|
| 
       36 
36 
     | 
    
         
             
              }
         
     | 
| 
       37 
37 
     | 
    
         
             
            }
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
              text-align 
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            .text-right {
         
     | 
| 
       44 
     | 
    
         
            -
              text-align: right !important;
         
     | 
| 
       45 
     | 
    
         
            -
            }
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
            .text-center {
         
     | 
| 
       48 
     | 
    
         
            -
              text-align: center !important;
         
     | 
| 
      
 39 
     | 
    
         
            +
            @each $align in $text-align {
         
     | 
| 
      
 40 
     | 
    
         
            +
              @include text-align-util('.text-#{$align}') {
         
     | 
| 
      
 41 
     | 
    
         
            +
                text-align: $align !important;
         
     | 
| 
      
 42 
     | 
    
         
            +
              }
         
     | 
| 
       49 
43 
     | 
    
         
             
            }
         
     | 
| 
       50 
44 
     | 
    
         | 
| 
       51 
45 
     | 
    
         
             
            p {
         
     | 
| 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            <table class="<%= classes %>">
         
     | 
| 
      
 1 
     | 
    
         
            +
            <table class="<%= classes %>" role="presentation">
         
     | 
| 
       2 
2 
     | 
    
         
             
              <tbody>
         
     | 
| 
       3 
3 
     | 
    
         
             
                <tr>
         
     | 
| 
       4 
4 
     | 
    
         
             
                  <td align="center">
         
     | 
| 
       5 
5 
     | 
    
         
             
                    <!--[if (gte mso 9)|(IE)]>
         
     | 
| 
       6 
     | 
    
         
            -
                      <table align="center">
         
     | 
| 
      
 6 
     | 
    
         
            +
                      <table align="center" role="presentation">
         
     | 
| 
       7 
7 
     | 
    
         
             
                        <tbody>
         
     | 
| 
       8 
8 
     | 
    
         
             
                          <tr>
         
     | 
| 
       9 
9 
     | 
    
         
             
                            <td width="600">
         
     | 
| 
       10 
10 
     | 
    
         
             
                    <![endif]-->
         
     | 
| 
       11 
     | 
    
         
            -
                    <table align="center">
         
     | 
| 
      
 11 
     | 
    
         
            +
                    <table align="center" role="presentation">
         
     | 
| 
       12 
12 
     | 
    
         
             
                      <tbody>
         
     | 
| 
       13 
13 
     | 
    
         
             
                        <tr>
         
     | 
| 
       14 
14 
     | 
    
         
             
                          <td>
         
     | 
| 
         @@ -1,10 +1,10 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require_relative '../ 
     | 
| 
      
 1 
     | 
    
         
            +
            require_relative '../bootstrap-email'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'optparse'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'fileutils'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            input = nil
         
     | 
| 
       6 
6 
     | 
    
         
             
            options = {
         
     | 
| 
       7 
     | 
    
         
            -
              destination: ' 
     | 
| 
      
 7 
     | 
    
         
            +
              destination: 'compiled',
         
     | 
| 
       8 
8 
     | 
    
         
             
              type: :file
         
     | 
| 
       9 
9 
     | 
    
         
             
            }
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
         @@ -17,7 +17,7 @@ parser = OptionParser.new do |opts| 
     | 
|
| 
       17 
17 
     | 
    
         
             
              opts.separator '  bootstrap-email email.html > out.html'
         
     | 
| 
       18 
18 
     | 
    
         
             
              opts.separator '  bootstrap-email ./public/index.html'
         
     | 
| 
       19 
19 
     | 
    
         
             
              opts.separator '  bootstrap-email -s \'<a href="#" class="btn btn-primary">Some Button</a>\''
         
     | 
| 
       20 
     | 
    
         
            -
              opts.separator '  bootstrap-email -p \'emails/*\' -d emails/ 
     | 
| 
      
 20 
     | 
    
         
            +
              opts.separator '  bootstrap-email -p \'emails/*\' -d emails/compiled'
         
     | 
| 
       21 
21 
     | 
    
         
             
              opts.separator '  bootstrap-email -p \'views/emails/*\' -d \'views/compiled_emails\''
         
     | 
| 
       22 
22 
     | 
    
         
             
              opts.separator '  cat input.html | bootstrap-email'
         
     | 
| 
       23 
23 
     | 
    
         
             
              opts.separator ''
         
     | 
| 
         @@ -13,21 +13,30 @@ module BootstrapEmail 
     | 
|
| 
       13 
13 
     | 
    
         
             
                  when :file
         
     | 
| 
       14 
14 
     | 
    
         
             
                    html = File.read(input)
         
     | 
| 
       15 
15 
     | 
    
         
             
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  html = add_layout!(html)
         
     | 
| 
       16 
17 
     | 
    
         
             
                  build_premailer_doc(html, options)
         
     | 
| 
       17 
18 
     | 
    
         
             
                end
         
     | 
| 
       18 
19 
     | 
    
         | 
| 
       19 
20 
     | 
    
         
             
                def perform_full_compile
         
     | 
| 
       20 
21 
     | 
    
         
             
                  compile_html!
         
     | 
| 
       21 
22 
     | 
    
         
             
                  inline_css!
         
     | 
| 
       22 
     | 
    
         
            -
                   
     | 
| 
       23 
     | 
    
         
            -
                  inject_comment!
         
     | 
| 
      
 23 
     | 
    
         
            +
                  configure_html!
         
     | 
| 
       24 
24 
     | 
    
         
             
                  finalize_document!
         
     | 
| 
       25 
25 
     | 
    
         
             
                end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                private
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
                def add_layout!(html)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  document = Nokogiri::HTML(html)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  return html unless document.at_css('head').nil?
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  BootstrapEmail::Erb.template(
         
     | 
| 
      
 34 
     | 
    
         
            +
                    File.expand_path('../../core/layout.html.erb', __dir__),
         
     | 
| 
      
 35 
     | 
    
         
            +
                    contents: html
         
     | 
| 
      
 36 
     | 
    
         
            +
                  )
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
       29 
39 
     | 
    
         
             
                def build_premailer_doc(html, options)
         
     | 
| 
       30 
     | 
    
         
            -
                  html = add_layout!(html)
         
     | 
| 
       31 
40 
     | 
    
         
             
                  SassC.load_paths << File.expand_path('../../core', __dir__)
         
     | 
| 
       32 
41 
     | 
    
         
             
                  css_string = BootstrapEmail::SassCache.compile('bootstrap-email', config_path: options[:config_path], style: :expanded)
         
     | 
| 
       33 
42 
     | 
    
         
             
                  self.premailer = Premailer.new(
         
     | 
| 
         @@ -39,80 +48,51 @@ module BootstrapEmail 
     | 
|
| 
       39 
48 
     | 
    
         
             
                  self.doc = premailer.doc
         
     | 
| 
       40 
49 
     | 
    
         
             
                end
         
     | 
| 
       41 
50 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
                def add_layout!(html)
         
     | 
| 
       43 
     | 
    
         
            -
                  document = Nokogiri::HTML(html)
         
     | 
| 
       44 
     | 
    
         
            -
                  return document.to_html unless document.at_css('head').nil?
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                  namespace = OpenStruct.new(contents: ERB.new(document.to_html).result)
         
     | 
| 
       47 
     | 
    
         
            -
                  template_html = File.read(File.expand_path('../../core/layout.html.erb', __dir__))
         
     | 
| 
       48 
     | 
    
         
            -
                  ERB.new(template_html).result(namespace.instance_eval { binding })
         
     | 
| 
       49 
     | 
    
         
            -
                end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
51 
     | 
    
         
             
                def compile_html!
         
     | 
| 
      
 52 
     | 
    
         
            +
                  BootstrapEmail::Component::Block.build(doc)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
       52 
54 
     | 
    
         
             
                  BootstrapEmail::Component::Button.build(doc)
         
     | 
| 
       53 
55 
     | 
    
         
             
                  BootstrapEmail::Component::Badge.build(doc)
         
     | 
| 
       54 
56 
     | 
    
         
             
                  BootstrapEmail::Component::Alert.build(doc)
         
     | 
| 
       55 
57 
     | 
    
         
             
                  BootstrapEmail::Component::Card.build(doc)
         
     | 
| 
       56 
     | 
    
         
            -
                  BootstrapEmail::Component::Paragraph.build(doc)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # BootstrapEmail::Component::Paragraph.build(doc) this might be too much
         
     | 
| 
       57 
59 
     | 
    
         
             
                  BootstrapEmail::Component::Hr.build(doc)
         
     | 
| 
       58 
60 
     | 
    
         
             
                  BootstrapEmail::Component::Container.build(doc)
         
     | 
| 
       59 
61 
     | 
    
         
             
                  BootstrapEmail::Component::Grid.build(doc)
         
     | 
| 
       60 
     | 
    
         
            -
                  BootstrapEmail::Component:: 
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 62 
     | 
    
         
            +
                  BootstrapEmail::Component::Stack.build(doc)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  BootstrapEmail::Component::Spacing.build(doc)
         
     | 
| 
       62 
65 
     | 
    
         
             
                  BootstrapEmail::Component::Padding.build(doc)
         
     | 
| 
       63 
66 
     | 
    
         
             
                  BootstrapEmail::Component::Margin.build(doc)
         
     | 
| 
       64 
     | 
    
         
            -
                  BootstrapEmail::Component::Spacing.build(doc)
         
     | 
| 
       65 
67 
     | 
    
         
             
                  BootstrapEmail::Component::Spacer.build(doc)
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
       66 
69 
     | 
    
         
             
                  BootstrapEmail::Component::Table.build(doc)
         
     | 
| 
       67 
70 
     | 
    
         
             
                  BootstrapEmail::Component::Body.build(doc)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  BootstrapEmail::Component::Align.build(doc)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  BootstrapEmail::Component::Color.build(doc)
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  BootstrapEmail::Component::PreviewText.build(doc)
         
     | 
| 
       68 
75 
     | 
    
         
             
                end
         
     | 
| 
       69 
76 
     | 
    
         | 
| 
       70 
77 
     | 
    
         
             
                def inline_css!
         
     | 
| 
       71 
78 
     | 
    
         
             
                  premailer.to_inline_css
         
     | 
| 
       72 
79 
     | 
    
         
             
                end
         
     | 
| 
       73 
80 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
                def  
     | 
| 
       75 
     | 
    
         
            -
                   
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                def inject_comment!
         
     | 
| 
       79 
     | 
    
         
            -
                  doc.at_css('head').prepend_child(bootstrap_email_comment)
         
     | 
| 
      
 81 
     | 
    
         
            +
                def configure_html!
         
     | 
| 
      
 82 
     | 
    
         
            +
                  BootstrapEmail::Component::ForceEncoding.build(doc)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  BootstrapEmail::Component::HeadStyle.build(doc)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  BootstrapEmail::Component::VersionComment.build(doc)
         
     | 
| 
       80 
85 
     | 
    
         
             
                end
         
     | 
| 
       81 
86 
     | 
    
         | 
| 
       82 
87 
     | 
    
         
             
                def finalize_document!
         
     | 
| 
      
 88 
     | 
    
         
            +
                  html = BootstrapEmail::Component::ForceEncoding.replace(doc.to_html)
         
     | 
| 
       83 
89 
     | 
    
         
             
                  case type
         
     | 
| 
       84 
90 
     | 
    
         
             
                  when :rails
         
     | 
| 
       85 
     | 
    
         
            -
                    (@mail.html_part || @mail).body =  
     | 
| 
      
 91 
     | 
    
         
            +
                    (@mail.html_part || @mail).body = html
         
     | 
| 
       86 
92 
     | 
    
         
             
                    @mail
         
     | 
| 
       87 
93 
     | 
    
         
             
                  when :string, :file
         
     | 
| 
       88 
     | 
    
         
            -
                     
     | 
| 
       89 
     | 
    
         
            -
                  end
         
     | 
| 
       90 
     | 
    
         
            -
                end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                def bootstrap_email_head
         
     | 
| 
       93 
     | 
    
         
            -
                  html_string = <<-INLINE
         
     | 
| 
       94 
     | 
    
         
            -
                    <style type="text/css">
         
     | 
| 
       95 
     | 
    
         
            -
                      #{purged_css_from_head}
         
     | 
| 
       96 
     | 
    
         
            -
                    </style>
         
     | 
| 
       97 
     | 
    
         
            -
                  INLINE
         
     | 
| 
       98 
     | 
    
         
            -
                  html_string
         
     | 
| 
       99 
     | 
    
         
            -
                end
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
                def bootstrap_email_comment
         
     | 
| 
       102 
     | 
    
         
            -
                  "\n    <!-- Compiled with Bootstrap Email version: #{BootstrapEmail::VERSION} -->"
         
     | 
| 
       103 
     | 
    
         
            -
                end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
                def purged_css_from_head
         
     | 
| 
       106 
     | 
    
         
            -
                  default, custom = BootstrapEmail::SassCache.compile('bootstrap-head').split('/*! allow_purge_after */')
         
     | 
| 
       107 
     | 
    
         
            -
                  # get each CSS declaration
         
     | 
| 
       108 
     | 
    
         
            -
                  custom.scan(/\w*\.[\w\-]*[\s\S\n]+?(?=})}{1}/).each do |group|
         
     | 
| 
       109 
     | 
    
         
            -
                    # get the first class for each comma separated CSS declaration
         
     | 
| 
       110 
     | 
    
         
            -
                    exist = group.scan(/(\.[\w\-]*).*?((,+?)|{+?)/).map(&:first).uniq.any? do |selector|
         
     | 
| 
       111 
     | 
    
         
            -
                      !doc.at_css(selector).nil?
         
     | 
| 
       112 
     | 
    
         
            -
                    end
         
     | 
| 
       113 
     | 
    
         
            -
                    custom.sub!(group, '') unless exist
         
     | 
| 
      
 94 
     | 
    
         
            +
                    html
         
     | 
| 
       114 
95 
     | 
    
         
             
                  end
         
     | 
| 
       115 
     | 
    
         
            -
                  (default + custom).gsub(/\n\s*\n+/, "\n")
         
     | 
| 
       116 
96 
     | 
    
         
             
                end
         
     | 
| 
       117 
97 
     | 
    
         
             
              end
         
     | 
| 
       118 
98 
     | 
    
         
             
            end
         
     | 
| 
         @@ -3,16 +3,17 @@ module BootstrapEmail 
     | 
|
| 
       3 
3 
     | 
    
         
             
                class Align < Base
         
     | 
| 
       4 
4 
     | 
    
         
             
                  def build
         
     | 
| 
       5 
5 
     | 
    
         
             
                   ['left', 'center', 'right'].each do |type|
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
                    full_type = "align-#{type}"
         
     | 
| 
      
 7 
     | 
    
         
            +
                     each_node(".#{full_type}") do |node|
         
     | 
| 
      
 8 
     | 
    
         
            +
                       align_helper(node, full_type, type)
         
     | 
| 
       8 
9 
     | 
    
         
             
                     end
         
     | 
| 
       9 
10 
     | 
    
         
             
                   end
         
     | 
| 
       10 
11 
     | 
    
         
             
                  end
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                  def align_helper(node, type)
         
     | 
| 
       13 
     | 
    
         
            -
                     
     | 
| 
       14 
     | 
    
         
            -
                      node['class'] = node['class'].sub( 
     | 
| 
       15 
     | 
    
         
            -
                      node = node.replace(template('table', classes:  
     | 
| 
      
 13 
     | 
    
         
            +
                  def align_helper(node, full_type, type)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    unless table?(node) || td?(node)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      node['class'] = node['class'].sub(full_type, '')
         
     | 
| 
      
 16 
     | 
    
         
            +
                      node = node.replace(template('table', classes: full_type, contents: node.to_html))[0]
         
     | 
| 
       16 
17 
     | 
    
         
             
                    end
         
     | 
| 
       17 
18 
     | 
    
         
             
                    node['align'] = type
         
     | 
| 
       18 
19 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -10,17 +10,45 @@ module BootstrapEmail 
     | 
|
| 
       10 
10 
     | 
    
         
             
                    new(doc).build
         
     | 
| 
       11 
11 
     | 
    
         
             
                  end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
                  private
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       13 
15 
     | 
    
         
             
                  def template(file, locals_hash = {})
         
     | 
| 
       14 
16 
     | 
    
         
             
                    locals_hash[:classes] = locals_hash[:classes].split.join(' ') if locals_hash[:classes]
         
     | 
| 
       15 
     | 
    
         
            -
                     
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
                    BootstrapEmail::Erb.template(
         
     | 
| 
      
 18 
     | 
    
         
            +
                      File.expand_path("../../../core/templates/#{file}.html.erb", __dir__),
         
     | 
| 
      
 19 
     | 
    
         
            +
                      locals_hash
         
     | 
| 
      
 20 
     | 
    
         
            +
                    )
         
     | 
| 
       18 
21 
     | 
    
         
             
                  end
         
     | 
| 
       19 
22 
     | 
    
         | 
| 
       20 
23 
     | 
    
         
             
                  def each_node(css_lookup, &blk)
         
     | 
| 
       21 
24 
     | 
    
         
             
                    # sort by youngest child and traverse backwards up the tree
         
     | 
| 
       22 
25 
     | 
    
         
             
                    doc.css(css_lookup).sort_by { |n| n.ancestors.size }.reverse!.each(&blk)
         
     | 
| 
       23 
26 
     | 
    
         
             
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def add_class(node, class_name)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    node['class'] ||= ''
         
     | 
| 
      
 30 
     | 
    
         
            +
                    node['class'] += class_name
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def margin?(node)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    margin_top?(node) || margin_bottom?(node)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  def margin_top?(node)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    node['class'].to_s.match?(/m[ty]{1}-(lg-)?\d+/)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def margin_bottom?(node)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    node['class'].to_s.match?(/m[by]{1}-(lg-)?\d+/)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def table?(node)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    node.name == 'table'
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def td?(node)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    node.name == 'td'
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
       24 
52 
     | 
    
         
             
                end
         
     | 
| 
       25 
53 
     | 
    
         
             
              end
         
     | 
| 
       26 
54 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module BootstrapEmail
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Component
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Block < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def build
         
     | 
| 
      
 5 
     | 
    
         
            +
                    each_node('block, .to-table') do |node|
         
     | 
| 
      
 6 
     | 
    
         
            +
                      # add .to-table if it's not already there
         
     | 
| 
      
 7 
     | 
    
         
            +
                      class_name = node['class'].to_s.split << 'to-table'
         
     | 
| 
      
 8 
     | 
    
         
            +
                      node.replace(template('table', classes: class_name.uniq.join(' '), contents: node.inner_html))
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -2,20 +2,8 @@ module BootstrapEmail 
     | 
|
| 
       2 
2 
     | 
    
         
             
              module Component
         
     | 
| 
       3 
3 
     | 
    
         
             
                class Body < Base
         
     | 
| 
       4 
4 
     | 
    
         
             
                  def build
         
     | 
| 
       5 
     | 
    
         
            -
                     
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
                    end
         
     | 
| 
       8 
     | 
    
         
            -
                  end
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                  def preview_text
         
     | 
| 
       11 
     | 
    
         
            -
                    preview_node = doc.at_css('preview')
         
     | 
| 
       12 
     | 
    
         
            -
                    return if preview_node.nil?
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    # apply spacing after the text max of 100 characters so it doesn't show body text
         
     | 
| 
       15 
     | 
    
         
            -
                    preview_node.content += ' ' * [(100 - preview_node.content.length.to_i), 0].max
         
     | 
| 
       16 
     | 
    
         
            -
                    node = template('div', classes: 'preview', contents: preview_node.content)
         
     | 
| 
       17 
     | 
    
         
            -
                    preview_node.remove
         
     | 
| 
       18 
     | 
    
         
            -
                    node
         
     | 
| 
      
 5 
     | 
    
         
            +
                    body = doc.at_css('body')
         
     | 
| 
      
 6 
     | 
    
         
            +
                    body.inner_html = template('body', classes: "#{body['class']} body", contents: body.inner_html)
         
     | 
| 
       19 
7 
     | 
    
         
             
                  end
         
     | 
| 
       20 
8 
     | 
    
         
             
                end
         
     | 
| 
       21 
9 
     | 
    
         
             
              end
         
     | 
| 
         @@ -3,10 +3,10 @@ module BootstrapEmail 
     | 
|
| 
       3 
3 
     | 
    
         
             
                class Card < Base
         
     | 
| 
       4 
4 
     | 
    
         
             
                  def build
         
     | 
| 
       5 
5 
     | 
    
         
             
                    each_node('.card') do |node|
         
     | 
| 
       6 
     | 
    
         
            -
                      node.replace(template('table', classes: node['class'], contents: node. 
     | 
| 
      
 6 
     | 
    
         
            +
                      node.replace(template('table', classes: node['class'], contents: node.inner_html))
         
     | 
| 
       7 
7 
     | 
    
         
             
                    end
         
     | 
| 
       8 
8 
     | 
    
         
             
                    each_node('.card-body') do |node|
         
     | 
| 
       9 
     | 
    
         
            -
                      node.replace(template('table', classes: node['class'], contents: node. 
     | 
| 
      
 9 
     | 
    
         
            +
                      node.replace(template('table', classes: node['class'], contents: node.inner_html))
         
     | 
| 
       10 
10 
     | 
    
         
             
                    end
         
     | 
| 
       11 
11 
     | 
    
         
             
                  end
         
     | 
| 
       12 
12 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 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;">➿</div>')
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -3,10 +3,10 @@ module BootstrapEmail 
     | 
|
| 
       3 
3 
     | 
    
         
             
                class Grid < Base
         
     | 
| 
       4 
4 
     | 
    
         
             
                  def build
         
     | 
| 
       5 
5 
     | 
    
         
             
                    each_node('.row') do |node|
         
     | 
| 
       6 
     | 
    
         
            -
                      node.replace(template(' 
     | 
| 
      
 6 
     | 
    
         
            +
                      node.replace(template('table-to-tr', classes: node['class'], contents: node.inner_html))
         
     | 
| 
       7 
7 
     | 
    
         
             
                    end
         
     | 
| 
       8 
8 
     | 
    
         
             
                    each_node('*[class*=col]') do |node|
         
     | 
| 
       9 
     | 
    
         
            -
                      node.replace(template(' 
     | 
| 
      
 9 
     | 
    
         
            +
                      node.replace(template('td', classes: node['class'], contents: node.inner_html))
         
     | 
| 
       10 
10 
     | 
    
         
             
                    end
         
     | 
| 
       11 
11 
     | 
    
         
             
                  end
         
     | 
| 
       12 
12 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module BootstrapEmail
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Component
         
     | 
| 
      
 3 
     | 
    
         
            +
                class HeadStyle < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def build
         
     | 
| 
      
 5 
     | 
    
         
            +
                    doc.at_css('head').add_child(bootstrap_email_head)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  private
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def bootstrap_email_head
         
     | 
| 
      
 11 
     | 
    
         
            +
                    html_string = <<-INLINE
         
     | 
| 
      
 12 
     | 
    
         
            +
                      <style type="text/css">
         
     | 
| 
      
 13 
     | 
    
         
            +
                        #{purged_css_from_head}
         
     | 
| 
      
 14 
     | 
    
         
            +
                      </style>
         
     | 
| 
      
 15 
     | 
    
         
            +
                    INLINE
         
     | 
| 
      
 16 
     | 
    
         
            +
                    html_string
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def purged_css_from_head
         
     | 
| 
      
 20 
     | 
    
         
            +
                    default, custom = BootstrapEmail::SassCache.compile('bootstrap-head').split('/*! allow_purge_after */')
         
     | 
| 
      
 21 
     | 
    
         
            +
                    # get each CSS declaration
         
     | 
| 
      
 22 
     | 
    
         
            +
                    custom.scan(/\w*\.[\w\-]*[\s\S\n]+?(?=})}{1}/).each do |group|
         
     | 
| 
      
 23 
     | 
    
         
            +
                      # get the first class for each comma separated CSS declaration
         
     | 
| 
      
 24 
     | 
    
         
            +
                      exist = group.scan(/(\.[\w\-]*).*?((,+?)|{+?)/).map(&:first).uniq.any? do |selector|
         
     | 
| 
      
 25 
     | 
    
         
            +
                        !doc.at_css(selector).nil?
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                      custom.sub!(group, '') unless exist
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                    (default + custom).gsub(/\n\s*\n+/, "\n")
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -3,7 +3,7 @@ module BootstrapEmail 
     | 
|
| 
       3 
3 
     | 
    
         
             
                class Hr < Base
         
     | 
| 
       4 
4 
     | 
    
         
             
                  def build
         
     | 
| 
       5 
5 
     | 
    
         
             
                    each_node('hr') do |node|
         
     | 
| 
       6 
     | 
    
         
            -
                      default_margin =  
     | 
| 
      
 6 
     | 
    
         
            +
                      default_margin = margin?(node) ? '' : 'my-5'
         
     | 
| 
       7 
7 
     | 
    
         
             
                      node.replace(template('table', classes: "#{default_margin} hr #{node['class']}", contents: ''))
         
     | 
| 
       8 
8 
     | 
    
         
             
                    end
         
     | 
| 
       9 
9 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -3,22 +3,11 @@ module BootstrapEmail 
     | 
|
| 
       3 
3 
     | 
    
         
             
                class Paragraph < Base
         
     | 
| 
       4 
4 
     | 
    
         
             
                  def build
         
     | 
| 
       5 
5 
     | 
    
         
             
                    each_node('p') do |node|
         
     | 
| 
       6 
     | 
    
         
            -
                      next if margin?(node) 
     | 
| 
      
 6 
     | 
    
         
            +
                      next if margin?(node)
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                      node 
     | 
| 
       9 
     | 
    
         
            -
                      node['class'] += 'mb-4'
         
     | 
| 
      
 8 
     | 
    
         
            +
                      add_class(node, 'mb-4')
         
     | 
| 
       10 
9 
     | 
    
         
             
                    end
         
     | 
| 
       11 
10 
     | 
    
         
             
                  end
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
                  private
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  def margin?(node)
         
     | 
| 
       16 
     | 
    
         
            -
                    node['class'].to_s.match?(/m[tby]{1}-(lg-)?\d+/)
         
     | 
| 
       17 
     | 
    
         
            -
                  end
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                  def space_y?(node)
         
     | 
| 
       20 
     | 
    
         
            -
                    node.parent['class'].to_s.match?(/space-y-(lg-)?\d+/)
         
     | 
| 
       21 
     | 
    
         
            -
                  end
         
     | 
| 
       22 
11 
     | 
    
         
             
                end
         
     | 
| 
       23 
12 
     | 
    
         
             
              end
         
     | 
| 
       24 
13 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module BootstrapEmail
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Component
         
     | 
| 
      
 3 
     | 
    
         
            +
                class PreviewText < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def build
         
     | 
| 
      
 5 
     | 
    
         
            +
                    preview_node = doc.at_css('preview')
         
     | 
| 
      
 6 
     | 
    
         
            +
                    return if preview_node.nil?
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    # apply spacing after the text max of 100 characters so it doesn't show body text
         
     | 
| 
      
 9 
     | 
    
         
            +
                    preview_node.inner_html += ' ' * [(100 - preview_node.content.length.to_i), 0].max
         
     | 
| 
      
 10 
     | 
    
         
            +
                    node = template('div', classes: 'preview', contents: preview_node.content)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    preview_node.remove
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    body = doc.at_css('body')
         
     | 
| 
      
 14 
     | 
    
         
            +
                    body.prepend_child(node)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -5,11 +5,10 @@ module BootstrapEmail 
     | 
|
| 
       5 
5 
     | 
    
         
             
                    each_node('*[class*=space-y-]') do |node|
         
     | 
| 
       6 
6 
     | 
    
         
             
                      spacer = node['class'].scan(/space-y-((lg-)?\d+)/)[0][0]
         
     | 
| 
       7 
7 
     | 
    
         
             
                      # get all direct children except the first
         
     | 
| 
       8 
     | 
    
         
            -
                      node.xpath('./*[position() 
     | 
| 
       9 
     | 
    
         
            -
                         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                         
     | 
| 
       12 
     | 
    
         
            -
                        child.replace(html)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      node.xpath('./*[position() < last()] | ./tbody/tr/td/*[position() < last()]').each do |child|
         
     | 
| 
      
 9 
     | 
    
         
            +
                        next if margin_bottom?(child)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                        add_class(child, "mb-#{spacer}")
         
     | 
| 
       13 
12 
     | 
    
         
             
                      end
         
     | 
| 
       14 
13 
     | 
    
         
             
                    end
         
     | 
| 
       15 
14 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module BootstrapEmail
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Component
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Stack < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def build
         
     | 
| 
      
 5 
     | 
    
         
            +
                    stack_x
         
     | 
| 
      
 6 
     | 
    
         
            +
                    stack_y
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def stack_x
         
     | 
| 
      
 10 
     | 
    
         
            +
                    each_node('.stack-x') do |node|
         
     | 
| 
      
 11 
     | 
    
         
            +
                      html = ''
         
     | 
| 
      
 12 
     | 
    
         
            +
                      node.xpath('./*').each do |child|
         
     | 
| 
      
 13 
     | 
    
         
            +
                        html += template('td', classes: 'stack-cell', contents: child.to_html)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                      node.replace(template('table-to-tr', classes: node['class'], contents: html))
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def stack_y
         
     | 
| 
      
 20 
     | 
    
         
            +
                    each_node('.stack-y') do |node|
         
     | 
| 
      
 21 
     | 
    
         
            +
                      html = ''
         
     | 
| 
      
 22 
     | 
    
         
            +
                      node.xpath('./*').each do |child|
         
     | 
| 
      
 23 
     | 
    
         
            +
                        html += template('tr', classes: 'stack-cell', contents: child.to_html)
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                      node.replace(template('table-to-tbody', classes: node['class'], contents: html))
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module BootstrapEmail
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Component
         
     | 
| 
      
 3 
     | 
    
         
            +
                class VersionComment < Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def build
         
     | 
| 
      
 5 
     | 
    
         
            +
                    doc.at_css('head').prepend_child(bootstrap_email_comment)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  private
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def bootstrap_email_comment
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "\n    <!-- Compiled with Bootstrap Email version: #{BootstrapEmail::VERSION} -->"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -5,6 +5,7 @@ ActiveSupport.on_load(:action_mailer, {yield: true}) do |action_mailer| 
     | 
|
| 
       5 
5 
     | 
    
         
             
                  bootstrap = BootstrapEmail::Compiler.new(mail(*args, &block), type: :rails)
         
     | 
| 
       6 
6 
     | 
    
         
             
                  bootstrap.perform_full_compile
         
     | 
| 
       7 
7 
     | 
    
         
             
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
                alias bootstrap_email bootstrap_mail
         
     | 
| 
       8 
9 
     | 
    
         
             
                alias make_bootstrap_mail bootstrap_mail
         
     | 
| 
       9 
10 
     | 
    
         
             
              end
         
     | 
| 
       10 
11 
     | 
    
         
             
            end
         
     | 
| 
         @@ -3,36 +3,47 @@ module BootstrapEmail 
     | 
|
| 
       3 
3 
     | 
    
         
             
                CACHE_DIR = File.expand_path('../../.sass-cache', __dir__)
         
     | 
| 
       4 
4 
     | 
    
         
             
                SASS_DIR = File.expand_path('../../core', __dir__)
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
                def self.compile( 
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 6 
     | 
    
         
            +
                def self.compile(type, config_path: nil, style: :compressed)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  new(type, config_path, style).compile
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
                attr_accessor :type, :style, :file_path, :config_file, :checksum
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(type, config_path, style)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.type = type
         
     | 
| 
      
 14 
     | 
    
         
            +
                  self.style = style
         
     | 
| 
      
 15 
     | 
    
         
            +
                  self.file_path = "#{SASS_DIR}/#{type}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  self.config_file = load_config(config_path)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  self.checksum = checksum_files
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def compile
         
     | 
| 
      
 21 
     | 
    
         
            +
                  cache_path = "#{CACHE_DIR}/#{checksum}/#{type}.css"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  unless cached?(cache_path)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    compile_and_cache_scss(cache_path)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  File.read(cache_path)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
       12 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
                private
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 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)) }
         
     | 
| 
       13 
33 
     | 
    
         
             
                  if config_path && File.exist?(config_path)
         
     | 
| 
       14 
34 
     | 
    
         
             
                    # check if custom config was passed in
         
     | 
| 
       15 
     | 
    
         
            -
                     
     | 
| 
      
 35 
     | 
    
         
            +
                    replace_config(File.read(config_path))
         
     | 
| 
       16 
36 
     | 
    
         
             
                  elsif locations.any?
         
     | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
      
 37 
     | 
    
         
            +
                    # look for common lookup locations of config
         
     | 
| 
      
 38 
     | 
    
         
            +
                    replace_config(File.read(File.expand_path(locations.first, Dir.pwd)))
         
     | 
| 
       18 
39 
     | 
    
         
             
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
       19 
41 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
                  if cached?(cache_path)
         
     | 
| 
       23 
     | 
    
         
            -
                    File.read(cache_path)
         
     | 
| 
       24 
     | 
    
         
            -
                  else
         
     | 
| 
       25 
     | 
    
         
            -
                    file = config_file.nil? ? File.read("#{path}.scss") : config_file
         
     | 
| 
       26 
     | 
    
         
            -
                    SassC::Engine.new(file, style: style).render.tap do |css|
         
     | 
| 
       27 
     | 
    
         
            -
                      Dir.mkdir(CACHE_DIR) unless File.directory?(CACHE_DIR)
         
     | 
| 
       28 
     | 
    
         
            -
                      Dir.mkdir("#{CACHE_DIR}/#{check}") unless File.directory?("#{CACHE_DIR}/#{check}")
         
     | 
| 
       29 
     | 
    
         
            -
                      File.write(cache_path, css)
         
     | 
| 
       30 
     | 
    
         
            -
                      puts "New css file cached for #{name}"
         
     | 
| 
       31 
     | 
    
         
            -
                    end
         
     | 
| 
       32 
     | 
    
         
            -
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                def replace_config(config_file)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  config_file.gsub("//= @import #{type};", "@import '#{file_path}';")
         
     | 
| 
       33 
44 
     | 
    
         
             
                end
         
     | 
| 
       34 
45 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
                def  
     | 
| 
      
 46 
     | 
    
         
            +
                def checksum_files
         
     | 
| 
       36 
47 
     | 
    
         
             
                  checksums = config_file.nil? ? [] : [Digest::SHA1.hexdigest(config_file)]
         
     | 
| 
       37 
48 
     | 
    
         
             
                  Dir.glob('../../core/**/*.scss', base: __dir__).each do |path|
         
     | 
| 
       38 
49 
     | 
    
         
             
                    checksums << Digest::SHA1.file(File.expand_path(path, __dir__)).hexdigest
         
     | 
| 
         @@ -40,8 +51,17 @@ module BootstrapEmail 
     | 
|
| 
       40 
51 
     | 
    
         
             
                  Digest::SHA1.hexdigest(checksums.join)
         
     | 
| 
       41 
52 
     | 
    
         
             
                end
         
     | 
| 
       42 
53 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                def  
     | 
| 
      
 54 
     | 
    
         
            +
                def cached?(cache_path)
         
     | 
| 
       44 
55 
     | 
    
         
             
                  File.file?(cache_path)
         
     | 
| 
       45 
56 
     | 
    
         
             
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def compile_and_cache_scss(cache_path)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  file = config_file || File.read("#{file_path}.scss")
         
     | 
| 
      
 60 
     | 
    
         
            +
                  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}")
         
     | 
| 
      
 63 
     | 
    
         
            +
                  File.write(cache_path, css)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  puts "New css file cached for #{type}"
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
       46 
66 
     | 
    
         
             
              end
         
     | 
| 
       47 
67 
     | 
    
         
             
            end
         
     | 
    
        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. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.0.alpha2
         
     | 
| 
       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- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2021-03-13 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: nokogiri
         
     | 
| 
         @@ -30,28 +30,28 @@ dependencies: 
     | 
|
| 
       30 
30 
     | 
    
         
             
                requirements:
         
     | 
| 
       31 
31 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       32 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       33 
     | 
    
         
            -
                    version: '1. 
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '1.7'
         
     | 
| 
       34 
34 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       35 
35 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       36 
36 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       37 
37 
     | 
    
         
             
                requirements:
         
     | 
| 
       38 
38 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       39 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
     | 
    
         
            -
                    version: '1. 
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '1.7'
         
     | 
| 
       41 
41 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       42 
42 
     | 
    
         
             
              name: sassc
         
     | 
| 
       43 
43 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       44 
44 
     | 
    
         
             
                requirements:
         
     | 
| 
       45 
45 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       46 
46 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       47 
     | 
    
         
            -
                    version: '2. 
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
       48 
48 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       49 
49 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       50 
50 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       51 
51 
     | 
    
         
             
                requirements:
         
     | 
| 
       52 
52 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       53 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       54 
     | 
    
         
            -
                    version: '2. 
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
       55 
55 
     | 
    
         
             
            description:
         
     | 
| 
       56 
56 
     | 
    
         
             
            email: stu@stuyam.com
         
     | 
| 
       57 
57 
     | 
    
         
             
            executables:
         
     | 
| 
         @@ -80,6 +80,7 @@ files: 
     | 
|
| 
       80 
80 
     | 
    
         
             
            - core/scss/components/_hr.scss
         
     | 
| 
       81 
81 
     | 
    
         
             
            - core/scss/components/_image.scss
         
     | 
| 
       82 
82 
     | 
    
         
             
            - core/scss/components/_preview.scss
         
     | 
| 
      
 83 
     | 
    
         
            +
            - core/scss/components/_stack.scss
         
     | 
| 
       83 
84 
     | 
    
         
             
            - core/scss/components/_table.scss
         
     | 
| 
       84 
85 
     | 
    
         
             
            - core/scss/utilities/_background.scss
         
     | 
| 
       85 
86 
     | 
    
         
             
            - core/scss/utilities/_border-radius.scss
         
     | 
| 
         @@ -90,38 +91,48 @@ files: 
     | 
|
| 
       90 
91 
     | 
    
         
             
            - core/scss/utilities/_spacing.scss
         
     | 
| 
       91 
92 
     | 
    
         
             
            - core/scss/utilities/_text-decoration.scss
         
     | 
| 
       92 
93 
     | 
    
         
             
            - core/scss/utilities/_typography.scss
         
     | 
| 
      
 94 
     | 
    
         
            +
            - core/scss/utilities/_valign.scss
         
     | 
| 
       93 
95 
     | 
    
         
             
            - core/templates/body.html.erb
         
     | 
| 
       94 
     | 
    
         
            -
            - core/templates/col.html.erb
         
     | 
| 
       95 
96 
     | 
    
         
             
            - core/templates/container.html.erb
         
     | 
| 
       96 
97 
     | 
    
         
             
            - core/templates/div.html.erb
         
     | 
| 
       97 
     | 
    
         
            -
            - core/templates/row.html.erb
         
     | 
| 
       98 
98 
     | 
    
         
             
            - core/templates/table-left.html.erb
         
     | 
| 
      
 99 
     | 
    
         
            +
            - core/templates/table-to-tbody.html.erb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - core/templates/table-to-tr.html.erb
         
     | 
| 
       99 
101 
     | 
    
         
             
            - core/templates/table.html.erb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - core/templates/td.html.erb
         
     | 
| 
      
 103 
     | 
    
         
            +
            - core/templates/tr.html.erb
         
     | 
| 
      
 104 
     | 
    
         
            +
            - lib/bootstrap-email.rb
         
     | 
| 
       100 
105 
     | 
    
         
             
            - lib/bootstrap-email/bootstrap_email_cli.rb
         
     | 
| 
       101 
106 
     | 
    
         
             
            - lib/bootstrap-email/compiler.rb
         
     | 
| 
       102 
107 
     | 
    
         
             
            - lib/bootstrap-email/components/alert.rb
         
     | 
| 
       103 
108 
     | 
    
         
             
            - lib/bootstrap-email/components/align.rb
         
     | 
| 
       104 
109 
     | 
    
         
             
            - lib/bootstrap-email/components/badge.rb
         
     | 
| 
       105 
110 
     | 
    
         
             
            - lib/bootstrap-email/components/base.rb
         
     | 
| 
      
 111 
     | 
    
         
            +
            - lib/bootstrap-email/components/block.rb
         
     | 
| 
       106 
112 
     | 
    
         
             
            - lib/bootstrap-email/components/body.rb
         
     | 
| 
       107 
113 
     | 
    
         
             
            - lib/bootstrap-email/components/button.rb
         
     | 
| 
       108 
114 
     | 
    
         
             
            - lib/bootstrap-email/components/card.rb
         
     | 
| 
       109 
115 
     | 
    
         
             
            - lib/bootstrap-email/components/color.rb
         
     | 
| 
       110 
116 
     | 
    
         
             
            - lib/bootstrap-email/components/container.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - lib/bootstrap-email/components/force_encoding.rb
         
     | 
| 
       111 
118 
     | 
    
         
             
            - lib/bootstrap-email/components/grid.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - lib/bootstrap-email/components/head_style.rb
         
     | 
| 
       112 
120 
     | 
    
         
             
            - lib/bootstrap-email/components/hr.rb
         
     | 
| 
       113 
121 
     | 
    
         
             
            - lib/bootstrap-email/components/margin.rb
         
     | 
| 
       114 
122 
     | 
    
         
             
            - lib/bootstrap-email/components/padding.rb
         
     | 
| 
       115 
123 
     | 
    
         
             
            - lib/bootstrap-email/components/paragraph.rb
         
     | 
| 
      
 124 
     | 
    
         
            +
            - lib/bootstrap-email/components/preview_text.rb
         
     | 
| 
       116 
125 
     | 
    
         
             
            - lib/bootstrap-email/components/spacer.rb
         
     | 
| 
       117 
126 
     | 
    
         
             
            - lib/bootstrap-email/components/spacing.rb
         
     | 
| 
      
 127 
     | 
    
         
            +
            - lib/bootstrap-email/components/stack.rb
         
     | 
| 
       118 
128 
     | 
    
         
             
            - lib/bootstrap-email/components/table.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - lib/bootstrap-email/components/version_comment.rb
         
     | 
| 
      
 130 
     | 
    
         
            +
            - lib/bootstrap-email/erb.rb
         
     | 
| 
       119 
131 
     | 
    
         
             
            - lib/bootstrap-email/initialize.rb
         
     | 
| 
       120 
132 
     | 
    
         
             
            - lib/bootstrap-email/rails/action_mailer.rb
         
     | 
| 
       121 
133 
     | 
    
         
             
            - lib/bootstrap-email/rails/engine.rb
         
     | 
| 
       122 
134 
     | 
    
         
             
            - lib/bootstrap-email/sass_cache.rb
         
     | 
| 
       123 
135 
     | 
    
         
             
            - lib/bootstrap-email/version.rb
         
     | 
| 
       124 
     | 
    
         
            -
            - lib/bootstrap_email.rb
         
     | 
| 
       125 
136 
     | 
    
         
             
            homepage: https://bootstrapemail.com
         
     | 
| 
       126 
137 
     | 
    
         
             
            licenses:
         
     | 
| 
       127 
138 
     | 
    
         
             
            - MIT
         
     | 
    
        data/core/templates/col.html.erb
    DELETED