malvolio 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +184 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +61 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/malvolio +6 -0
  12. data/bin/setup +8 -0
  13. data/lib/generators/malvolio/create_generator.rb +27 -0
  14. data/lib/generators/malvolio/create_with_inky_generator.rb +27 -0
  15. data/lib/generators/malvolio/templates/base/config.yaml +1 -0
  16. data/lib/generators/malvolio/templates/base/index.html +16 -0
  17. data/lib/generators/malvolio/templates/base/index.scss +0 -0
  18. data/lib/generators/malvolio/templates/base_with_inky/config.yaml +1 -0
  19. data/lib/generators/malvolio/templates/base_with_inky/index.html +22 -0
  20. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/_foundation_emails.scss +27 -0
  21. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/_global.scss +95 -0
  22. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_alignment.scss +88 -0
  23. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_button.scss +312 -0
  24. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_callout.scss +85 -0
  25. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_code.scss +0 -0
  26. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_media-query.scss +139 -0
  27. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_menu.scss +83 -0
  28. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_normalize.scss +86 -0
  29. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_outlook-first.scss +11 -0
  30. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_thumbnail.scss +49 -0
  31. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_typography.scss +404 -0
  32. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_visibility.scss +66 -0
  33. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/grid/_block-grid.scss +32 -0
  34. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/grid/_grid.scss +180 -0
  35. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/settings/_settings.scss +148 -0
  36. data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/util/_util.scss +22 -0
  37. data/lib/generators/malvolio/templates/base_with_inky/scss/index.scss +1 -0
  38. data/lib/malvolio.rb +7 -0
  39. data/lib/malvolio/cli.rb +50 -0
  40. data/lib/malvolio/compiler.rb +85 -0
  41. data/lib/malvolio/version.rb +3 -0
  42. data/malvolio.gemspec +46 -0
  43. metadata +228 -0
@@ -0,0 +1,32 @@
1
+ // Foundation for Emails by ZURB
2
+ // zurb.com/ink/
3
+ // Licensed under MIT Open Source
4
+
5
+ ////
6
+ /// @group block-grid
7
+ ////
8
+
9
+ /// The highest number of `.x-up` classes available when using the block grid CSS.
10
+ /// @type Number
11
+ $block-grid-max: 8 !default;
12
+
13
+ /// Gutter between elements in a block grid.
14
+ /// @type Number
15
+ $block-grid-gutter: $global-gutter !default;
16
+
17
+ .block-grid {
18
+ width: 100%;
19
+ max-width: $global-width;
20
+
21
+ td {
22
+ display: inline-block;
23
+ padding: $block-grid-gutter / 2;
24
+ }
25
+ }
26
+
27
+ // Sizing classes
28
+ @for $i from 2 through $block-grid-max {
29
+ .up-#{$i} td {
30
+ width: floor(($global-width - $i * $block-grid-gutter) / $i) !important;
31
+ }
32
+ }
@@ -0,0 +1,180 @@
1
+ // Foundation for Emails by ZURB
2
+ // zurb.com/ink/
3
+ // Licensed under MIT Open Source
4
+
5
+ ////
6
+ /// @group grid
7
+ ////
8
+
9
+ /// Default number of columns for an email.
10
+ /// @type Number
11
+ $grid-column-count: 12 !default;
12
+
13
+ /// Default padding for the bottom of a column.
14
+ /// @type Number
15
+ $column-padding-bottom: $global-padding !default;
16
+
17
+ /// Default border radius for the container. Use a px value
18
+ /// @type Number
19
+ $container-radius: 0 !default;
20
+
21
+ //For viewing email in browser
22
+ @media only screen {
23
+ html {
24
+ min-height: 100%;
25
+ background: $body-background;
26
+ }
27
+ }
28
+
29
+ table {
30
+ &.body {
31
+ background: $body-background;
32
+ height: 100%;
33
+ width: 100%;
34
+ }
35
+
36
+ &.container {
37
+ background: $container-background;
38
+ width: $global-width;
39
+ margin: 0 auto;
40
+ Margin: 0 auto;
41
+ text-align: inherit;
42
+ }
43
+
44
+ &.row {
45
+ padding: 0;
46
+ width: 100%;
47
+ position: relative;
48
+ }
49
+
50
+ &.spacer {
51
+ width: 100%;
52
+ td {
53
+ mso-line-height-rule: exactly;
54
+ }
55
+ }
56
+ }
57
+
58
+ table.container table.row {
59
+ display: table;
60
+ }
61
+
62
+ td.columns,
63
+ td.column,
64
+ th.columns,
65
+ th.column {
66
+ margin: 0 auto;
67
+ Margin: 0 auto;
68
+ padding-left: $global-gutter;
69
+ padding-bottom: $column-padding-bottom;
70
+
71
+ // Prevents Nested columns from double the padding
72
+ .column,
73
+ .columns {
74
+ padding-left: 0 !important;
75
+ padding-right: 0 !important;
76
+
77
+ center {
78
+ min-width: none !important;
79
+ }
80
+ }
81
+ }
82
+
83
+ td.columns.last,
84
+ td.column.last,
85
+ th.columns.last,
86
+ th.column.last {
87
+ padding-right: $global-gutter;
88
+ }
89
+
90
+ //makes sure nested tables are 100% width
91
+ td.columns,
92
+ td.column,
93
+ th.columns,
94
+ th.column {
95
+ table {
96
+ width: 100%;
97
+
98
+ &.button {
99
+ width:auto;
100
+
101
+ &.expanded{
102
+ width: 100%;
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ @for $i from 1 through $grid-column-count {
109
+ td.large-#{$i},
110
+ th.large-#{$i} {
111
+ width: -zf-grid-calc-px($i, $grid-column-count, $global-width);
112
+ padding-left: $global-gutter / 2;
113
+ padding-right: $global-gutter / 2;
114
+ }
115
+
116
+ td.large-#{$i}.first,
117
+ th.large-#{$i}.first {
118
+ padding-left: $global-gutter;
119
+ }
120
+
121
+ td.large-#{$i}.last,
122
+ th.large-#{$i}.last {
123
+ padding-right: $global-gutter;
124
+ }
125
+
126
+ //Collapsed logic
127
+ .collapse {
128
+ > tbody > tr > td.large-#{$i},
129
+ > tbody > tr > th.large-#{$i} {
130
+ padding-right: 0;
131
+ padding-left: 0;
132
+ width: -zf-grid-calc-px($i, $grid-column-count, $global-width) + $global-gutter;
133
+ }
134
+
135
+ //Gotta give it that extra love for the first and last columns.
136
+ td.large-#{$i}.first,
137
+ th.large-#{$i}.first,
138
+ td.large-#{$i}.last,
139
+ th.large-#{$i}.last {
140
+ width: -zf-grid-calc-px($i, $grid-column-count, $global-width) + ($global-gutter * 1.5);
141
+ }
142
+ }
143
+
144
+ td.large-#{$i} center,
145
+ th.large-#{$i} center {
146
+ min-width: -zf-grid-calc-px($i, $grid-column-count, $global-width) - ($global-gutter * 2);
147
+ }
148
+
149
+ .body .columns td.large-#{$i},
150
+ .body .column td.large-#{$i},
151
+ .body .columns th.large-#{$i},
152
+ .body .column th.large-#{$i} {
153
+ width: -zf-grid-calc-pct($i, $grid-column-count);
154
+ }
155
+ }
156
+
157
+ @for $i from 1 through ($grid-column-count - 1) {
158
+ td.large-offset-#{$i},
159
+ td.large-offset-#{$i}.first,
160
+ td.large-offset-#{$i}.last,
161
+ th.large-offset-#{$i},
162
+ th.large-offset-#{$i}.first,
163
+ th.large-offset-#{$i}.last {
164
+ //1.5 takes in effect a whole empty cell.
165
+ padding-left: -zf-grid-calc-px($i, $grid-column-count, $global-width) + $global-gutter * 2;
166
+ }
167
+ }
168
+
169
+ td.expander,
170
+ th.expander {
171
+ visibility: hidden;
172
+ width: 0;
173
+ padding: 0 !important;
174
+ }
175
+
176
+ // adds radius to container
177
+ table.container.radius {
178
+ border-radius: $container-radius;
179
+ border-collapse: separate;
180
+ }
@@ -0,0 +1,148 @@
1
+ // Foundation for Emails Settings
2
+ // ------------------------------
3
+ //
4
+ // Table of Contents:
5
+ //
6
+ // 1. Global
7
+ // 2. Grid
8
+ // 3. Block Grid
9
+ // 4. Typography
10
+ // 5. Button
11
+ // 6. Callout
12
+ // 7. Menu
13
+ // 8. Thumbnail
14
+
15
+
16
+ // 1. Global
17
+ // ---------
18
+
19
+ $primary-color: #2199e8;
20
+ $secondary-color: #777777;
21
+ $success-color: #3adb76;
22
+ $warning-color: #ffae00;
23
+ $alert-color: #ec5840;
24
+ $light-gray: #f3f3f3;
25
+ $medium-gray: #cacaca;
26
+ $dark-gray: #8a8a8a;
27
+ $black: #0a0a0a;
28
+ $white: #fefefe;
29
+ $pre-color: #ff6908;
30
+ $global-width: 580px;
31
+ $global-width-small: 95%;
32
+ $global-gutter: 16px;
33
+ $body-background: $light-gray;
34
+ $container-background: $white;
35
+ $global-padding: 16px;
36
+ $global-margin: 16px;
37
+ $global-radius: 3px;
38
+ $global-rounded: 500px;
39
+ $global-breakpoint: $global-width + $global-gutter;
40
+
41
+ // 2. Grid
42
+ // -------
43
+
44
+ $grid-column-count: 12;
45
+ $column-padding-bottom: $global-padding;
46
+ $container-radius: 0;
47
+
48
+ // 3. Block Grid
49
+ // -------------
50
+
51
+ $block-grid-max: 8;
52
+ $block-grid-gutter: $global-gutter;
53
+
54
+ // 4. Typography
55
+ // -------------
56
+
57
+ $global-font-color: $black;
58
+ $body-font-family: Helvetica, Arial, sans-serif;
59
+ $global-font-weight: normal;
60
+ $header-color: inherit;
61
+ $global-line-height: 130%;
62
+ $global-font-size: 16px;
63
+ $body-line-height: $global-line-height;
64
+ $header-font-family: $body-font-family;
65
+ $header-font-weight: $global-font-weight;
66
+ $h1-font-size: 34px;
67
+ $h2-font-size: 30px;
68
+ $h3-font-size: 28px;
69
+ $h4-font-size: 24px;
70
+ $h5-font-size: 20px;
71
+ $h6-font-size: 18px;
72
+ $header-margin-bottom: 10px;
73
+ $paragraph-margin-bottom: 10px;
74
+ $small-font-size: 80%;
75
+ $small-font-color: $medium-gray;
76
+ $lead-font-size: $global-font-size * 1.25;
77
+ $lead-line-height: 160%;
78
+ $text-padding: 10px;
79
+ $subheader-lineheight: 1.4;
80
+ $subheader-color: $dark-gray;
81
+ $subheader-font-weight: $global-font-weight;
82
+ $subheader-margin-top: 4px;
83
+ $subheader-margin-bottom: 8px;
84
+ $hr-width: $global-width;
85
+ $hr-border: 1px solid $black;
86
+ $hr-margin: 20px auto;
87
+ $anchor-text-decoration: none;
88
+ $anchor-color: $primary-color;
89
+ $anchor-color-visited: $anchor-color;
90
+ $anchor-color-hover: darken($primary-color, 10%);
91
+ $anchor-color-active: $anchor-color-hover;
92
+ $stat-font-size: 40px;
93
+ $remove-ios-blue: true;
94
+
95
+ // 5. Button
96
+ // ---------
97
+
98
+ $button-padding: (
99
+ tiny: 4px 8px 4px 8px,
100
+ small: 5px 10px 5px 10px,
101
+ default: 8px 16px 8px 16px,
102
+ large: 10px 20px 10px 20px,
103
+ );
104
+ $button-font-size: (
105
+ tiny: 10px,
106
+ small: 12px,
107
+ default: 16px,
108
+ large: 20px,
109
+ );
110
+ $button-color: $white;
111
+ $button-color-alt: $medium-gray;
112
+ $button-font-weight: bold;
113
+ $button-margin: 0 0 $global-margin 0;
114
+ $button-background: $primary-color;
115
+ $button-border: 2px solid $button-background;
116
+ $button-radius: $global-radius;
117
+ $button-rounded: $global-rounded;
118
+
119
+ // 6. Callout
120
+ // ----------
121
+
122
+ $callout-background: $white;
123
+ $callout-background-fade: 85%;
124
+ $callout-padding: 10px;
125
+ $callout-margin-bottom: $global-margin;
126
+ $callout-border: 1px solid darken($callout-background, 20%);
127
+ $callout-border-secondary: 1px solid darken($secondary-color, 20%);
128
+ $callout-border-success: 1px solid darken($success-color, 20%);
129
+ $callout-border-warning: 1px solid darken($warning-color, 20%);
130
+ $callout-border-alert: 1px solid darken($alert-color, 20%);
131
+
132
+ // 7. Menu
133
+ // -------
134
+
135
+ $menu-item-padding: 10px;
136
+ $menu-item-gutter: 10px;
137
+ $menu-item-color: $primary-color;
138
+
139
+ // 8. Thumbnail
140
+ // ------------
141
+
142
+ $thumbnail-border: solid 4px $white;
143
+ $thumbnail-margin-bottom: $global-margin;
144
+ $thumbnail-shadow: 0 0 0 1px rgba($black, 0.2);
145
+ $thumbnail-shadow-hover: 0 0 6px 1px rgba($primary-color, 0.5);
146
+ $thumbnail-transition: box-shadow 200ms ease-out;
147
+ $thumbnail-radius: $global-radius;
148
+
@@ -0,0 +1,22 @@
1
+ // Foundation for Emails by ZURB
2
+ // foundation.zurb.com
3
+ // Licensed under MIT Open Source
4
+
5
+ /// Calculates a percentage value for a grid column width.
6
+ /// @access private
7
+ /// @param {number} $colNumber - Column count of the column.
8
+ /// @param {number} $totalColumns - Column count of the entire row.
9
+ /// @returns {number} A percentage width value.
10
+ @function -zf-grid-calc-pct($colNumber, $totalColumns) {
11
+ @return floor(percentage(($colNumber / $totalColumns)) * 1000000) / 1000000;
12
+ }
13
+
14
+ /// Calculates a pixel value for a grid column width.
15
+ /// @access private
16
+ /// @param {number} $columnNumber - Column count of the column.
17
+ /// @param {number} $totalColumns - Column count of the entire row.
18
+ /// @param {number} $containerWidth - Width of the surrounding container, in pixels.
19
+ /// @returns {number} A pixel width value.
20
+ @function -zf-grid-calc-px($columnNumber, $totalColumns, $containerWidth) {
21
+ @return ($containerWidth / $totalColumns * $columnNumber - $global-gutter);
22
+ }
@@ -0,0 +1 @@
1
+ @import "foundation_emails/foundation_emails";
@@ -0,0 +1,7 @@
1
+ require "malvolio/version"
2
+ require "malvolio/cli"
3
+ require "malvolio/compiler"
4
+
5
+ module Malvolio
6
+ class CompilationError < StandardError; end
7
+ end
@@ -0,0 +1,50 @@
1
+ require "thor"
2
+ require "rails/generators"
3
+ require "filewatcher"
4
+
5
+ module Malvolio
6
+ class CLI < Thor
7
+ option :inky, type: :boolean
8
+ desc "new NAME [--inky]", "creates a new email project"
9
+ def new(name)
10
+ if options[:inky]
11
+ ::Rails::Generators.invoke("malvolio:create_with_inky", [name])
12
+ else
13
+ ::Rails::Generators.invoke("malvolio:create", [name])
14
+ end
15
+ end
16
+
17
+ option :no_warnings, type: :boolean
18
+ desc "build [PATH] [--no-warnings]", "compile the project to a finished HTML email"
19
+ def build(path = nil)
20
+ safely do
21
+ Malvolio::Compiler.new(path, options[:no_warnings]).run!
22
+ end
23
+ end
24
+
25
+ option :no_warnings, type: :boolean
26
+ desc "watch [PATH] [--no-warnings]", "watch the project files and build and file changes"
27
+ def watch(path = nil)
28
+ path = File.expand_path(path || ".")
29
+ compiler = Malvolio::Compiler.new(path, options[:no_warnings])
30
+ html_files = Dir[File.join(path, "src", "**", "*.html")]
31
+ css_files = Dir[File.join(path, "src", "**", "*.css")]
32
+ sass_files = Dir[File.join(path, "src", "**", "*.scss")]
33
+ files = html_files + css_files + sass_files
34
+ puts "Now watching project for changes at #{path}"
35
+ Filewatcher.new(files).watch do
36
+ safely { compiler.run! }
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def safely(&block)
43
+ begin
44
+ yield
45
+ rescue Malvolio::CompilationError => e
46
+ puts e
47
+ end
48
+ end
49
+ end
50
+ end