inky-rb 0.0.2 → 0.0.3
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/Gemfile.lock +4 -2
- data/README.md +87 -0
- data/inky.gemspec +5 -1
- data/lib/component_factory.rb +42 -6
- data/lib/inky.rb +25 -2
- data/lib/inky/rails/version.rb +1 -1
- data/spec/components_spec.rb +109 -1
- metadata +3 -3
- data/inky-0.0.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b80cbab70f46992b028d1922f75f4e174feaed9
|
4
|
+
data.tar.gz: c423de651a2e9360171ca5c53ea84b387bff8032
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbb5a18634c5da418d8f343de6b1106ae2ac61c689b256c5a112fdca6218daf0843af331d50cea4174db1b3cadf1e7c115c4d27d770d3f4f119e9a92f7490d44
|
7
|
+
data.tar.gz: e804bf2d79119958f5facaeeeb96cc752cdf059a00b83567b621efbc2272f657e0d7d68e02479b733e2eaa3dd5ad022176fe97e81056ed4d1f700a34bf9b29cd
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
inky (0.0.
|
4
|
+
inky-rb (0.0.2)
|
5
|
+
foundation_emails (~> 2)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
8
9
|
specs:
|
9
10
|
diff-lcs (1.2.5)
|
11
|
+
foundation_emails (2.1.0.1)
|
10
12
|
rake (11.1.2)
|
11
13
|
rspec-core (3.4.1)
|
12
14
|
rspec-support (~> 3.4.0)
|
@@ -20,7 +22,7 @@ PLATFORMS
|
|
20
22
|
|
21
23
|
DEPENDENCIES
|
22
24
|
bundler (~> 1.6)
|
23
|
-
inky!
|
25
|
+
inky-rb!
|
24
26
|
rake
|
25
27
|
rspec-core
|
26
28
|
rspec-expectations
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Inky
|
2
|
+
|
3
|
+
Inky is an HTML-based templating language that converts simple HTML into complex, responsive email-ready HTML. Designed for [Foundation for Emails](http://foundation.zurb.com/emails), a responsive email framework from [ZURB](http://zurb.com).
|
4
|
+
|
5
|
+
Give Inky simple HTML like this:
|
6
|
+
|
7
|
+
```html
|
8
|
+
<row>
|
9
|
+
<columns large="6"></columns>
|
10
|
+
<columns large="6"></columns>
|
11
|
+
</row>
|
12
|
+
```
|
13
|
+
|
14
|
+
And get complicated, but battle-tested, email-ready HTML like this:
|
15
|
+
|
16
|
+
```html
|
17
|
+
<table class="row">
|
18
|
+
<tbody>
|
19
|
+
<tr>
|
20
|
+
<th class="small-12 large-6 columns first">
|
21
|
+
<table>
|
22
|
+
<tr>
|
23
|
+
<th class="expander"></th>
|
24
|
+
</tr>
|
25
|
+
</table>
|
26
|
+
</th>
|
27
|
+
<th class="small-12 large-6 columns first">
|
28
|
+
<table>
|
29
|
+
<tr>
|
30
|
+
<th class="expander"></th>
|
31
|
+
</tr>
|
32
|
+
</table>
|
33
|
+
</th>
|
34
|
+
</tr>
|
35
|
+
</tbody>
|
36
|
+
</table>
|
37
|
+
```
|
38
|
+
|
39
|
+
## Installation
|
40
|
+
|
41
|
+
Add this line to your application's Gemfile:
|
42
|
+
|
43
|
+
$ gem 'foundation-rails', require: 'inky'
|
44
|
+
|
45
|
+
And then execute:
|
46
|
+
|
47
|
+
$ bundle
|
48
|
+
|
49
|
+
Or install it yourself as:
|
50
|
+
|
51
|
+
$ gem install foundation-rails
|
52
|
+
|
53
|
+
## Usage
|
54
|
+
|
55
|
+
Inky can be embedded into your asset pipeline, combining with premailer to let you generate amazing HTML emails without the nightmare of table-based email development.
|
56
|
+
|
57
|
+
Simply use the file extension `.inky` and make sure your email layout includes a scss file that includes the foundation-emails styles.
|
58
|
+
```
|
59
|
+
@import 'foundation-emails'
|
60
|
+
```
|
61
|
+
|
62
|
+
## Custom Elements
|
63
|
+
|
64
|
+
Inky simplifies the process of creating HTML emails by expanding out simple tags like `<row>` and `<column>` into full table syntax. The names of the tags can be changed with the `components` setting.
|
65
|
+
|
66
|
+
Here are the names of the defaults:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
{
|
70
|
+
button: 'button',
|
71
|
+
row: 'row',
|
72
|
+
columns: 'columns',
|
73
|
+
container: 'container',
|
74
|
+
inky: 'inky',
|
75
|
+
block_grid: 'block-grid',
|
76
|
+
menu: 'menu',
|
77
|
+
center: 'center',
|
78
|
+
callout: 'callout',
|
79
|
+
spacer: 'spacer',
|
80
|
+
wrapper: 'wrapper',
|
81
|
+
menu_item: 'item'
|
82
|
+
}
|
83
|
+
```
|
84
|
+
|
85
|
+
## Programmatic Use
|
86
|
+
|
87
|
+
The Inky parser can be accessed directly for programmatic use.
|
data/inky.gemspec
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'inky/rails/version'
|
4
|
+
|
1
5
|
Gem::Specification.new do |s|
|
2
6
|
s.name = 'inky-rb'
|
3
|
-
s.version =
|
7
|
+
s.version = Inky::Rails::VERSION
|
4
8
|
s.date = '2016-02-12'
|
5
9
|
s.summary = 'Inky is an HTML-based templating language that converts simple HTML into complex, responsive email-ready HTML. Designed for Foundation for Emails, a responsive email framework from ZURB. '
|
6
10
|
s.description = 'Inky is an HTML-based templating language that converts simple HTML into complex, responsive email-ready HTML. Designed for Foundation for Emails, a responsive email framework from ZURB. '
|
data/lib/component_factory.rb
CHANGED
@@ -10,6 +10,17 @@ module ComponentFactory
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def _pass_through_attributes(elem)
|
14
|
+
ignored = ['class', 'id', 'href', 'size', 'large', 'no-expander', 'small', 'target'];
|
15
|
+
elem.attributes.map do |name, value|
|
16
|
+
if ignored.include?(name.downcase)
|
17
|
+
''
|
18
|
+
else
|
19
|
+
"#{name}=\"#{value}\""
|
20
|
+
end
|
21
|
+
end.join(' ')
|
22
|
+
end
|
23
|
+
|
13
24
|
def _has_class(elem, klass)
|
14
25
|
!!elem.attributes['class'] && elem.attributes['class'].split(' ').include?(klass)
|
15
26
|
end
|
@@ -18,13 +29,18 @@ module ComponentFactory
|
|
18
29
|
(elem.attributes['class'] ? (defaults.concat(elem.attributes['class'].split(' '))) : defaults).uniq
|
19
30
|
end
|
20
31
|
|
32
|
+
def _target_attribute(elem)
|
33
|
+
elem.attributes['target'] ? " target=\"#{elem.attributes['target']}\"" : ''
|
34
|
+
end
|
35
|
+
|
21
36
|
def _transform_button(component, inner)
|
22
37
|
expand = _has_class(component, 'expand')
|
23
38
|
if component.attributes['href']
|
39
|
+
target = _target_attribute(component)
|
24
40
|
if expand
|
25
|
-
inner = "<a href=\"#{component.attributes['href']}\" align=\"center\" class=\"float-center\">#{inner}</a>"
|
41
|
+
inner = "<a href=\"#{component.attributes['href']}\"#{target} align=\"center\" class=\"float-center\">#{inner}</a>"
|
26
42
|
else
|
27
|
-
inner = "<a href=\"#{component.attributes['href']}\">#{inner}</a>"
|
43
|
+
inner = "<a href=\"#{component.attributes['href']}\"#{target}>#{inner}</a>"
|
28
44
|
end
|
29
45
|
end
|
30
46
|
inner = "<center>#{inner}</center>" if expand
|
@@ -43,7 +59,8 @@ module ComponentFactory
|
|
43
59
|
end
|
44
60
|
|
45
61
|
def _transform_menu_item(component, inner)
|
46
|
-
|
62
|
+
target = _target_attribute(component)
|
63
|
+
"<th class=\"menu-item\"><a href=\"#{component.attributes['href']}\"#{target}>#{inner}</a></th>"
|
47
64
|
end
|
48
65
|
|
49
66
|
def _transform_container(component, inner)
|
@@ -53,7 +70,8 @@ module ComponentFactory
|
|
53
70
|
|
54
71
|
def _transform_row(component, inner)
|
55
72
|
classes = _class_array(component, ['row'])
|
56
|
-
|
73
|
+
attrs = _pass_through_attributes(component)
|
74
|
+
"<table #{attrs} class=\"#{classes.join(' ')}\"><tbody><tr>#{inner}</tr></tbody></table>"
|
57
75
|
end
|
58
76
|
|
59
77
|
# in inky.js this is factored out into makeClumn. TBD if we need that here.
|
@@ -105,8 +123,26 @@ module ComponentFactory
|
|
105
123
|
|
106
124
|
def _transform_spacer(component, inner)
|
107
125
|
classes = _class_array(component, ['spacer'])
|
108
|
-
size = component.attributes['size']
|
109
|
-
|
126
|
+
size = component.attributes['size']
|
127
|
+
size_sm = component.attributes['size-sm']
|
128
|
+
size_lg = component.attributes['size-lg']
|
129
|
+
if size_sm || size_lg
|
130
|
+
html = ''
|
131
|
+
if size_sm
|
132
|
+
html += "<table class=\"#{classes.join(' ')} hide-for-large\"><tbody><tr><td height=\"#{size_sm}px\" style=\"font-size:#{size_sm}px;line-height:#{size_sm}px;\"> </td></tr></tbody></table>"
|
133
|
+
end
|
134
|
+
if size_lg
|
135
|
+
html += "<table class=\"#{classes.join(' ')} show-for-large\"><tbody><tr><td height=\"#{size_lg}px\" style=\"font-size:#{size_lg}px;line-height:#{size_lg}px;\"> </td></tr></tbody></table>"
|
136
|
+
end
|
137
|
+
if size_sm && size_lg
|
138
|
+
# REXML doesn't like replacing a single element with a double
|
139
|
+
html = "<span>#{html}</span>"
|
140
|
+
end
|
141
|
+
return html
|
142
|
+
else
|
143
|
+
size ||= 16
|
144
|
+
return "<table class=\"#{classes.join(' ')}\"><tbody><tr><td height=\"#{size}px\" style=\"font-size:#{size}px;line-height:#{size}px;\"> </td></tr></tbody></table>"
|
145
|
+
end
|
110
146
|
end
|
111
147
|
|
112
148
|
def _transform_wrapper(component, inner)
|
data/lib/inky.rb
CHANGED
@@ -31,11 +31,13 @@ module Inky
|
|
31
31
|
|
32
32
|
def release_the_kraken(xml_string)
|
33
33
|
xml_string = xml_string.gsub(/doctype/i, 'DOCTYPE')
|
34
|
-
|
34
|
+
raws, str = Inky::Core.extract_raws(xml_string)
|
35
|
+
xml_doc = REXML::Document.new(str)
|
35
36
|
if self.components_exist?(xml_doc)
|
36
37
|
self.transform_doc(xml_doc.root)
|
37
38
|
end
|
38
|
-
|
39
|
+
str = xml_doc.to_s
|
40
|
+
return Inky::Core.re_inject_raws(str, raws)
|
39
41
|
end
|
40
42
|
|
41
43
|
|
@@ -53,6 +55,27 @@ module Inky
|
|
53
55
|
end
|
54
56
|
elem
|
55
57
|
end
|
58
|
+
|
59
|
+
def self.extract_raws(string)
|
60
|
+
raws = []
|
61
|
+
i = 0
|
62
|
+
regex = /\< *raw *\>(.*?)\<\/ *raw *\>/i;
|
63
|
+
str = string
|
64
|
+
while raw = str.match(regex)
|
65
|
+
raws[i] = raw[1]
|
66
|
+
str = str.sub(regex, "###RAW#{i}###")
|
67
|
+
i = i + 1
|
68
|
+
end
|
69
|
+
return [raws, str]
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.re_inject_raws(string, raws)
|
73
|
+
str = string
|
74
|
+
raws.each_with_index do |val, i|
|
75
|
+
str = str.sub("###RAW#{i}###", val)
|
76
|
+
end
|
77
|
+
return str
|
78
|
+
end
|
56
79
|
end
|
57
80
|
end
|
58
81
|
begin
|
data/lib/inky/rails/version.rb
CHANGED
data/spec/components_spec.rb
CHANGED
@@ -69,6 +69,25 @@ RSpec.describe "Button" do
|
|
69
69
|
HTML
|
70
70
|
compare(input, expected);
|
71
71
|
end
|
72
|
+
|
73
|
+
it 'creates a button with target="_blank" attribute' do
|
74
|
+
input = '<button href="http://zurb.com" target="_blank">Button</button>'
|
75
|
+
expected = <<-HTML
|
76
|
+
<table class="button">
|
77
|
+
<tr>
|
78
|
+
<td>
|
79
|
+
<table>
|
80
|
+
<tr>
|
81
|
+
<td><a href="http://zurb.com" target="_blank">Button</a></td>
|
82
|
+
</tr>
|
83
|
+
</table>
|
84
|
+
</td>
|
85
|
+
</tr>
|
86
|
+
</table>
|
87
|
+
HTML
|
88
|
+
compare(input, expected)
|
89
|
+
end
|
90
|
+
|
72
91
|
it 'creates a button with classes' do
|
73
92
|
input = '<button class="small alert" href="http://zurb.com">Button</button>'
|
74
93
|
expected = <<-HTML
|
@@ -135,6 +154,29 @@ RSpec.describe "Menu" do
|
|
135
154
|
compare(input, expected)
|
136
155
|
end
|
137
156
|
|
157
|
+
it 'creates a menu with items tags inside, containing target="_blank" attribute' do
|
158
|
+
input = <<-INKY
|
159
|
+
<menu>
|
160
|
+
<item href="http://zurb.com" target="_blank">Item</item>
|
161
|
+
</menu>
|
162
|
+
INKY
|
163
|
+
expected = <<-HTML
|
164
|
+
<table class="menu">
|
165
|
+
<tr>
|
166
|
+
<td>
|
167
|
+
<table>
|
168
|
+
<tr>
|
169
|
+
<th class="menu-item"><a href="http://zurb.com" target="_blank">Item</a></th>
|
170
|
+
</tr>
|
171
|
+
</table>
|
172
|
+
</td>
|
173
|
+
</tr>
|
174
|
+
</table>
|
175
|
+
HTML
|
176
|
+
|
177
|
+
compare(input, expected)
|
178
|
+
end
|
179
|
+
|
138
180
|
it 'creates a menu with classes' do
|
139
181
|
input = <<-INKY
|
140
182
|
<menu class="vertical">
|
@@ -225,7 +267,61 @@ RSpec.describe "Spacer" do
|
|
225
267
|
|
226
268
|
compare(input, expected);
|
227
269
|
end
|
228
|
-
|
270
|
+
|
271
|
+
it 'creates a spacer element for small screens with correct size' do
|
272
|
+
input = '<spacer size-sm="10"></spacer>'
|
273
|
+
expected = <<-HTML
|
274
|
+
<table class="spacer hide-for-large">
|
275
|
+
<tbody>
|
276
|
+
<tr>
|
277
|
+
<td height="10px" style="font-size:10px;line-height:10px;"> </td>
|
278
|
+
</tr>
|
279
|
+
</tbody>
|
280
|
+
</table>
|
281
|
+
HTML
|
282
|
+
|
283
|
+
compare(input, expected)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'creates a spacer element for large screens with correct size' do
|
287
|
+
input = '<spacer size-lg="20"></spacer>'
|
288
|
+
expected = <<-HTML
|
289
|
+
<table class="spacer show-for-large">
|
290
|
+
<tbody>
|
291
|
+
<tr>
|
292
|
+
<td height="20px" style="font-size:20px;line-height:20px;"> </td>
|
293
|
+
</tr>
|
294
|
+
</tbody>
|
295
|
+
</table>
|
296
|
+
HTML
|
297
|
+
|
298
|
+
compare(input, expected)
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'creates a spacer element for small and large screens with correct sizes' do
|
302
|
+
input = '<spacer size-sm="10" size-lg="20"></spacer>'
|
303
|
+
expected = <<-HTML
|
304
|
+
<span>
|
305
|
+
<table class="spacer hide-for-large">
|
306
|
+
<tbody>
|
307
|
+
<tr>
|
308
|
+
<td height="10px" style="font-size:10px;line-height:10px;"> </td>
|
309
|
+
</tr>
|
310
|
+
</tbody>
|
311
|
+
</table>
|
312
|
+
<table class="spacer show-for-large">
|
313
|
+
<tbody>
|
314
|
+
<tr>
|
315
|
+
<td height="20px" style="font-size:20px;line-height:20px;"> </td>
|
316
|
+
</tr>
|
317
|
+
</tbody>
|
318
|
+
</table>
|
319
|
+
</span>
|
320
|
+
HTML
|
321
|
+
|
322
|
+
compare(input, expected)
|
323
|
+
end
|
324
|
+
|
229
325
|
it 'copies classes to the final spacer HTML' do
|
230
326
|
input = '<spacer size="10" class="bgcolor"></spacer>'
|
231
327
|
expected = <<-HTML
|
@@ -256,3 +352,15 @@ RSpec.describe "Wrapper" do
|
|
256
352
|
compare(input, expected);
|
257
353
|
end
|
258
354
|
end
|
355
|
+
|
356
|
+
RSpec.describe "raw" do
|
357
|
+
it 'creates a wrapper that ignores anything inside' do
|
358
|
+
input = "<raw><<LCG Program\TG LCG Coupon Code Default='246996'>></raw>"
|
359
|
+
expected = "<<LCG Program\TG LCG Coupon Code Default='246996'>>"
|
360
|
+
|
361
|
+
# Can't do vanilla compare because the second will fail to parse
|
362
|
+
inky = Inky::Core.new
|
363
|
+
output = inky.release_the_kraken(input)
|
364
|
+
expect(output).to eql(expected)
|
365
|
+
end
|
366
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inky-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ZURB
|
@@ -64,8 +64,8 @@ files:
|
|
64
64
|
- ".gitignore"
|
65
65
|
- Gemfile
|
66
66
|
- Gemfile.lock
|
67
|
+
- README.md
|
67
68
|
- Rakefile
|
68
|
-
- inky-0.0.0.gem
|
69
69
|
- inky.gemspec
|
70
70
|
- lib/component_factory.rb
|
71
71
|
- lib/inky.rb
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|
96
96
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.4
|
97
|
+
rubygems_version: 2.6.4
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
100
|
summary: Inky is an HTML-based templating language that converts simple HTML into
|
data/inky-0.0.0.gem
DELETED
Binary file
|