inkcite 1.1.2 → 1.2.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 +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
|