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.
- checksums.yaml +7 -0
- data/Gemfile +17 -10
- data/VERSION +1 -1
- data/bin/epubforge +1 -1
- data/config/actions/epub.rb +50 -0
- data/config/actions/forge.rb +34 -13
- data/config/actions/git.rb +106 -0
- data/config/actions/help.rb +13 -13
- data/config/actions/html.rb +33 -0
- data/config/actions/mobi.rb +60 -0
- data/config/actions/new.rb +182 -0
- data/config/actions/word_count.rb +26 -24
- data/config/{actions → actions_to_ignore}/generate.rb +1 -1
- data/config/{actions → actions_to_ignore}/generate_chapter.rb +0 -0
- data/config/{actions → actions_to_ignore}/git_backup.rb +2 -2
- data/config/{actions → actions_to_ignore}/globals.rb +1 -1
- data/config/{actions → actions_to_ignore}/kindle.rb +3 -3
- data/config/{actions → actions_to_ignore}/local_action.rb +1 -1
- data/config/{actions → actions_to_ignore}/mobify.rb +3 -3
- data/config/actions_to_ignore/notes_to_epub.rb +19 -0
- data/config/actions_to_ignore/notes_to_kindle.rb +18 -0
- data/config/{actions → actions_to_ignore}/spell.rb +1 -1
- data/config/{actions → actions_to_ignore}/version.rb +3 -3
- data/config/{actions → actions_to_ignore}/wrap_scene_notes_in_hidden_div.rb +1 -1
- data/config/converters/epub_to_mobi.calibre.rb +8 -0
- data/config/converters/epub_to_mobi.kindlegen.rb +11 -0
- data/config/html_translators/default_kramdown.html_translator.rb +9 -0
- data/config/html_translators/default_markdown.html_translator.rb +10 -0
- data/config/html_translators/default_markdown_pandoc.html_translator.rb +10 -0
- data/config/html_translators/default_textile_pandoc.html_translator.rb +8 -0
- data/config/html_translators/default_xhtml.html_translator.rb +7 -0
- data/config/html_translators/fallback_html.html_translator.rb +9 -0
- data/config/html_translators/fallback_markdown.html_translator.rb +8 -0
- data/config/html_translators/fallback_textile.html_translator.rb +7 -0
- data/config/html_translators/fallback_txt.html_translator.rb +8 -0
- data/config/html_translators/fallback_unknown.html_translator.rb +7 -0
- data/lib/epubforge.rb +37 -82
- data/lib/{action/thor_action.rb → epubforge/action/action.rb} +89 -69
- data/lib/epubforge/action/action2.rb +109 -0
- data/lib/epubforge/action/action_definition.rb +62 -0
- data/lib/epubforge/action/actions_lookup.rb +45 -0
- data/lib/epubforge/action/chatterbox.rb +93 -0
- data/lib/{action → epubforge/action}/cli_command.rb +2 -2
- data/lib/{action → epubforge/action}/cli_sequence.rb +0 -0
- data/lib/{action → epubforge/action}/file_transformer.rb +0 -0
- data/lib/{action → epubforge/action}/hooks_interface.rb +2 -2
- data/lib/{action → epubforge/action}/run_description.rb +12 -9
- data/lib/{action → epubforge/action}/runner.rb +23 -24
- data/lib/{epub → epubforge/builder}/assets/asset.rb +1 -1
- data/lib/{epub → epubforge/builder}/assets/font.rb +1 -1
- data/lib/epubforge/builder/assets/html.rb +9 -0
- data/lib/{epub → epubforge/builder}/assets/image.rb +1 -1
- data/lib/epubforge/builder/assets/markdown.rb +9 -0
- data/lib/{epub → epubforge/builder}/assets/page.rb +12 -4
- data/lib/{epub → epubforge/builder}/assets/stylesheet.rb +1 -1
- data/lib/epubforge/builder/assets/textile.rb +9 -0
- data/lib/epubforge/builder/assets/xhtml.rb +9 -0
- data/lib/epubforge/builder/builder.rb +134 -0
- data/lib/{epub/builder.rb → epubforge/builder/epub.rb} +58 -161
- data/lib/epubforge/builder/html.rb +22 -0
- data/lib/epubforge/builder/packager.rb +16 -0
- data/lib/epubforge/core_extensions/array.rb +2 -0
- data/lib/{core_extensions → epubforge/core_extensions}/kernel.rb +0 -0
- data/lib/epubforge/core_extensions/nil_class.rb +2 -0
- data/lib/epubforge/core_extensions/object.rb +24 -0
- data/lib/{core_extensions → epubforge/core_extensions}/string.rb +1 -5
- data/lib/{custom_helpers.rb → epubforge/custom_helpers.rb} +0 -1
- data/lib/{errors.rb → epubforge/exceptions/errors.rb} +0 -0
- data/lib/{project → epubforge/project}/project.rb +23 -17
- data/lib/epubforge/utils/action_loader.rb +8 -0
- data/lib/epubforge/utils/class_loader.rb +102 -0
- data/lib/epubforge/utils/converter.rb +94 -0
- data/lib/{utils → epubforge/utils}/downloader.rb +0 -0
- data/lib/{utils → epubforge/utils}/file_orderer.rb +0 -0
- data/lib/epubforge/utils/file_path.rb +8 -0
- data/lib/epubforge/utils/html_translator.rb +126 -0
- data/lib/epubforge/utils/html_translator_queue.rb +113 -0
- data/lib/epubforge/utils/htmlizer.rb +61 -0
- data/lib/{utils → epubforge/utils}/misc.rb +0 -0
- data/lib/epubforge/utils/root_path.rb +8 -0
- data/lib/epubforge/utils/settings.rb +147 -0
- data/lib/epubforge/utils/template_evaluator.rb +7 -0
- data/templates/{default/book/afterword.markdown.template → project/book/afterword.markdown} +0 -0
- data/templates/project/book/chapter-%0000chapter%.markdown.template +4 -0
- data/templates/{default → project}/book/cover.xhtml.template +2 -2
- data/templates/{default/book/foreword.markdown.template → project/book/foreword.markdown} +0 -0
- data/templates/{default → project}/book/images/cover.png +0 -0
- data/templates/{default/book/stylesheets/stylesheet.css.template → project/book/stylesheets/stylesheet.css} +0 -0
- data/templates/project/book/title_page.markdown.template +5 -0
- data/templates/project/notes/character.%character.name_for_file%.markdown.template +15 -0
- data/templates/{default → project}/notes/images/cover.png +0 -0
- data/templates/{default/notes/stylesheets/stylesheet.css.template → project/notes/stylesheets/stylesheet.css} +0 -0
- data/templates/{default → project}/settings/actions/local_action.rb.example +1 -1
- data/templates/project/settings/config.rb.template +70 -0
- data/templates/project/settings/html_translators/example_translator.rb +29 -0
- data/templates/{default → project}/settings/wordcount.template +1 -1
- data/test/answers01.yml +30 -0
- data/test/helper.rb +62 -39
- data/test/misc/config.rb +5 -7
- data/test/test_epubforge.rb +18 -14
- data/test/{test_htmlizers.rb → test_html_translators.rb} +4 -8
- data/test/test_template_evaluator.rb +42 -0
- data/test/test_utils.rb +0 -11
- metadata +186 -189
- data/config/actions/gitify.rb +0 -72
- data/config/actions/init.rb +0 -138
- data/config/actions/notes_to_epub.rb +0 -18
- data/config/actions/notes_to_kindle.rb +0 -17
- data/config/htmlizers.rb +0 -70
- data/lib/action/actions_lookup.rb +0 -45
- data/lib/core_extensions/array.rb +0 -5
- data/lib/core_extensions/nil_class.rb +0 -5
- data/lib/core_extensions/object.rb +0 -5
- data/lib/epub/assets/html.rb +0 -8
- data/lib/epub/assets/markdown.rb +0 -8
- data/lib/epub/assets/textile.rb +0 -8
- data/lib/epub/assets/xhtml.rb +0 -8
- data/lib/epub/packager.rb +0 -16
- data/lib/utils/action_loader.rb +0 -7
- data/lib/utils/class_loader.rb +0 -102
- data/lib/utils/directory_builder.rb +0 -181
- data/lib/utils/file_path.rb +0 -152
- data/lib/utils/html_translator.rb +0 -100
- data/lib/utils/html_translator_queue.rb +0 -70
- data/lib/utils/htmlizer.rb +0 -92
- data/lib/utils/root_path.rb +0 -20
- data/lib/utils/settings.rb +0 -146
- data/lib/utils/template_evaluator.rb +0 -20
- data/templates/default/book/chapter-%i%.markdown.sequence +0 -4
- data/templates/default/book/title_page.markdown.template +0 -4
- data/templates/default/notes/character.named.markdown.template +0 -4
- data/templates/default/payload.rb +0 -65
- data/templates/default/settings/config.rb.form +0 -55
- data/templates/default/settings/htmlizers.rb +0 -0
- 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.
|
|
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.
|
|
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
|
|
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 ==
|
|
10
|
+
super( hookset ) unless self == Action
|
|
11
11
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def self.included( base )
|
|
15
|
-
if base ==
|
|
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
|
-
:
|
|
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
|
-
@
|
|
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
|
-
|
|
27
|
-
@
|
|
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
|
-
|
|
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.
|
|
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, :
|
|
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.
|
|
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.
|
|
53
|
+
return false unless @run_description.action
|
|
64
54
|
|
|
65
|
-
if @run_description.project.nil? && @run_description.
|
|
66
|
-
@run_description.errors << "Could not find a project directory, but the action #{@run_description.
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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,14 +1,22 @@
|
|
|
1
1
|
module EpubForge
|
|
2
|
-
module
|
|
2
|
+
module Builder
|
|
3
3
|
module Assets
|
|
4
4
|
class Page < Asset
|
|
5
|
-
attr_reader :
|
|
6
|
-
|
|
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::
|
|
36
|
+
@html = Utils::HtmlTranslator.translate( @original_file )
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
def get_title
|
|
@@ -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
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
25
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|