git-scribe 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/LICENSE +22 -0
  2. data/README.asc +67 -0
  3. data/bin/git-scribe +6 -0
  4. data/lib/git-scribe.rb +294 -0
  5. metadata +70 -0
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2007-2009 Scott Chacon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.asc ADDED
@@ -0,0 +1,67 @@
1
+ Git Scribe
2
+ ==========
3
+
4
+ The git-scribe tool is a simple command line toolset to help you use Git, GitHub and Asciidoc
5
+ to write e-books. This provides tools for setting up the structure, collaborating with co-authors, doing technical and copy-editing, handling translations, taking errata, as well as publishing online, pdf, mobi (Kindle) and epub (iBooks, Nook) versions.
6
+
7
+ The project is targeted for writing books of any length, but should also be usable for articles and stuff too, though for a while you'll have to just do it as a really short book.
8
+
9
+ Features
10
+ ========
11
+
12
+ Eventually, these are the feature goals for the project:
13
+
14
+ * Easy: Syntax-Highlighted Code, Formula, Diagrams
15
+ * Site Generation: Comment, Search, Permalinks
16
+ * Pegging versions of the book to versions of the tool it documents
17
+ * Technical and Copy editing workflow tools
18
+ * Translation workflow tools
19
+ * Selling (possibly): Kindle, iBooks, Lulu, Pledgie(?)
20
+
21
+ The idea is that you use the tool to generate a known structure, write in asciidoc and let the tool handle everything else for you. I want authors to be able to focus on writing and not have to worry about anything else.
22
+
23
+ A good AsciiDoc cheat sheet: http://powerman.name/doc/asciidoc#_text
24
+
25
+ Disclaimer
26
+ ==========
27
+
28
+ This tool is a work in progress. At the 1.0 release, this file will be totally up to date, but for now I may have documented some stuff that doesn't yet work. Contact me personally if you are interested in working on it.
29
+
30
+ Installing
31
+ ==========
32
+
33
+ You can install git-scribe via RubyGems.
34
+
35
+ $ gem install git-scribe
36
+
37
+ For local generation (evenutally pushing to GitHub will handle gen for you), it depends on a couple things like:
38
+
39
+ * Ruby
40
+ * asciidoc, a2x
41
+ * xslt stuff
42
+ * FOP for PDF gen
43
+
44
+ Usage
45
+ =====
46
+
47
+ Initialize a new book with `init` (not yet completed).
48
+
49
+ $ git scribe init
50
+
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
+
53
+ $ git scribe gen [site|html|pdf|epub|mobi|all]
54
+
55
+ Roadmap
56
+ =======
57
+
58
+ See the_dream.asc for what this file should look like eventually.
59
+
60
+ Contributing
61
+ ============
62
+
63
+ If you want to hack on this, fork it, improve it and send me a pull request.
64
+
65
+ To get started using it, just clone it and call the ./bin/git-scribe script directly from either the `example` subdir or your own book directory. If you add a feature, make sure it's included in the example subdirectory so I can test it out.
66
+
67
+
data/bin/git-scribe ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'git-scribe'
5
+
6
+ GitScribe.start(ARGV)
data/lib/git-scribe.rb ADDED
@@ -0,0 +1,294 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+ require 'liquid'
4
+
5
+ require 'fileutils'
6
+ require 'pp'
7
+
8
+ class GitScribe
9
+
10
+ SCRIBE_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
11
+
12
+ def initialize(args)
13
+ @command = args.shift
14
+ @args = args
15
+ end
16
+
17
+ def self.start(args)
18
+ GitScribe.new(args).run
19
+ end
20
+
21
+ def run
22
+ if @command && self.respond_to?(@command)
23
+ self.send @command
24
+ else
25
+ help
26
+ end
27
+ end
28
+
29
+ ## COMMANDS ##
30
+
31
+ def help
32
+ puts "No command: #{@command}"
33
+ puts "TODO: tons of help"
34
+ end
35
+
36
+ # start a new scribe directory with skeleton structure
37
+ def init
38
+ end
39
+
40
+ # check that we have everything needed
41
+ def check
42
+ # look for a2x (asciidoc, latex, xsltproc)
43
+ end
44
+
45
+ BOOK_FILE = 'book.asc'
46
+
47
+ OUTPUT_TYPES = ['pdf', 'epub', 'mobi', 'html', 'site']
48
+
49
+ # generate the new media
50
+ def gen
51
+ type = @args.shift || 'all'
52
+ prepare_output_dir
53
+
54
+ gather_and_process
55
+
56
+ types = type == 'all' ? OUTPUT_TYPES : [type]
57
+
58
+ output = []
59
+ Dir.chdir("output") do
60
+ types.each do |out_type|
61
+ call = 'do_' + out_type
62
+ if self.respond_to? call
63
+ self.send call
64
+ else
65
+ puts "NOT A THING: #{call}"
66
+ end
67
+ end
68
+ # clean up
69
+ # `rm #{BOOK_FILE}`
70
+ # TODO: open media (?)
71
+ end
72
+ end
73
+
74
+ def prepare_output_dir
75
+ Dir.mkdir('output') rescue nil
76
+ Dir.chdir('output') do
77
+ Dir.mkdir('stylesheets') rescue nil
78
+ puts SCRIBE_ROOT
79
+ from_stdir = File.join(SCRIBE_ROOT, 'stylesheets')
80
+ pp from_stdir
81
+ FileUtils.cp_r from_stdir, '.'
82
+ end
83
+ end
84
+
85
+ def a2x(type)
86
+ "a2x -f #{type} -d book "
87
+ end
88
+
89
+ def a2x_wss(type)
90
+ a2x(type) + " --stylesheet=stylesheets/handbookish.css"
91
+ end
92
+
93
+ def do_pdf
94
+ puts "GENERATING PDF"
95
+ # TODO: syntax highlighting (fop?)
96
+ puts `asciidoc -b docbook #{BOOK_FILE}`
97
+ strparams = {'callout.graphics' => 0,
98
+ 'navig.graphics' => 0,
99
+ 'admon.textlabel' => 1,
100
+ 'admon.graphics' => 0}
101
+ param = strparams.map { |k, v| "--stringparam #{k} #{v}" }.join(' ')
102
+ puts cmd = "xsltproc --nonet #{param} --output #{local('book.fo')} #{base('docbook-xsl/fo.xsl')} #{local('book.xml')}"
103
+ puts `#{cmd}`
104
+ cmd = "fop -fo #{local('book.fo')} -pdf #{local('book.pdf')}"
105
+ puts `#{cmd}`
106
+ #puts `#{a2x('pdf')} -v --fop #{BOOK_FILE}`
107
+ if $?.exitstatus == 0
108
+ 'book.pdf'
109
+ end
110
+ end
111
+
112
+ def local(file)
113
+ File.expand_path(File.join(Dir.pwd, file))
114
+ end
115
+
116
+ def base(file)
117
+ File.join(SCRIBE_ROOT, file)
118
+ end
119
+
120
+ def do_epub
121
+ puts "GENERATING EPUB"
122
+ # TODO: look for custom stylesheets
123
+ `#{a2x_wss('epub')} -v #{BOOK_FILE}`
124
+ puts 'exit status', $?.exitstatus
125
+ 'book.epub'
126
+ end
127
+
128
+ def do_html
129
+ puts "GENERATING HTML"
130
+ # TODO: look for custom stylesheets
131
+ #puts `#{a2x_wss('xhtml')} -v #{BOOK_FILE}`
132
+ styledir = local('stylesheets')
133
+ puts cmd = "asciidoc -a stylesdir=#{styledir} -a theme=handbookish #{BOOK_FILE}"
134
+ `#{cmd}`
135
+ puts 'exit status', $?.exitstatus
136
+ 'book.html'
137
+ end
138
+
139
+ def do_site
140
+ puts "GENERATING SITE"
141
+ # TODO: check if html was already done
142
+ puts `asciidoc -b docbook #{BOOK_FILE}`
143
+ xsldir = base('docbook-xsl/xhtml')
144
+ `xsltproc --stringparam html.stylesheet stylesheets/handbookish.css --nonet #{xsldir}/chunk.xsl book.xml`
145
+
146
+ source = File.read('index.html')
147
+ html = Nokogiri::HTML.parse(source, nil, 'utf-8')
148
+
149
+ sections = []
150
+ c = -1
151
+
152
+ # each chapter
153
+ html.css('.toc > dl').each do |section|
154
+ section.children.each do |item|
155
+ if item.name == 'dt' # section
156
+ c += 1
157
+ sections[c] ||= {'number' => c}
158
+ link = item.css('a').first
159
+ sections[c]['title'] = title = link.text
160
+ sections[c]['href'] = href = link['href']
161
+ clean_title = title.downcase.gsub(/[^a-z0-9\-_]+/, '_') + '.html'
162
+ sections[c]['link'] = clean_title
163
+ if href[0, 10] == 'index.html'
164
+ sections[c]['link'] = 'title.html'
165
+ end
166
+ sections[c]['sub'] = []
167
+ end
168
+ if item.name == 'dd' # subsection
169
+ item.css('dt').each do |sub|
170
+ link = sub.css('a').first
171
+ data = {}
172
+ data['title'] = title = link.text
173
+ data['href'] = href = link['href']
174
+ data['link'] = sections[c]['link'] + '#' + href.split('#').last
175
+ sections[c]['sub'] << data
176
+ end
177
+ end
178
+ end
179
+ puts
180
+ end
181
+
182
+ pp sections
183
+
184
+ book_title = html.css('head > title').text
185
+ content = html.css('body > div')[1]
186
+ content.css('.toc').first.remove
187
+ content = content.inner_html
188
+
189
+ puts content
190
+ sections.each do |s|
191
+ content.gsub!(s['href'], s['link'])
192
+ end
193
+
194
+ template_dir = File.join(SCRIBE_ROOT, 'site', 'default')
195
+
196
+ # copy the template files in
197
+ files = Dir.glob(template_dir + '/*')
198
+ FileUtils.cp_r files, '.'
199
+
200
+ Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_dir)
201
+ index_template = Liquid::Template.parse(File.read(File.join(template_dir, 'index.html')))
202
+ page_template = Liquid::Template.parse(File.read(File.join(template_dir, 'page.html')))
203
+
204
+ # write the index page
205
+ main_data = {
206
+ 'book_title' => book_title,
207
+ 'sections' => sections
208
+ }
209
+ File.open('index.html', 'w+') do |f|
210
+ f.puts index_template.render( main_data )
211
+ end
212
+
213
+ # write the title page
214
+ File.open('title.html', 'w+') do |f|
215
+ data = {
216
+ 'title' => sections.first['title'],
217
+ 'sub' => sections.first['sub'],
218
+ 'prev' => {'link' => 'index.html', 'title' => "Main"},
219
+ 'home' => {'link' => 'index.html', 'title' => "Home"},
220
+ 'next' => sections[1],
221
+ 'content' => content
222
+ }
223
+ data.merge!(main_data)
224
+ f.puts page_template.render( data )
225
+ end
226
+
227
+ # write the other pages
228
+ sections.each_with_index do |section, i|
229
+
230
+ if i > 0 # skip title page
231
+ source = File.read(section['href'])
232
+ html = Nokogiri::HTML.parse(source, nil, 'utf-8')
233
+
234
+ content = html.css('body > div')[1].to_html
235
+ sections.each do |s|
236
+ content.gsub!(s['href'], s['link'])
237
+ end
238
+
239
+ File.open(section['link'], 'w+') do |f|
240
+ next_section = nil
241
+ if i <= sections.size
242
+ next_section = sections[i+1]
243
+ end
244
+ data = {
245
+ 'title' => section['title'],
246
+ 'sub' => section['sub'],
247
+ 'prev' => sections[i-1],
248
+ 'home' => {'link' => 'index.html', 'title' => "Home"},
249
+ 'next' => next_section,
250
+ 'content' => content
251
+ }
252
+ data.merge!(main_data)
253
+ f.puts page_template.render( data )
254
+ end
255
+ #File.unlink(section['href'])
256
+
257
+ puts i
258
+ puts section['title']
259
+ puts section['href']
260
+ puts section['link']
261
+ puts
262
+ end
263
+
264
+ #File.unlink
265
+ end
266
+ end
267
+
268
+
269
+ # create a new file by concatenating all the ones we find
270
+ def gather_and_process
271
+ files = Dir.glob("book/*")
272
+ FileUtils.cp_r files, 'output'
273
+ end
274
+
275
+ # DISPLAY HELPER FUNCTIONS #
276
+
277
+ def l(info, size)
278
+ clean(info)[0, size].ljust(size)
279
+ end
280
+
281
+ def r(info, size)
282
+ clean(info)[0, size].rjust(size)
283
+ end
284
+
285
+ def clean(info)
286
+ info.to_s.gsub("\n", ' ')
287
+ end
288
+
289
+ # API/DATA HELPER FUNCTIONS #
290
+
291
+ def git(command)
292
+ `git #{command}`.chomp
293
+ end
294
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-scribe
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Scott Chacon
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-15 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: " git-scribe is a workflow tool for starting, writing, reviewing and publishing\n multiple forms of a book. it allows you to use asciidoc plain text markup to\n write, review and translate a work and provides a simple toolkit for generating\n common digital outputs for publishing - epub, mobi, pdf and html. it is also\n integrated into github functionality, letting you automate the publishing and\n collaboration process.\n"
23
+ email: schacon@gmail.com
24
+ executables:
25
+ - git-scribe
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - LICENSE
32
+ - README.asc
33
+ - lib/git-scribe.rb
34
+ - bin/git-scribe
35
+ has_rdoc: true
36
+ homepage: http://github.com/schacon/git-scribe
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 3
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.7
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: git-scribe is an authors toolkit for writing and publishing books
69
+ test_files: []
70
+