epubforge 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,22 @@
|
|
1
|
+
module EpubForge
|
2
|
+
module Builder
|
3
|
+
class Html < Builder
|
4
|
+
def build
|
5
|
+
@html_content = ""
|
6
|
+
|
7
|
+
@sections.each do |section|
|
8
|
+
@html_content << section.html
|
9
|
+
@html_content << "\n\n" # couldn't hurt?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def package( html_filename )
|
14
|
+
html_filename.write( wrap_page( @html_content ) )
|
15
|
+
end
|
16
|
+
|
17
|
+
def clean
|
18
|
+
# do nothing
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# module EpubForge
|
2
|
+
# module Epub
|
3
|
+
# class Packager
|
4
|
+
# def initialize( src_dir, dst_filename )
|
5
|
+
# @src_dir = src_dir
|
6
|
+
# @dst_filename = dst_filename
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# def package
|
10
|
+
# @dst_filename = @dst_filename.expand
|
11
|
+
# FileUtils.rm( @dst_filename ) if @dst_filename.exist?
|
12
|
+
# `cd #{@src_dir} && zip -Xr #{@dst_filename.to_s.epf_backhashed_filename} mimetype META-INF OEBPS`
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
# end
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# class Object
|
2
|
+
# def umethods( regex = /.*/ )
|
3
|
+
# (self.methods.sort - Object.new.methods).grep( regex )
|
4
|
+
# end
|
5
|
+
#
|
6
|
+
# def get_and_set( *method_names )
|
7
|
+
# for name in method_names
|
8
|
+
# if self.is_a?(Class) || self.is_a?(Module)
|
9
|
+
# eval "define_method( :#{name} ) do |*args|
|
10
|
+
# self.instance_variable_set( :@#{name}, args.first ) if args.length == 1
|
11
|
+
# self.instance_variable_get( :@#{name} )
|
12
|
+
# end"
|
13
|
+
# else
|
14
|
+
# m = Module.new
|
15
|
+
# m.get_and_set( *method_names )
|
16
|
+
# self.extend( m )
|
17
|
+
# end
|
18
|
+
# # define_method( name ) do |*args|
|
19
|
+
# # self.instance_variable_set( :"@#{__method__}", args.first ) if args.length == 1
|
20
|
+
# # self.instance_variable_get( :"@#{__method__}" )
|
21
|
+
# # end
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
@@ -1,8 +1,4 @@
|
|
1
1
|
class String
|
2
|
-
def epf_blank?
|
3
|
-
self.strip.length == 0
|
4
|
-
end
|
5
|
-
|
6
2
|
def epf_camelize
|
7
3
|
gsub(/(?:^|_)(.)/) { $1.upcase }
|
8
4
|
end
|
@@ -28,7 +24,7 @@ class String
|
|
28
24
|
nocaps = %w(a and at be but in is nor of or so teh the to with)
|
29
25
|
upcase = %w(Ii Ii: Iii M.d.) # TODO: ick
|
30
26
|
|
31
|
-
words = self.downcase.gsub(/\u00a0/, ' ').split(/(\s|\n)+/).map(&:strip).delete_if(&:
|
27
|
+
words = self.downcase.gsub(/\u00a0/, ' ').split(/(\s|\n)+/).map(&:strip).delete_if(&:fwf_blank?)
|
32
28
|
first_word = true
|
33
29
|
|
34
30
|
for word in words
|
File without changes
|
@@ -4,29 +4,26 @@ module EpubForge
|
|
4
4
|
CONFIG_FILE_NAME = "config.rb"
|
5
5
|
PROJECT_ACTIONS_DIRECTORY = "actions"
|
6
6
|
|
7
|
-
attr_reader :
|
8
|
-
:notes_dir, :project_basename, :
|
9
|
-
:
|
10
|
-
:filename_for_mobi_notes, :actions_dir
|
7
|
+
attr_reader :root_dir, :config_file, :config, :book_dir,
|
8
|
+
:notes_dir, :project_basename, :filename_for_book,
|
9
|
+
:filename_for_notes, :actions_dir
|
11
10
|
|
12
|
-
def initialize(
|
13
|
-
@
|
11
|
+
def initialize( root_dir )
|
12
|
+
@root_dir = FunWith::Files::FilePath.new( root_dir ).expand
|
14
13
|
|
15
14
|
load_configuration
|
16
15
|
|
17
|
-
@notes_dir = config.notes_dir || @
|
18
|
-
@book_dir = config.book_dir || @
|
16
|
+
@notes_dir = config.notes_dir || @root_dir.join( "notes" )
|
17
|
+
@book_dir = config.book_dir || @root_dir.join( "book" )
|
19
18
|
|
20
19
|
@project_basename = default_project_basename
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@filename_for_epub_notes = @target_dir.join( "#{default_project_basename}.notes.epub" )
|
24
|
-
@filename_for_mobi_notes = @target_dir.join( "#{default_project_basename}.notes.mobi" )
|
20
|
+
@filename_for_book = @root_dir.join( "#{default_project_basename}" )
|
21
|
+
@filename_for_notes = @root_dir.join( "#{default_project_basename}.notes" )
|
25
22
|
end
|
26
23
|
|
27
24
|
# shorthand string that 'names' the project, like the_vampire_of_the_leeky_hills. Variable-ish, used within filenames
|
28
25
|
def default_project_basename
|
29
|
-
config.filename || @
|
26
|
+
config.filename || @root_dir.basename.to_s.gsub( /\.epubforge$/ , '' )
|
30
27
|
end
|
31
28
|
|
32
29
|
# TODO: should test be more definitive?
|
@@ -38,11 +35,11 @@ module EpubForge
|
|
38
35
|
end
|
39
36
|
|
40
37
|
def project_exists?
|
41
|
-
@
|
38
|
+
@root_dir.exist? && config_file.exist?
|
42
39
|
end
|
43
40
|
|
44
41
|
def settings_folder(*args)
|
45
|
-
@settings_folder ||= @
|
42
|
+
@settings_folder ||= @root_dir.join( SETTINGS_FOLDER )
|
46
43
|
@settings_folder.join( *args )
|
47
44
|
end
|
48
45
|
|
@@ -71,11 +68,20 @@ module EpubForge
|
|
71
68
|
raise "Project#pages cannot take #{order.class} as an ordering object."
|
72
69
|
end
|
73
70
|
|
74
|
-
orderer.reorder( @book_dir.glob( ext: EpubForge::
|
71
|
+
orderer.reorder( @book_dir.glob( ext: EpubForge::Builder::PAGE_FILE_EXTENSIONS ) )
|
75
72
|
end
|
76
73
|
|
77
74
|
def load_configuration
|
78
|
-
|
75
|
+
puts "NO CONFIGURATION FILE DETECTED" unless config_file.file?
|
76
|
+
|
77
|
+
begin
|
78
|
+
self.install_fwc_config_from_file( config_file )
|
79
|
+
true
|
80
|
+
rescue SyntaxError => e
|
81
|
+
puts "Syntax Error in project configuration file #{config_file}. Quitting.".paint(:red)
|
82
|
+
puts e.message
|
83
|
+
exit(-1)
|
84
|
+
end
|
79
85
|
end
|
80
86
|
end
|
81
87
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# module EpubForge
|
2
|
+
# module Utils
|
3
|
+
# # filepath string with metadata, representing a class
|
4
|
+
# # file that can be loaded.
|
5
|
+
# class ClassLoader < FunWith::Files::FilePath
|
6
|
+
# def self.loaded_classes
|
7
|
+
# @loaded_classes ||= []
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# def self.loaded_directories
|
11
|
+
# @loaded_directories ||= []
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# def self.namespace( nsp = nil )
|
15
|
+
# @namespace = nsp unless nsp.nil?
|
16
|
+
# @namespace
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# def class_name
|
20
|
+
# unless @class_name
|
21
|
+
# base = self.basename.to_s.split(".")[0].epf_camelize
|
22
|
+
# @class_name = "#{self.class.namespace}::#{base}"
|
23
|
+
# end
|
24
|
+
# @class_name
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Returns true if an error was raised when trying to require the file,
|
28
|
+
# # or if the expected class is not loaded after the file was required.
|
29
|
+
# # Proper naming is very important here.
|
30
|
+
# def require_me
|
31
|
+
# begin
|
32
|
+
# require self.to_s
|
33
|
+
# rescue NameError => e
|
34
|
+
# puts "Error encounterd while trying to load #{self.class_name} from #{self}"
|
35
|
+
# puts e.message
|
36
|
+
# puts e.backtrace.map{|line| "\t#{line}" }
|
37
|
+
# return false
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# return self.class_loaded?
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# def class_loaded?
|
44
|
+
# begin
|
45
|
+
# self.to_class
|
46
|
+
# return true
|
47
|
+
# rescue NameError # There's gotta be another way I should be doing this.
|
48
|
+
# return false
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# def to_class
|
53
|
+
# return @klass unless @klass.nil?
|
54
|
+
# @klass = Utils::Misc.constantize( self.class_name )
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# def self.require_me( *loadables )
|
58
|
+
# @loaded_classes ||= []
|
59
|
+
# @loaded_directories ||= []
|
60
|
+
#
|
61
|
+
# for loadable in loadables
|
62
|
+
# loadable = self.new( loadable )
|
63
|
+
#
|
64
|
+
# if loadable.file?
|
65
|
+
# if loadable.require_me
|
66
|
+
# @loaded_classes << loadable.to_class
|
67
|
+
# else
|
68
|
+
# puts "Warning: Failed to load #{loadable.class_name} from file #{loadable}"
|
69
|
+
# end
|
70
|
+
# elsif loadable.directory?
|
71
|
+
# @loaded_directories << loadable
|
72
|
+
# loadable.glob( "**", "*.rb" ).each do |entry|
|
73
|
+
# self.require_me( entry )
|
74
|
+
# end
|
75
|
+
# else
|
76
|
+
# puts "Warning: Could not find file #{loadable} to load classes from."
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# # just loading all the files is simpler, and probably little harm from reloading. Plus, I want
|
82
|
+
# # to be able to split up existing ThorClasses across multiple files.
|
83
|
+
# def self.load_me( *loadables )
|
84
|
+
# silence_warnings do
|
85
|
+
# for loadable in loadables
|
86
|
+
# loadable = loadable.fwf_filepath
|
87
|
+
#
|
88
|
+
# if loadable.file?
|
89
|
+
# load( loadable )
|
90
|
+
# elsif loadable.directory?
|
91
|
+
# for entry in loadable.glob( :ext => "rb", :recursive => true )
|
92
|
+
# load( entry )
|
93
|
+
# end
|
94
|
+
# else
|
95
|
+
# puts "Warning: No idea what I'm trying to load (#{loadable}:#{loadable.class})"
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
# end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module EpubForge
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
# TODO: Starting to get the feeling that an HtmlTranslator is just a subtype of Converter.
|
5
|
+
class Converter
|
6
|
+
get_and_set :command, :executable, :help, :input_format, :label, :output_format
|
7
|
+
|
8
|
+
include FunWith::Patterns::Loader
|
9
|
+
loader_pattern_configure( :bracketwise_lookup,
|
10
|
+
:warn_on_key_change,
|
11
|
+
{ :key => :label, :verbose => true } )
|
12
|
+
|
13
|
+
def self.all
|
14
|
+
self.loader_pattern_registry
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.converts( input_format, output_format = :any )
|
18
|
+
self.all.select{ |k,v|
|
19
|
+
if v.input_format == input_format
|
20
|
+
output_format == :any || v.output_format == output_format
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end
|
24
|
+
}.values
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize( &block )
|
28
|
+
instance_exec( &block )
|
29
|
+
@command ||= "{{x}} {{o}} '{{src}}' '{{dst}}'" # default
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# def label( lbl = nil )
|
34
|
+
# @label = lbl unless lbl.nil?
|
35
|
+
# @label
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# def from( fmt = nil)
|
39
|
+
# @src_format = fmt unless fmt.nil?
|
40
|
+
# @src_format
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# def to( fmt = nil)
|
44
|
+
# @dst_format = fmt unless fmt.nil?
|
45
|
+
# @dst_format
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# def executable( executable_name = nil )
|
49
|
+
# @executable_name = executable_name unless executable_name.nil?
|
50
|
+
# @executable_name
|
51
|
+
# end
|
52
|
+
|
53
|
+
def is_executable_installed?
|
54
|
+
@executable && `which #{executable}`.strip.fwf_blank? == false
|
55
|
+
end
|
56
|
+
#
|
57
|
+
# def command( cmd = nil )
|
58
|
+
# @command = cmd unless cmd.nil?
|
59
|
+
# @command ||= "{{x}} {{opts}} '{{src}}' '{{dst}}'" # default
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
|
63
|
+
# opts {
|
64
|
+
# :dest => Destination (output) file,
|
65
|
+
# :command_line_options => Arguments to feed to the executable. Just a string, replaces the {{o}} in @command
|
66
|
+
# }
|
67
|
+
def convert( src, opts = {} )
|
68
|
+
src = src.fwf_filepath
|
69
|
+
dst = opts[:dest].is_a?(String) ? opts[:dest].fwf_filepath : opts[:dest]
|
70
|
+
|
71
|
+
if dst.nil?
|
72
|
+
dst = src.gsub( /#{@input_format}$/, @output_format.to_s )
|
73
|
+
end
|
74
|
+
|
75
|
+
if is_executable_installed?
|
76
|
+
if src.file?
|
77
|
+
cmd = command.gsub("{{x}}", executable.to_s).gsub("{{o}}", opts[:command_line_options]).gsub("{{src}}", src).gsub("{{dst}}", dst)
|
78
|
+
puts "running command : #{cmd}"
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
`#{cmd}`
|
83
|
+
$?.success?
|
84
|
+
else
|
85
|
+
warn( "Source file #{src} does not exist.".paint(:red,:bold))
|
86
|
+
false
|
87
|
+
end
|
88
|
+
else
|
89
|
+
false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module EpubForge
|
2
|
+
module Utils
|
3
|
+
# An individual translator, which receives a filename, determines if it's up to the job
|
4
|
+
# then returns the resulting HTML translation.
|
5
|
+
class HtmlTranslator
|
6
|
+
include HtmlTranslatorQueue
|
7
|
+
|
8
|
+
get_and_set( :name, :opts, :format, :cmd )
|
9
|
+
|
10
|
+
def self.translate( filename, opts = {} )
|
11
|
+
translator = opts[:translator]
|
12
|
+
translator = self.named( translator ) if translator.is_a?( Symbol )
|
13
|
+
opts = opts[:opts] || ""
|
14
|
+
|
15
|
+
if translator
|
16
|
+
if result = translator.translate( filename, {opts: opts } )
|
17
|
+
return result
|
18
|
+
else
|
19
|
+
puts "Named HtmlTranslator #{translator} did not return html. Falling back on other html translators"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
for translator in HtmlTranslator.each_translator
|
24
|
+
if result = translator.translate( filename, opts )
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
"<!-- COULD NOT FIND HTML TRANSLATOR FOR FORMAT (#{filename}) -->"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Unneeded?
|
33
|
+
# def self.format_from_filename( filename )
|
34
|
+
# ext = filename.fwf_filepath.ext
|
35
|
+
# ext.fwf_blank? ? :unknown : ext.to_sym
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
def initialize( &block )
|
42
|
+
# set some defaults
|
43
|
+
group( :user )
|
44
|
+
opts( "" )
|
45
|
+
|
46
|
+
self.instance_exec( &block ) if block_given?
|
47
|
+
self # explicitly return. Thought that wasn't necessary, but...
|
48
|
+
end
|
49
|
+
|
50
|
+
def group( g = nil )
|
51
|
+
if g
|
52
|
+
raise "group must be one of the following symbols: #{HtmlTranslatorQueue::GROUP_NAMES.inspect}" unless HtmlTranslatorQueue::GROUP_NAMES.include?(g)
|
53
|
+
@group = g
|
54
|
+
end
|
55
|
+
|
56
|
+
@group
|
57
|
+
end
|
58
|
+
|
59
|
+
def executable( executable_name = nil )
|
60
|
+
if executable_name
|
61
|
+
@executable_name = HtmlTranslator.location( executable_name ) || `which #{executable_name}`.strip
|
62
|
+
end
|
63
|
+
@executable_name || ""
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def custom_proc( *args, &block )
|
68
|
+
if block_given?
|
69
|
+
@custom_proc = block
|
70
|
+
elsif args.first.is_a?(Proc)
|
71
|
+
@custom_proc = args.first
|
72
|
+
end
|
73
|
+
|
74
|
+
@custom_proc
|
75
|
+
end
|
76
|
+
|
77
|
+
def installed?
|
78
|
+
executable.length > 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def handles_format?( f )
|
82
|
+
@format == get_file_format( f ) || @format == :unknown
|
83
|
+
end
|
84
|
+
|
85
|
+
def can_do_job?( f )
|
86
|
+
handles_format?( f ) && ( has_executable_installed? || has_custom_proc? )
|
87
|
+
end
|
88
|
+
|
89
|
+
def has_executable_installed?
|
90
|
+
executable.is_a?(String) && ! executable.fwf_blank? # 'which will return an empty string if the given executable isn't in the path'
|
91
|
+
end
|
92
|
+
|
93
|
+
def has_custom_proc?
|
94
|
+
@custom_proc.is_a?( Proc )
|
95
|
+
end
|
96
|
+
|
97
|
+
# opts allows you to override the normal command line arguments
|
98
|
+
# Maybe a description of the job's requirements should be more
|
99
|
+
# elaborate than just a filename. OTOH, simple can have its advantages.
|
100
|
+
def translate( filename, opts = "" )
|
101
|
+
return false unless can_do_job?( filename )
|
102
|
+
|
103
|
+
result = ""
|
104
|
+
if @custom_proc
|
105
|
+
result += @custom_proc.call( filename, *opts )
|
106
|
+
elsif @cmd
|
107
|
+
exec_string = cmd.gsub( /\{\{f\}\}/, "\"#{filename.to_s}\"" )
|
108
|
+
opts = @opts if opts.fwf_blank?
|
109
|
+
exec_string.gsub!( /\{\{o\}\}/, opts )
|
110
|
+
exec_string.gsub!( /\{\{x\}\}/, executable )
|
111
|
+
|
112
|
+
result += `#{exec_string}`
|
113
|
+
else
|
114
|
+
return false
|
115
|
+
end
|
116
|
+
|
117
|
+
result += "\n\n<!-- generated from #{@format} by html translator #{@name} -->\n"
|
118
|
+
result
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_file_format( file )
|
122
|
+
file.fwf_filepath.ext.to_sym
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|