malvolio 0.1.0

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.
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