git-scribe 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,14 +44,18 @@ For local generation (evenutally pushing to GitHub will handle gen for you), it
44
44
  Usage
45
45
  =====
46
46
 
47
- Initialize a new book with `init` (not yet completed).
47
+ Initialize a new book with `init`:
48
48
 
49
49
  $ git scribe init
50
50
 
51
51
  This will set up the outline for your book. All the book content goes into the 'book' subdirectory with 'book.asc' as the starting point. If you want to split the writing up into multiple files you can simply include them in the book.asc file.
52
52
 
53
+ Then you can generate your book content with the 'git scribe gen' command:
54
+
53
55
  $ git scribe gen [site|html|pdf|epub|mobi|all]
54
56
 
57
+ Eventually, simply pushing to GitHub will take care of this for you.
58
+
55
59
  Roadmap
56
60
  =======
57
61
 
data/lib/git-scribe.rb CHANGED
@@ -1,17 +1,40 @@
1
1
  require 'rubygems'
2
2
  require 'nokogiri'
3
3
  require 'liquid'
4
+ require 'subcommand'
4
5
 
5
6
  require 'fileutils'
6
7
  require 'pp'
7
8
 
8
9
  class GitScribe
9
10
 
11
+ BOOK_FILE = 'book.asc'
12
+ OUTPUT_TYPES = ['pdf', 'epub', 'mobi', 'html', 'site']
10
13
  SCRIBE_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
11
14
 
12
15
  def initialize(args)
13
- @command = args.shift
14
- @args = args
16
+ @options = {}
17
+ global_options do |opts|
18
+ opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
19
+ opts.description = "git-scribe helps you write books with the power of Git"
20
+ opts.separator ""
21
+ opts.separator "Global options are:"
22
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
23
+ @options[:verbose] = v
24
+ end
25
+ end
26
+
27
+ command :init do |opts|
28
+ opts.banner = "Usage: init [options]"
29
+ opts.description = "initialize a new book layout"
30
+ opts.on("-l", "--lang", "choose a default language (en)") do |v|
31
+ @options[:lang] = lang || 'en'
32
+ end
33
+ end
34
+
35
+ pp @options
36
+
37
+ opt_parse
15
38
  end
16
39
 
17
40
  def self.start(args)
@@ -28,27 +51,56 @@ class GitScribe
28
51
 
29
52
  ## COMMANDS ##
30
53
 
31
- def help
32
- puts "No command: #{@command}"
33
- puts "TODO: tons of help"
34
- end
35
54
 
36
55
  # start a new scribe directory with skeleton structure
37
56
  def init
57
+ name = ARGV.shift
58
+ die("needs a directory name") if !name
59
+ die("directory already exists") if File.exists?(name)
60
+
61
+ puts "inititalizing #{name}"
62
+ from_stdir = File.join(SCRIBE_ROOT, 'template')
63
+ FileUtils.cp_r from_stdir, name
38
64
  end
39
65
 
40
66
  # check that we have everything needed
41
67
  def check
42
- # look for a2x (asciidoc, latex, xsltproc)
43
- end
68
+ # check for asciidoc
69
+ if !check_can_run('asciidoc')
70
+ puts "asciidoc is not present, please install it for anything to work"
71
+ else
72
+ puts "asciidoc - ok"
73
+ end
44
74
 
45
- BOOK_FILE = 'book.asc'
75
+ # check for xsltproc
76
+ if !check_can_run('xsltproc --version')
77
+ puts "xsltproc is not present, please install it for html generation"
78
+ else
79
+ puts "xsltproc - ok"
80
+ end
46
81
 
47
- OUTPUT_TYPES = ['pdf', 'epub', 'mobi', 'html', 'site']
82
+ # check for a2x - should be installed with asciidoc, but you never know
83
+ if !check_can_run('a2x')
84
+ puts "a2x is not present, please install it for epub generation"
85
+ else
86
+ puts "a2x - ok"
87
+ end
88
+
89
+ # check for fop
90
+ if !check_can_run('fop -version')
91
+ puts "fop is not present, please install for PDF generation"
92
+ else
93
+ puts "fop - ok"
94
+ end
95
+ end
48
96
 
97
+ def check_can_run(command)
98
+ `#{command} 2>&1`
99
+ $?.exitstatus == 0
100
+ end
49
101
  # generate the new media
50
102
  def gen
51
- type = @args.shift || 'all'
103
+ type = ARGV.shift || 'all'
52
104
  prepare_output_dir
53
105
 
54
106
  gather_and_process
@@ -66,8 +118,7 @@ class GitScribe
66
118
  end
67
119
  end
68
120
  # clean up
69
- # `rm #{BOOK_FILE}`
70
- # TODO: open media (?)
121
+ `rm #{BOOK_FILE}`
71
122
  end
72
123
  end
73
124
 
data/lib/subcommand.rb ADDED
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env ruby -w
2
+ ######################################
3
+ # A tiny wrapper over optparse that gives easy subcommand facility.
4
+ # It also neatly prints help for global and subcommands
5
+ # as well as summarizes subcommands in global help.
6
+ #
7
+ # Thanks to Robert Klemme for his idea on lazy loading the subcommand option parsers.
8
+ #
9
+ # @author Rahul Kumar, Jun 2010
10
+ # @date 2010-06-20 22:33
11
+ #
12
+ # @examples
13
+ # if a program has subcommands foo and baz
14
+ #
15
+ # ruby subcommand.rb help
16
+ # ruby subcommand.rb --help
17
+ # ruby subcommand.rb help foo
18
+ # ruby subcommand.rb foo --help
19
+ # ruby subcommand.rb baz --quiet "some text"
20
+ # ruby subcommand.rb --verbose foo --force file.zzz
21
+ #
22
+ # == STEPS
23
+ # 1. define global_options (optional)
24
+ #
25
+ # global_options do |opts|
26
+ # opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
27
+ # opts.description = "Stupid program that does something"
28
+ # opts.separator ""
29
+ # opts.separator "Global options are:"
30
+ # opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
31
+ # options[:verbose] = v
32
+ # end
33
+ # end
34
+ #
35
+ # 2. define commands using command().
36
+ # command :foo do |opts|
37
+ # opts.banner = "Usage: foo [options]"
38
+ # opts.description = "desc for foo"
39
+ # opts.on("-f", "--[no-]force", "force verbosely") do |v|
40
+ # options[:force] = v
41
+ # end
42
+ # end
43
+ #
44
+ # 3. call opt_parse()
45
+ #
46
+ # 4. As before, handle ARGS and options hash.
47
+ #
48
+ # TODO: add aliases for commands
49
+ ######################################
50
+ require 'optparse'
51
+
52
+ # Allow command to have a description to generate help
53
+ class OptionParser
54
+ attr_accessor :description
55
+ #attr_accessor :action
56
+ end
57
+
58
+ module Subcommands
59
+ ##
60
+ # specify a single command and all its options
61
+ # If multiple names are given, they are treated as aliases.
62
+ # Do repeatedly for each command
63
+ # Yields the optionparser
64
+ def command *names
65
+ name = names.shift
66
+ @commands ||= {}
67
+ @aliases ||= {}
68
+ if names.length > 0
69
+ names.each do |n|
70
+ #puts "aliases #{n} => #{name} "
71
+ @aliases[n.to_s] = name.to_s
72
+ end
73
+ end
74
+ # Thanks to Robert Klemme for the lazy loading idea.
75
+ opt = lambda { OptionParser.new do |opts|
76
+ yield opts
77
+ # append desc to banner in next line
78
+ opts.banner << "\n#{opts.description}\n" if opts.description
79
+ end }
80
+ @commands[name.to_s] = opt
81
+ end
82
+ # specify global options and banner and description
83
+ # Yields the optionparser
84
+ def global_options
85
+ if !defined? @global
86
+ @global = OptionParser.new do |opts|
87
+ yield opts
88
+ end
89
+ else
90
+ yield @global
91
+ end
92
+ end
93
+ def print_actions
94
+ cmdtext = "Commands are:"
95
+ @commands.each_pair do |c, opt|
96
+ #puts "inside opt.call loop"
97
+ desc = opt.call.description
98
+ cmdtext << "\n #{c} : #{desc}"
99
+ end
100
+
101
+ # print aliases
102
+ unless @aliases.empty?
103
+ cmdtext << "\n\nAliases: \n"
104
+ @aliases.each_pair { |name, val| cmdtext << " #{name} - #{val}\n" }
105
+ end
106
+
107
+ cmdtext << "\n\nSee '#{$0} help COMMAND' for more information on a specific command."
108
+ end
109
+ ## add text of subcommands in help and --help option
110
+ def add_subcommand_help
111
+ # user has defined some, but lets add subcommand information
112
+
113
+ cmdtext = print_actions
114
+
115
+ global_options do |opts|
116
+ # lets add the description user gave into banner
117
+ opts.banner << "\n#{opts.description}\n" if opts.description
118
+ opts.separator ""
119
+ opts.separator cmdtext
120
+ end
121
+ end
122
+ # this is so that on pressing --help he gets same subcommand help as when doing help.
123
+ # This is to be added in your main program, after defining global options
124
+ # if you want detailed help on --help. This is since optionparser's default
125
+ # --help will not print your actions/commands
126
+ def add_help_option
127
+ global_options do |opts|
128
+ opts.on("-h", "--help", "Print this help") do |v|
129
+ add_subcommand_help
130
+ puts @global
131
+ exit
132
+ end
133
+ end
134
+ end
135
+ # first parse global optinos
136
+ # then parse subcommand options if valid subcommand
137
+ # special case of "help command" so we print help of command - git style (3)
138
+ # in all invalid cases print global help
139
+ # @return command name if relevant
140
+ def opt_parse
141
+ # if user has not defined global, we need to create it
142
+ @command_name = nil
143
+ if !defined? @global
144
+ global_options do |opts|
145
+ opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
146
+ opts.separator ""
147
+ opts.separator "Global options are:"
148
+ opts.on("-h", "--help", "Print this help") do |v|
149
+ add_subcommand_help
150
+ puts @global
151
+ exit
152
+ end
153
+ opts.separator ""
154
+ #opts.separator subtext # FIXME: no such variable supposed to have subcommand help
155
+ end
156
+ else
157
+ end
158
+ @global.order!
159
+ cmd = ARGV.shift
160
+ if cmd
161
+ #$stderr.puts "Command: #{cmd}, args:#{ARGV}, #{@commands.keys} "
162
+ sc = @commands[cmd]
163
+ #puts "sc: #{sc}: #{@commands}"
164
+ unless sc
165
+ # see if an alias exists
166
+ sc, cmd = _check_alias cmd
167
+ end
168
+ # if valid command parse the args
169
+ if sc
170
+ @command_name = cmd
171
+ sc.call.order!
172
+ else
173
+ # else if help <command> then print its help GIT style (3)
174
+ if !ARGV.empty? && cmd == "help"
175
+ cmd = ARGV.shift
176
+ #$stderr.puts " 110 help #{cmd}"
177
+ sc = @commands[cmd]
178
+ # if valid command print help, else print global help
179
+ unless sc
180
+ sc, cmd = _check_alias cmd
181
+ end
182
+ if sc
183
+ #puts " 111 help #{cmd}"
184
+ puts sc.call
185
+ else
186
+ # no help for this command XXX check for alias
187
+ puts "Invalid command: #{cmd}."
188
+ add_subcommand_help
189
+ puts @global
190
+ end
191
+ else
192
+ # invalid command
193
+ puts "Invalid command: #{cmd}" unless cmd == "help"
194
+ add_subcommand_help
195
+ puts @global
196
+ end
197
+ exit 0
198
+ end
199
+ end
200
+ return @command_name
201
+ end
202
+ def alias_command name, *args
203
+ @aliases[name.to_s] = args
204
+ end
205
+ def _check_alias cmd
206
+ alas = @aliases[cmd]
207
+ #$stderr.puts "195 alas: #{alas} "
208
+ if alas
209
+ case alas
210
+ when Array
211
+ cmd = alas.shift
212
+ #$stderr.puts "Array cmd: #{cmd} "
213
+ ARGV.unshift alas.shift unless alas.empty?
214
+ #$stderr.puts "ARGV #{ARGV} "
215
+ else
216
+ cmd = alas
217
+ end
218
+ end
219
+ sc = @commands[cmd] if cmd
220
+ return sc, cmd
221
+ end
222
+ end
223
+
224
+ if __FILE__ == $PROGRAM_NAME
225
+ include Subcommands
226
+ options = {}
227
+ appname = File.basename($0)
228
+ # global is optional
229
+ global_options do |opts|
230
+ opts.banner = "Usage: #{appname} [options] [subcommand [options]]"
231
+ opts.description = "Stupid program that does something"
232
+ opts.separator ""
233
+ opts.separator "Global options are:"
234
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
235
+ options[:verbose] = v
236
+ end
237
+ end
238
+ add_help_option
239
+ # define a command
240
+ command :foo, :goo do |opts|
241
+ opts.banner = "Usage: foo [options]"
242
+ opts.description = "desc for foo"
243
+ opts.on("-f", "--[no-]force", "force verbosely") do |v|
244
+ options[:force] = v
245
+ end
246
+ end
247
+ command :baz do |opts|
248
+ opts.banner = "Usage: baz [options]"
249
+ opts.description = "desc for baz"
250
+ opts.on("-q", "--[no-]quiet", "quietly run ") do |v|
251
+ options[:quiet] = v
252
+ end
253
+ end
254
+ alias_command :bar, 'baz'
255
+ alias_command :boo, 'foo', '--force'
256
+ alias_command :zoo, 'foo', 'ruby'
257
+
258
+ # do the parsing.
259
+ cmd = opt_parse()
260
+
261
+ puts "cmd: #{cmd}"
262
+ puts "options ......"
263
+ p options
264
+ puts "ARGV:"
265
+ p ARGV
266
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-scribe
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Scott Chacon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-15 00:00:00 -05:00
18
+ date: 2011-02-17 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -29,8 +29,9 @@ extra_rdoc_files: []
29
29
 
30
30
  files:
31
31
  - LICENSE
32
- - README.asc
32
+ - README.asciidoc
33
33
  - lib/git-scribe.rb
34
+ - lib/subcommand.rb
34
35
  - bin/git-scribe
35
36
  has_rdoc: true
36
37
  homepage: http://github.com/schacon/git-scribe