epubforge 0.0.10 → 0.0.11

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 (135) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +17 -10
  3. data/VERSION +1 -1
  4. data/bin/epubforge +1 -1
  5. data/config/actions/epub.rb +50 -0
  6. data/config/actions/forge.rb +34 -13
  7. data/config/actions/git.rb +106 -0
  8. data/config/actions/help.rb +13 -13
  9. data/config/actions/html.rb +33 -0
  10. data/config/actions/mobi.rb +60 -0
  11. data/config/actions/new.rb +182 -0
  12. data/config/actions/word_count.rb +26 -24
  13. data/config/{actions → actions_to_ignore}/generate.rb +1 -1
  14. data/config/{actions → actions_to_ignore}/generate_chapter.rb +0 -0
  15. data/config/{actions → actions_to_ignore}/git_backup.rb +2 -2
  16. data/config/{actions → actions_to_ignore}/globals.rb +1 -1
  17. data/config/{actions → actions_to_ignore}/kindle.rb +3 -3
  18. data/config/{actions → actions_to_ignore}/local_action.rb +1 -1
  19. data/config/{actions → actions_to_ignore}/mobify.rb +3 -3
  20. data/config/actions_to_ignore/notes_to_epub.rb +19 -0
  21. data/config/actions_to_ignore/notes_to_kindle.rb +18 -0
  22. data/config/{actions → actions_to_ignore}/spell.rb +1 -1
  23. data/config/{actions → actions_to_ignore}/version.rb +3 -3
  24. data/config/{actions → actions_to_ignore}/wrap_scene_notes_in_hidden_div.rb +1 -1
  25. data/config/converters/epub_to_mobi.calibre.rb +8 -0
  26. data/config/converters/epub_to_mobi.kindlegen.rb +11 -0
  27. data/config/html_translators/default_kramdown.html_translator.rb +9 -0
  28. data/config/html_translators/default_markdown.html_translator.rb +10 -0
  29. data/config/html_translators/default_markdown_pandoc.html_translator.rb +10 -0
  30. data/config/html_translators/default_textile_pandoc.html_translator.rb +8 -0
  31. data/config/html_translators/default_xhtml.html_translator.rb +7 -0
  32. data/config/html_translators/fallback_html.html_translator.rb +9 -0
  33. data/config/html_translators/fallback_markdown.html_translator.rb +8 -0
  34. data/config/html_translators/fallback_textile.html_translator.rb +7 -0
  35. data/config/html_translators/fallback_txt.html_translator.rb +8 -0
  36. data/config/html_translators/fallback_unknown.html_translator.rb +7 -0
  37. data/lib/epubforge.rb +37 -82
  38. data/lib/{action/thor_action.rb → epubforge/action/action.rb} +89 -69
  39. data/lib/epubforge/action/action2.rb +109 -0
  40. data/lib/epubforge/action/action_definition.rb +62 -0
  41. data/lib/epubforge/action/actions_lookup.rb +45 -0
  42. data/lib/epubforge/action/chatterbox.rb +93 -0
  43. data/lib/{action → epubforge/action}/cli_command.rb +2 -2
  44. data/lib/{action → epubforge/action}/cli_sequence.rb +0 -0
  45. data/lib/{action → epubforge/action}/file_transformer.rb +0 -0
  46. data/lib/{action → epubforge/action}/hooks_interface.rb +2 -2
  47. data/lib/{action → epubforge/action}/run_description.rb +12 -9
  48. data/lib/{action → epubforge/action}/runner.rb +23 -24
  49. data/lib/{epub → epubforge/builder}/assets/asset.rb +1 -1
  50. data/lib/{epub → epubforge/builder}/assets/font.rb +1 -1
  51. data/lib/epubforge/builder/assets/html.rb +9 -0
  52. data/lib/{epub → epubforge/builder}/assets/image.rb +1 -1
  53. data/lib/epubforge/builder/assets/markdown.rb +9 -0
  54. data/lib/{epub → epubforge/builder}/assets/page.rb +12 -4
  55. data/lib/{epub → epubforge/builder}/assets/stylesheet.rb +1 -1
  56. data/lib/epubforge/builder/assets/textile.rb +9 -0
  57. data/lib/epubforge/builder/assets/xhtml.rb +9 -0
  58. data/lib/epubforge/builder/builder.rb +134 -0
  59. data/lib/{epub/builder.rb → epubforge/builder/epub.rb} +58 -161
  60. data/lib/epubforge/builder/html.rb +22 -0
  61. data/lib/epubforge/builder/packager.rb +16 -0
  62. data/lib/epubforge/core_extensions/array.rb +2 -0
  63. data/lib/{core_extensions → epubforge/core_extensions}/kernel.rb +0 -0
  64. data/lib/epubforge/core_extensions/nil_class.rb +2 -0
  65. data/lib/epubforge/core_extensions/object.rb +24 -0
  66. data/lib/{core_extensions → epubforge/core_extensions}/string.rb +1 -5
  67. data/lib/{custom_helpers.rb → epubforge/custom_helpers.rb} +0 -1
  68. data/lib/{errors.rb → epubforge/exceptions/errors.rb} +0 -0
  69. data/lib/{project → epubforge/project}/project.rb +23 -17
  70. data/lib/epubforge/utils/action_loader.rb +8 -0
  71. data/lib/epubforge/utils/class_loader.rb +102 -0
  72. data/lib/epubforge/utils/converter.rb +94 -0
  73. data/lib/{utils → epubforge/utils}/downloader.rb +0 -0
  74. data/lib/{utils → epubforge/utils}/file_orderer.rb +0 -0
  75. data/lib/epubforge/utils/file_path.rb +8 -0
  76. data/lib/epubforge/utils/html_translator.rb +126 -0
  77. data/lib/epubforge/utils/html_translator_queue.rb +113 -0
  78. data/lib/epubforge/utils/htmlizer.rb +61 -0
  79. data/lib/{utils → epubforge/utils}/misc.rb +0 -0
  80. data/lib/epubforge/utils/root_path.rb +8 -0
  81. data/lib/epubforge/utils/settings.rb +147 -0
  82. data/lib/epubforge/utils/template_evaluator.rb +7 -0
  83. data/templates/{default/book/afterword.markdown.template → project/book/afterword.markdown} +0 -0
  84. data/templates/project/book/chapter-%0000chapter%.markdown.template +4 -0
  85. data/templates/{default → project}/book/cover.xhtml.template +2 -2
  86. data/templates/{default/book/foreword.markdown.template → project/book/foreword.markdown} +0 -0
  87. data/templates/{default → project}/book/images/cover.png +0 -0
  88. data/templates/{default/book/stylesheets/stylesheet.css.template → project/book/stylesheets/stylesheet.css} +0 -0
  89. data/templates/project/book/title_page.markdown.template +5 -0
  90. data/templates/project/notes/character.%character.name_for_file%.markdown.template +15 -0
  91. data/templates/{default → project}/notes/images/cover.png +0 -0
  92. data/templates/{default/notes/stylesheets/stylesheet.css.template → project/notes/stylesheets/stylesheet.css} +0 -0
  93. data/templates/{default → project}/settings/actions/local_action.rb.example +1 -1
  94. data/templates/project/settings/config.rb.template +70 -0
  95. data/templates/project/settings/html_translators/example_translator.rb +29 -0
  96. data/templates/{default → project}/settings/wordcount.template +1 -1
  97. data/test/answers01.yml +30 -0
  98. data/test/helper.rb +62 -39
  99. data/test/misc/config.rb +5 -7
  100. data/test/test_epubforge.rb +18 -14
  101. data/test/{test_htmlizers.rb → test_html_translators.rb} +4 -8
  102. data/test/test_template_evaluator.rb +42 -0
  103. data/test/test_utils.rb +0 -11
  104. metadata +186 -189
  105. data/config/actions/gitify.rb +0 -72
  106. data/config/actions/init.rb +0 -138
  107. data/config/actions/notes_to_epub.rb +0 -18
  108. data/config/actions/notes_to_kindle.rb +0 -17
  109. data/config/htmlizers.rb +0 -70
  110. data/lib/action/actions_lookup.rb +0 -45
  111. data/lib/core_extensions/array.rb +0 -5
  112. data/lib/core_extensions/nil_class.rb +0 -5
  113. data/lib/core_extensions/object.rb +0 -5
  114. data/lib/epub/assets/html.rb +0 -8
  115. data/lib/epub/assets/markdown.rb +0 -8
  116. data/lib/epub/assets/textile.rb +0 -8
  117. data/lib/epub/assets/xhtml.rb +0 -8
  118. data/lib/epub/packager.rb +0 -16
  119. data/lib/utils/action_loader.rb +0 -7
  120. data/lib/utils/class_loader.rb +0 -102
  121. data/lib/utils/directory_builder.rb +0 -181
  122. data/lib/utils/file_path.rb +0 -152
  123. data/lib/utils/html_translator.rb +0 -100
  124. data/lib/utils/html_translator_queue.rb +0 -70
  125. data/lib/utils/htmlizer.rb +0 -92
  126. data/lib/utils/root_path.rb +0 -20
  127. data/lib/utils/settings.rb +0 -146
  128. data/lib/utils/template_evaluator.rb +0 -20
  129. data/templates/default/book/chapter-%i%.markdown.sequence +0 -4
  130. data/templates/default/book/title_page.markdown.template +0 -4
  131. data/templates/default/notes/character.named.markdown.template +0 -4
  132. data/templates/default/payload.rb +0 -65
  133. data/templates/default/settings/config.rb.form +0 -55
  134. data/templates/default/settings/htmlizers.rb +0 -0
  135. data/test/test_directory_builder.rb +0 -141
@@ -27,7 +27,7 @@ module EpubForge
27
27
  protected
28
28
  def local_exec( cmd )
29
29
  cmd = (cmd == :undo ? @undo : @command)
30
- return pseudo_success if cmd.epf_blank?
30
+ return pseudo_success if cmd.fwf_blank?
31
31
 
32
32
  execute_locally = @local_dir ? "cd #{@local_dir} && " : ""
33
33
 
@@ -39,7 +39,7 @@ module EpubForge
39
39
 
40
40
  def remote_exec( cmd )
41
41
  cmd = (cmd == :undo ? @undo : @command)
42
- return pseudo_success if cmd.epf_blank?
42
+ return pseudo_success if cmd.fwf_blank?
43
43
 
44
44
  execute_remotely = (@remote_dir ? "cd #{@remote_dir} && " : "") + cmd
45
45
 
File without changes
@@ -7,12 +7,12 @@ module EpubForge
7
7
  end
8
8
 
9
9
  def run_hooks( hookset )
10
- super( hookset ) unless self == ThorAction
10
+ super( hookset ) unless self == Action
11
11
 
12
12
  end
13
13
 
14
14
  def self.included( base )
15
- if base == ThorAction
15
+ if base == Action
16
16
  base.add_hook(:before) do
17
17
  @project = @options[:project]
18
18
  end
@@ -5,7 +5,7 @@ module EpubForge
5
5
  :project,
6
6
  :namespace,
7
7
  :subcommand,
8
- :klass,
8
+ :action,
9
9
  :errors,
10
10
  :state,
11
11
  :execution_returned
@@ -13,9 +13,7 @@ module EpubForge
13
13
  def initialize
14
14
  @args = nil
15
15
  @project = nil
16
- @namepace = nil
17
- @subcommand = nil
18
- @klass = nil
16
+ @action = nil
19
17
  @errors = []
20
18
  @state = :initialized
21
19
  end
@@ -23,8 +21,12 @@ module EpubForge
23
21
  def run
24
22
  if self.runnable?
25
23
  handle_errors do
26
- @args[0] = (@args[0]).split(":").last
27
- @execution_returned = self.klass.start( @args )
24
+ puts "Run Description: #{@args.inspect}"
25
+ @args.shift if @args.first == self.action.keyword # TODO: Remove this arg before getting here
26
+
27
+ # If there is a project, it is sent to the action's execution as the first argument
28
+ @args.unshift( self.project ) if self.project
29
+ @execution_returned = self.action.run( *@args )
28
30
  end
29
31
  end
30
32
 
@@ -50,7 +52,8 @@ module EpubForge
50
52
  if self.errors?
51
53
  self.finish
52
54
  self.report_errors
53
- exit( -1 )
55
+
56
+ exit( -1 ) unless EpubForge.gem_test_mode?
54
57
  end
55
58
  end
56
59
 
@@ -59,7 +62,7 @@ module EpubForge
59
62
  end
60
63
 
61
64
  def errors?
62
- !@errors.epf_blank?
65
+ !@errors.fwf_blank?
63
66
  end
64
67
 
65
68
  def success?
@@ -76,7 +79,7 @@ module EpubForge
76
79
 
77
80
  def to_s
78
81
  str = "RunDescription:\n"
79
- [ :args, :project, :namespace, :subcommand, :klass, :errors, :state ].each do |data|
82
+ [ :args, :project, :action, :errors, :state ].each do |data|
80
83
  str << "#{data} : #{self.send(data).inspect}\n"
81
84
  end
82
85
 
@@ -14,18 +14,6 @@ module EpubForge
14
14
  @run_description = RunDescription.new
15
15
  end
16
16
 
17
- def load_actions_dirs
18
- ThorAction.actions_lookup.add_actions( EpubForge::ACTIONS_DIR )
19
- ThorAction.actions_lookup.add_actions( EpubForge::USER_ACTIONS_DIR ) if EpubForge::USER_ACTIONS_DIR.directory?
20
- end
21
-
22
- def load_project_machinery
23
- if @run_description.project
24
- ThorAction.actions_lookup.add_actions( @run_description.project.settings_folder( "actions" ) )
25
- Utils::Htmlizer.instance.add_htmlizers( @run_description.project.settings_folder( "htmlizers.rb" ) )
26
- end
27
- end
28
-
29
17
  def run
30
18
  @run_description.run
31
19
  @run_description
@@ -49,29 +37,33 @@ module EpubForge
49
37
 
50
38
  protected
51
39
  def parse_args
52
- @args << "help" if @args.epf_blank?
40
+ @args << "help" if @args.fwf_blank?
53
41
  @run_description = RunDescription.new
54
42
 
43
+ # map_command_to_action # if it's one of the default actions
55
44
  fetch_project
45
+ load_project_machinery
46
+
47
+ map_command_to_action # unless @run_description.action # check for project-specific actions
48
+
56
49
  @run_description.quit_on_errors
57
50
 
58
- load_actions_dirs
59
- load_project_machinery
60
51
 
61
- map_command_to_klass
62
52
 
63
- return false unless @run_description.klass
53
+ return false unless @run_description.action
64
54
 
65
- if @run_description.project.nil? && @run_description.klass.project_required?
66
- @run_description.errors << "Could not find a project directory, but the action #{@run_description.klass} requires one. Current directory is not an epubforge project."
55
+ if @run_description.project.nil? && @run_description.action.project_required?
56
+ @run_description.errors << "Could not find a project directory (current directory not a project, no project given as an argument), but the action #{@run_description.action} requires one."
67
57
  else
68
58
  @run_description.args = @args
69
59
  end
70
60
  end
71
61
 
72
- def map_command_to_klass
73
- @run_description.klass = ThorAction.command_to_action_classes[@args.first]
74
- if @run_description.klass.nil?
62
+ # TODO: Need to determine if the project is there, and if it's needed, then load all the
63
+ # actions at once.
64
+ def map_command_to_action
65
+ @run_description.action = Action2[ @args.first ]
66
+ if @run_description.action.nil?
75
67
  @run_description.errors << "Unrecognized keyword <#{@args.first}>. Quitting."
76
68
  end
77
69
  end
@@ -83,7 +75,7 @@ module EpubForge
83
75
  # 3) the current working directory (if it's an existing project)
84
76
  #
85
77
  # As a side-effect, replaces implicit directories with an explicit --project flag as the final argument
86
- # because Thor seems to like explicit flags.
78
+ # because Thor seems to like explicit flags. Though I'm moving away from Thor.
87
79
  def fetch_project
88
80
  project_dir = fetch_project_by_project_flag
89
81
  project_dir ||= fetch_project_by_second_arg
@@ -126,7 +118,14 @@ module EpubForge
126
118
  end
127
119
 
128
120
  def print_help
129
-
121
+ end
122
+
123
+ def load_project_machinery
124
+ if proj = @run_description.project
125
+ Action2.loader_pattern_load_from_dir( proj.settings_folder( "actions" ) )
126
+ Utils::HtmlTranslator.loader_pattern_load_from_dir( proj.settings_folder( "html_translators" ) )
127
+ Utils::Converter.loader_pattern_load_from_dir( proj.settings_folder( "converters" ) )
128
+ end
130
129
  end
131
130
  end
132
131
  end
@@ -1,5 +1,5 @@
1
1
  module EpubForge
2
- module Epub
2
+ module Builder
3
3
  module Assets
4
4
  class Asset
5
5
  def media_type
@@ -1,5 +1,5 @@
1
1
  module EpubForge
2
- module Epub
2
+ module Builder
3
3
  module Assets
4
4
  class Font < Asset
5
5
  attr_reader :ext, :filename, :name
@@ -0,0 +1,9 @@
1
+ # I don't think I need separate classes for each format.
2
+ # module EpubForge
3
+ # module Builder
4
+ # module Assets
5
+ # class HTML < Page
6
+ # end
7
+ # end
8
+ # end
9
+ # end
@@ -1,5 +1,5 @@
1
1
  module EpubForge
2
- module Epub
2
+ module Builder
3
3
  module Assets
4
4
  class Image < Asset
5
5
  attr_reader :ext, :filename, :name
@@ -0,0 +1,9 @@
1
+ # I don't think I need separate classes for each format.
2
+ # module EpubForge
3
+ # module Builder
4
+ # module Assets
5
+ # class Markdown < Page
6
+ # end
7
+ # end
8
+ # end
9
+ # end
@@ -1,14 +1,22 @@
1
1
  module EpubForge
2
- module Epub
2
+ module Builder
3
3
  module Assets
4
4
  class Page < Asset
5
- attr_reader :html, :original_file, :title, :project, :media_type, :dest_extension, :dest_filename
6
- attr_reader :section_id
5
+ attr_reader :dest_extension,
6
+ :dest_filename,
7
+ :html,
8
+ :media_type,
9
+ :original_file,
10
+ :project,
11
+ :section_id,
12
+ :source_format,
13
+ :title
7
14
 
8
15
  def initialize file, metadata, project
9
16
  raise "NIL" if project.nil?
10
17
 
11
18
  @original_file = file.fwf_filepath
19
+ @source_format = @original_file.ext.to_sym
12
20
 
13
21
  @metadata = metadata
14
22
  @project = project
@@ -25,7 +33,7 @@ module EpubForge
25
33
  end
26
34
 
27
35
  def get_html
28
- @html = Utils::Htmlizer.instance.translate( @original_file )
36
+ @html = Utils::HtmlTranslator.translate( @original_file )
29
37
  end
30
38
 
31
39
  def get_title
@@ -1,5 +1,5 @@
1
1
  module EpubForge
2
- module Epub
2
+ module Builder
3
3
  module Assets
4
4
  class Stylesheet < Asset
5
5
  attr_accessor :filename, :name, :contents
@@ -0,0 +1,9 @@
1
+ # I don't think I need separate classes for each format.
2
+ # module EpubForge
3
+ # module Builder
4
+ # module Assets
5
+ # class Textile < Page
6
+ # end
7
+ # end
8
+ # end
9
+ # end
@@ -0,0 +1,9 @@
1
+ # I don't think I need separate classes for each format.
2
+ # module EpubForge
3
+ # module Builder
4
+ # module Assets
5
+ # class XHTML < Page
6
+ # end
7
+ # end
8
+ # end
9
+ # end
@@ -0,0 +1,134 @@
1
+ # Avoiding namespace collision.
2
+ XmlBuilder = Builder
3
+
4
+ # Coaxing the project into a sort of universal format. The parent class handles the
5
+ module EpubForge
6
+ module Builder
7
+ PAGE_FILE_EXTENSIONS = %w(html markdown textile xhtml)
8
+ IMAGE_FILE_EXTENSIONS = %w(jpg png gif)
9
+ FONT_FILE_EXTENSION = %w(ttf otf)
10
+
11
+ MEDIA_TYPES = { "gif" => "image/gif", "jpg" => "image/jpeg", "png" => "image/png",
12
+ "css" => "text/css", "js" => "application/javascript", "pdf" => "application/pdf",
13
+ "txt" => "text/plain", "xhtml" => "application/xhtml+xml",
14
+ "ttf" => "application/x-font-ttf", "otf" => "application/x-font-opentype"
15
+ }
16
+
17
+ IMAGE_DIR, STYLE_DIR, TEXT_DIR, FONT_DIR = %w(Images Styles Text Fonts).map{ |dir|
18
+ "/".fwf_filepath.join("OEBPS", dir)
19
+ }
20
+
21
+ class Builder
22
+ attr_reader :stylesheets
23
+ attr_reader :project
24
+
25
+ def initialize project, opts = {}
26
+ target_file = opts[:target_file] || project.filename_for_book.ext("epub") # TODO: But what about notes?
27
+
28
+ # puts "--------------- forgin' #{ target_file } ------------------"
29
+
30
+ @project = project
31
+ @config = project.config
32
+ @book_dir_short = opts[:book_dir] ? opts[:book_dir].split.last.to_s : "book"
33
+ @book_dir = @project.root_dir.join( @book_dir_short ) # TODO: .expand?
34
+
35
+ @config.page_orderer = Utils::FileOrderer.new( opts[:page_order] || @config.pages[@book_dir_short] )
36
+
37
+ @metadata = @config.metadata || {}
38
+
39
+
40
+ initialize_page_assets
41
+ initialize_image_assets
42
+ initialize_stylesheet_assets
43
+ initialize_font_assets
44
+ install_cover
45
+
46
+ @scratch_dir = FunWith::Files::FilePath.tmpdir.join( "ebookdir" )
47
+ end
48
+
49
+ def initialize_page_assets
50
+ page_files = @book_dir.glob( ext: PAGE_FILE_EXTENSIONS )
51
+ @section_files = @config.page_orderer.reorder( page_files )
52
+
53
+ @sections = @section_files.map do |section|
54
+ case section.to_s.split(".").last
55
+ when "markdown", "html", "textile", "xhtml"
56
+ Assets::Page.new( section, @metadata, self )
57
+ # Assets::Markdown.new( section, @metadata, self )
58
+ # when "html"
59
+ # Assets::HTML.new( section, @metadata, self )
60
+ # when "textile"
61
+ # Assets::Textile.new( section, @metadata, self )
62
+ # when "xhtml"
63
+ # Assets::XHTML.new( section, @metadata, self ) # These files are inserted into the book unaltered
64
+ else
65
+ raise "UNKNOWN EXTENSION TYPE"
66
+ end
67
+ end
68
+ end
69
+
70
+ def initialize_image_assets
71
+ images = @book_dir.glob( "images", ext: IMAGE_FILE_EXTENSIONS )
72
+ @images = images.map{ |img| Assets::Image.new(img) }
73
+ end
74
+
75
+ def initialize_stylesheet_assets
76
+ @stylesheets = @book_dir.glob( "stylesheets", "*.css" ).map do |sheet|
77
+ Assets::Stylesheet.new( sheet )
78
+ end
79
+ end
80
+
81
+ def initialize_font_assets
82
+ @fonts = @book_dir.glob( "fonts", ext: FONT_FILE_EXTENSION ).map do |font|
83
+ Assets::Font.new( font )
84
+ end
85
+ end
86
+
87
+
88
+ def install_cover
89
+ # Existing cover is moved to the very front
90
+ if @cover_section = @sections.detect(&:cover?)
91
+ # no need to do anything
92
+ elsif @cover_image = @images.detect(&:cover?)
93
+ # actually install cover
94
+ contents = "<div id='cover'><img class='cover' src='#{@cover_image.link.relative_path_from(TEXT_DIR)}' alt='#{@metadata.name}, by #{@metadata.author}'/></div>"
95
+ cover_file = @project.book_dir.join( "cover.xhtml" )
96
+ cover_file.write( wrap_page( contents, "cover" ) )
97
+ @cover_section = Assets::Page.new( cover_file, @metadata, @project )
98
+ @sections.unshift( @cover_section )
99
+ puts "cover page generated"
100
+ else
101
+ return false
102
+ end
103
+ end
104
+
105
+
106
+
107
+ protected
108
+
109
+ # Useful for multiple builders
110
+ # body_id provides a section-specific hook for CSS customizing.
111
+ def wrap_page( content = "", body_id = "body_class" )
112
+ b = XmlBuilder::XmlMarkup.new( :indent => 2)
113
+ b.instruct! :xml, :encoding => "utf-8", :standalone => "no"
114
+ b.declare! :DOCTYPE, :html, :PUBLIC, "-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
115
+
116
+ b.html :xmlns => "http://www.w3.org/1999/xhtml" do
117
+ b.head do
118
+ b.title( @metadata["name"] )
119
+ for sheet in @stylesheets
120
+ b.link :href => sheet.link.relative_path_from("/OEBPS/Text"), :media => "all", :rel => "stylesheet", :type => "text/css"
121
+ end
122
+ end
123
+
124
+
125
+ b.body( :id => body_id ) do
126
+ b << content
127
+ end
128
+ end
129
+
130
+ b.target!.to_s
131
+ end
132
+ end
133
+ end
134
+ end
@@ -1,91 +1,67 @@
1
- # Avoiding namespace collision.
2
- XmlBuilder = Builder
3
-
4
1
  module EpubForge
5
- module Epub
6
- PAGE_FILE_EXTENSIONS = %w(html markdown textile xhtml)
7
- IMAGE_FILE_EXTENSIONS = %w(jpg png gif)
8
- FONT_FILE_EXTENSION = %w(ttf otf)
9
-
10
- MEDIA_TYPES = { "gif" => "image/gif", "jpg" => "image/jpeg", "png" => "image/png",
11
- "css" => "text/css", "js" => "application/javascript", "pdf" => "application/pdf",
12
- "txt" => "text/plain", "xhtml" => "application/xhtml+xml",
13
- "ttf" => "application/x-font-ttf", "otf" => "application/x-font-opentype"
14
- }
15
-
16
- IMAGE_DIR, STYLE_DIR, TEXT_DIR, FONT_DIR = %w(Images Styles Text Fonts).map{ |dir|
17
- "/".fwf_filepath.join("OEBPS", dir)
18
- }
19
-
20
- class Builder
21
- attr_reader :stylesheets
22
- attr_reader :project
2
+ module Builder
3
+ class Epub < Builder
4
+ def package( epub_filename )
5
+ epub_filename = epub_filename.fwf_filepath.expand
6
+ FileUtils.rm( epub_filename ) if epub_filename.exist?
7
+ `cd #{@scratch_dir} && zip -Xr #{epub_filename.to_s.epf_backhashed_filename} mimetype META-INF OEBPS`
8
+ end
23
9
 
24
- def initialize project, opts = {}
25
- puts "--------------- forgin' #{project.filename_for_epub_book} ------------------"
26
- @project = project
27
- @config = project.config
28
- @book_dir_short = opts[:book_dir] ? opts[:book_dir].split.last.to_s : "book"
29
- @book_dir = @project.target_dir.join( @book_dir_short ).fwf_filepath.expand
30
- @config = @project.config
31
-
32
- @config.page_orderer = Utils::FileOrderer.new( opts[:page_order] || @config.pages[@book_dir_short] )
33
-
34
- @metadata = @config.metadata || {}
35
-
36
- page_files = @book_dir.glob( ext: PAGE_FILE_EXTENSIONS )
37
- @section_files = @config.page_orderer.reorder( page_files )
38
-
39
- @sections = @section_files.map do |section|
40
- case section.to_s.split(".").last
41
- when "markdown"
42
- Assets::Markdown.new( section, @metadata, self )
43
- when "html"
44
- Assets::HTML.new( section, @metadata, self )
45
- when "textile"
46
- Assets::Textile.new( section, @metadata, self )
47
- when "xhtml"
48
- Assets::XHTML.new( section, @metadata, self ) # These files are inserted into the book unaltered
49
- else
50
- raise "UNKNOWN EXTENSION TYPE"
51
- end
52
- end
53
-
54
- # @sections.each_with_index{ |sec, i| sec.section_number = i }
55
-
56
- images = @book_dir.glob( "images", ext: IMAGE_FILE_EXTENSIONS )
57
- @images = images.map{ |img| Assets::Image.new(img) }
58
-
59
- @stylesheets = @book_dir.glob( "stylesheets", "*.css" ).map do |sheet|
60
- Assets::Stylesheet.new( sheet )
61
- end
62
-
63
- @fonts = @book_dir.glob( "fonts", ext: FONT_FILE_EXTENSION ).map do |font|
64
- Assets::Font.new( font )
65
- end
66
-
67
- install_cover
68
-
69
- @scratch_dir = FunWith::Files::FilePath.tmpdir.join( "ebookdir" )
10
+ def clean
11
+ # do nothing? Remove scratch dir?
70
12
  end
71
13
 
72
- def install_cover
73
- # Existing cover is moved to the very front
74
- if @cover_section = @sections.detect(&:cover?)
75
- # no need to do anything
76
- elsif @cover_image = @images.detect(&:cover?)
77
- # actually install cover
78
- contents = "<div id='cover'><img class='cover' src='#{@cover_image.link.relative_path_from(TEXT_DIR)}' alt='#{@metadata.name}, by #{@metadata.author}'/></div>"
79
- cover_file = @project.book_dir.join( "cover.xhtml" )
80
- cover_file.write( wrap_page( contents ) )
81
- @cover_section = Assets::Page.new( cover_file, @metadata, @project )
82
- @sections.unshift( @cover_section )
83
- puts "cover page generated"
84
- else
85
- return false
14
+ # zips up contents
15
+ def build
16
+ FunWith::Files::DirectoryBuilder.create( @scratch_dir ) do |build|
17
+
18
+ build.file( "mimetype", mimetype )
19
+
20
+ build.dir( "META-INF" ) do
21
+ build.file("container.xml", container)
22
+ end
23
+
24
+ build.dir( "OEBPS" ) do
25
+ build.file( "toc.ncx", toc )
26
+ build.file( "content.opf", content_opf )
27
+
28
+ build.dir( "Text" ) do
29
+ @sections.each do |section|
30
+ content = section.html
31
+ content = wrap_page( content, section.section_id ) unless section.source_format == :xhtml
32
+
33
+ build.file( section.dest_filename, content )
34
+ end
35
+ end
36
+
37
+ unless @images.fwf_blank?
38
+ build.dir "Images" do
39
+ for img in @images
40
+ build.copy( img.filename )
41
+ end
42
+ end
43
+ end
44
+
45
+ unless @stylesheets.fwf_blank?
46
+ build.dir "Styles" do
47
+ for sheet in @stylesheets
48
+ build.file( sheet.name, sheet.contents )
49
+ end
50
+ end
51
+ end
52
+
53
+ unless @fonts.fwf_blank?
54
+ build.dir "Fonts" do
55
+ for font in @fonts
56
+ build.copy( font.filename )
57
+ end
58
+ end
59
+ end
60
+ end
86
61
  end
87
62
  end
88
-
63
+
64
+ protected
89
65
  def toc
90
66
  b = XmlBuilder::XmlMarkup.new(:indent => 2)
91
67
  b.instruct! # <?xml version="1.0" encoding="UTF-8"?>
@@ -222,85 +198,6 @@ module EpubForge
222
198
 
223
199
  b.target!.to_s
224
200
  end
225
-
226
- # zips up contents
227
- def build
228
- Utils::DirectoryBuilder.create( @scratch_dir ) do |build|
229
-
230
- build.file( "mimetype", mimetype )
231
-
232
- build.dir( "META-INF" ) do
233
- build.file("container.xml", container)
234
- end
235
-
236
- build.dir( "OEBPS" ) do
237
- build.file( "toc.ncx", toc )
238
- build.file( "content.opf", content_opf )
239
-
240
- build.dir( "Text" ) do
241
- @sections.each do |section|
242
- build.file( section.dest_filename,
243
- section.is_a?( Assets::XHTML ) ? section.html : wrap_page( section.html )
244
- )
245
- end
246
- end
247
-
248
- unless @images.epf_blank?
249
- build.dir "Images" do
250
- for img in @images
251
- build.copy( img.filename )
252
- end
253
- end
254
- end
255
-
256
- unless @stylesheets.epf_blank?
257
- build.dir "Styles" do
258
- for sheet in @stylesheets
259
- build.file( sheet.name, sheet.contents )
260
- end
261
- end
262
- end
263
-
264
- unless @fonts.epf_blank?
265
- build.dir "Fonts" do
266
- for font in @fonts
267
- build.copy( font.filename )
268
- end
269
- end
270
- end
271
- end
272
- end
273
- end
274
-
275
- def package epub_filename
276
- Packager.new( @scratch_dir, epub_filename ).package
277
- end
278
-
279
- def clean
280
- # do nothing
281
- end
282
-
283
- protected
284
- def wrap_page content = ""
285
- b = XmlBuilder::XmlMarkup.new( :indent => 2)
286
- b.instruct! :xml, :encoding => "utf-8", :standalone => "no"
287
- b.declare! :DOCTYPE, :html, :PUBLIC, "-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
288
-
289
- b.html :xmlns => "http://www.w3.org/1999/xhtml" do
290
- b.head do
291
- b.title( @metadata["name"] )
292
- for sheet in @stylesheets
293
- b.link :href => sheet.link.relative_path_from("/OEBPS/Text"), :media => "screen", :rel => "stylesheet", :type => "text/css"
294
- end
295
- end
296
-
297
- b.body do
298
- b << content
299
- end
300
- end
301
-
302
- b.target!.to_s
303
- end
304
201
  end
305
202
  end
306
203
  end