antwort 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +19 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG.md +249 -0
  7. data/Gemfile +3 -0
  8. data/Guardfile +14 -0
  9. data/README.md +108 -0
  10. data/Rakefile +14 -0
  11. data/antwort.gemspec +45 -0
  12. data/bin/antwort +5 -0
  13. data/lib/antwort.rb +13 -0
  14. data/lib/antwort/builder.rb +8 -0
  15. data/lib/antwort/builder/builder.rb +104 -0
  16. data/lib/antwort/builder/email.rb +61 -0
  17. data/lib/antwort/builder/flattener.rb +37 -0
  18. data/lib/antwort/builder/helpers/logic.rb +82 -0
  19. data/lib/antwort/builder/helpers/sanitizers.rb +29 -0
  20. data/lib/antwort/builder/partial.rb +80 -0
  21. data/lib/antwort/builder/style.rb +59 -0
  22. data/lib/antwort/cli.rb +7 -0
  23. data/lib/antwort/cli/cli.rb +275 -0
  24. data/lib/antwort/cli/helpers.rb +44 -0
  25. data/lib/antwort/cli/send.rb +79 -0
  26. data/lib/antwort/cli/upload.rb +89 -0
  27. data/lib/antwort/helpers.rb +19 -0
  28. data/lib/antwort/server.rb +70 -0
  29. data/lib/antwort/server/assets.rb +23 -0
  30. data/lib/antwort/server/helpers.rb +67 -0
  31. data/lib/antwort/server/markup.rb +39 -0
  32. data/lib/antwort/version.rb +3 -0
  33. data/spec/builder/builder_spec.rb +30 -0
  34. data/spec/builder/email_spec.rb +21 -0
  35. data/spec/builder/flattener_spec.rb +64 -0
  36. data/spec/builder/helpers_logic_spec.rb +244 -0
  37. data/spec/builder/partial_spec.rb +87 -0
  38. data/spec/builder/style_spec.rb +66 -0
  39. data/spec/cli/helpers_spec.rb +60 -0
  40. data/spec/cli/upload_spec.rb +47 -0
  41. data/spec/cli_spec.rb +46 -0
  42. data/spec/fixtures/assets/images/1-demo/placeholder.png +0 -0
  43. data/spec/fixtures/assets/images/newsletter/placeholder.png +0 -0
  44. data/spec/fixtures/assets/images/shared/placeholder-grey.png +0 -0
  45. data/spec/fixtures/assets/images/shared/placeholder-white.png +0 -0
  46. data/spec/fixtures/build/demo-123456/build.html +7 -0
  47. data/spec/fixtures/build/demo-123457/build.html +7 -0
  48. data/spec/fixtures/build/demo-bar-123/build.html +7 -0
  49. data/spec/fixtures/build/foo-1/build.html +7 -0
  50. data/spec/fixtures/data/1-demo.yml +3 -0
  51. data/spec/fixtures/emails/1-demo/index.html.erb +9 -0
  52. data/spec/fixtures/emails/2-no-layout/index.html.erb +6 -0
  53. data/spec/fixtures/emails/3-no-title/index.html.erb +1 -0
  54. data/spec/fixtures/views/404.html.erb +1 -0
  55. data/spec/fixtures/views/index.html.erb +14 -0
  56. data/spec/fixtures/views/layout.erb +8 -0
  57. data/spec/fixtures/views/server.erb +5 -0
  58. data/spec/server_spec.rb +54 -0
  59. data/spec/spec_helper.rb +38 -0
  60. data/spec/support/capture.rb +17 -0
  61. data/template/email/css/include.scss +5 -0
  62. data/template/email/css/inline.scss +5 -0
  63. data/template/email/email.html.erb +11 -0
  64. data/template/email/images/.empty_directory +0 -0
  65. data/template/project/.env.sample +21 -0
  66. data/template/project/.gitignore.tt +17 -0
  67. data/template/project/.ruby-version +1 -0
  68. data/template/project/Gemfile.tt +9 -0
  69. data/template/project/Guardfile +9 -0
  70. data/template/project/assets/css/demo/include.scss +3 -0
  71. data/template/project/assets/css/demo/inline.scss +33 -0
  72. data/template/project/assets/css/server.scss +167 -0
  73. data/template/project/assets/css/shared/_base.scss +64 -0
  74. data/template/project/assets/css/shared/_mixins.scss +25 -0
  75. data/template/project/assets/css/shared/_reset.scss +59 -0
  76. data/template/project/assets/css/shared/_vars.scss +12 -0
  77. data/template/project/assets/css/shared/include.scss +23 -0
  78. data/template/project/assets/css/shared/inline.scss +9 -0
  79. data/template/project/assets/images/.gitkeep +0 -0
  80. data/template/project/assets/images/shared/placeholder.png +0 -0
  81. data/template/project/build/.empty_directory +0 -0
  82. data/template/project/data/.empty_directory +0 -0
  83. data/template/project/data/config.yml +3 -0
  84. data/template/project/data/demo.yml +4 -0
  85. data/template/project/emails/demo/_partial.html.erb +9 -0
  86. data/template/project/emails/demo/index.html.erb +54 -0
  87. data/template/project/views/404.html.erb +8 -0
  88. data/template/project/views/index.html.erb +18 -0
  89. data/template/project/views/layout.erb +38 -0
  90. data/template/project/views/markup/_button.html.erb +5 -0
  91. data/template/project/views/markup/_image_tag.html.erb +10 -0
  92. data/template/project/views/server.erb +32 -0
  93. metadata +443 -0
@@ -0,0 +1,38 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'pathname'
4
+ require 'antwort'
5
+ require 'rspec'
6
+ require 'rack/test'
7
+
8
+ Pathname.glob(Pathname(__dir__) + 'support' '**/*.rb').each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ # Run specs in random order to surface order dependencies. If you find an
12
+ # order dependency and want to debug it, you can fix the order by providing
13
+ # the seed, which is printed after each run.
14
+ # --seed 1234
15
+ config.order = 'random'
16
+
17
+ config.include Rack::Test::Methods
18
+
19
+ config.filter_run focus: true
20
+ config.run_all_when_everything_filtered = true
21
+ config.raise_errors_for_deprecations!
22
+
23
+ config.mock_with :rspec do |mocks|
24
+ mocks.syntax = :expect
25
+ end
26
+
27
+ # move to .env later
28
+ config.before :suite do
29
+ ENV['AWS_ACCESS_KEY_ID'] ||= 'MY_TEST_ACCESS_KEY'
30
+ ENV['AWS_SECRET_ACCESS_KEY'] ||= 'MY_TEST_SECRET_ACCESS_KEY'
31
+ ENV['AWS_BUCKET'] ||= 'MY_TEST_BUCKET'
32
+ end
33
+
34
+ def fixtures_root
35
+ File.join(File.dirname(__FILE__), "fixtures")
36
+ end
37
+
38
+ end
@@ -0,0 +1,17 @@
1
+ # Source: https://github.com/erikhuda/thor
2
+ # License: MIT
3
+
4
+ def capture(stream)
5
+ begin
6
+ stream = stream.to_s
7
+ eval "$#{stream} = StringIO.new"
8
+ yield
9
+ result = eval("$#{stream}").string
10
+ ensure
11
+ eval("$#{stream} = #{stream.upcase}")
12
+ end
13
+
14
+ result
15
+ end
16
+
17
+ alias silence capture
@@ -0,0 +1,5 @@
1
+ // include.scss
2
+
3
+ @import "../shared/include";
4
+
5
+ // Add email specific styles here.
@@ -0,0 +1,5 @@
1
+ // inline.scss
2
+
3
+ @import "../shared/inline";
4
+
5
+ // Add email specific styles here.
@@ -0,0 +1,11 @@
1
+ ---
2
+ title: (New Email)
3
+ ---
4
+
5
+ <div class="title">New Email</div>
6
+ <br><br>
7
+
8
+ <div class="body-text">
9
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
10
+ tempor incididunt ut labore et dolore magna aliqua.
11
+ </div>
File without changes
@@ -0,0 +1,21 @@
1
+ # Settings required for sending test emails
2
+ SEND_TO: me@example.com
3
+ SEND_FROM: me@example.com
4
+ SMTP_SERVER: smtp.mandrillapp.com
5
+ SMTP_PORT: 587
6
+ SMTP_USERNAME: username
7
+ SMTP_PASSWORD: password
8
+
9
+ # Required for building emails
10
+ # Where are your assets served from?
11
+ ASSET_SERVER: https://example.s3.amazonaws.com
12
+
13
+ # Any empty links, e.g. '/' or '#' will be overwritten to use a full URL instead
14
+ # Otherwise clients like Outlook.com struggle
15
+ HREF_PLACEHOLDER: http://example.com
16
+
17
+ # Required for uploading images
18
+ AWS_ACCESS_KEY_ID: ''
19
+ AWS_SECRET_ACCESS_KEY: ''
20
+ AWS_BUCKET: ''
21
+ FOG_REGION: ''
@@ -0,0 +1,17 @@
1
+ # Ignore Mac Finder file
2
+ .DS_Store
3
+
4
+ # Ignore bundler config
5
+ .bundle
6
+
7
+ # Ignore environment config
8
+ .env
9
+
10
+ # Ignore the build directory
11
+ build
12
+
13
+ # Ignore Sass
14
+ *.sass-cache
15
+
16
+ # Ignore temp and Cache
17
+ tmp
@@ -0,0 +1 @@
1
+ 2.2.2
@@ -0,0 +1,9 @@
1
+ <% if @user %>
2
+ source 'https://<%= @user %>:<%= @key %>@offsides-gems.herokuapp.com/'
3
+ <% else %>
4
+ # Forgot credentials? Contact support@antwort.co.
5
+ # source 'https://USERNAME:KEY@offsides-gems.herokuapp.com/'
6
+ <% end %>
7
+ source 'https://rubygems.org'
8
+
9
+ gem 'antwort'
@@ -0,0 +1,9 @@
1
+ guard 'livereload' do
2
+ watch(%r{^.rb})
3
+ watch(%r{^emails/.*/(.*)\.(erb)})
4
+ watch(%r{^emails/(.*)\.erb})
5
+ watch(%r{^views/.*/(.*)\.(erb)})
6
+ watch(%r{^views/(.*)\.erb})
7
+ watch(%r{^assets/css/.*/(.*)\.(css|scss)})
8
+ watch(%r{^assets/css/(.*)\.(css|scss)})
9
+ end
@@ -0,0 +1,3 @@
1
+ // demo/include.scss
2
+
3
+ @import "../shared/include";
@@ -0,0 +1,33 @@
1
+ // demo/inline.scss
2
+
3
+ @import "../shared/inline";
4
+
5
+ // Use email specific stylesheets for custom code that isn't used elsewhere.
6
+ // This helps for overriding default styles.
7
+
8
+ code {
9
+ font-size: 14px;
10
+ line-height: 16px;
11
+ font-family: 'Courier New', Courier, monospace;
12
+ background-color: #eeeeee;
13
+ color: #333333;
14
+
15
+ display: inline-block;
16
+ padding: 0 4px;
17
+ vertical-align: middle;
18
+ }
19
+
20
+ .table {
21
+ td {
22
+ border: 1px solid #dddddd;
23
+ border-left-width: 0;
24
+ padding-top: 10px;
25
+ padding-bottom: 10px;
26
+ &:first-child {
27
+ border-left-width: 1px;
28
+ }
29
+ }
30
+ }
31
+
32
+ // Note: These layout styles may not work across all email clients.
33
+ // They are here for documentation purposes.
@@ -0,0 +1,167 @@
1
+
2
+ $bodyFont: 'Helvetica Neue', Helvetica, sans-serif;
3
+ $headlineFont: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif;
4
+
5
+ $bodyColor: #444;
6
+ $blue: #018696;
7
+ $darkBlue: #374550;
8
+ $green: #ACC642;
9
+ $orange: #DF4726;
10
+ $yellow: #FFC526;
11
+ $linkColor: #7AA6B6;
12
+ $linkVisitedColor: darken($linkColor, 10%);
13
+ $linkHoverColor: lighten($linkColor, 10%);
14
+ $borderColor: #ddd;
15
+
16
+ html {
17
+ font-size: 100%;
18
+ -webkit-text-size-adjust: 100%;
19
+ -ms-text-size-adjust: 100%;
20
+ text-rendering: optimizeLegibility;
21
+ }
22
+
23
+ body {
24
+ color: $bodyColor;
25
+ font: 400 14px/1.5em $bodyFont;
26
+ padding: 0;
27
+ margin: 0;
28
+ }
29
+
30
+ a {
31
+ outline: none;
32
+ }
33
+
34
+ a:link {
35
+ color: $linkColor;
36
+ }
37
+
38
+ a:visited {
39
+ color: $linkVisitedColor;
40
+ }
41
+
42
+ a:hover,
43
+ a:active {
44
+ color: $linkHoverColor;
45
+ }
46
+
47
+ a:focus {
48
+ outline: none;
49
+ outline-style: none;
50
+ -moz-outline-style: none;
51
+ }
52
+
53
+ hr {
54
+ border: 0;
55
+ border-bottom: 1px solid $borderColor;
56
+ margin: 2em 0;
57
+ }
58
+
59
+ code {
60
+ background-color: #f3f3f3;
61
+ padding: 2px 6px;
62
+ }
63
+
64
+ h1 {
65
+ font: 600 2em/1.5em $headlineFont;
66
+ }
67
+
68
+ h2 {
69
+ font: 600 1.5em/1.5em $headlineFont;
70
+ color: $orange;
71
+ }
72
+
73
+ h3 {
74
+ font-weight: 500;
75
+ font-size: 1.25em; // 20/16
76
+ line-height: 1.5em;
77
+ font-family: $bodyFont;
78
+ }
79
+
80
+ h4 {
81
+ font: 400 1.125em/1.5em $bodyFont; // 18/16
82
+ }
83
+
84
+ .lead {
85
+ font: 300 1.6em/1.4em $headlineFont;
86
+ color: #666;
87
+ }
88
+
89
+ //-- Layout
90
+
91
+ header {
92
+ margin-bottom: 2em;
93
+ padding: 1.25em 0;
94
+ background-color: $darkBlue;
95
+ color: #eee;
96
+
97
+ h1 {
98
+ margin: 0;
99
+ font-size: 1.25em;
100
+ color: $yellow;
101
+ font-weight: 600;
102
+ text-transform: uppercase;
103
+ }
104
+
105
+ span {
106
+ color: $yellow;
107
+ font-weight: 800;
108
+ }
109
+
110
+ em {
111
+ font-style: normal;
112
+ font-weight: 300;
113
+ color: #ddd;
114
+ text-transform: none;
115
+ }
116
+
117
+ .container {
118
+ position: relative;
119
+ }
120
+
121
+ .support-link {
122
+ display: inline-block;
123
+ position: absolute;
124
+ right: 0;
125
+ top: 50%;
126
+ height: 2em;
127
+ line-height: 2em;
128
+ margin-top: -1em;
129
+
130
+ a:link, a:visited {
131
+ color: #879C9E;
132
+ text-decoration: none;
133
+ }
134
+ }
135
+ }
136
+
137
+ footer {
138
+ margin-top: 2em;
139
+
140
+ p {
141
+ font-size: 0.85em;
142
+ color: #bbb;
143
+ }
144
+
145
+ a:link, a:visited {
146
+ color: #bbb;
147
+ }
148
+
149
+ a:hover, a:active {
150
+ color: $linkHoverColor;
151
+ }
152
+
153
+ .container {
154
+ border-top: 1px solid #eee;
155
+ }
156
+ }
157
+
158
+ .container {
159
+ width: 62.5em;
160
+ max-width: 90%;
161
+ margin-right: auto;
162
+ margin-left: auto;
163
+ }
164
+
165
+ .content {
166
+ min-height: 200px;
167
+ }
@@ -0,0 +1,64 @@
1
+ // shared/based.scss
2
+
3
+ @import "_vars";
4
+ @import "_mixins";
5
+
6
+ body {
7
+ margin: 0;
8
+ padding: 0;
9
+ }
10
+
11
+ .container {
12
+ width: 600px;
13
+ max-width: 600px;
14
+ }
15
+
16
+ .container-padding {
17
+ padding-left: $gutter;
18
+ padding-right: $gutter;
19
+ }
20
+
21
+ .content {
22
+ background-color: #ffffff;
23
+ }
24
+
25
+ .title {
26
+ font-weight: bold;
27
+ font-size: 24px;
28
+ line-height: 28px;
29
+ font-family: $fontFamily;
30
+ }
31
+
32
+ .body-text {
33
+ font-size: 16px;
34
+ line-height: 20px;
35
+ font-family: $fontFamily;
36
+ }
37
+
38
+
39
+ //-- Buttons
40
+
41
+ .button {
42
+ td {
43
+ @include border-radius(3px);
44
+ background-color: $buttonBgColor;
45
+ }
46
+
47
+ a {
48
+ @include border-radius(3px);
49
+ @include font(bold, 14px, 20px);
50
+ text-decoration: none;
51
+ display: inline-block;
52
+ padding: 12px 18px;
53
+ border: 1px solid darken($buttonBgColor, 5%);
54
+ background-color: $buttonBgColor;
55
+ color: $buttonColor;
56
+ }
57
+
58
+ &.green {
59
+ td, a {
60
+ background-color: $greenBtnBgColor;
61
+ border-color: darken($greenBtnBgColor, 5%);
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,25 @@
1
+ //
2
+ // Mixins
3
+ // -------------------
4
+ // shared properties that we don't want to repeatedly define
5
+
6
+ @mixin padding($top: $gutter, $right: $gutter, $bottom: $gutter, $left: $gutter) {
7
+ padding-top: $top;
8
+ padding-right: $right;
9
+ padding-bottom: $bottom;
10
+ padding-left: $left;
11
+ }
12
+
13
+ @mixin border-radius($radius: 4px){
14
+ -webkit-border-radius: $radius;
15
+ -moz-border-radius: $radius;
16
+ border-radius: $radius;
17
+ }
18
+
19
+ @mixin font($weight: normal, $size: 14px, $line-height: 20px, $family: $fontFamily) {
20
+ font-weight: $weight;
21
+ font-size: $size;
22
+ line-height: $line-height;
23
+ font-family: $family;
24
+ }
25
+