kitabu 1.0.6 → 2.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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -3
  3. data/.travis.yml +18 -0
  4. data/CHANGELOG.md +9 -0
  5. data/Gemfile.lock +67 -50
  6. data/README.md +235 -0
  7. data/attachments/browser-version.png +0 -0
  8. data/attachments/cover.png +0 -0
  9. data/attachments/kitabu.epub +0 -0
  10. data/attachments/kitabu.mobi +0 -0
  11. data/attachments/kitabu.pdf +0 -0
  12. data/{spec/support/mybook/output → examples/kitabu/output/epub/images}/.gitkeep +0 -0
  13. data/examples/kitabu/output/epub/images/kitabu-icon.png +0 -0
  14. data/examples/kitabu/output/epub/images/kitabu-icon.svg +19 -0
  15. data/examples/kitabu/output/epub/images/kitabu-word.png +0 -0
  16. data/examples/kitabu/output/epub/images/kitabu-word.svg +14 -0
  17. data/examples/kitabu/output/epub/images/kitabu.png +0 -0
  18. data/examples/kitabu/output/epub/images/kitabu.svg +20 -0
  19. data/examples/kitabu/output/epub/section_0.html +266 -0
  20. data/examples/kitabu/output/epub/section_1.html +246 -0
  21. data/examples/kitabu/output/epub/section_2.html +520 -0
  22. data/examples/kitabu/output/epub/section_3.html +282 -0
  23. data/examples/kitabu/output/epub/section_4.html +276 -0
  24. data/examples/kitabu/output/epub/styles/epub.css +437 -0
  25. data/examples/kitabu/output/epub/styles/html.css +712 -0
  26. data/examples/kitabu/output/epub/styles/pdf.css +840 -0
  27. data/examples/kitabu/output/epub/styles/print.css +1278 -0
  28. data/examples/kitabu/output/epub/toc.html +37 -0
  29. data/{spec/support/mybook/templates/epub/style.css → examples/kitabu/output/images/.gitkeep} +0 -0
  30. data/examples/kitabu/output/images/kitabu-icon.png +0 -0
  31. data/examples/kitabu/output/images/kitabu-icon.svg +19 -0
  32. data/examples/kitabu/output/images/kitabu-word.png +0 -0
  33. data/examples/kitabu/output/images/kitabu-word.svg +14 -0
  34. data/examples/kitabu/output/images/kitabu.png +0 -0
  35. data/examples/kitabu/output/images/kitabu.svg +20 -0
  36. data/examples/kitabu/output/kitabu.epub +0 -0
  37. data/examples/kitabu/output/kitabu.html +513 -0
  38. data/examples/kitabu/output/kitabu.mobi +0 -0
  39. data/examples/kitabu/output/kitabu.pdf +0 -0
  40. data/examples/kitabu/output/kitabu.pdf.html +729 -0
  41. data/examples/kitabu/output/kitabu.print.html +729 -0
  42. data/examples/kitabu/output/kitabu.print.pdf +0 -0
  43. data/examples/kitabu/output/kitabu.txt +440 -0
  44. data/examples/kitabu/output/styles/epub.css +437 -0
  45. data/examples/kitabu/output/styles/html.css +712 -0
  46. data/examples/kitabu/output/styles/pdf.css +840 -0
  47. data/examples/kitabu/output/styles/print.css +1278 -0
  48. data/kitabu.gemspec +7 -5
  49. data/lib/kitabu.rb +10 -20
  50. data/lib/kitabu/cli.rb +0 -5
  51. data/lib/kitabu/dependency.rb +0 -4
  52. data/lib/kitabu/exporter.rb +2 -0
  53. data/lib/kitabu/extensions/rouge.rb +9 -0
  54. data/lib/kitabu/generator.rb +9 -21
  55. data/lib/kitabu/helpers.rb +47 -0
  56. data/lib/kitabu/markdown.rb +31 -0
  57. data/lib/kitabu/parser.rb +21 -3
  58. data/lib/kitabu/parser/epub.rb +31 -18
  59. data/lib/kitabu/parser/html.rb +48 -29
  60. data/lib/kitabu/parser/mobi.rb +1 -1
  61. data/lib/kitabu/parser/pdf.rb +52 -8
  62. data/lib/kitabu/version.rb +2 -2
  63. data/spec/kitabu/cli/export_spec.rb +4 -4
  64. data/spec/kitabu/cli/new_spec.rb +2 -2
  65. data/spec/kitabu/markdown_spec.rb +24 -0
  66. data/spec/kitabu/parser/html_spec.rb +20 -25
  67. data/spec/kitabu/parser/mobi_spec.rb +14 -0
  68. data/spec/kitabu/parser/pdf_spec.rb +18 -1
  69. data/spec/kitabu/parser/txt_spec.rb +14 -0
  70. data/spec/spec_helper.rb +10 -6
  71. data/spec/support/mybook/config/helper.rb +4 -29
  72. data/spec/support/mybook/config/kitabu.yml +0 -10
  73. data/spec/support/mybook/templates/epub/cover.erb +4 -3
  74. data/{templates → spec/support/mybook/templates/epub}/cover.png +0 -0
  75. data/spec/support/mybook/templates/epub/page.erb +3 -2
  76. data/spec/support/mybook/templates/html/layout.erb +10 -13
  77. data/spec/support/mybook/templates/styles/epub.scss +3 -0
  78. data/spec/support/mybook/templates/styles/html.scss +3 -0
  79. data/spec/support/mybook/templates/styles/pdf.scss +3 -0
  80. data/spec/support/mybook/templates/styles/print.scss +3 -0
  81. data/spec/support/mybook/text/{01_Markdown_Chapter.markdown → 01_Markdown_Chapter.md} +2 -3
  82. data/spec/support/mybook/text/02_ERB_Chapter.md.erb +7 -0
  83. data/spec/support/mybook/text/{04_With_Directory/Some_Chapter.mkdn → 03_With_Directory/Some_Chapter.md} +0 -0
  84. data/spec/support/mybook/text/{CHANGELOG.textile → CHANGELOG.md} +2 -2
  85. data/spec/support/mybook/text/{TOC.textile → TOC.md} +0 -0
  86. data/spec/support/mybook/text/{_00_Introduction.markdown → _00_Introduction.md} +0 -0
  87. data/spec/support/shared.rb +14 -10
  88. data/templates/Gemfile +3 -3
  89. data/templates/Guardfile +1 -5
  90. data/templates/config.erb +5 -5
  91. data/templates/cover.erb +4 -3
  92. data/templates/epub.erb +3 -2
  93. data/templates/helper.rb +28 -29
  94. data/templates/images/.gitkeep +0 -0
  95. data/templates/images/kitabu-icon.png +0 -0
  96. data/templates/images/kitabu-icon.svg +19 -0
  97. data/templates/images/kitabu-word.png +0 -0
  98. data/templates/images/kitabu-word.svg +14 -0
  99. data/templates/images/kitabu.png +0 -0
  100. data/templates/images/kitabu.svg +20 -0
  101. data/{examples/RailsGuides/templates → templates/templates/epub}/cover.erb +4 -3
  102. data/templates/templates/epub/cover.png +0 -0
  103. data/templates/templates/epub/page.erb +16 -0
  104. data/templates/{layout.erb → templates/html/layout.erb} +22 -11
  105. data/templates/templates/styles/epub.scss +1 -0
  106. data/templates/templates/styles/files/_normalize.scss +427 -0
  107. data/templates/templates/styles/html.scss +252 -0
  108. data/templates/templates/styles/pdf.scss +371 -0
  109. data/templates/templates/styles/print.scss +2 -0
  110. data/templates/text/01_Getting_Started.md +26 -0
  111. data/templates/text/02_Creating_Chapters.md +22 -0
  112. data/templates/text/03_Syntax_Highlighting.erb +69 -0
  113. data/templates/text/04_Dynamic_Content.erb +64 -0
  114. data/templates/text/05_Exporting_Files.md +49 -0
  115. metadata +143 -83
  116. data/README.rdoc +0 -218
  117. data/examples/RailsGuides/config/helper.rb +0 -29
  118. data/examples/RailsGuides/config/kitabu.yml +0 -44
  119. data/examples/RailsGuides/images/challenge.png +0 -0
  120. data/examples/RailsGuides/images/posts_index.png +0 -0
  121. data/examples/RailsGuides/images/rails_welcome.png +0 -0
  122. data/examples/RailsGuides/output/RailsGuides.epub +0 -0
  123. data/examples/RailsGuides/output/RailsGuides.html +0 -1556
  124. data/examples/RailsGuides/output/RailsGuides.pdf +3 -4934
  125. data/examples/RailsGuides/templates/layout.css +0 -352
  126. data/examples/RailsGuides/templates/layout.erb +0 -43
  127. data/examples/RailsGuides/templates/syntax.css +0 -62
  128. data/examples/RailsGuides/templates/user.css +0 -19
  129. data/examples/RailsGuides/text/01_Guide_Assumptions.mkdn +0 -13
  130. data/examples/RailsGuides/text/02_What_is_Rails.mkdn +0 -106
  131. data/examples/RailsGuides/text/03_Creating_a_new_Rails_project.mkdn +0 -200
  132. data/examples/RailsGuides/text/04_Hello_Rails.mkdn +0 -62
  133. data/examples/RailsGuides/text/05_Getting_Up_and_Running_Quickly_with_Scaffolding.mkdn +0 -4
  134. data/examples/RailsGuides/text/06_Creating_a_resource.mkdn +0 -503
  135. data/examples/RailsGuides/text/07_Adding_a_second_model.mkdn +0 -232
  136. data/examples/RailsGuides/text/08_Refactoring.mkdn +0 -123
  137. data/examples/RailsGuides/text/09_Deleting_comments.mkdn +0 -57
  138. data/examples/RailsGuides/text/09_Security.mkdn +0 -56
  139. data/examples/RailsGuides/text/10_Building_a_multi_model_form.mkdn +0 -130
  140. data/examples/RailsGuides/text/11_View_helpers.mkdn +0 -50
  141. data/examples/RailsGuides/text/12_Whats_next.mkdn +0 -14
  142. data/examples/RailsGuides/text/13_Configuration_gotchas.mkdn +0 -10
  143. data/lib/kitabu/adapters/markdown.rb +0 -34
  144. data/lib/kitabu/extensions/redcloth.rb +0 -69
  145. data/lib/kitabu/syntax.rb +0 -130
  146. data/spec/kitabu/extensions/redcloth_spec.rb +0 -57
  147. data/spec/kitabu/syntax_spec.rb +0 -106
  148. data/spec/support/mybook/templates/html/layout.css +0 -353
  149. data/spec/support/mybook/templates/html/syntax.css +0 -58
  150. data/spec/support/mybook/templates/html/user.css +0 -1
  151. data/spec/support/mybook/text/02_Textile_Chapter.textile +0 -3
  152. data/spec/support/mybook/text/03_HTML_Chapter.html +0 -3
  153. data/templates/epub.css +0 -500
  154. data/templates/layout.css +0 -353
  155. data/templates/sample.md +0 -6
  156. data/templates/syntax.css +0 -58
  157. data/templates/user.css +0 -1
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
6
6
  s.name = "kitabu"
7
7
  s.version = Kitabu::Version::STRING
8
8
  s.platform = Gem::Platform::RUBY
9
- s.required_ruby_version = ">= 1.9"
9
+ s.required_ruby_version = ">= 2.0"
10
10
  s.authors = ["Nando Vieira"]
11
11
  s.email = ["fnando.vieira@gmail.com"]
12
12
  s.homepage = "http://rubygems.org/gems/kitabu"
13
- s.summary = "A framework that generates PDF and e-Pub from Markdown, Textile, and HTML files."
13
+ s.summary = "A framework for creating e-books from Markdown using Ruby. Using the Prince PDF generator, you'll be able to get high quality PDFs. Also supports EPUB, Mobi, Text and HTML generation."
14
14
  s.description = s.summary
15
15
  s.license = "MIT"
16
16
 
@@ -21,17 +21,19 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_dependency "activesupport"
23
23
  s.add_dependency "nokogiri"
24
- s.add_dependency "RedCloth"
25
- s.add_dependency "rdiscount"
26
24
  s.add_dependency "i18n"
27
25
  s.add_dependency "thor"
26
+ s.add_dependency "redcarpet"
28
27
  s.add_dependency "eeepub-with-cover-support"
29
- s.add_dependency "coderay"
28
+ s.add_dependency "rouge"
30
29
  s.add_dependency "notifier"
31
30
  s.add_dependency "rubyzip"
32
31
  s.add_dependency "zip-zip"
32
+ s.add_dependency "sass"
33
+ s.add_dependency "sass-globbing"
33
34
 
34
35
  s.add_development_dependency "rspec"
35
36
  s.add_development_dependency "rake"
36
37
  s.add_development_dependency "pry-meta"
38
+ s.add_development_dependency "codeclimate-test-reporter"
37
39
  end
@@ -8,32 +8,22 @@ require "notifier"
8
8
  require "open3"
9
9
  require "optparse"
10
10
  require "ostruct"
11
- require "RedCloth"
12
11
  require "tempfile"
13
12
  require "pathname"
14
13
  require "thor"
15
14
  require "thor/group"
16
15
  require "yaml"
17
16
  require "cgi"
17
+ require "erb"
18
18
 
19
- I18n.enforce_available_locales = false
19
+ require "redcarpet"
20
+ require "rouge"
21
+ require "rouge/plugins/redcarpet"
20
22
 
21
- %w[pygments.rb coderay].each do |lib|
22
- begin
23
- require lib
24
- rescue LoadError => e
25
- next
26
- end
27
- end
23
+ require "sass"
24
+ require "sass-globbing"
28
25
 
29
- %w[maruku peg_markdown bluecloth redcarpet rdiscount].each do |lib|
30
- begin
31
- require lib
32
- break
33
- rescue LoadError => e
34
- next
35
- end
36
- end
26
+ I18n.enforce_available_locales = false
37
27
 
38
28
  Encoding.default_internal = "utf-8"
39
29
  Encoding.default_external = "utf-8"
@@ -42,19 +32,19 @@ module Kitabu
42
32
  ROOT = Pathname.new(File.dirname(__FILE__) + "/..")
43
33
 
44
34
  require "kitabu/extensions/string"
45
- require "kitabu/extensions/redcloth"
35
+ require "kitabu/extensions/rouge"
46
36
  require "kitabu/errors"
47
37
  require "kitabu/version"
48
38
  require "kitabu/generator"
49
39
  require "kitabu/toc"
50
40
  require "kitabu/cli"
51
- require "kitabu/adapters/markdown"
41
+ require "kitabu/markdown"
52
42
  require "kitabu/parser"
53
43
  require "kitabu/exporter"
54
- require "kitabu/syntax"
55
44
  require "kitabu/stream"
56
45
  require "kitabu/dependency"
57
46
  require "kitabu/stats"
47
+ require "kitabu/helpers"
58
48
 
59
49
  def self.config(root_dir = nil)
60
50
  root_dir ||= Pathname.new(Dir.pwd)
@@ -65,11 +65,6 @@ module Kitabu
65
65
  :installed => Kitabu::Dependency.html2text?
66
66
  }
67
67
 
68
- result << {
69
- :description => "pygments.rb: A generic syntax highlight. If installed, replaces CodeRay.",
70
- :installed => Kitabu::Dependency.pygments_rb?
71
- }
72
-
73
68
  result.each do |result|
74
69
  text = color(result[:name], :blue)
75
70
  text << "\n" << result[:description]
@@ -11,9 +11,5 @@ module Kitabu
11
11
  def self.html2text?
12
12
  @html2text ||= `which html2text` && $?.success?
13
13
  end
14
-
15
- def self.pygments_rb?
16
- @pygments_rb ||= defined?(Pygments)
17
- end
18
14
  end
19
15
  end
@@ -21,6 +21,8 @@ module Kitabu
21
21
  helper = root_dir.join("config/helper.rb")
22
22
  load(helper) if helper.exist?
23
23
 
24
+ FileUtils.rm_rf root_dir.join("output").to_s
25
+
24
26
  export_pdf = [nil, "pdf"].include?(options[:only])
25
27
  export_epub = [nil, "mobi", "epub"].include?(options[:only])
26
28
  export_mobi = [nil, "mobi"].include?(options[:only])
@@ -0,0 +1,9 @@
1
+ module Rouge
2
+ module Plugins
3
+ module Redcarpet
4
+ def rouge_formatter(lexer)
5
+ Formatters::HTML.new({css_class: "highlight #{lexer.tag}"}.merge(lexer.options))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -14,22 +14,16 @@ module Kitabu
14
14
  File.dirname(__FILE__) + "/../../templates"
15
15
  end
16
16
 
17
- def copy_html_templates
18
- copy_file "layout.erb" , "templates/html/layout.erb"
19
- copy_file "layout.css" , "templates/html/layout.css"
20
- copy_file "user.css" , "templates/html/user.css"
21
- copy_file "syntax.css" , "templates/html/syntax.css"
17
+ def copy_templates
18
+ directory "templates", "templates"
22
19
  end
23
20
 
24
- def copy_epub_templates
25
- copy_file "cover.erb" , "templates/epub/cover.erb"
26
- copy_file "epub.css" , "templates/epub/user.css"
27
- copy_file "epub.erb" , "templates/epub/page.erb"
28
- copy_file "cover.png" , "templates/epub/cover.png"
21
+ def copy_sample_texts
22
+ directory "text", "text"
29
23
  end
30
24
 
31
- def copy_sample_page
32
- copy_file "sample.md" , "text/01_Welcome.md"
25
+ def copy_images
26
+ directory "images", "images"
33
27
  end
34
28
 
35
29
  def copy_config_file
@@ -44,27 +38,21 @@ module Kitabu
44
38
  end
45
39
 
46
40
  def copy_gemfile
47
- copy_file "Gemfile", "Gemfile"
41
+ copy_file "Gemfile"
48
42
  end
49
43
 
50
44
  def create_directories
51
45
  empty_directory "output"
52
- empty_directory "images"
53
- empty_directory "code"
54
46
  end
55
47
 
56
48
  def create_git_files
57
49
  create_file ".gitignore" do
58
- "output/*.{html,epub,pdf}\noutput/tmp"
50
+ "/output"
59
51
  end
60
-
61
- create_file "output/.gitkeep"
62
- create_file "images/.gitkeep"
63
- create_file "code/.gitkeep"
64
52
  end
65
53
 
66
54
  def copy_guardfile
67
- copy_file "Guardfile", "Guardfile"
55
+ copy_file "Guardfile"
68
56
  end
69
57
 
70
58
  def bundle_install
@@ -0,0 +1,47 @@
1
+ module Kitabu
2
+ module Helpers
3
+ def highlight_theme(name = theme)
4
+ html = '<style type="text/css">'
5
+ html << Rouge::Theme.find(name).render(scope: '.highlight')
6
+ html << '</style>'
7
+ html
8
+ end
9
+
10
+ def image_tag(path, attributes = {})
11
+ html = %[<img src="images/#{path}" />]
12
+ end
13
+
14
+ def escape_html(content)
15
+ CGI.escape_html(content.to_s)
16
+ end
17
+
18
+ def note(class_name = :info, &block)
19
+ content = block_content(block)
20
+ output << '<div class="note %s">' % escape_html(class_name)
21
+ output << markdown(content)
22
+ output << '</div>'
23
+ end
24
+
25
+ def block_content(block)
26
+ output, @_output = @_output.dup, ''
27
+ content = block.call
28
+ @_output = output
29
+ content
30
+ end
31
+
32
+ def markdown(content, deindent_content = true)
33
+ content = deindent(content) if deindent_content
34
+ Markdown.render(content)
35
+ end
36
+
37
+ def deindent(content)
38
+ content = content.to_s
39
+ indent = (content.scan(/^[ \t]*(?=\S)/) || []).size
40
+ content.gsub(/^[ \t]{#{indent}}/, '')
41
+ end
42
+
43
+ def output
44
+ @_output
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ module Kitabu
2
+ module Markdown
3
+ class Renderer < Redcarpet::Render::HTML
4
+ include Redcarpet::Render::SmartyPants
5
+ include Rouge::Plugins::Redcarpet
6
+ end
7
+
8
+ class << self
9
+ # Set markdown renderer
10
+ attr_accessor :processor
11
+ end
12
+
13
+ renderer = Renderer.new(hard_wrap: true, safe_links_only: true)
14
+
15
+ self.processor = Redcarpet::Markdown.new(renderer, {
16
+ tables: true,
17
+ footnotes: true,
18
+ space_after_headers: true,
19
+ superscript: true,
20
+ highlight: true,
21
+ strikethrough: true,
22
+ autolink: true,
23
+ fenced_code_blocks: true,
24
+ no_intra_emphasis: true
25
+ })
26
+
27
+ def self.render(text)
28
+ processor.render(text)
29
+ end
30
+ end
31
+ end
@@ -41,12 +41,13 @@ module Kitabu
41
41
  # Render a eRb template using +locals+ as data seed.
42
42
  #
43
43
  def render_template(file, locals = {})
44
- ERB.new(File.read(file)).result OpenStruct.new(locals).instance_eval{ binding }
44
+ context = OpenStruct.new(locals).extend(Helpers)
45
+ ERB.new(File.read(file), 0, "%<>", "@_output").result context.instance_eval { binding }
45
46
  end
46
47
 
47
- def spawn_command(cmd)
48
+ def spawn_command(command)
48
49
  begin
49
- stdout_and_stderr, status = Open3.capture2e(*cmd)
50
+ stdout_and_stderr, status = Open3.capture2e(*command)
50
51
  rescue Errno::ENOENT => e
51
52
  puts e.message
52
53
  else
@@ -54,6 +55,23 @@ module Kitabu
54
55
  status.success?
55
56
  end
56
57
  end
58
+
59
+ def ui
60
+ @ui ||= Thor::Base.shell.new
61
+ end
62
+
63
+ def handle_error(error)
64
+ ui.say "#{error.class}: #{error.message}", :red
65
+ ui.say error.backtrace.join("\n"), :white
66
+ end
67
+
68
+ def copy_directory(source, target)
69
+ source = root_dir.join("#{source}/.")
70
+ target = root_dir.join(target)
71
+
72
+ FileUtils.mkdir_p target
73
+ FileUtils.cp_r source, target, remove_destination: true
74
+ end
57
75
  end
58
76
  end
59
77
  end
@@ -4,10 +4,10 @@ module Kitabu
4
4
  def sections
5
5
  @sections ||= html.css("div.chapter").each_with_index.map do |chapter, index|
6
6
  OpenStruct.new({
7
- :index => index,
8
- :filename => "section_#{index}.html",
9
- :filepath => tmp_dir.join("section_#{index}.html").to_s,
10
- :html => Nokogiri::HTML(chapter.inner_html)
7
+ index: index,
8
+ filename: "section_#{index}.html",
9
+ filepath: tmp_dir.join("section_#{index}.html").to_s,
10
+ html: Nokogiri::HTML(chapter.inner_html)
11
11
  })
12
12
  end
13
13
  end
@@ -21,15 +21,9 @@ module Kitabu
21
21
  end
22
22
 
23
23
  def parse
24
- epub.title config[:title]
25
- epub.language config[:language]
26
- epub.creator config[:authors].to_sentence
27
- epub.publisher config[:publisher]
28
- epub.date config[:published_at]
29
- epub.uid config[:uid]
30
- epub.identifier config[:identifier][:id], :scheme => config[:identifier][:type]
31
- epub.cover_page cover_image if cover_image && File.exist?(cover_image)
32
-
24
+ copy_styles!
25
+ copy_images!
26
+ set_metadata!
33
27
  write_sections!
34
28
  write_toc!
35
29
 
@@ -40,11 +34,30 @@ module Kitabu
40
34
  epub.save(epub_path)
41
35
 
42
36
  true
43
- rescue Exception
44
- p $!, $@
37
+ rescue Exception => error
38
+ handle_error(error)
45
39
  false
46
40
  end
47
41
 
42
+ def copy_styles!
43
+ copy_directory("output/styles", "output/epub/styles")
44
+ end
45
+
46
+ def copy_images!
47
+ copy_directory("output/images", "output/epub/images")
48
+ end
49
+
50
+ def set_metadata!
51
+ epub.title config[:title]
52
+ epub.language config[:language]
53
+ epub.creator config[:authors].to_sentence
54
+ epub.publisher config[:publisher]
55
+ epub.date config[:published_at]
56
+ epub.uid config[:uid]
57
+ epub.identifier config[:identifier][:id], scheme: config[:identifier][:type]
58
+ epub.cover_page cover_image if cover_image && File.exist?(cover_image)
59
+ end
60
+
48
61
  def write_toc!
49
62
  toc = TOC::Epub.new(navigation)
50
63
 
@@ -116,8 +129,8 @@ module Kitabu
116
129
  def navigation
117
130
  sections.map do |section|
118
131
  {
119
- :label => section.html.css("h2:first-of-type").text,
120
- :content => section.filename
132
+ label: section.html.css("h2:first-of-type").text,
133
+ content: section.filename
121
134
  }
122
135
  end
123
136
  end
@@ -135,7 +148,7 @@ module Kitabu
135
148
  end
136
149
 
137
150
  def tmp_dir
138
- root_dir.join("output/tmp")
151
+ root_dir.join("output/epub")
139
152
  end
140
153
 
141
154
  def toc_path
@@ -11,7 +11,7 @@ module Kitabu
11
11
 
12
12
  # List of recognized extensions.
13
13
  #
14
- EXTENSIONS = %w[md mkdn markdown textile html]
14
+ EXTENSIONS = %w[md erb]
15
15
 
16
16
  class << self
17
17
  # The footnote index control. We have to manipulate footnotes
@@ -25,12 +25,16 @@ module Kitabu
25
25
  #
26
26
  def parse
27
27
  reset_footnote_index!
28
+ copy_images!
29
+ export_stylesheets!
28
30
 
29
31
  File.open(root_dir.join("output/#{name}.html"), "w") do |file|
30
32
  file << parse_layout(content)
31
33
  end
34
+
32
35
  true
33
- rescue Exception
36
+ rescue Exception => error
37
+ handle_error(error)
34
38
  false
35
39
  end
36
40
 
@@ -68,7 +72,7 @@ module Kitabu
68
72
  if File.file?(entry)
69
73
  [entry]
70
74
  else
71
- Dir.glob("#{entry}/**/*.{#{EXTENSIONS.join(",")}}").sort
75
+ Dir["#{entry}/**/*.{#{EXTENSIONS.join(",")}}"].sort
72
76
  end
73
77
  end
74
78
 
@@ -94,24 +98,18 @@ module Kitabu
94
98
 
95
99
  # Render +file+ considering its extension.
96
100
  #
97
- def render_file(file, plain_syntax = false)
98
- file_format = format(file)
99
-
100
- content = Kitabu::Syntax.render(root_dir, file_format, File.read(file), plain_syntax)
101
-
102
- content = case file_format
103
- when :markdown
104
- Markdown.to_html(content)
105
- when :textile
106
- RedCloth.convert(content)
101
+ def render_file(file)
102
+ if format(file) == :erb
103
+ content = render_template(file, config)
107
104
  else
108
- content
105
+ content = File.read(file)
109
106
  end
110
107
 
111
- render_footnotes(content, plain_syntax)
108
+ content = Kitabu::Markdown.render(content)
109
+ render_footnotes(content)
112
110
  end
113
111
 
114
- def render_footnotes(content, plain_syntax = false)
112
+ def render_footnotes(content)
115
113
  html = Nokogiri::HTML(content)
116
114
  footnotes = html.css("p[id^='fn']")
117
115
 
@@ -144,13 +142,10 @@ module Kitabu
144
142
  end
145
143
 
146
144
  def format(file)
147
- case File.extname(file).downcase
148
- when ".markdown", ".mkdn", ".md"
149
- :markdown
150
- when ".textile"
151
- :textile
145
+ if File.extname(file) == '.erb'
146
+ :erb
152
147
  else
153
- :html
148
+ :markdown
154
149
  end
155
150
  end
156
151
 
@@ -159,9 +154,9 @@ module Kitabu
159
154
  def parse_layout(html)
160
155
  toc = TOC::HTML.generate(html)
161
156
  locals = config.merge({
162
- :content => toc.content,
163
- :toc => toc.to_html,
164
- :changelog => render_changelog
157
+ content: toc.content,
158
+ toc: toc.to_html,
159
+ changelog: render_changelog
165
160
  })
166
161
  render_template(root_dir.join("templates/html/layout.erb"), locals)
167
162
  end
@@ -171,19 +166,43 @@ module Kitabu
171
166
  #
172
167
  def render_changelog
173
168
  changelog = Dir[root_dir.join("text/CHANGELOG.*")].first
174
- return render_file(changelog) if changelog
175
- nil
169
+ render_file(changelog) if changelog
176
170
  end
177
171
 
178
172
  # Render all +files+ from a given chapter.
179
173
  #
180
- def render_chapter(files, plain_syntax = false)
174
+ def render_chapter(files)
181
175
  String.new.tap do |chapter|
182
176
  files.each do |file|
183
- chapter << render_file(file, plain_syntax) << "\n\n"
177
+ chapter << render_file(file) << "\n\n"
184
178
  end
185
179
  end
186
180
  end
181
+
182
+ # Copy images
183
+ #
184
+ def copy_images!
185
+ copy_directory("images", "output/images")
186
+ end
187
+
188
+ # Export all root stylesheets.
189
+ #
190
+ def export_stylesheets!
191
+ files = Dir[root_dir.join("templates/styles/*.{scss,sass}").to_s]
192
+ options = {
193
+ style: :expanded,
194
+ line_numbers: true,
195
+ load_paths: [root_dir.join("templates/styles")]
196
+ }
197
+
198
+ files.each do |file|
199
+ _, file_name, syntax = *File.basename(file).match(/(.*?)\.(.*?)$/)
200
+ engine = Sass::Engine.new(File.read(file), options.merge(syntax: syntax.to_sym))
201
+ target = root_dir.join("output/styles", "#{file_name}.css")
202
+ FileUtils.mkdir_p(File.dirname(target))
203
+ File.open(target, "w") {|io| io << engine.render }
204
+ end
205
+ end
187
206
  end
188
207
  end
189
208
  end