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
@@ -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
@@ -0,0 +1,2 @@
1
+ class Array
2
+ end
@@ -0,0 +1,2 @@
1
+ class NilClass
2
+ end
@@ -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(&:epf_blank?)
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
@@ -63,4 +63,3 @@ module EpubForge
63
63
  end
64
64
  end
65
65
 
66
- EpubForge.extend( EpubForge::CustomHelpers )
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 :target_dir, :config_file, :config, :book_dir,
8
- :notes_dir, :project_basename, :filename_for_epub_book,
9
- :filename_for_mobi_book, :filename_for_epub_notes,
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( target_dir )
13
- @target_dir = FunWith::Files::FilePath.new( target_dir ).expand
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 || @target_dir.join( "notes" )
18
- @book_dir = config.book_dir || @target_dir.join( "book" )
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
- @filename_for_epub_book = @target_dir.join( "#{default_project_basename}.epub" )
22
- @filename_for_mobi_book = @target_dir.join( "#{default_project_basename}.mobi" )
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 || @target_dir.basename.to_s.gsub( /\.epubforge$/ , '' )
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
- @target_dir.exist? && config_file.exist?
38
+ @root_dir.exist? && config_file.exist?
42
39
  end
43
40
 
44
41
  def settings_folder(*args)
45
- @settings_folder ||= @target_dir.join( 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::Epub::PAGE_FILE_EXTENSIONS ) )
71
+ orderer.reorder( @book_dir.glob( ext: EpubForge::Builder::PAGE_FILE_EXTENSIONS ) )
75
72
  end
76
73
 
77
74
  def load_configuration
78
- self.install_fwc_config_from_file( config_file )
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,8 @@
1
+ # module EpubForge
2
+ # module Action
3
+ # class Registry
4
+ # include FunWith::Patterns::Loader
5
+ # alias :loader_pattern_registry_key :keyword
6
+ # end
7
+ # end
8
+ # 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,8 @@
1
+ # Should be obsoleted by FunWith::Files::FilePath
2
+ # Emptying to see if anything breaks.
3
+ module EpubForge
4
+ module Utils
5
+ class FilePath < Pathname
6
+ end
7
+ end
8
+ end
@@ -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