epubforge 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
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