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
@@ -1,65 +1,80 @@
|
|
1
1
|
module EpubForge
|
2
2
|
module Action
|
3
3
|
module SharedActionInterface
|
4
|
-
def actions_lookup
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
4
|
+
# def actions_lookup
|
5
|
+
# if self == Action
|
6
|
+
# @actions_lookup ||= ActionsLookup.new
|
7
|
+
# else
|
8
|
+
# Action.actions_lookup
|
9
|
+
# end
|
10
|
+
# end
|
11
11
|
|
12
|
-
def register_action_subclass( klass )
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
12
|
+
# def register_action_subclass( klass )
|
13
|
+
# if self == Action
|
14
|
+
# @subclasses ||= []
|
15
|
+
# @subclasses = (@subclasses + [klass]).uniq
|
16
|
+
# else
|
17
|
+
# Action.register_action_subclass( klass )
|
18
|
+
# end
|
19
|
+
# end
|
20
20
|
|
21
|
-
def subclasses
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
21
|
+
# def subclasses
|
22
|
+
# if self == Action
|
23
|
+
# @subclasses
|
24
|
+
# else
|
25
|
+
# Action.subclasses
|
26
|
+
# end
|
27
|
+
# end
|
28
28
|
|
29
|
-
def command_to_action_classes
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
29
|
+
# def command_to_action_classes
|
30
|
+
# if self == Action
|
31
|
+
# @command_klass_lookup ||= {}
|
32
|
+
# else
|
33
|
+
# Action.command_to_action_classes
|
34
|
+
# end
|
35
|
+
# end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
get_and_set( :description )
|
38
|
+
# def description( str = nil )
|
39
|
+
# @description = str if str
|
40
|
+
# @description
|
41
|
+
# end
|
41
42
|
|
42
43
|
# eventually replace description
|
43
44
|
def desc( usage, description, options = {} )
|
45
|
+
verbose = defined?(EpubForge::Action::Character) && self == EpubForge::Action::Character
|
46
|
+
puts "--------------IN DESC()----------------" if verbose
|
47
|
+
puts self.method_options.inspect if verbose
|
44
48
|
self.command_to_action_classes[usage] = self
|
45
49
|
super( usage, description, options )
|
50
|
+
puts self.method_options.inspect if verbose
|
51
|
+
puts "--------------END DESC()----------------" if verbose
|
46
52
|
end
|
47
53
|
|
48
|
-
# TODO: Get rid of this
|
49
|
-
def keywords( *args )
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
54
|
+
# # TODO: Get rid of this
|
55
|
+
# def keywords( *args )
|
56
|
+
# if args.fwf_blank?
|
57
|
+
# @keywords ||= []
|
58
|
+
# else
|
59
|
+
# @keywords = args.map(&:to_s)
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# @keywords
|
63
|
+
# end
|
58
64
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
65
|
+
# If given one arg, sets keyword
|
66
|
+
# if given no args, fetches keyword
|
67
|
+
get_and_set( :keyword, :usage ) #
|
68
|
+
# def keyword( k = nil )
|
69
|
+
# @keyword = k unless k.nil?
|
70
|
+
# @keyword
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
#
|
74
|
+
# def usage( str = nil )
|
75
|
+
# @usage = str if str
|
76
|
+
# @usage
|
77
|
+
# end
|
63
78
|
|
64
79
|
def project_required?
|
65
80
|
@project_required = true if @project_required.nil?
|
@@ -83,11 +98,11 @@ module EpubForge
|
|
83
98
|
end
|
84
99
|
end
|
85
100
|
|
86
|
-
class
|
87
|
-
def self.inherited( subclass )
|
88
|
-
|
89
|
-
|
90
|
-
end
|
101
|
+
class Action < Thor
|
102
|
+
# def self.inherited( subclass )
|
103
|
+
# self.register_action_subclass( subclass )
|
104
|
+
# subclass.include_standard_options
|
105
|
+
# end
|
91
106
|
|
92
107
|
include Thor::Actions
|
93
108
|
extend SharedActionInterface
|
@@ -102,6 +117,9 @@ module EpubForge
|
|
102
117
|
ON_BLUE = Thor::Shell::Color::ON_BLUE
|
103
118
|
|
104
119
|
|
120
|
+
|
121
|
+
|
122
|
+
|
105
123
|
protected
|
106
124
|
def say_when_verbose( *args )
|
107
125
|
say( *args ) if @verbose
|
@@ -142,9 +160,9 @@ module EpubForge
|
|
142
160
|
end
|
143
161
|
|
144
162
|
choice_text = ""
|
145
|
-
choices.each_with_index
|
163
|
+
choices.each_with_index do |choice,i|
|
146
164
|
choice_text << "\t\t#{i}) #{choice.first}\n"
|
147
|
-
|
165
|
+
end
|
148
166
|
|
149
167
|
selection = ask( "#{statement}\n\tChoices:\n#{choice_text}>>> ", BLUE )
|
150
168
|
choices[selection.to_i].last
|
@@ -153,6 +171,8 @@ module EpubForge
|
|
153
171
|
def ask_prettily( statement )
|
154
172
|
ask( statement, BLUE )
|
155
173
|
end
|
174
|
+
|
175
|
+
|
156
176
|
|
157
177
|
# hope this doesn't break anything. Sure enough, it broke a lot of things.
|
158
178
|
# def destination_root=( root )
|
@@ -160,16 +180,6 @@ module EpubForge
|
|
160
180
|
# @destination_stack << (root ? root.fwf_filepath.expand : '')
|
161
181
|
# end
|
162
182
|
|
163
|
-
# Instead, use these instead of destination_root. Thor gets strings instead of
|
164
|
-
# filepaths, like it wants, and I get filepaths instead of strings, like I want.
|
165
|
-
def destination_root_filepath
|
166
|
-
self.destination_root.fwf_filepath
|
167
|
-
end
|
168
|
-
|
169
|
-
def destination_root_filepath=(root)
|
170
|
-
self.destination_root = root.to_s
|
171
|
-
end
|
172
|
-
|
173
183
|
def executable_installed?( name )
|
174
184
|
name = name.to_sym
|
175
185
|
|
@@ -218,7 +228,7 @@ module EpubForge
|
|
218
228
|
end
|
219
229
|
|
220
230
|
def project_already_gitted?
|
221
|
-
@project.
|
231
|
+
@project.root_dir.join( ".git" ).directory?
|
222
232
|
end
|
223
233
|
|
224
234
|
def quit_with_error( msg, errno = -1 )
|
@@ -227,12 +237,22 @@ module EpubForge
|
|
227
237
|
end
|
228
238
|
|
229
239
|
def before_start
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
240
|
+
variablize_options( :project, :debug, :help, :verbose )
|
241
|
+
# @project = @options[:project]
|
242
|
+
# @debug = @options[:debug]
|
243
|
+
# @help = @options[:help]
|
244
|
+
# @verbose = @options[:verbose]
|
234
245
|
@project = Project.new( @project ) unless @project.nil?
|
235
246
|
end
|
247
|
+
|
248
|
+
# takes a series of symbols or an array of symbols
|
249
|
+
# for each symbol, creates an instance var from @options[:symbol]
|
250
|
+
def variablize_options( *symbols )
|
251
|
+
symbols.flatten! # in case someone passes an array
|
252
|
+
for sym in symbols
|
253
|
+
self.instance_variable_set( :"@#{sym}", @options[sym] )
|
254
|
+
end
|
255
|
+
end
|
236
256
|
end
|
237
257
|
end
|
238
258
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module EpubForge
|
2
|
+
module Action
|
3
|
+
class Action2
|
4
|
+
get_and_set( :project, :args )
|
5
|
+
get_and_set_boolean( :verbose )
|
6
|
+
|
7
|
+
include FunWith::Patterns::Loader
|
8
|
+
loader_pattern_configure( :bracketwise_lookup,
|
9
|
+
:warn_on_key_change,
|
10
|
+
{ :verbose => true } )
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
include Chatterbox
|
15
|
+
|
16
|
+
def self.loader_pattern_load_item( file )
|
17
|
+
begin
|
18
|
+
file.fwf_filepath.load
|
19
|
+
rescue Exception => e
|
20
|
+
puts "Error loading #{file}: #{e.message}"
|
21
|
+
for line in e.backtrace
|
22
|
+
puts "\t#{line}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
nil # returning true will break loader
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.define_action( keyword, &block )
|
30
|
+
puts "defining action #{keyword}" if EpubForge.gem_test_mode?
|
31
|
+
definition = ActionDefinition.new
|
32
|
+
definition.keyword( keyword )
|
33
|
+
definition.klass( self )
|
34
|
+
|
35
|
+
yield definition if block_given?
|
36
|
+
|
37
|
+
EpubForge::Action::Action2.loader_pattern_register_item( definition )
|
38
|
+
end
|
39
|
+
|
40
|
+
# # Instead, use these instead of destination_root. Thor gets strings instead of
|
41
|
+
# # filepaths, like it wants, and I get filepaths instead of strings, like I want.
|
42
|
+
# def destination_root_filepath
|
43
|
+
# self.destination_root.fwf_filepath
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# def destination_root_filepath=(root)
|
47
|
+
# @destination_root_file
|
48
|
+
# self.destination_root = root.to_s
|
49
|
+
# end
|
50
|
+
attr_accessor :destination_root_filepath
|
51
|
+
|
52
|
+
def executable_installed?( name )
|
53
|
+
name = name.to_sym
|
54
|
+
|
55
|
+
if @executables.nil?
|
56
|
+
@executables = {}
|
57
|
+
for exe, path in (EpubForge.config[:exe_paths] || {})
|
58
|
+
@executables[exe] = path.fwf_filepath
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
@executables[name] ||= begin
|
63
|
+
_which = `which #{name}`.strip
|
64
|
+
(_which.length == 0) ? false : _which.fwf_filepath
|
65
|
+
end
|
66
|
+
|
67
|
+
@executables[name]
|
68
|
+
end
|
69
|
+
|
70
|
+
def requirements
|
71
|
+
@requirements ||= []
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_requirement( *args, &block )
|
75
|
+
@requirements ||= []
|
76
|
+
@requirements.push( [args, block] )
|
77
|
+
end
|
78
|
+
|
79
|
+
def requires_executable( ex, fail_msg )
|
80
|
+
add_requirement( ex, fail_msg ) do
|
81
|
+
executable_installed?( ex, fail_msg )
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def must_target_a_project( project_dir )
|
86
|
+
add_requirement( project_dir ) do
|
87
|
+
Project.is_project_dir?( project_dir )
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def git_installed?
|
92
|
+
executable_installed?('git')
|
93
|
+
end
|
94
|
+
|
95
|
+
def ebook_convert_installed?
|
96
|
+
executable_installed?('ebook-convert')
|
97
|
+
end
|
98
|
+
|
99
|
+
def project_already_gitted?
|
100
|
+
@project.root_dir.join( ".git" ).directory?
|
101
|
+
end
|
102
|
+
|
103
|
+
def quit_with_error( msg, errno = -1 )
|
104
|
+
STDERR.write( "\n#{msg}\n")
|
105
|
+
exit( errno )
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module EpubForge
|
2
|
+
module Action
|
3
|
+
class ActionDefinition
|
4
|
+
# attr_accessor :default_args, :keyword, :klass, :proc
|
5
|
+
|
6
|
+
get_and_set :help, :usage, :default_args, :keyword, :klass, :proc
|
7
|
+
get_and_set_boolean :project_required, :verbose
|
8
|
+
|
9
|
+
alias :loader_pattern_registry_key :keyword
|
10
|
+
|
11
|
+
def execute( &block )
|
12
|
+
proc( block )
|
13
|
+
end
|
14
|
+
|
15
|
+
def run( *args )
|
16
|
+
action = klass.new # one of the action classes (New or Git or Epub, etc.)
|
17
|
+
puts( "Sending args to Action(#{self.keyword}) : #{ 'NO ARGS' if args.fwf_blank? }".paint(:pink) ) if EpubForge.gem_test_mode?
|
18
|
+
for arg, i in args.each_with_index
|
19
|
+
puts " #{i}: #{arg.inspect}".paint(:pink) if verbose?
|
20
|
+
end
|
21
|
+
|
22
|
+
if args.first.is_a?(Project)
|
23
|
+
action.project( args.first )
|
24
|
+
action.args( args[1..-1] )
|
25
|
+
else
|
26
|
+
action.args( args )
|
27
|
+
end
|
28
|
+
|
29
|
+
action.instance_exec( &@proc )
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def default( name, value )
|
34
|
+
(@default_args ||= {})[name] = value
|
35
|
+
end
|
36
|
+
|
37
|
+
# def project_required?
|
38
|
+
# @project_required = true if @project_required.nil?
|
39
|
+
# @project_required
|
40
|
+
# end
|
41
|
+
|
42
|
+
# def verbose?
|
43
|
+
# @verbose == true
|
44
|
+
# end
|
45
|
+
|
46
|
+
# Most actions require -- nay, demand! -- a project to act upon.
|
47
|
+
# Add the line 'project_not_required' to the class definition
|
48
|
+
# to keep it from failing out if it can't find an existing project.
|
49
|
+
# Used for things like initializing new projects, printing help,
|
50
|
+
# or... my imagination fails me.
|
51
|
+
def project_required?
|
52
|
+
@project_required = true if @project_required.nil?
|
53
|
+
@project_required
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def project_not_required
|
58
|
+
@project_required = false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# module EpubForge
|
2
|
+
# module Action
|
3
|
+
# class ActionsLookup
|
4
|
+
# attr_accessor :actions, :actions_directories, :keywords
|
5
|
+
#
|
6
|
+
# def initialize
|
7
|
+
# clear
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# def clear
|
11
|
+
# @keywords = {}
|
12
|
+
# @actions = []
|
13
|
+
# @actions_directories = []
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def add_actions( *args )
|
17
|
+
# Utils::ActionLoader.load_me( *args )
|
18
|
+
#
|
19
|
+
# new_actions = Utils::ActionLoader.loaded_classes - @actions
|
20
|
+
# @actions += new_actions
|
21
|
+
# new_directories = Utils::ActionLoader.loaded_directories - @actions_directories
|
22
|
+
# @actions_directories += new_directories
|
23
|
+
#
|
24
|
+
# for action in new_actions
|
25
|
+
# for keyword in action.keywords
|
26
|
+
# @keywords[keyword] = action
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # Find all the actions with keywords that start with the given string.
|
32
|
+
# # If this results in more than one action being found, the proper
|
33
|
+
# # response is to panic and flail arms.
|
34
|
+
# def keyword_to_action( keyword )
|
35
|
+
# exact_match = @keywords.keys.select{ |k| k == keyword }
|
36
|
+
#
|
37
|
+
# return [@keywords[exact_match.first]] if exact_match.length == 1
|
38
|
+
#
|
39
|
+
# # if no exact match can be found, find a partial match, at the beginning
|
40
|
+
# # of the keywords.
|
41
|
+
# @keywords.keys.select{ |k| k.match(/^#{keyword}/) }.map{ |k| @keywords[k] }.uniq
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
# end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module EpubForge
|
2
|
+
module Action
|
3
|
+
module Chatterbox
|
4
|
+
def say( message, color = nil )
|
5
|
+
puts message.paint(color)
|
6
|
+
end
|
7
|
+
|
8
|
+
def ask( question, opts = {} )
|
9
|
+
while true
|
10
|
+
opts[:colors] ||= opts[:color]
|
11
|
+
|
12
|
+
answer = nil
|
13
|
+
input = Readline.readline( question.paint(opts[:colors] ) + " " ).strip
|
14
|
+
input.strip
|
15
|
+
|
16
|
+
if input.fwf_blank?
|
17
|
+
if opts[:default]
|
18
|
+
answer = opts[:default]
|
19
|
+
elsif opts[:blank_allowed] || (opts[:possible_answers] || []).include?("")
|
20
|
+
answer = input
|
21
|
+
end
|
22
|
+
elsif opts[:possible_answers]
|
23
|
+
answer = input if opts[:possible_answers].include?( input )
|
24
|
+
else
|
25
|
+
answer = input
|
26
|
+
end
|
27
|
+
|
28
|
+
if answer.nil?
|
29
|
+
say( "'#{input}' is not a valid answer.", :red )
|
30
|
+
say( "Possible answers: #{ opts[:possible_answers].inspect }") if opts[:possible_answers]
|
31
|
+
end
|
32
|
+
|
33
|
+
return answer unless answer.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def yes?( message, opts = {} )
|
38
|
+
opts[:colors] ||= :blue
|
39
|
+
opts[:possible_answers] = ["Y", "y", "N", "n", "yes", "no"]
|
40
|
+
opts[:default] ||= "y"
|
41
|
+
|
42
|
+
answer = ask( "#{message} (Y/n)", opts ).downcase[0..1]
|
43
|
+
|
44
|
+
answer == "y"
|
45
|
+
end
|
46
|
+
|
47
|
+
def yes_prettily?( statement )
|
48
|
+
yes?( statement, :color => :pink )
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def no?( message, color = nil )
|
53
|
+
opts[:allowed] = ["Y", "y", "N", "n"]
|
54
|
+
opts[:default] = "n"
|
55
|
+
answer = ask( "#{message} (y/N)", opts ).downcase
|
56
|
+
|
57
|
+
answer == "n"
|
58
|
+
end
|
59
|
+
|
60
|
+
def say_instruction( instruction )
|
61
|
+
puts instruction.paint(:yellow)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def ask_from_menu( statement, choices )
|
66
|
+
choices.map! do |choice|
|
67
|
+
choice.is_a?(String) ? [choice] : choice # I'm being too clever by half here. .first/.last still works.
|
68
|
+
end
|
69
|
+
|
70
|
+
choice_text = ""
|
71
|
+
choices.each_with_index do |choice,i|
|
72
|
+
choice_text << "\t\t#{i}) #{choice.first}\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
selection = ask( "#{statement}\n\tChoices:\n#{choice_text}>>> ".paint(:blue) )
|
76
|
+
choices[selection.to_i].last
|
77
|
+
end
|
78
|
+
|
79
|
+
def ask_prettily( question, *args )
|
80
|
+
ask( question.paint(:blue), *args )
|
81
|
+
end
|
82
|
+
|
83
|
+
def say_all_is_well( statement )
|
84
|
+
say( statement, :green )
|
85
|
+
end
|
86
|
+
|
87
|
+
def say_error( statement )
|
88
|
+
say( statement.paint(:bg_red, :bold) )
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|