html_email_creator 1.0.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.
Files changed (53) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +49 -0
  4. data/README.markdown +5 -0
  5. data/Rakefile +7 -0
  6. data/bin/html_email_creator +35 -0
  7. data/html_email_creator.gemspec +41 -0
  8. data/lib/html_email_creator/email.rb +93 -0
  9. data/lib/html_email_creator/email_creator.rb +45 -0
  10. data/lib/html_email_creator/email_version.rb +26 -0
  11. data/lib/html_email_creator/extensions.rb +46 -0
  12. data/lib/html_email_creator/filters.rb +9 -0
  13. data/lib/html_email_creator/formatter.rb +30 -0
  14. data/lib/html_email_creator/formatters/formatter.rb +31 -0
  15. data/lib/html_email_creator/formatters/html_email.rb +24 -0
  16. data/lib/html_email_creator/formatters/markdown.rb +24 -0
  17. data/lib/html_email_creator/formatters/plain_text_email.rb +22 -0
  18. data/lib/html_email_creator/formatters/unknown_formatter.rb +17 -0
  19. data/lib/html_email_creator/helper.rb +25 -0
  20. data/lib/html_email_creator/information.rb +4 -0
  21. data/lib/html_email_creator/layout.rb +15 -0
  22. data/lib/html_email_creator/processor.rb +125 -0
  23. data/lib/html_email_creator/settings.rb +95 -0
  24. data/lib/html_email_creator/tags/include_tag.rb +71 -0
  25. data/lib/html_email_creator/version.rb +3 -0
  26. data/lib/html_email_creator.rb +46 -0
  27. data/spec/fixtures/complex_with_config/.html_config.yaml +11 -0
  28. data/spec/fixtures/complex_with_config/Emails/polite_email.yaml +7 -0
  29. data/spec/fixtures/complex_with_config/Includes/Emails/love.md +1 -0
  30. data/spec/fixtures/complex_with_config/Includes/Footers/polite.md +3 -0
  31. data/spec/fixtures/complex_with_config/Layouts/.keep +0 -0
  32. data/spec/fixtures/complex_with_config/Layouts/basic.liquid +25 -0
  33. data/spec/fixtures/complex_with_config/Output/.keep +0 -0
  34. data/spec/fixtures/default_config/Emails/Newsletter/.keep +0 -0
  35. data/spec/fixtures/default_config/Layouts/.keep +0 -0
  36. data/spec/fixtures/default_config/Output/.keep +0 -0
  37. data/spec/fixtures/with_config/.html_config.yaml +11 -0
  38. data/spec/fixtures/with_config/Emails/first_email.yaml +7 -0
  39. data/spec/fixtures/with_config/Includes/Emails/barfoo.md +1 -0
  40. data/spec/fixtures/with_config/Includes/Emails/foobar.md +1 -0
  41. data/spec/fixtures/with_config/Includes/Quotes/henry_ford.txt +1 -0
  42. data/spec/fixtures/with_config/Layouts/.keep +0 -0
  43. data/spec/fixtures/with_config/Layouts/simple.liquid +7 -0
  44. data/spec/fixtures/with_config/Output/.keep +0 -0
  45. data/spec/html_email_creator/email_creator_spec.rb +119 -0
  46. data/spec/html_email_creator/email_spec.rb +29 -0
  47. data/spec/html_email_creator/formatter_spec.rb +40 -0
  48. data/spec/html_email_creator/layout_spec.rb +55 -0
  49. data/spec/html_email_creator/processor_spec.rb +111 -0
  50. data/spec/html_email_creator/settings_spec.rb +70 -0
  51. data/spec/html_email_creator/tags/include_tag_spec.rb +11 -0
  52. data/spec/spec_helper.rb +32 -0
  53. metadata +244 -0
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in html_email_creator.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ html_email_creator (0.0.1)
5
+ commander (>= 4.0.6)
6
+ inline-style (>= 0.5.0)
7
+ kramdown (>= 0.13.3)
8
+ liquid (>= 2.3.0)
9
+ nokogiri (>= 1.5.0)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ addressable (2.2.6)
15
+ commander (4.0.6)
16
+ highline (~> 1.5.0)
17
+ css_parser (1.2.5)
18
+ addressable
19
+ diff-lcs (1.1.3)
20
+ facets (2.9.2)
21
+ ffi (1.0.10)
22
+ highline (1.5.2)
23
+ inline-style (0.5.0)
24
+ css_parser
25
+ facets
26
+ maca-fork-csspool
27
+ nokogiri
28
+ kramdown (0.13.3)
29
+ liquid (2.3.0)
30
+ maca-fork-csspool (2.0.2)
31
+ ffi
32
+ nokogiri (1.5.0)
33
+ rake (0.9.2.2)
34
+ rspec (2.7.0)
35
+ rspec-core (~> 2.7.0)
36
+ rspec-expectations (~> 2.7.0)
37
+ rspec-mocks (~> 2.7.0)
38
+ rspec-core (2.7.1)
39
+ rspec-expectations (2.7.0)
40
+ diff-lcs (~> 1.1.2)
41
+ rspec-mocks (2.7.0)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ html_email_creator!
48
+ rake (>= 0.9.2)
49
+ rspec
data/README.markdown ADDED
@@ -0,0 +1,5 @@
1
+ # HTML Email Creator
2
+
3
+ ## Writing Emails
4
+
5
+ http://kramdown.rubyforge.org/syntax.html
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'commander/import'
4
+ require 'html_email_creator'
5
+ require 'html_email_creator/version'
6
+ require 'html_email_creator/information'
7
+
8
+ # :name is optional, otherwise uses the basename of this executable
9
+ program :name, 'HTML Email Creator'
10
+ program :version, HtmlEmailCreator::VERSION
11
+ program :description, HtmlEmailCreator::DESCRIPTION
12
+
13
+ command :create do |c|
14
+ c.syntax = 'html_email_creator create <email or directory>'
15
+ c.description = 'Creates a single email or all emails from the directory'
16
+ c.option '--recursive', 'If creating directory, find from sub directories too.'
17
+ c.action do |args, options|
18
+ # TODO implement me
19
+ recursive = options.recursive ? true : false
20
+ full_path = File.expand_path(args.first)
21
+ # run in this directory
22
+ Dir.chdir(File.dirname(full_path))
23
+ results = HtmlEmailCreator::EmailCreator.new.save_emails(full_path, recursive)
24
+ say "Creation completed!\n\n"
25
+ results.each_pair do |file, format|
26
+ say "#{file}:"
27
+ say " Output:"
28
+ format.values.each do |output|
29
+
30
+ say " #{output}"
31
+ end
32
+ end
33
+ say "\nHave a nice day :)"
34
+ end
35
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'html_email_creator/version'
6
+ require 'html_email_creator/information'
7
+
8
+ Gem::Specification.new do |s|
9
+ s.platform = Gem::Platform::RUBY
10
+ s.name = "html_email_creator"
11
+ s.version = HtmlEmailCreator::VERSION
12
+ s.summary = HtmlEmailCreator::SUMMARY
13
+ s.description = HtmlEmailCreator::DESCRIPTION
14
+ s.default_executable = "html_email_creator"
15
+
16
+ s.required_ruby_version = '>= 1.9.2'
17
+ s.rubygems_version = ">= 1.3.6"
18
+ s.rubyforge_project = "html_email_creator"
19
+
20
+ s.author = 'Pekka Mattila'
21
+ s.email = 'pekka.mattila@gmail.com'
22
+ s.homepage = 'https://github.com/pekkaj/HTML-Email-Creator'
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+
29
+ # Runtime Dependencies
30
+
31
+ s.add_runtime_dependency "commander", ">= 4.0.6"
32
+ s.add_runtime_dependency "kramdown", ">= 0.13.3"
33
+ s.add_runtime_dependency "liquid", ">= 2.3.0"
34
+ s.add_runtime_dependency "nokogiri", ">= 1.5.0"
35
+ s.add_runtime_dependency "inline-style", ">= 0.5.0"
36
+
37
+ # Development Dependencies
38
+
39
+ s.add_development_dependency "rspec"
40
+ s.add_development_dependency "rake", ">= 0.9.2"
41
+ end
@@ -0,0 +1,93 @@
1
+ require "liquid"
2
+
3
+ module HtmlEmailCreator
4
+ class Email
5
+ attr_reader :settings
6
+
7
+ def self.find_emails(file_or_directory, recursively = false)
8
+ if File.directory?(file_or_directory)
9
+ if recursively
10
+ Dir.glob(File.join(file_or_directory, "**", "*.yaml"))
11
+ else
12
+ Dir.glob(File.join(file_or_directory, "*.yaml"))
13
+ end
14
+ else
15
+ return [] unless File.extname(file_or_directory) == ".yaml"
16
+ [file_or_directory]
17
+ end
18
+ end
19
+
20
+ def initialize(configuration, settings = HtmlEmailCreator.settings)
21
+ @settings = settings
22
+ @configuration = create_configuration(configuration)
23
+ end
24
+
25
+ # Renders emails using configuration. Returns Hash[format, EmailVersion].
26
+ def render_all
27
+ # render only once
28
+ return @versions if @versions
29
+
30
+ @versions = {}
31
+ output_formats.each do |format|
32
+ @versions[format] = render_only(format)
33
+ end
34
+ @versions
35
+ end
36
+
37
+ # Renders email in a specific format
38
+ def render_only(format)
39
+ formatter = HtmlEmailCreator::Formatter.new(rendered_email, @settings).find(format)
40
+ HtmlEmailCreator::EmailVersion.new(formatter, output_basename, @settings)
41
+ end
42
+
43
+ # Convenience method for rendering HTML email.
44
+ def render_html_email
45
+ render_only(HtmlEmailCreator::Formatters::HtmlEmail.id)
46
+ end
47
+
48
+ # Convenience method for rendering plain text email.
49
+ def render_plain_text_email
50
+ render_only(HtmlEmailCreator::Formatters::PlainTextEmail.id)
51
+ end
52
+
53
+ private
54
+
55
+ def rendered_email
56
+ @email ||= HtmlEmailCreator::Layout.new(fill_blanks(IO.read(layout_path)), settings.extension_data).to_html
57
+ end
58
+
59
+ def output_formats
60
+ @configuration["output_formats"]
61
+ end
62
+
63
+ def create_configuration(configuration)
64
+ config_hash = if configuration.kind_of?(String)
65
+ YAML.load_file(configuration)
66
+ else
67
+ configuration
68
+ end
69
+
70
+ defaults = {
71
+ "output_formats" => ["plain_text_email", "html_email"]
72
+ }
73
+
74
+ config_hash.merge(defaults)
75
+ end
76
+
77
+ def output_basename
78
+ @configuration["config"]["output"]
79
+ end
80
+
81
+ def layout_path
82
+ File.join(@settings.layouts_path, @configuration["config"]["layout"])
83
+ end
84
+
85
+ def fill_blanks(layout)
86
+ filled_layout = layout.dup
87
+ @configuration["config"]["data"].each_pair do |key, value|
88
+ filled_layout.gsub!(/\{\{\s*#{key}\s*\}\}/, value)
89
+ end
90
+ filled_layout
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,45 @@
1
+ module HtmlEmailCreator
2
+ class EmailCreator
3
+ def create_email(file_or_configuration, format)
4
+ email(file_or_configuration).render_only(format)
5
+ end
6
+
7
+ def create_html_email(file_or_configuration)
8
+ email(file_or_configuration).render_html_email
9
+ end
10
+
11
+ def create_plain_text_email(file_or_configuration)
12
+ email(file_or_configuration).render_plain_text_email
13
+ end
14
+
15
+ def create_all_email_versions(file_or_configuration)
16
+ email(file_or_configuration).render_all
17
+ end
18
+
19
+ def save_email(file_or_configuration)
20
+ formats_and_paths = {}
21
+ create_all_email_versions(file_or_configuration).each_value do |version|
22
+ formats_and_paths[version.id] = version.save
23
+ end
24
+ formats_and_paths
25
+ end
26
+
27
+ def save_emails(file_or_directory, recursively = false)
28
+ files = {}
29
+ HtmlEmailCreator::Email.find_emails(file_or_directory, recursively).each do |file|
30
+ files[file] = save_email(file)
31
+ end
32
+ files
33
+ end
34
+
35
+ private
36
+
37
+ def email(file_or_configuration)
38
+ if file_or_configuration.kind_of?(String)
39
+ # Is file so update settings before creating email (makes sure that we have the latest settings file)
40
+ HtmlEmailCreator.update_settings(File.dirname(file_or_configuration))
41
+ end
42
+ Email.new(file_or_configuration, HtmlEmailCreator.settings)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,26 @@
1
+ module HtmlEmailCreator
2
+ class EmailVersion
3
+ def initialize(formatter, output_basename, settings)
4
+ @formatter = formatter
5
+ @output_basename = output_basename
6
+ @settings = settings
7
+ end
8
+
9
+ def get
10
+ @formatter.format
11
+ end
12
+
13
+ def id
14
+ @formatter.id
15
+ end
16
+
17
+ def save
18
+ FileUtils.mkdir_p(@settings.output_path) unless File.exists?(@settings.output_path)
19
+ file = File.join(@settings.output_path, "#{@output_basename}.#{@formatter.extension}")
20
+ File.open(file, "w") do |file|
21
+ file.write(get)
22
+ end
23
+ file
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,46 @@
1
+ require 'kramdown'
2
+
3
+ module HtmlEmailCreator
4
+ class Extensions
5
+ @@EXTENSIONS = {
6
+ 'aweber' => {
7
+ 'email' => '{!email}',
8
+ 'subscription_date' => '{!signdate long}',
9
+ 'unsubscribe_url' => '{!remove_web}',
10
+ 'full_name' => '{!name_fix}',
11
+ 'first_name' => '{!firstname_fix}',
12
+ 'last_name' => '{!lastname_fix}',
13
+ 'company_signature' => '{!signature}',
14
+ 'company_address' => '{!contact_address}',
15
+ 'tomorrow' => '{!date dayname+1}',
16
+ 'after_2_days' => '{!date dayname+2}',
17
+ 'after_3_days' => '{!date dayname+3}',
18
+ 'after_4_days' => '{!date dayname+4}',
19
+ 'after_5_days' => '{!date dayname+5}',
20
+ 'after_6_days' => '{!date dayname+6}',
21
+ 'after_7_days' => '{!date dayname+7}'
22
+ }
23
+ }
24
+
25
+ def initialize(settings = HtmlEmailCreator.settings)
26
+ @settings = settings
27
+ end
28
+
29
+ def built_in(*extensions)
30
+ new_data = {}
31
+ extensions.flatten.each do |extension|
32
+ data = @@EXTENSIONS[extension]
33
+ new_data.merge!(data.dup) if data
34
+ end
35
+ new_data
36
+ end
37
+
38
+ def custom(data = {}, extensions)
39
+ new_data = {}
40
+ extensions.each_pair do |key, value|
41
+ new_data[key] = value
42
+ end
43
+ new_data
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ require "liquid"
2
+
3
+ module HtmlEmailCreator
4
+ module Filters
5
+ def photo(input, alt)
6
+ "<img src=\"#{HtmlEmailCreator.settings.cdn_url}/#{input}\" alt=\"#{alt}\" border=\"0\" />"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ require "liquid"
2
+
3
+ module HtmlEmailCreator
4
+ class Formatter
5
+ @@DEFAULT = HtmlEmailCreator::Formatters::UnknownFormatter
6
+ @@CONFIG = {}
7
+
8
+ [
9
+ HtmlEmailCreator::Formatters::Markdown,
10
+ HtmlEmailCreator::Formatters::PlainTextEmail,
11
+ HtmlEmailCreator::Formatters::HtmlEmail
12
+ ].each do |klass|
13
+ @@CONFIG[klass.id] = klass
14
+ end
15
+
16
+ def initialize(text, settings = HtmlEmailCreator.settings)
17
+ @text = text
18
+ @settings = settings
19
+ end
20
+
21
+ def find(format)
22
+ klass = @@CONFIG[format.to_sym] || @@DEFAULT
23
+ klass.send(:new, @text, @settings)
24
+ end
25
+
26
+ def find_by_filename(filename)
27
+ find(File.extname(filename).split(".").last)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module HtmlEmailCreator
2
+ module Formatters
3
+ class Formatter
4
+ def self.id
5
+ raise "id needs to be defined"
6
+ end
7
+
8
+ def self.extension
9
+ raise "extension needs to be defined"
10
+ end
11
+
12
+ def initialize(text, settings)
13
+ @text = text
14
+ @settings = settings
15
+ end
16
+
17
+ # override to implement a correct formatter
18
+ def format
19
+ @text
20
+ end
21
+
22
+ def id
23
+ self.class.id
24
+ end
25
+
26
+ def extension
27
+ self.class.extension
28
+ end
29
+ end
30
+ end
31
+ end