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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +184 -0
- data/LICENSE.txt +21 -0
- data/README.md +61 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/malvolio +6 -0
- data/bin/setup +8 -0
- data/lib/generators/malvolio/create_generator.rb +27 -0
- data/lib/generators/malvolio/create_with_inky_generator.rb +27 -0
- data/lib/generators/malvolio/templates/base/config.yaml +1 -0
- data/lib/generators/malvolio/templates/base/index.html +16 -0
- data/lib/generators/malvolio/templates/base/index.scss +0 -0
- data/lib/generators/malvolio/templates/base_with_inky/config.yaml +1 -0
- data/lib/generators/malvolio/templates/base_with_inky/index.html +22 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/_foundation_emails.scss +27 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/_global.scss +95 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_alignment.scss +88 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_button.scss +312 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_callout.scss +85 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_code.scss +0 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_media-query.scss +139 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_menu.scss +83 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_normalize.scss +86 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_outlook-first.scss +11 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_thumbnail.scss +49 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_typography.scss +404 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/components/_visibility.scss +66 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/grid/_block-grid.scss +32 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/grid/_grid.scss +180 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/settings/_settings.scss +148 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/util/_util.scss +22 -0
- data/lib/generators/malvolio/templates/base_with_inky/scss/index.scss +1 -0
- data/lib/malvolio.rb +7 -0
- data/lib/malvolio/cli.rb +50 -0
- data/lib/malvolio/compiler.rb +85 -0
- data/lib/malvolio/version.rb +3 -0
- data/malvolio.gemspec +46 -0
- metadata +228 -0
data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/grid/_block-grid.scss
ADDED
@@ -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
|
+
}
|
data/lib/generators/malvolio/templates/base_with_inky/scss/foundation_emails/settings/_settings.scss
ADDED
@@ -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";
|
data/lib/malvolio.rb
ADDED
data/lib/malvolio/cli.rb
ADDED
@@ -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
|