inkcite 1.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/bin/release-major +1 -1
- data/bin/release-minor +1 -1
- data/bin/release-patch +0 -1
- data/inkcite.gemspec +1 -0
- data/lib/inkcite.rb +1 -0
- data/lib/inkcite/cli/init.rb +3 -1
- data/lib/inkcite/cli/server.rb +5 -0
- data/lib/inkcite/email.rb +2 -2
- data/lib/inkcite/mailer.rb +69 -32
- data/lib/inkcite/minifier.rb +1 -0
- data/lib/inkcite/renderer.rb +2 -0
- data/lib/inkcite/renderer/base.rb +52 -27
- data/lib/inkcite/renderer/increment.rb +21 -0
- data/lib/inkcite/renderer/link.rb +4 -0
- data/lib/inkcite/renderer/property.rb +28 -0
- data/lib/inkcite/renderer/table.rb +2 -2
- data/lib/inkcite/util.rb +6 -4
- data/lib/inkcite/version.rb +1 -1
- data/lib/inkcite/view.rb +71 -25
- data/test/minifier_spec.rb +20 -0
- data/test/renderer/table_spec.rb +34 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dff1fb6ce80d821e6c797a6c691e904ed6dfb60d
|
4
|
+
data.tar.gz: dcea60b5e3efe7edabc97186822e09e8cf43c8d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b19819db8870689817a7947159c7d30ff14e7a237c485dd42d43443691da47f2af0573e34df9f1873cdb14c8a20b71516ff0a23e6b9abdf06eac3747fd7a315
|
7
|
+
data.tar.gz: 118adc599578c2d779d841ea78c8808a8a49334b084809e48eae9e6499e505d93218e5c5ab25026c7cf14b34ec930c39b4bc45401a928d3562eaed823f43aa80
|
data/README.md
CHANGED
@@ -89,6 +89,11 @@ By default, this will create the production version of your email. This
|
|
89
89
|
includes fully-qualified URLs for images, link tracking and tagging and a host
|
90
90
|
of other preflight features.
|
91
91
|
|
92
|
+
## Learn More
|
93
|
+
|
94
|
+
Documentation for Inkcite is generously hosted by the friendly folks at [Readme].
|
95
|
+
Get started here: https://inkcite.readme.io/
|
96
|
+
|
92
97
|
## Bug Reports
|
93
98
|
|
94
99
|
Github Issues is used for managing bug reports and feature requests. If you
|
@@ -108,3 +113,4 @@ details.
|
|
108
113
|
[Litmus]: http://litmus.com
|
109
114
|
[rubyinstaller]: http://rubyinstaller.org/
|
110
115
|
[LICENSE]: https://github.com/inkceptional/inkcite/blob/master/LICENSE
|
116
|
+
[Readme]: https://readme.io
|
data/bin/release-major
CHANGED
@@ -1 +1 @@
|
|
1
|
-
gem bump --version major --release
|
1
|
+
gem bump --version major --push --release
|
data/bin/release-minor
CHANGED
@@ -1 +1 @@
|
|
1
|
-
gem bump --version minor --release
|
1
|
+
gem bump --version minor --push --release
|
data/bin/release-patch
CHANGED
@@ -1 +0,0 @@
|
|
1
|
-
gem bump --version patch --release
|
data/inkcite.gemspec
CHANGED
data/lib/inkcite.rb
CHANGED
data/lib/inkcite/cli/init.rb
CHANGED
@@ -36,7 +36,9 @@ module Inkcite
|
|
36
36
|
|
37
37
|
# Copy the main Inkcite project files
|
38
38
|
FILES.each do |file|
|
39
|
-
|
39
|
+
from_file = File.join(from_path, file)
|
40
|
+
next unless File.exists?(from_file)
|
41
|
+
FileUtils.cp(from_file, full_init_path)
|
40
42
|
puts "Created #{File.join(path, file)}"
|
41
43
|
end
|
42
44
|
|
data/lib/inkcite/cli/server.rb
CHANGED
@@ -19,7 +19,11 @@ module Inkcite
|
|
19
19
|
nil
|
20
20
|
end
|
21
21
|
|
22
|
+
puts
|
22
23
|
puts "Inkcite #{Inkcite::VERSION} is starting up ..."
|
24
|
+
puts 'Documentation available at http://inkcite.readme.io'
|
25
|
+
puts 'Press CTRL-C to exit server mode'
|
26
|
+
puts
|
23
27
|
|
24
28
|
begin
|
25
29
|
@server = ::WEBrick::HTTPServer.new({
|
@@ -47,6 +51,7 @@ module Inkcite
|
|
47
51
|
|
48
52
|
puts "Your email is being served at http://#{host}:#{port}"
|
49
53
|
puts "Point your mobile device to http://#{ip}:#{port}" if ip
|
54
|
+
puts
|
50
55
|
|
51
56
|
@server.start
|
52
57
|
|
data/lib/inkcite/email.rb
CHANGED
@@ -23,7 +23,7 @@ module Inkcite
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def config
|
26
|
-
Util.read_yml(File.join(path, 'config.yml'), true)
|
26
|
+
Util.read_yml(File.join(path, 'config.yml'), :fail_if_not_exists => true)
|
27
27
|
end
|
28
28
|
|
29
29
|
def formats env
|
@@ -139,7 +139,7 @@ module Inkcite
|
|
139
139
|
META_FILE = '.inkcite'
|
140
140
|
|
141
141
|
def meta_data
|
142
|
-
Util.read_yml(File.join(path, meta_file_name)
|
142
|
+
Util.read_yml(File.join(path, meta_file_name))
|
143
143
|
end
|
144
144
|
|
145
145
|
def meta_file_name
|
data/lib/inkcite/mailer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mail'
|
2
|
+
require 'mailgun'
|
2
3
|
|
3
4
|
module Inkcite
|
4
5
|
class Mailer
|
@@ -27,11 +28,11 @@ module Inkcite
|
|
27
28
|
cc = recipients[:internal]
|
28
29
|
|
29
30
|
self.send(email, {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
:to => to,
|
32
|
+
:cc => cc,
|
33
|
+
:bcc => true,
|
34
|
+
:tag => "Preview ##{count}"
|
35
|
+
})
|
35
36
|
|
36
37
|
end
|
37
38
|
|
@@ -40,8 +41,8 @@ module Inkcite
|
|
40
41
|
count = increment(email, :developer)
|
41
42
|
|
42
43
|
self.send(email, {
|
43
|
-
|
44
|
-
|
44
|
+
:tag => "Developer Test ##{count}"
|
45
|
+
})
|
45
46
|
|
46
47
|
end
|
47
48
|
|
@@ -57,10 +58,10 @@ module Inkcite
|
|
57
58
|
count = increment(email, :internal)
|
58
59
|
|
59
60
|
self.send(email, {
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
:to => recipients[:internal],
|
62
|
+
:bcc => true,
|
63
|
+
:tag => "Internal Proof ##{count}"
|
64
|
+
})
|
64
65
|
|
65
66
|
end
|
66
67
|
|
@@ -87,46 +88,82 @@ module Inkcite
|
|
87
88
|
|
88
89
|
def self.send_version email, version, opt
|
89
90
|
|
90
|
-
|
91
|
+
# The version of the email we will be sending.
|
92
|
+
view = email.view(:preview, :email, version)
|
93
|
+
|
94
|
+
# Subject line tag such as "Preview #3"
|
95
|
+
tag = opt[:tag]
|
96
|
+
|
97
|
+
subject = view.subject
|
98
|
+
subject = "#{subject} (#{tag})" unless tag.blank?
|
99
|
+
|
100
|
+
if config = email.config[:mailgun]
|
101
|
+
send_version_via_mailgun config, view, subject, opt
|
102
|
+
elsif config = email.config[:smtp]
|
103
|
+
send_version_via_smtp config, view, subject, opt
|
104
|
+
else
|
105
|
+
puts 'Unable to send previews. Please configure mailgun or smtp sections in config.yml'
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def self.send_version_via_mailgun config, view, subject, opt
|
113
|
+
|
114
|
+
# The address of the developer
|
115
|
+
from = config[:from]
|
116
|
+
|
117
|
+
# First, instantiate the Mailgun Client with your API key
|
118
|
+
mg_client = Mailgun::Client.new config[:'api-key']
|
119
|
+
|
120
|
+
# Define your message parameters
|
121
|
+
message_params = {
|
122
|
+
:from => from,
|
123
|
+
:to => opt[:to] || from,
|
124
|
+
:subject => subject,
|
125
|
+
:html => view.render!
|
126
|
+
}
|
127
|
+
|
128
|
+
message_params[:cc] = opt[:cc] unless opt[:cc].blank?
|
129
|
+
message_params[:bcc] = from if opt[:bcc] == true
|
130
|
+
|
131
|
+
# Send your message through the client
|
132
|
+
mg_client.send_message config[:domain], message_params
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.send_version_via_smtp config, view, _subject, opt
|
91
137
|
|
92
138
|
Mail.defaults do
|
93
139
|
delivery_method :smtp, {
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
140
|
+
:address => config[:host],
|
141
|
+
:port => config[:port],
|
142
|
+
:user_name => config[:username],
|
143
|
+
:password => config[:password],
|
144
|
+
:authentication => :plain,
|
145
|
+
:enable_starttls_auto => true
|
146
|
+
}
|
101
147
|
end
|
102
148
|
|
103
149
|
# The address of the developer
|
104
150
|
_from = config[:from]
|
105
151
|
|
106
|
-
# Subject line tag such as "Preview #3"
|
107
|
-
_tag = opt[:tag]
|
108
|
-
|
109
152
|
# True if the developer should be bcc'd.
|
110
153
|
_bcc = opt[:bcc] == true
|
111
154
|
|
112
|
-
# The version of the email we will be sending.
|
113
|
-
_view = email.view(:preview, :email, version)
|
114
|
-
|
115
|
-
_subject = _view.subject
|
116
|
-
_subject = "#{_subject} (#{_tag})" unless _tag.blank?
|
117
|
-
|
118
155
|
mail = Mail.new do
|
119
156
|
|
120
|
-
to
|
121
|
-
cc
|
122
|
-
from
|
157
|
+
to opt[:to] || _from
|
158
|
+
cc opt[:cc]
|
159
|
+
from _from
|
123
160
|
subject _subject
|
124
161
|
|
125
162
|
bcc(_from) if _bcc
|
126
163
|
|
127
164
|
html_part do
|
128
165
|
content_type 'text/html; charset=UTF-8'
|
129
|
-
body
|
166
|
+
body view.render!
|
130
167
|
end
|
131
168
|
|
132
169
|
end
|
data/lib/inkcite/minifier.rb
CHANGED
data/lib/inkcite/renderer.rb
CHANGED
@@ -10,6 +10,7 @@ require_relative 'renderer/footnote'
|
|
10
10
|
require_relative 'renderer/google_analytics'
|
11
11
|
require_relative 'renderer/image'
|
12
12
|
require_relative 'renderer/in_browser'
|
13
|
+
require_relative 'renderer/increment'
|
13
14
|
require_relative 'renderer/like'
|
14
15
|
require_relative 'renderer/link'
|
15
16
|
require_relative 'renderer/litmus'
|
@@ -149,6 +150,7 @@ module Inkcite
|
|
149
150
|
|
150
151
|
# Dynamic renderers for custom behavior and tags.
|
151
152
|
@renderers ||= {
|
153
|
+
:'++' => Increment.new,
|
152
154
|
:a => Link.new,
|
153
155
|
:button => Button.new,
|
154
156
|
:div => Div.new,
|
@@ -3,41 +3,48 @@ module Inkcite
|
|
3
3
|
class Base
|
4
4
|
|
5
5
|
# Constants for style and property names with dashes in them.
|
6
|
-
BACKGROUND_COLOR
|
7
|
-
BACKGROUND_IMAGE
|
8
|
-
BACKGROUND_REPEAT
|
6
|
+
BACKGROUND_COLOR = :'background-color'
|
7
|
+
BACKGROUND_IMAGE = :'background-image'
|
8
|
+
BACKGROUND_REPEAT = :'background-repeat'
|
9
9
|
BACKGROUND_POSITION = :'background-position'
|
10
|
-
BACKGROUND_SIZE
|
11
|
-
BORDER_BOTTOM
|
12
|
-
BORDER_COLLAPSE
|
13
|
-
BORDER_RADIUS
|
14
|
-
BORDER_SPACING
|
15
|
-
BOX_SHADOW
|
16
|
-
FONT_FAMILY
|
17
|
-
FONT_SIZE
|
18
|
-
FONT_WEIGHT
|
19
|
-
LETTER_SPACING
|
20
|
-
LINE_HEIGHT
|
21
|
-
LINK_COLOR
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
10
|
+
BACKGROUND_SIZE = :'background-size'
|
11
|
+
BORDER_BOTTOM = :'border-bottom'
|
12
|
+
BORDER_COLLAPSE = :'border-collapse'
|
13
|
+
BORDER_RADIUS = :'border-radius'
|
14
|
+
BORDER_SPACING = :'border-spacing'
|
15
|
+
BOX_SHADOW = :'box-shadow'
|
16
|
+
FONT_FAMILY = :'font-family'
|
17
|
+
FONT_SIZE = :'font-size'
|
18
|
+
FONT_WEIGHT = :'font-weight'
|
19
|
+
LETTER_SPACING = :'letter-spacing'
|
20
|
+
LINE_HEIGHT = :'line-height'
|
21
|
+
LINK_COLOR = :'#link'
|
22
|
+
MARGIN = :'margin'
|
23
|
+
MARGIN_BOTTOM = :'margin-bottom'
|
24
|
+
MARGIN_LEFT = :'margin-left'
|
25
|
+
MARGIN_RIGHT = :'margin-right'
|
26
|
+
MARGIN_TOP = :'margin-top'
|
27
|
+
PADDING_X = :'padding-x'
|
28
|
+
PADDING_Y = :'padding-y'
|
29
|
+
TEXT_ALIGN = :'text-align'
|
30
|
+
TEXT_DECORATION = :'text-decoration'
|
31
|
+
TEXT_SHADOW = :'text-shadow'
|
32
|
+
TEXT_SHADOW_BLUR = :'shadow-blur'
|
33
|
+
TEXT_SHADOW_OFFSET = :'shadow-offset'
|
34
|
+
VERTICAL_ALIGN = :'vertical-align'
|
35
|
+
|
36
|
+
# CSS Margins
|
37
|
+
MARGINS = [MARGIN_TOP, MARGIN_LEFT, MARGIN_BOTTOM, MARGIN_RIGHT]
|
31
38
|
|
32
39
|
# CSS Directions
|
33
|
-
DIRECTIONS = [
|
40
|
+
DIRECTIONS = [:top, :right, :bottom, :left]
|
34
41
|
|
35
42
|
# Attribute and CSS dimensions
|
36
|
-
DIMENSIONS = [
|
43
|
+
DIMENSIONS = [:width, :height]
|
37
44
|
|
38
45
|
# Common value declarations
|
39
46
|
POUND_SIGN = '#'
|
40
|
-
NONE
|
47
|
+
NONE = 'none'
|
41
48
|
|
42
49
|
# Zero-width space character
|
43
50
|
ZERO_WIDTH_SPACE = '​'
|
@@ -122,6 +129,24 @@ module Inkcite
|
|
122
129
|
font
|
123
130
|
end
|
124
131
|
|
132
|
+
def mix_margins element, opt, ctx
|
133
|
+
|
134
|
+
# Check to see if the 'all' margin attribute is specified.
|
135
|
+
all_margin = opt[MARGIN]
|
136
|
+
|
137
|
+
# Applying individual margins helps ensure compatibility across
|
138
|
+
# all email clients. Cough! Cough! Looking at you Outlook.
|
139
|
+
MARGINS.each do |margin|
|
140
|
+
|
141
|
+
# Check for specific direction margin (e.g. margin-left) which
|
142
|
+
# would override all margins. Otherwise, inherit all margin.
|
143
|
+
amt = (opt[margin] || all_margin).to_i
|
144
|
+
element.style[margin] = px(amt) if amt > 0
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
125
150
|
def mix_text_shadow element, opt, ctx
|
126
151
|
|
127
152
|
shadow = detect(opt[:shadow], opt[TEXT_SHADOW])
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Inkcite
|
2
|
+
module Renderer
|
3
|
+
class Increment < Base
|
4
|
+
|
5
|
+
def render tag, opt, ctx
|
6
|
+
|
7
|
+
# Get the unique ID for which a counter will be incremented.
|
8
|
+
# Or use the default value.
|
9
|
+
id = opt[:id] || DEFAULT
|
10
|
+
ctx.unique_id(id).to_s
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Tip o' the hat to the most-used index variable name.
|
17
|
+
DEFAULT = 'i'
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -42,6 +42,10 @@ module Inkcite
|
|
42
42
|
id = opt[:id]
|
43
43
|
href = opt[:href]
|
44
44
|
|
45
|
+
# If a URL wasn't provided in the HTML, then check to see if there is
|
46
|
+
# a link declared in the project's links_tsv file.
|
47
|
+
href = ctx.links_tsv[id] if href.blank?
|
48
|
+
|
45
49
|
# True if the href is missing. If so, we may try to look it up by it's ID
|
46
50
|
# or we'll insert a default TBD link.
|
47
51
|
missing = href.blank?
|
@@ -10,6 +10,33 @@ module Inkcite
|
|
10
10
|
return nil
|
11
11
|
end
|
12
12
|
|
13
|
+
# True if this is a opening tag - e.g. {feature ...}, not {/feature}
|
14
|
+
is_open_tag = !tag.starts_with?(SLASH)
|
15
|
+
|
16
|
+
# When a custom opening tag is encountered, if there is a corresponding
|
17
|
+
# closing tag, we'll save the options provided at open so that they
|
18
|
+
# can be pop'd by the closing tag and used in the closing HTML.
|
19
|
+
if is_open_tag
|
20
|
+
|
21
|
+
# Verify that a closing tag has been defined and push the opts
|
22
|
+
# onto the stack. No need to push opts and pollute the stack if
|
23
|
+
# there is no closing tag to take advantage of them.
|
24
|
+
close_tag = "#{SLASH}#{tag}"
|
25
|
+
ctx.tag_stack(tag) << opt unless ctx[close_tag].blank?
|
26
|
+
|
27
|
+
else
|
28
|
+
|
29
|
+
# Chop off the forward slash to reveal the original open tag. Then
|
30
|
+
# grab the tag stack for said open tag. Pop the most recently provided
|
31
|
+
# opts off the stack so those values are available again.
|
32
|
+
open_tag = tag[1..-1]
|
33
|
+
tag_stack = ctx.tag_stack(open_tag)
|
34
|
+
|
35
|
+
# The provided opts take precedence over the ones passed to the open tag.
|
36
|
+
opt = tag_stack.pop.merge(opt) if tag_stack
|
37
|
+
|
38
|
+
end
|
39
|
+
|
13
40
|
# Need to clone the property - otherwise, we modify the original property.
|
14
41
|
# Which is bad.
|
15
42
|
html = html.clone
|
@@ -33,6 +60,7 @@ module Inkcite
|
|
33
60
|
|
34
61
|
DOLLAR = '$'
|
35
62
|
EQUALS = '='
|
63
|
+
SLASH = '/'
|
36
64
|
|
37
65
|
end
|
38
66
|
end
|
@@ -41,8 +41,8 @@ module Inkcite
|
|
41
41
|
border_collapse = opt[BORDER_COLLAPSE]
|
42
42
|
table.style[BORDER_COLLAPSE] = border_collapse unless border_collapse.blank?
|
43
43
|
|
44
|
-
|
45
|
-
table
|
44
|
+
# Apply margins.
|
45
|
+
mix_margins table, opt, ctx
|
46
46
|
|
47
47
|
mobile = opt[:mobile]
|
48
48
|
|
data/lib/inkcite/util.rb
CHANGED
@@ -55,11 +55,13 @@ module Inkcite
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
def self.read_yml file,
|
58
|
+
def self.read_yml file, opts={}
|
59
59
|
if File.exist?(file)
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
yml = YAML.load_file(file)
|
61
|
+
symbolize_keys(yml) unless opts[:symbolize_keys] == false
|
62
|
+
yml
|
63
|
+
elsif opts[:fail_if_not_exists]
|
64
|
+
raise "File not found: #{file}"
|
63
65
|
else
|
64
66
|
{}
|
65
67
|
end
|
data/lib/inkcite/version.rb
CHANGED
data/lib/inkcite/view.rb
CHANGED
@@ -239,6 +239,22 @@ module Inkcite
|
|
239
239
|
@links ||= {}
|
240
240
|
end
|
241
241
|
|
242
|
+
# Returns a hash of the links.tsv file from the project which is used
|
243
|
+
# to populate the {a} and {button} hrefs when an href isn't defined.
|
244
|
+
def links_tsv
|
245
|
+
@links_tsv ||= begin
|
246
|
+
links_tsv_file = @email.project_file(LINKS_TSV_FILE)
|
247
|
+
if File.exists?(links_tsv_file)
|
248
|
+
Hash[CSV.read(links_tsv_file, { :col_sep => "\t" })]
|
249
|
+
else
|
250
|
+
{}
|
251
|
+
end
|
252
|
+
rescue Exception => e
|
253
|
+
error("There was a problem reading #{LINKS_TSV_FILE}: #{e.message}")
|
254
|
+
{}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
242
258
|
def meta key
|
243
259
|
md = meta_data
|
244
260
|
md.nil?? nil : md[key]
|
@@ -451,8 +467,6 @@ module Inkcite
|
|
451
467
|
def write_links_csv out
|
452
468
|
|
453
469
|
unless @links.blank?
|
454
|
-
|
455
|
-
require 'csv'
|
456
470
|
csv = CSV.new(out, :force_quotes => true)
|
457
471
|
|
458
472
|
# Write each link to the CSV file.
|
@@ -501,6 +515,12 @@ module Inkcite
|
|
501
515
|
# Used to mark a helper.tsv line as a comment.
|
502
516
|
COMMENT = '//'
|
503
517
|
|
518
|
+
# Name of the local font cache file used for local storage of
|
519
|
+
# Google Font CSS
|
520
|
+
FONT_CACHE_FILE = '.inkcite_fonts'
|
521
|
+
|
522
|
+
# Tab-separated file containing links declarations.
|
523
|
+
LINKS_TSV_FILE = 'links.tsv'
|
504
524
|
|
505
525
|
def assert_in_browser msg
|
506
526
|
raise msg if email? && !development?
|
@@ -591,6 +611,54 @@ module Inkcite
|
|
591
611
|
html
|
592
612
|
end
|
593
613
|
|
614
|
+
def inline_google_fonts
|
615
|
+
|
616
|
+
reset = ''
|
617
|
+
|
618
|
+
# Google Web Fonts support courtesy of
|
619
|
+
# http://www.emaildesignreview.com/html-email-coding/web-fonts-in-email-1482/
|
620
|
+
font_urls = self[:fonts]
|
621
|
+
unless font_urls.blank?
|
622
|
+
require 'open-uri'
|
623
|
+
|
624
|
+
# Load the previously cached font, if any
|
625
|
+
font_cache_path = @email.project_file(FONT_CACHE_FILE)
|
626
|
+
font_cache = Util.read_yml(font_cache_path, :symbolize_keys => false)
|
627
|
+
|
628
|
+
# True if the cache needs to be updated because a new URL was
|
629
|
+
# added to it.
|
630
|
+
updated = false
|
631
|
+
|
632
|
+
# If you use @font-face in HTML email, Outlook 07/10/13 will default all
|
633
|
+
# text back to Times New Roman.
|
634
|
+
# http://www.emaildesignreview.com/html-email-coding/web-fonts-in-email-1482/
|
635
|
+
reset << '@media screen {'
|
636
|
+
|
637
|
+
# Iterate through the configured fonts. Check to see if we've already cached
|
638
|
+
# Google's response. If not, retrieve it and add it to the
|
639
|
+
font_urls.each do |url|
|
640
|
+
if font_cache[url].blank?
|
641
|
+
begin
|
642
|
+
font_cache[url] = open(url).read
|
643
|
+
updated = true
|
644
|
+
rescue
|
645
|
+
error 'Unable to load Google Web Font', { :url => url }
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
reset << font_cache[url]
|
650
|
+
end
|
651
|
+
reset << '}'
|
652
|
+
|
653
|
+
# If the fontcache was updated, update it in our sekret file.
|
654
|
+
File.write(font_cache_path, font_cache.to_yaml) if updated
|
655
|
+
|
656
|
+
end
|
657
|
+
|
658
|
+
reset
|
659
|
+
end
|
660
|
+
|
661
|
+
|
594
662
|
def inline_scripts
|
595
663
|
|
596
664
|
code = ''
|
@@ -659,29 +727,7 @@ module Inkcite
|
|
659
727
|
reset << 'o\:* { behavior: url(#default#VML); display: inline-block; }'
|
660
728
|
end
|
661
729
|
|
662
|
-
|
663
|
-
# http://www.emaildesignreview.com/html-email-coding/web-fonts-in-email-1482/
|
664
|
-
font_urls = self[:fonts]
|
665
|
-
unless font_urls.blank?
|
666
|
-
require 'open-uri'
|
667
|
-
|
668
|
-
# If you use @font-face in HTML email, Outlook 07/10/13 will default all
|
669
|
-
# text back to Times New Roman.
|
670
|
-
# http://www.emaildesignreview.com/html-email-coding/web-fonts-in-email-1482/
|
671
|
-
reset << "@media screen {"
|
672
|
-
|
673
|
-
# Iterate through the configured fonts and
|
674
|
-
font_urls.each do |url|
|
675
|
-
begin
|
676
|
-
reset << open(url).read
|
677
|
-
rescue
|
678
|
-
error "Unable to load Google Web Font", { :url => url }
|
679
|
-
end
|
680
|
-
|
681
|
-
end
|
682
|
-
reset << "}"
|
683
|
-
|
684
|
-
end
|
730
|
+
reset << inline_google_fonts
|
685
731
|
|
686
732
|
# Responsive styles.
|
687
733
|
reset += @media_query.to_a unless @media_query.blank?
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'inkcite'
|
4
|
+
|
5
|
+
describe Inkcite::View do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@view = Inkcite::Email.new('test/project/').view(:production, :email)
|
9
|
+
@view.is_enabled?(:minify).must_equal(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "won't create compound words out of line breaks" do
|
13
|
+
Inkcite::Minifier.html(%w(I am a multi-line string.), @view).must_equal('I am a multi-line string.')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "removes trailing line-breaks" do
|
17
|
+
Inkcite::Minifier.html(["This string has trailing line-breaks.\n\r\f"], @view).must_equal('This string has trailing line-breaks.')
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'inkcite'
|
4
|
+
|
5
|
+
describe Inkcite::Renderer::Table do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@view = Inkcite::Email.new('test/project/').view(:development, :email)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'defaults border, cellpadding and cellspacing to zero' do
|
12
|
+
Inkcite::Renderer.render('{table}{/table}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0><tr></tr></table>')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'supports custom margins in px' do
|
16
|
+
Inkcite::Renderer.render('{table margin-top=15}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-top:15px"><tr>')
|
17
|
+
Inkcite::Renderer.render('{table margin-left=16}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-left:16px"><tr>')
|
18
|
+
Inkcite::Renderer.render('{table margin-bottom=17}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-bottom:17px"><tr>')
|
19
|
+
Inkcite::Renderer.render('{table margin-right=18}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-right:18px"><tr>')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'supports multiple custom margins in px' do
|
23
|
+
Inkcite::Renderer.render('{table margin-top=15 margin-left=6}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-left:6px;margin-top:15px"><tr>')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'supports a single all margin attribute' do
|
27
|
+
Inkcite::Renderer.render('{table margin=15}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-bottom:15px;margin-left:15px;margin-right:15px;margin-top:15px"><tr>')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'supports unified margins with directional override' do
|
31
|
+
Inkcite::Renderer.render('{table margin=15 margin-left=8}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="margin-bottom:15px;margin-left:8px;margin-right:15px;margin-top:15px"><tr>')
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inkcite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeffrey D. Hoffman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: mailgun-ruby
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: net-sftp
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -250,6 +264,7 @@ files:
|
|
250
264
|
- lib/inkcite/renderer/image.rb
|
251
265
|
- lib/inkcite/renderer/image_base.rb
|
252
266
|
- lib/inkcite/renderer/in_browser.rb
|
267
|
+
- lib/inkcite/renderer/increment.rb
|
253
268
|
- lib/inkcite/renderer/like.rb
|
254
269
|
- lib/inkcite/renderer/link.rb
|
255
270
|
- lib/inkcite/renderer/litmus.rb
|
@@ -274,6 +289,7 @@ files:
|
|
274
289
|
- lib/inkcite/view/media_query.rb
|
275
290
|
- lib/inkcite/view/tag_stack.rb
|
276
291
|
- test/email_spec.rb
|
292
|
+
- test/minifier_spec.rb
|
277
293
|
- test/parser_spec.rb
|
278
294
|
- test/project/config.yml
|
279
295
|
- test/project/helpers.tsv
|
@@ -288,6 +304,7 @@ files:
|
|
288
304
|
- test/renderer/link_spec.rb
|
289
305
|
- test/renderer/mobile_image_spec.rb
|
290
306
|
- test/renderer/mobile_style_spec.rb
|
307
|
+
- test/renderer/table_spec.rb
|
291
308
|
- test/renderer/td_spec.rb
|
292
309
|
- test/renderer_spec.rb
|
293
310
|
- test/view_spec.rb
|
@@ -317,6 +334,7 @@ specification_version: 4
|
|
317
334
|
summary: Simplifying email development
|
318
335
|
test_files:
|
319
336
|
- test/email_spec.rb
|
337
|
+
- test/minifier_spec.rb
|
320
338
|
- test/parser_spec.rb
|
321
339
|
- test/project/config.yml
|
322
340
|
- test/project/helpers.tsv
|
@@ -331,6 +349,7 @@ test_files:
|
|
331
349
|
- test/renderer/link_spec.rb
|
332
350
|
- test/renderer/mobile_image_spec.rb
|
333
351
|
- test/renderer/mobile_style_spec.rb
|
352
|
+
- test/renderer/table_spec.rb
|
334
353
|
- test/renderer/td_spec.rb
|
335
354
|
- test/renderer_spec.rb
|
336
355
|
- test/view_spec.rb
|