antwort 0.0.12 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +12 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +28 -1
- data/README.md +1 -1
- data/antwort.gemspec +2 -2
- data/lib/antwort.rb +5 -4
- data/lib/antwort/builder/builder.rb +15 -24
- data/lib/antwort/builder/email.rb +47 -22
- data/lib/antwort/builder/flattener.rb +8 -9
- data/lib/antwort/builder/partial.rb +12 -11
- data/lib/antwort/builder/style.rb +26 -27
- data/lib/antwort/{builder.rb → builders.rb} +3 -3
- data/lib/antwort/cli.rb +0 -1
- data/lib/antwort/cli/cli.rb +42 -48
- data/lib/antwort/cli/send.rb +11 -14
- data/lib/antwort/cli/upload.rb +29 -28
- data/lib/antwort/core.rb +4 -0
- data/lib/antwort/email/build.rb +41 -0
- data/lib/antwort/email/collection.rb +41 -0
- data/lib/antwort/email/data.rb +27 -0
- data/lib/antwort/email/template.rb +88 -0
- data/lib/antwort/helpers/file_helper.rb +27 -0
- data/lib/antwort/{helpers.rb → helpers/helper.rb} +2 -2
- data/lib/antwort/helpers/logic_helper.rb +81 -0
- data/lib/antwort/helpers/markup_helper.rb +37 -0
- data/lib/antwort/{builder/helpers/sanitizers.rb → helpers/sanitizers_helper.rb} +2 -4
- data/lib/antwort/helpers/server_helper.rb +32 -0
- data/lib/antwort/{server.rb → server/server.rb} +26 -23
- data/{template/project → lib/antwort/server}/views/404.html.erb +1 -1
- data/{template/project → lib/antwort/server}/views/index.html.erb +4 -6
- data/{template/project → lib/antwort/server}/views/layout.erb +5 -5
- data/{template/project/views/markup/_button.html.erb → lib/antwort/server/views/markup/button.html.erb} +0 -0
- data/{template/project/views/markup/_image_tag.html.erb → lib/antwort/server/views/markup/image_tag.html.erb} +0 -0
- data/{template/project → lib/antwort/server}/views/server.erb +0 -0
- data/lib/antwort/version.rb +1 -1
- data/spec/builder/builder_spec.rb +17 -22
- data/spec/builder/email_spec.rb +11 -12
- data/spec/builder/flattener_spec.rb +20 -21
- data/spec/builder/helpers_logic_spec.rb +69 -73
- data/spec/builder/partial_spec.rb +42 -51
- data/spec/builder/style_spec.rb +25 -34
- data/spec/{cli_spec.rb → cli/cli_spec.rb} +8 -9
- data/spec/cli/send_spec.rb +80 -0
- data/spec/cli/upload_spec.rb +17 -9
- data/spec/email/build_spec.rb +13 -0
- data/spec/email/collection_spec.rb +56 -0
- data/spec/email/data_spec.rb +40 -0
- data/spec/email/template_spec.rb +116 -0
- data/spec/fixtures/assets/css/demo/include.scss +3 -0
- data/spec/fixtures/assets/css/demo/inline.scss +33 -0
- data/spec/fixtures/assets/css/no-images/include.scss +1 -0
- data/spec/fixtures/assets/css/no-images/inline.scss +2 -0
- data/spec/fixtures/assets/css/shared/_base.scss +64 -0
- data/spec/fixtures/assets/css/shared/_mixins.scss +25 -0
- data/spec/fixtures/assets/css/shared/_reset.scss +59 -0
- data/spec/fixtures/assets/css/shared/_vars.scss +12 -0
- data/spec/fixtures/assets/css/shared/include.scss +23 -0
- data/spec/fixtures/assets/css/shared/inline.scss +9 -0
- data/spec/fixtures/build/demo-20160101/demo.html +177 -0
- data/spec/fixtures/build/demo-20160101/source/demo.html +118 -0
- data/spec/fixtures/build/demo-20160101/source/include.css +58 -0
- data/spec/fixtures/build/demo-20160101/source/inline.css +83 -0
- data/spec/fixtures/build/demo-20160102/demo.html +177 -0
- data/spec/fixtures/build/demo-20160102/source/demo.html +118 -0
- data/spec/fixtures/build/demo-20160102/source/include.css +58 -0
- data/spec/fixtures/build/demo-20160102/source/inline.css +83 -0
- data/{template/project/data/.empty_directory → spec/fixtures/emails/1-demo/_bar.erb} +0 -0
- data/spec/fixtures/emails/1-demo/_foo.erb +0 -0
- data/spec/fixtures/emails/1-demo/index.html.erb +2 -2
- data/spec/fixtures/emails/4-custom-layout/index.html.erb +6 -0
- data/spec/fixtures/emails/4-custom-layout/layout.erb +5 -0
- data/spec/fixtures/emails/demo/index.html.erb +4 -0
- data/spec/fixtures/emails/no-images/index.html.erb +4 -0
- data/spec/fixtures/emails/shared/_foo.erb +0 -0
- data/spec/fixtures/{views → emails/shared}/layout.erb +0 -0
- data/spec/helpers/file_helper_spec.rb +30 -0
- data/spec/server/server_spec.rb +57 -0
- data/spec/spec_helper.rb +18 -7
- data/template/project/Gemfile.tt +1 -7
- metadata +92 -42
- data/lib/antwort/builder/helpers/logic.rb +0 -82
- data/lib/antwort/cli/helpers.rb +0 -44
- data/lib/antwort/server/helpers.rb +0 -67
- data/lib/antwort/server/markup.rb +0 -39
- data/spec/cli/helpers_spec.rb +0 -60
- data/spec/fixtures/build/demo-123456/build.html +0 -7
- data/spec/fixtures/build/demo-123457/build.html +0 -7
- data/spec/fixtures/build/demo-bar-123/build.html +0 -7
- data/spec/fixtures/views/404.html.erb +0 -1
- data/spec/fixtures/views/index.html.erb +0 -14
- data/spec/fixtures/views/server.erb +0 -5
- data/spec/server_spec.rb +0 -54
- data/template/project/.ruby-version +0 -1
- data/template/project/data/config.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd6a9e87317ec613b9765863c31b6daeef686c17
|
4
|
+
data.tar.gz: 0c1222631e2b670ae9ae6fc6198c727a787720b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43964bd735a1b4e471e75c11c0dbe30e60376863e8c9e1c4f252286af2a84f8093bd8d6f18ca93e0a726d9fffcb630a0ba75889ddb073eea260f16c2e1395911
|
7
|
+
data.tar.gz: c9ca766f6c01f9fffb96edec91dc656cfaad821349a04910df6deb73d35f8830a15a730699a9c7643af83d01fd0d98941fca1f6db92d9b4ad850fcef6692cc30
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
AllCops:
|
2
|
+
TargetRubyVersion: 2.2
|
2
3
|
Include:
|
3
4
|
- '*.gemspec'
|
4
5
|
- '**/Gemfile'
|
@@ -17,3 +18,14 @@ Metrics/MethodLength:
|
|
17
18
|
|
18
19
|
Documentation:
|
19
20
|
Enabled: false
|
21
|
+
|
22
|
+
Lint/Eval:
|
23
|
+
Exclude:
|
24
|
+
- 'spec/support/capture.rb'
|
25
|
+
|
26
|
+
Metrics/AbcSize:
|
27
|
+
Max: 25
|
28
|
+
|
29
|
+
Metrics/ClassLength:
|
30
|
+
Exclude:
|
31
|
+
- 'lib/antwort/cli/cli.rb'
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 1.0.0
|
4
|
+
|
5
|
+
Released: 31 October 2016
|
6
|
+
|
7
|
+
This release jumped to version 1.0 because it is not compatible with previously generated projects. This update features a great deal of refactoring under the hood:
|
8
|
+
|
9
|
+
__Added__
|
10
|
+
|
11
|
+
* Send test emails to multiple recipients.
|
12
|
+
* Cannot remove 'shared' folder.
|
13
|
+
|
14
|
+
__Refactored__
|
15
|
+
|
16
|
+
* Extracted code into models: `EmailCollection`, `EmailData`, `EmailTemplate`.
|
17
|
+
* Re-organized CLI code to leverage new classes.
|
18
|
+
* Re-organized helpers.
|
19
|
+
* Cleaned up and removed unused files.
|
20
|
+
* Internalized server code, removing it from project code.
|
21
|
+
* Added more spces.
|
22
|
+
* Added more ruby conventions to method names, esp. `?` and `!` in method names.
|
23
|
+
* Ran code through rubocop.
|
24
|
+
|
25
|
+
__Fixed__
|
26
|
+
|
27
|
+
* various template bugs, e.g. missing/unused variables.
|
28
|
+
|
29
|
+
|
3
30
|
## 0.0.12
|
4
31
|
|
5
32
|
Released: 14 March 2016
|
@@ -28,7 +55,7 @@ __Added__
|
|
28
55
|
|
29
56
|
* New `--all` flag to `build` command, which will build all emails.
|
30
57
|
* `each_with_index` loops are also now preserved. Example conversion: `cats.each_with_index do |cat, i|` becomes `{% for cat in cats with: {@index: i} %}`
|
31
|
-
* Locals passed to partials are now referenced using a more generic `with` instead of ruby-esqe `locals` like so: {% partial 'foo' with: {size: 1} %}
|
58
|
+
* Locals passed to partials are now referenced using a more generic `with` instead of ruby-esqe `locals` like so: `{% partial 'foo' with: {size: 1} %}`
|
32
59
|
* ERB's `unless` is now converted to `if !(condition)`
|
33
60
|
* ERB Statements without output or conditionals are also now preserved. Example: `<% product.merge({featured: false}) %>`
|
34
61
|
* `button` and `image_tag` helpers are converted to use statement `{% … %}` syntax, not `{{ … }}` output syntax
|
data/README.md
CHANGED
data/antwort.gemspec
CHANGED
@@ -10,14 +10,14 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.description = 'E-Mail development, build and test system.'
|
11
11
|
s.authors = ['Julie Ng']
|
12
12
|
s.email = 'hello@antwort.co'
|
13
|
-
s.homepage = 'https://antwort.co'
|
13
|
+
s.homepage = 'https://antwort.co/gem'
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
17
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
19
|
s.require_paths = ['lib']
|
20
|
-
s.required_ruby_version = '~> 2.
|
20
|
+
s.required_ruby_version = '~> 2.2'
|
21
21
|
|
22
22
|
s.add_runtime_dependency 'rake'
|
23
23
|
s.add_runtime_dependency 'thor'
|
data/lib/antwort.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'dotenv'
|
3
|
-
Dotenv.load
|
3
|
+
Dotenv.load unless ENV['RACK_ENV'] == 'test'
|
4
4
|
|
5
5
|
# Namespace
|
6
6
|
module Antwort
|
7
7
|
end
|
8
8
|
|
9
|
-
require 'antwort/helpers'
|
9
|
+
require 'antwort/helpers/helper'
|
10
|
+
require 'antwort/helpers/file_helper'
|
11
|
+
require 'antwort/core'
|
10
12
|
require 'antwort/cli'
|
11
|
-
require 'antwort/
|
12
|
-
require 'antwort/server'
|
13
|
+
require 'antwort/server/server'
|
13
14
|
require 'antwort/version'
|
@@ -7,22 +7,25 @@ module Antwort
|
|
7
7
|
class Builder
|
8
8
|
include Thor::Shell
|
9
9
|
include Antwort::Helpers
|
10
|
-
include Antwort::
|
10
|
+
include Antwort::FileHelpers
|
11
11
|
include Antwort::LogicHelpers
|
12
12
|
include Antwort::MarkupSanitizers
|
13
13
|
|
14
|
-
attr_reader :
|
14
|
+
attr_reader :template, :build_id, :build_dir, :markup_dir, :source_dir, :scss_dir, :asset_server, :css, :css_style
|
15
15
|
|
16
16
|
def initialize(attrs = {})
|
17
17
|
attrs = symbolize_keys!(attrs)
|
18
|
-
|
19
|
-
@build_id
|
20
|
-
@
|
18
|
+
|
19
|
+
@build_id = attrs[:id]
|
20
|
+
@template = EmailTemplate.new(attrs[:email])
|
21
|
+
|
22
|
+
@build_dir = "./build/#{template.name}-#{build_id}"
|
21
23
|
@markup_dir = "#{build_dir}/source"
|
22
|
-
@source_dir = "./emails/#{
|
23
|
-
@scss_dir = "./assets/css/#{
|
24
|
+
@source_dir = "./emails/#{template.name}"
|
25
|
+
@scss_dir = "./assets/css/#{template.name}"
|
24
26
|
@css_style = attrs[:'css-style'].to_sym
|
25
27
|
@asset_server = ENV['ASSET_SERVER'] || '/assets'
|
28
|
+
|
26
29
|
post_initialize(attrs)
|
27
30
|
end
|
28
31
|
|
@@ -30,9 +33,9 @@ module Antwort
|
|
30
33
|
nil
|
31
34
|
end
|
32
35
|
|
33
|
-
def create_build_directories
|
36
|
+
def create_build_directories!
|
34
37
|
return if Dir.exist? build_dir
|
35
|
-
Dir.mkdir
|
38
|
+
Dir.mkdir 'build' unless Dir.exist? './build'
|
36
39
|
Dir.mkdir(build_dir)
|
37
40
|
Dir.mkdir("#{build_dir}/source")
|
38
41
|
end
|
@@ -47,7 +50,7 @@ module Antwort
|
|
47
50
|
css
|
48
51
|
end
|
49
52
|
|
50
|
-
def build_css
|
53
|
+
def build_css!
|
51
54
|
compile_scss(source: "#{scss_dir}/inline.scss", destination: "#{markup_dir}/inline.css")
|
52
55
|
compile_scss(source: "#{scss_dir}/include.scss", destination: "#{markup_dir}/include.css")
|
53
56
|
@css = load_css
|
@@ -59,25 +62,13 @@ module Antwort
|
|
59
62
|
|
60
63
|
if File.file? source_file
|
61
64
|
content = Tilt::ScssTemplate.new(source_file, style: @css_style).render
|
62
|
-
create_file(content: content, path: destination_file)
|
65
|
+
create_file!(content: content, path: destination_file)
|
63
66
|
else
|
64
67
|
say 'Build failed. ', :red
|
65
|
-
say "#{source_file}.scss for #{
|
68
|
+
say "#{source_file}.scss for #{template.name} not found."
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
69
|
-
def create_file(attrs)
|
70
|
-
content = attrs[:content]
|
71
|
-
path = attrs[:path]
|
72
|
-
|
73
|
-
file = File.new(path, 'w')
|
74
|
-
file.write(content)
|
75
|
-
file.close
|
76
|
-
say ' create ', :green
|
77
|
-
say path.gsub(/\A.\//, '')
|
78
|
-
file
|
79
|
-
end
|
80
|
-
|
81
72
|
def use_asset_server(markup = '')
|
82
73
|
replaced = "#{asset_server}/"
|
83
74
|
output = markup.gsub('/assets/', replaced)
|
@@ -5,39 +5,36 @@ module Antwort
|
|
5
5
|
def post_initialize(*)
|
6
6
|
app ||= Antwort::Server.new
|
7
7
|
mock ||= Rack::MockRequest.new(app)
|
8
|
+
@request = mock.get("/template/#{template.name}")
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@
|
13
|
-
@inlined_file = "#{build_dir}/#{template_name}.html"
|
10
|
+
if template_is_valid?
|
11
|
+
create_build_directories!
|
12
|
+
@html_markup = remove_livereload(@request.body)
|
13
|
+
@inlined_file = "#{build_dir}/#{template.name}.html"
|
14
14
|
else
|
15
|
-
|
16
|
-
say "Template '#{template_name}' not found."
|
15
|
+
show_error_message
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
|
-
def build
|
19
|
+
def build!
|
21
20
|
unless html_markup.nil?
|
22
|
-
build_css
|
23
|
-
build_html
|
24
|
-
inline_css
|
21
|
+
build_css!
|
22
|
+
build_html!
|
23
|
+
inline_css!
|
25
24
|
end
|
26
25
|
|
27
|
-
until File.exist?(@inlined_file)
|
28
|
-
|
29
|
-
end
|
30
|
-
return true
|
26
|
+
sleep 1 until File.exist?(@inlined_file)
|
27
|
+
true
|
31
28
|
end
|
32
29
|
|
33
|
-
def build_html
|
30
|
+
def build_html!
|
34
31
|
markup = html_markup
|
35
|
-
markup = markup.gsub("/assets/#{
|
36
|
-
.gsub("/assets/#{
|
37
|
-
create_file(content: markup, path: "#{markup_dir}/#{
|
32
|
+
markup = markup.gsub("/assets/#{template.name}/inline.css", 'inline.css')
|
33
|
+
.gsub("/assets/#{template.name}/include.css", 'include.css')
|
34
|
+
create_file!(content: markup, path: "#{markup_dir}/#{template.name}.html")
|
38
35
|
end
|
39
36
|
|
40
|
-
def inline_css
|
37
|
+
def inline_css!
|
41
38
|
markup = preserve_nbsps(html_markup)
|
42
39
|
document = Roadie::Document.new(markup)
|
43
40
|
|
@@ -46,10 +43,10 @@ module Antwort
|
|
46
43
|
|
47
44
|
inlined = restore_nbsps(document.transform)
|
48
45
|
inlined = cleanup_markup(inlined)
|
49
|
-
|
46
|
+
inlined = remove_roadie_flags(inlined)
|
50
47
|
inlined = remove_excessive_newlines(inlined)
|
51
48
|
inlined = flatten_inlined_css(inlined)
|
52
|
-
create_file(content: inlined, path: @inlined_file)
|
49
|
+
create_file!(content: inlined, path: @inlined_file)
|
53
50
|
end
|
54
51
|
|
55
52
|
def cleanup_markup(markup)
|
@@ -57,5 +54,33 @@ module Antwort
|
|
57
54
|
content = add_included_css(content)
|
58
55
|
content
|
59
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def show_error_message
|
61
|
+
msg = if template_not_found?
|
62
|
+
"Template '#{template.name}' not found."
|
63
|
+
elsif template_has_error?
|
64
|
+
"Template '#{template.name}' is not rendering succesfully. Verify with `antwort server` that the template is valid and try again."
|
65
|
+
else
|
66
|
+
"Error building #{template.name}."
|
67
|
+
end
|
68
|
+
|
69
|
+
say 'Error: ', :red
|
70
|
+
say msg
|
71
|
+
exit
|
72
|
+
end
|
73
|
+
|
74
|
+
def template_is_valid?
|
75
|
+
@request.status == 200
|
76
|
+
end
|
77
|
+
|
78
|
+
def template_not_found?
|
79
|
+
@request.status == 404
|
80
|
+
end
|
81
|
+
|
82
|
+
def template_has_error?
|
83
|
+
@request.status == 500
|
84
|
+
end
|
60
85
|
end
|
61
86
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
module Antwort
|
2
2
|
class Flattener
|
3
|
-
|
4
3
|
attr_reader :source, :styles, :flattened, :flattened_keys
|
5
4
|
|
6
|
-
def initialize(source='')
|
5
|
+
def initialize(source = '')
|
7
6
|
@source = source
|
8
7
|
@styles = find_styles
|
9
8
|
@flattened_keys = []
|
@@ -15,7 +14,7 @@ module Antwort
|
|
15
14
|
@styles.each do |m|
|
16
15
|
style = Antwort::Style.new(m)
|
17
16
|
@flattened_keys.concat(style.duplicate_keys) if style.duplicates?
|
18
|
-
copy.sub!(m, style.flattened_str)
|
17
|
+
copy.sub!(m, style.flattened_str)
|
19
18
|
end
|
20
19
|
|
21
20
|
@flattened = copy
|
@@ -23,15 +22,15 @@ module Antwort
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def flattened?
|
26
|
-
|
25
|
+
!@flattened_keys.empty?
|
27
26
|
end
|
28
27
|
|
29
28
|
private
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
def find_styles
|
31
|
+
a = []
|
32
|
+
@source.scan(/style="(.+?)"/).each { |match| a.push(match.first) }
|
33
|
+
a
|
34
|
+
end
|
36
35
|
end
|
37
36
|
end
|
@@ -1,21 +1,22 @@
|
|
1
1
|
module Antwort
|
2
2
|
class PartialBuilder < Builder
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :partials
|
4
4
|
|
5
5
|
def post_initialize(*)
|
6
|
-
@
|
7
|
-
|
6
|
+
@partials = @template.partials.push('index.html.erb')
|
7
|
+
|
8
|
+
if partials.empty?
|
8
9
|
say 'Error: ', :red
|
9
|
-
puts "No partials found in #{
|
10
|
+
puts "No partials found in #{template.name} folder."
|
10
11
|
return
|
11
12
|
else
|
12
|
-
create_build_directories
|
13
|
+
create_build_directories!
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
def build
|
17
|
+
def build!
|
17
18
|
@css = load_css
|
18
|
-
|
19
|
+
partials.each { |t| build_html t }
|
19
20
|
end
|
20
21
|
|
21
22
|
def build_html(partial_name)
|
@@ -28,7 +29,7 @@ module Antwort
|
|
28
29
|
inlined = restore_nbsps(inlined)
|
29
30
|
inlined = flatten_inlined_css(inlined)
|
30
31
|
filename = adjust_filename(partial_name)
|
31
|
-
create_file(content: inlined, path: "#{build_dir}/#{filename}")
|
32
|
+
create_file!(content: inlined, path: "#{build_dir}/#{filename}")
|
32
33
|
end
|
33
34
|
|
34
35
|
def inline(markup)
|
@@ -45,7 +46,7 @@ module Antwort
|
|
45
46
|
end
|
46
47
|
|
47
48
|
def adjust_filename(filename)
|
48
|
-
filename = @
|
49
|
+
filename = @template.name if filename == 'index.html.erb'
|
49
50
|
|
50
51
|
name = filename.gsub('.erb', '')
|
51
52
|
name << '.html' unless name[-5, 5] == '.html'
|
@@ -73,8 +74,8 @@ module Antwort
|
|
73
74
|
end
|
74
75
|
|
75
76
|
def preserve_operators_from_nokogiri(html = '')
|
76
|
-
html.gsub(
|
77
|
-
.gsub(
|
77
|
+
html.gsub(/{%\s*if(.*?)<(.*?)%}/, '{%\1<\2%}')
|
78
|
+
.gsub(/{%\s*if(.*?)>(.*?)%}/, '{%\1>\2%}')
|
78
79
|
end
|
79
80
|
end
|
80
81
|
end
|
@@ -3,7 +3,7 @@ module Antwort
|
|
3
3
|
attr_reader :keys, :duplicate_keys, :flattened, :original
|
4
4
|
|
5
5
|
def initialize(style = '')
|
6
|
-
@style
|
6
|
+
@style = style
|
7
7
|
@keys = []
|
8
8
|
@duplicate_keys = []
|
9
9
|
@flattened = []
|
@@ -23,37 +23,36 @@ module Antwort
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def duplicates?
|
26
|
-
|
26
|
+
!@duplicate_keys.empty?
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
@keys << key
|
46
|
-
end
|
31
|
+
def convert_to_hash
|
32
|
+
str = String.new(@style)
|
33
|
+
h = {}
|
34
|
+
|
35
|
+
str.split(';').each do |s|
|
36
|
+
key = s.split(':').first.strip
|
37
|
+
val = s.split(':').last.strip
|
38
|
+
h[key] = val
|
39
|
+
@original << { key => val }
|
40
|
+
|
41
|
+
if @keys.include? key
|
42
|
+
@duplicate_keys << key
|
43
|
+
else
|
44
|
+
@keys << key
|
47
45
|
end
|
48
|
-
@flattened = h
|
49
46
|
end
|
47
|
+
@flattened = h
|
48
|
+
end
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
# convert our flatted styles hash back into a string
|
51
|
+
def hash_to_str(hash)
|
52
|
+
str = ''
|
53
|
+
hash.each { |k, v| str << "#{k}:#{v};" }
|
54
|
+
str.chop! if str[-1] == ';' # remove trailing ';'
|
55
|
+
str
|
56
|
+
end
|
58
57
|
end
|
59
|
-
end
|
58
|
+
end
|