epubber 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +58 -0
  6. data/Rakefile +9 -0
  7. data/epubber.gemspec +23 -0
  8. data/lib/epubber/generator.rb +63 -0
  9. data/lib/epubber/generators/chapters.rb +20 -0
  10. data/lib/epubber/generators/content.rb +10 -0
  11. data/lib/epubber/generators/endnotes.rb +14 -0
  12. data/lib/epubber/generators/generator.rb +29 -0
  13. data/lib/epubber/generators/introduction.rb +14 -0
  14. data/lib/epubber/generators/static.rb +21 -0
  15. data/lib/epubber/generators/toc.rb +13 -0
  16. data/lib/epubber/models/book.rb +87 -0
  17. data/lib/epubber/models/chapter.rb +26 -0
  18. data/lib/epubber/models/concerns/has_chapters.rb +23 -0
  19. data/lib/epubber/models/concerns/has_endnotes.rb +17 -0
  20. data/lib/epubber/models/concerns/has_introduction.rb +17 -0
  21. data/lib/epubber/models/endnotes.rb +16 -0
  22. data/lib/epubber/models/introduction.rb +16 -0
  23. data/lib/epubber/services/compressor.rb +45 -0
  24. data/lib/epubber/services/persistance.rb +35 -0
  25. data/lib/epubber/services/template.rb +27 -0
  26. data/lib/epubber/version.rb +3 -0
  27. data/lib/epubber.rb +12 -0
  28. data/lib/templates/META-INF/com.apple.ibooks.display-options.xml +6 -0
  29. data/lib/templates/META-INF/container.xml +6 -0
  30. data/lib/templates/OEBPS/Styles/style.css +16 -0
  31. data/lib/templates/OEBPS/Text/acknowledgements.xhtml +15 -0
  32. data/lib/templates/OEBPS/Text/chapter.xhtml +16 -0
  33. data/lib/templates/OEBPS/Text/cover.xhtml +21 -0
  34. data/lib/templates/OEBPS/Text/dedication.xhtml +15 -0
  35. data/lib/templates/OEBPS/Text/endnotes.xhtml +16 -0
  36. data/lib/templates/OEBPS/Text/foreword.xhtml +15 -0
  37. data/lib/templates/OEBPS/Text/frontmatter.xhtml +15 -0
  38. data/lib/templates/OEBPS/Text/introduction.xhtml +16 -0
  39. data/lib/templates/OEBPS/Text/toc.xhtml +37 -0
  40. data/lib/templates/OEBPS/content.opf +180 -0
  41. data/lib/templates/OEBPS/toc.ncx +79 -0
  42. data/lib/templates/mimetype +1 -0
  43. data/test/test_epubber.rb +31 -0
  44. metadata +115 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 42daf1a5cfc9933d3bbccdffd13be03d45b585e4
4
+ data.tar.gz: b349d1f7b7ea333a6ceb4d470dbce023daba2534
5
+ SHA512:
6
+ metadata.gz: 424d892bfbc55f533d5c921b8884441a3f342388d99be0241694d9912ef6def42c7cf8b33456a0d305506bbbccf409ed55be0a80e26e65d56f1164d6273fd2e9
7
+ data.tar.gz: 53fd7dd832c3baea3aba7008a8f7b3f167e1002f4a7ad0f32d57b34f79f6a2893305d6d1df7d490e710944d355256c878eb764de65c89a7fc3305b5f5fba91a5
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in epubber.gemspec
4
+ gemspec
5
+
6
+ # Use liquid template engine
7
+ gem 'liquid'
8
+ # For packaging
9
+ gem 'rubyzip'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Federico Ramirez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Epubber
2
+ This gem allows you to easily build EPUB files programatically.
3
+
4
+ ## Installation
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'epubber'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install epubber
18
+
19
+ ## Usage
20
+ Epubber's DSL is rather simple:
21
+
22
+ ```ruby
23
+ path = Epubber.generate do
24
+ title 'My First EPUB book'
25
+ author 'Ramirez, Federico'
26
+ description 'This is an example EPUB'
27
+ url 'http://my-url.com'
28
+
29
+ chapter do
30
+ title 'Chapter 1'
31
+ content '<p>This is some content!</p>'
32
+ end
33
+
34
+ chapter do
35
+ title 'Chapter 2'
36
+ content '<p>Some more content this is.</p>'
37
+ end
38
+ end
39
+
40
+ # Now the `path` variable contains the full path of the generated EPUB file.
41
+ # Defaults to `#{title}.epub`
42
+ ```
43
+
44
+ You can configure the generator
45
+
46
+ ```ruby
47
+ path = Epubber.generate filename: 'some-file.epub', workspace: '/tmp' do
48
+ # Ebook code here...
49
+ end
50
+ ```
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it ( https://github.com/gosukiwi/epubber/fork )
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ end
7
+
8
+ desc 'Run tests'
9
+ task :default => :test
data/epubber.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'epubber/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "epubber"
8
+ spec.version = Epubber::VERSION
9
+ spec.authors = ["Federico Ramirez"]
10
+ spec.email = ["fedra.arg@gmail.com"]
11
+ spec.summary = %q{Generate EPUB files programatically}
12
+ #spec.description = %q{TODO: Write a longer description. Optional.}
13
+ spec.homepage = "https://github.com/gosukiwi/epubber"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,63 @@
1
+ require 'epubber/generators/chapters'
2
+ require 'epubber/generators/content'
3
+ require 'epubber/generators/toc'
4
+ require 'epubber/generators/introduction'
5
+ require 'epubber/generators/static'
6
+ require 'epubber/generators/endnotes'
7
+ require 'epubber/services/persistance'
8
+ require 'epubber/services/compressor'
9
+
10
+ # Given a book and a place to work in, generates all required EPUB files
11
+ class Epubber::Generator
12
+ attr_reader :working_dir, :book, :filename
13
+ def initialize(book: book, filename: filename, working_dir: working_dir)
14
+ @book = book
15
+ @filename = filename || "#{book.title}.epub"
16
+ @working_dir = working_dir || '/tmp/epubber'
17
+ @persistance = Epubber::Services::Persistance.new File.join(@working_dir, 'workspace')
18
+ @generators = []
19
+
20
+ register_generators book: book, persistance: @persistance
21
+ end
22
+
23
+ def register_generators(params)
24
+ add_generator Epubber::Generators::Content.new(params)
25
+ add_generator Epubber::Generators::Introduction.new(params)
26
+ add_generator Epubber::Generators::Toc.new(params)
27
+ add_generator Epubber::Generators::Chapters.new(params)
28
+ add_generator Epubber::Generators::Static.new(params)
29
+ add_generator Epubber::Generators::Endnotes.new(params)
30
+ end
31
+
32
+ def generate
33
+ @generators.each { |generator| generator.generate }
34
+ pack
35
+ end
36
+
37
+ protected
38
+
39
+ def clean_tmp
40
+ @persistance.clean
41
+ end
42
+
43
+ def compressor
44
+ Epubber::Services::Compressor.new
45
+ end
46
+
47
+ def compress
48
+ file = File.join working_dir, "#{filename}"
49
+ dir = File.join working_dir, 'workspace'
50
+ compressor.compress dir, file
51
+ return file
52
+ end
53
+
54
+ def pack
55
+ path = compress
56
+ clean_tmp
57
+ return path
58
+ end
59
+
60
+ def add_generator(generator)
61
+ @generators << generator
62
+ end
63
+ end
@@ -0,0 +1,20 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Chapters < Generator
5
+ def generate
6
+ compiled_template = template.compile 'OEBPS/Text/chapter.xhtml'
7
+ book.chapters.each do |chapter|
8
+ generate_chapter compiled_template, chapter
9
+ end
10
+ end
11
+
12
+ protected
13
+
14
+ def generate_chapter(compiled_template, chapter)
15
+ context = chapter.contextify
16
+ content = compiled_template.render context
17
+ persist file: "OEBPS/Text/chapter#{context['id']}.xhtml", content: content
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Content < Generator
5
+ def generate
6
+ content = template.parse file: 'OEBPS/content.opf', context: book_context
7
+ persist file: 'OEBPS/content.opf', content: content
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Endnotes < Generator
5
+ def generate
6
+ # Because this is an optional generator, don't do anything if there's no
7
+ # introduction in the book
8
+ return if book.endnotes.nil?
9
+
10
+ content = template.parse file: 'OEBPS/Text/endnotes.xhtml', context: book_context
11
+ persist file: 'OEBPS/Text/endnotes.xhtml', content: content
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require 'epubber/services/template'
2
+
3
+ module Epubber::Generators
4
+ class Generator
5
+ attr_reader :book, :persistance
6
+ def initialize(book: book, persistance: persistance)
7
+ @book = book
8
+ @persistance = persistance
9
+ end
10
+
11
+ protected
12
+
13
+ def book_context
14
+ { 'book' => book.contextify }
15
+ end
16
+
17
+ def template
18
+ Epubber::Services::Template.new
19
+ end
20
+
21
+ def template_path(file)
22
+ template.path file
23
+ end
24
+
25
+ def persist(file: file, content: content)
26
+ persistance.persist file: file, content: content
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Introduction < Generator
5
+ def generate
6
+ # Because this is an optional generator, don't do anything if there's no
7
+ # introduction in the book
8
+ return if book.introduction.nil?
9
+
10
+ content = template.parse file: 'OEBPS/Text/introduction.xhtml', context: book_context
11
+ persist file: 'OEBPS/Text/introduction.xhtml', content: content
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Static < Generator
5
+ def generate
6
+ files = ['mimetype', 'META-INF/container.xml', 'META-INF/com.apple.ibooks.display-options.xml',
7
+ 'OEBPS/Text/cover.xhtml', 'OEBPS/Styles/style.css']
8
+ files.each do |file|
9
+ copy file
10
+ end
11
+ end
12
+
13
+ protected
14
+
15
+ # Get the file from the template and copy it unchanged
16
+ def copy(file)
17
+ content = File.open(template_path(file)).read
18
+ persist file: file, content: content
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ require 'epubber/generators/generator'
2
+
3
+ module Epubber::Generators
4
+ class Toc < Generator
5
+ def generate
6
+ content = template.parse file: 'OEBPS/toc.ncx', context: book_context
7
+ persist file: 'OEBPS/toc.ncx', content: content
8
+
9
+ content = template.parse file: 'OEBPS/Text/toc.xhtml', context: book_context
10
+ persist file: 'OEBPS/Text/toc.xhtml', content: content
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,87 @@
1
+ require 'securerandom'
2
+ require 'epubber/models/concerns/has_chapters'
3
+ require 'epubber/models/concerns/has_introduction'
4
+ require 'epubber/models/concerns/has_endnotes'
5
+
6
+ # Represents a book with it's chapters.
7
+ module Epubber::Models
8
+ class Book
9
+ # Related models and their DSL goodies
10
+ include Epubber::Models::Concerns::HasChapters
11
+ include Epubber::Models::Concerns::HasIntroduction
12
+ include Epubber::Models::Concerns::HasEndnotes
13
+
14
+ def initialize
15
+ @title = not_specified
16
+ @author = not_specified
17
+ @description = not_specified
18
+ @publisher = not_specified
19
+ @language = 'en'
20
+ @url = not_specified
21
+ # LIST / OF / SUBJECTS => https://www.bisg.org/complete-bisac-subject-headings-2014-edition
22
+ @subjects = 'NON000000 NON-CLASSIFIABLE'
23
+ @isbn = nil
24
+ end
25
+
26
+ def title(text = nil)
27
+ return @title if text.nil?
28
+ @title = text
29
+ end
30
+
31
+ def author(text)
32
+ @author = text
33
+ end
34
+
35
+ def publisher(text)
36
+ @publisher = text
37
+ end
38
+
39
+ def description(text)
40
+ @description = text
41
+ end
42
+
43
+ def language(lang)
44
+ @language = lang
45
+ end
46
+
47
+ def url(url)
48
+ @url = url
49
+ end
50
+
51
+ def subjects(subjects)
52
+ @subjects = subjects
53
+ end
54
+
55
+ def isbn(isbn)
56
+ @isbn = isbn
57
+ end
58
+
59
+ # Return a hash which can be used as a template's context
60
+ def contextify
61
+ context = {
62
+ # Attributes
63
+ "title" => @title,
64
+ "author" => @author,
65
+ "description" => @description,
66
+ "publisher" => @publisher,
67
+ "language" => @language,
68
+ "url" => @url,
69
+ "subjects" => @subjects,
70
+ "uuid" => ::SecureRandom.uuid,
71
+ "isbn" => @isbn
72
+ }
73
+
74
+ # Related models
75
+ context["chapters"] = contextified_chapters
76
+ context["introduction"] = contextified_introduction
77
+ context["endnotes"] = contextified_endnotes
78
+ return context
79
+ end
80
+
81
+ protected
82
+
83
+ def not_specified
84
+ 'Not specified'
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,26 @@
1
+ # Represents a book's chapter
2
+ module Epubber::Models
3
+ class Chapter
4
+ def initialize
5
+ @id = 0
6
+ @title = 'Not specified'
7
+ @content = '<p>Not specified</p>'
8
+ end
9
+
10
+ def id(idx)
11
+ @id = idx
12
+ end
13
+
14
+ def title(text)
15
+ @title = text
16
+ end
17
+
18
+ def content(text)
19
+ @content = text
20
+ end
21
+
22
+ def contextify
23
+ { 'id' => @id, 'title' => @title, 'content' => @content }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require 'epubber/models/chapter'
2
+
3
+ module Epubber::Models::Concerns
4
+ module HasChapters
5
+ def chapters
6
+ @chapters ||= []
7
+ end
8
+
9
+ # Add chapter
10
+ def chapter(&block)
11
+ chapter = Epubber::Models::Chapter.new
12
+ chapter.instance_eval &block
13
+ chapter.id(chapters.count + 1)
14
+ chapters << chapter
15
+ end
16
+
17
+ def contextified_chapters
18
+ chapters.map do |chapter|
19
+ chapter.contextify
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ require 'epubber/models/endnotes'
2
+
3
+ module Epubber::Models::Concerns
4
+ module HasEndnotes
5
+ def endnotes(&block)
6
+ @endnotes ||= nil
7
+ return @endnotes unless block_given?
8
+ @endnotes = Epubber::Models::Endnotes.new
9
+ @endnotes.instance_eval &block
10
+ end
11
+
12
+ def contextified_endnotes
13
+ return nil if endnotes.nil?
14
+ return endnotes.contextify
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'epubber/models/introduction'
2
+
3
+ module Epubber::Models::Concerns
4
+ module HasIntroduction
5
+ def introduction(&block)
6
+ @introduction ||= nil
7
+ return @introduction unless block_given?
8
+ @introduction = Epubber::Models::Introduction.new
9
+ @introduction.instance_eval &block
10
+ end
11
+
12
+ def contextified_introduction
13
+ return nil if introduction.nil?
14
+ return introduction.contextify
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # Represents a book's introduction
2
+ module Epubber::Models
3
+ class Endnotes
4
+ def initialize
5
+ @content = '<p>Not specified</p>'
6
+ end
7
+
8
+ def content(content)
9
+ @content = content
10
+ end
11
+
12
+ def contextify
13
+ { 'content' => @content }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # Represents a book's introduction
2
+ module Epubber::Models
3
+ class Introduction
4
+ def initialize
5
+ @content = '<p>Not specified</p>'
6
+ end
7
+
8
+ def content(content)
9
+ @content = content
10
+ end
11
+
12
+ def contextify
13
+ { 'content' => @content }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,45 @@
1
+ require 'zip'
2
+
3
+ module Epubber::Services
4
+ class Compressor
5
+ def compress(dir, file)
6
+ FileUtils.rm file if File.exists?(file)
7
+ generator = ZipFileGenerator.new dir, file
8
+ generator.write
9
+ end
10
+ end
11
+
12
+ # Helper class to create the actual zip file
13
+ class ZipFileGenerator
14
+ # Initialize with the directory to zip and the location of the output archive.
15
+ def initialize(inputDir, outputFile)
16
+ @inputDir = inputDir
17
+ @outputFile = outputFile
18
+ end
19
+
20
+ # Zip the input directory.
21
+ def write()
22
+ entries = Dir.entries(@inputDir); entries.delete("."); entries.delete("..")
23
+ io = Zip::File.open(@outputFile, Zip::File::CREATE);
24
+
25
+ writeEntries(entries, "", io)
26
+ io.close();
27
+ end
28
+
29
+ private
30
+
31
+ def writeEntries(entries, path, io)
32
+ entries.each { |e|
33
+ zipFilePath = path == "" ? e : File.join(path, e)
34
+ diskFilePath = File.join(@inputDir, zipFilePath)
35
+ if File.directory?(diskFilePath)
36
+ io.mkdir(zipFilePath)
37
+ subdir =Dir.entries(diskFilePath); subdir.delete("."); subdir.delete("..")
38
+ writeEntries(subdir, zipFilePath, io)
39
+ else
40
+ io.get_output_stream(zipFilePath) { |f| f.puts(File.open(diskFilePath, "rb").read())}
41
+ end
42
+ }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ module Epubber::Services
2
+ class Persistance
3
+ attr_reader :workspace
4
+ def initialize(workspace)
5
+ @workspace = workspace
6
+ end
7
+
8
+ # Persist a file into the working directory with the spcified contents.
9
+ # The file argument is the relative path to the new file, eg: test/chapters/file.xhtml
10
+ def persist(file: file, content: content)
11
+ create_path_for file
12
+ write file, content
13
+ end
14
+
15
+ # Remove the working directory, thus cleaning the file system
16
+ def clean
17
+ FileUtils.remove_dir workspace, true
18
+ end
19
+
20
+ protected
21
+
22
+ def write(file, content)
23
+ File.write path(file), content
24
+ end
25
+
26
+ def create_path_for(file)
27
+ dir = File.dirname path(file)
28
+ FileUtils.mkdir_p dir unless File.directory?(dir)
29
+ end
30
+
31
+ def path(file)
32
+ File.join workspace, file
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ require 'liquid'
2
+
3
+ module Epubber::Services
4
+ class Template
5
+ # Compiles and renderes a template file in the given context
6
+ def parse(file: file, context: context)
7
+ compile(file).render context
8
+ end
9
+
10
+ # Compiles a file and returns a template instance ready to be rendered
11
+ def compile(file)
12
+ Liquid::Template.parse load(file)
13
+ end
14
+
15
+ # Returns the full path for a given template file
16
+ def path(file)
17
+ File.join File.dirname(__FILE__), '../../templates/', file
18
+ end
19
+
20
+ protected
21
+
22
+ # Opens a file from disk located inside ./templates
23
+ def load(file)
24
+ File.open(path(file)).read
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Epubber
2
+ VERSION = "0.0.1"
3
+ end
data/lib/epubber.rb ADDED
@@ -0,0 +1,12 @@
1
+ require "epubber/version"
2
+ require "epubber/models/book"
3
+ require "epubber/generator"
4
+
5
+ module Epubber
6
+ def self.generate(filename: filename = nil, working_dir: working_dir = nil, &block)
7
+ book = Epubber::Models::Book.new
8
+ book.instance_eval &block
9
+ generator = Epubber::Generator.new book: book, working_dir: working_dir, filename: filename
10
+ generator.generate
11
+ end
12
+ end