manbook 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+ gem 'activesupport'
6
+ gem 'open4'
7
+ gem 'nokogiri'
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "rake", "0.8.7" # http://stackoverflow.com/questions/6085610
13
+ gem "bundler", "~> 1.0.0"
14
+ gem "jeweler", "~> 1.6.4"
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,25 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.1.1)
5
+ multi_json (~> 1.0)
6
+ git (1.2.5)
7
+ jeweler (1.6.4)
8
+ bundler (~> 1.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ multi_json (1.0.3)
12
+ nokogiri (1.4.3.1)
13
+ open4 (1.3.0)
14
+ rake (0.8.7)
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ activesupport
21
+ bundler (~> 1.0.0)
22
+ jeweler (~> 1.6.4)
23
+ nokogiri
24
+ open4
25
+ rake (= 0.8.7)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Nicholas E. Rabenau
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ manbook -- produces an eBook from man pages
2
+ ============================================
3
+
4
+ ## SYNOPSIS
5
+
6
+ manbook <MANPAGE>
7
+ manbook <MANPAGE1> [<MANPAGE2> ...]
8
+ manbook <MANPAGE> --output <DIRECTORY>
9
+ manbook <MANPAGE1> [<MANPAGE2> ...] --output <DIRECTORY>
10
+ manbook --all --output <DIRECTORY>
11
+
12
+ mktoc <DIRECTORY>
13
+
14
+ ## DESCRIPTION
15
+
16
+ The `manbook` command can be used to produce an eBook from one or more
17
+ man pages.
18
+
19
+ `mktoc` produces table-of-content files, suitable for MOBI files (Kindle,
20
+ etc) from the HTML files in a directory.
21
+
22
+ ## QUICKSTART
23
+
24
+ gem install manbook
25
+ manbook --help
26
+ mktoc --help
27
+
28
+ ## MANPAGE
29
+
30
+ `manbook` expects to be passed the name of one or more man pages. It will
31
+ use the MANPATH environment variable to find the man page and convert it to
32
+ HTML.
33
+
34
+ If more than one man page was passed, an additional index page will be
35
+ created. If the man pages are from different sections, `manbook` will create
36
+ separate indexes by section together with an index file for each section.
37
+
38
+ ## OPTIONS
39
+
40
+ You can specify an individual man page or a list of man pages using a few
41
+ options.
42
+
43
+ * `-o`, `--output`:
44
+ Specifies the output file (when operating on a single man page) or
45
+ the output directory (when operating on multiple man pages) where
46
+ the HTML files will be written to.
47
+
48
+ * `-a`, `--all`:
49
+ Produce a book with all man pages found.
50
+
51
+ See `manbook --help` to view the options at any time.
52
+
53
+ ## INSTALL
54
+
55
+ gem install manbook
56
+
57
+ ## EXAMPLES
58
+
59
+ manbook ls
60
+ manbook ls grep bash --output ./my-favorite-pages/
61
+ manbook -a -o ./manpages/
62
+
63
+ mktoc ./my-favorite-pages/
64
+ mktoc --title "Kindle and the Fourty Amazons" ./my-favorite-pages/
65
+
66
+ # HISTORY #
67
+ After I bought a Kindle, the idea was born to put the man pages of my Mac onto my Kindle. My requirements are:
68
+
69
+ 1. Input should be exactly the man pages on /my/ system, not someone else's FreeBSD or whathever
70
+ 1. Should respect my MANPATH (not just look in /usr/share/man)
71
+ 1. Pages should be as plain-text as possible (no PDF).
72
+ 1. eBook should provide an index with a list of all man pages by section and by name
73
+
74
+ When I looked around for an existing solution, all I found was:
75
+
76
+ * http://askubuntu.com/questions/21903/man-pages-offline-for-e-reader
77
+ * http://www.macgeekery.com/tips/cli/pretty-print_manual_pages_as_ps_pdf_or_html
78
+
79
+ and a few other, not-quite-complete scripts. None of them satisfied my requirements, so I decided to write my own tool. Thus, `manbook` was born.
80
+
81
+ ## BUGS
82
+
83
+ Requires the `groff` script to be in your path and executable.
84
+
85
+ Requires Ruby and RubyGems.
86
+
87
+ Please report other bugs at <http://github.com/nerab/manbook/issues>
88
+
89
+ ## CONTRIBUTING
90
+
91
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
92
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
93
+ * Fork the project
94
+ * Start a feature/bugfix branch
95
+ * Commit and push until you are happy with your contribution
96
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
97
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
98
+
99
+ ## COPYRIGHT
100
+
101
+ manbook is Copyright (C) 2011 Nicolas E. Rabenau. See LICENSE.txt for further details.
102
+
103
+ ## SEE ALSO
104
+
105
+ groff(1), <http://en.wikipedia.org/wiki/Man_page>, [mail2kindle](https://gist.github.com/1410840)
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "manbook"
18
+ gem.homepage = "http://github.com/nerab/manbook"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Produces an eBook from man pages}
21
+ gem.description = %Q{The manbook command can be used to produce an eBook from one or more man pages.}
22
+ gem.email = "nerab@gmx.net"
23
+ gem.authors = ["Nicholas E. Rabenau"]
24
+ gem.executables << 'manbook'
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ task :default => :test
37
+
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "manbook #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ * Do not overwrite existing files unless --force was given
2
+ * Potentially list authors
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/manbook ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'rubygems'
6
+
7
+ help = <<HELP
8
+ The manbook command can be used to produce an eBook from one or more man pages.
9
+
10
+ Author: Nicolas E. Rabenau nerab@gmx.at
11
+ Homepage: http://rubydoc.info/gems/manbook/file/README.md
12
+
13
+ Basic Usage:
14
+
15
+ manbook <MANPAGE>
16
+ manbook <MANPAGE1> [<MANPAGE2> ...]
17
+ manbook <MANPAGE> --output <DIRECTORY>
18
+ manbook <MANPAGE1> [<MANPAGE2> ...] --output <DIRECTORY>
19
+ manbook --all --output <DIRECTORY>
20
+
21
+ Options:
22
+ HELP
23
+
24
+ def usage
25
+ "Run '#{File.basename(__FILE__)} --help' for further help."
26
+ end
27
+
28
+ require 'optparse'
29
+ require 'manbook'
30
+
31
+ output_dir = '.'
32
+
33
+ opts = OptionParser.new do |opts|
34
+ opts.banner = help
35
+
36
+ opts.on("--verbose", "Verbose mode - displays additional diagnostic information") do |file|
37
+ ManBook.logger = Logger.new(STDERR)
38
+ ManBook.logger.formatter = ManBook::LogFormatter.new
39
+ ManBook.logger.level = Logger::INFO
40
+ end
41
+
42
+ opts.on("--trace", "Trace (debug) mode - displays debug information and stack traces") do |file|
43
+ ManBook.logger = Logger.new(STDERR)
44
+ ManBook.logger.formatter = ManBook::LogFormatter.new
45
+ ManBook.logger.level = Logger::DEBUG
46
+ end
47
+
48
+ opts.on("--version", "Display current version") do
49
+ puts "#{File.basename(__FILE__)} " + ManBook::VERSION
50
+ exit 0
51
+ end
52
+
53
+ opts.on("--all", "Create a book with all man pages") do |dir|
54
+ ManBook.logger.info "Creating a book with all man pages"
55
+ raise "Not yet implemented"
56
+ end
57
+
58
+ opts.on("--output DIR", "Use DIR as output directory") do |dir|
59
+ ManBook.logger.info "Using '#{dir}' as output directory"
60
+ output_dir = dir
61
+ unless File.exist?(output_dir)
62
+ ManBook.logger.info "Creating output directory as it does not exist yet: #{output_dir}"
63
+ Dir.mkdir(output_dir)
64
+ end
65
+ end
66
+ end
67
+
68
+ begin
69
+ opts.parse!
70
+
71
+ raise "Which man page do you want to convert?" if ARGV.empty?
72
+
73
+ ARGV.each{|man_page|
74
+ html_file = File.join(output_dir, "#{File.basename(man_page)}.html")
75
+ ManBook.logger.debug("Output page is #{html_file}")
76
+
77
+ begin
78
+ ManBook::HtmlFormatter.new(man_page).convert(html_file)
79
+ rescue ManBook::ManPageNotFoundError => e
80
+ ManBook.logger.error e.message
81
+ ManBook.logger.debug "Backtrace:\n#{e.backtrace.join("\n")}"
82
+ end
83
+ }
84
+ rescue
85
+ ManBook.logger.error $!.message
86
+ ManBook.logger.debug "Backtrace:\n#{$!.backtrace.join("\n")}"
87
+ ManBook.logger.info usage
88
+ exit(1)
89
+ end
data/bin/mktoc ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'rubygems'
6
+
7
+ help = <<HELP
8
+ Creates table of contents (TOC) files for all HTML files in a directory. This
9
+ tool was built to prepare HTML pages for the Kindle.
10
+
11
+ Author: Nicolas E. Rabenau nerab@gmx.at
12
+ Homepage: http://rubydoc.info/gems/manbook/file/README.md
13
+
14
+ Basic Usage:
15
+
16
+ mktoc <DIRECTORY>
17
+
18
+ Options:
19
+ HELP
20
+
21
+ def usage
22
+ "Run '#{File.basename(__FILE__)} --help' for further help."
23
+ end
24
+
25
+ require 'optparse'
26
+ require 'manbook'
27
+ require 'erb'
28
+
29
+ INDEX_HTML = 'index.html'
30
+ ABOUT_HTML = 'about.html'
31
+ INDEX_OPF = 'index.opf'
32
+ INDEX_NCX = 'index.ncx'
33
+ OUTPUT_FILE = 'manbook.mobi'
34
+ GENERATOR = "#{File.basename(__FILE__)} v#{ManBook::VERSION}"
35
+
36
+ # defaults
37
+ @book_title = ManBook::TITLE_DEFAULT
38
+ @cover_image = ManBook::COVER_IMAGE_DEFAULT
39
+
40
+ opts = OptionParser.new do |opts|
41
+ opts.banner = help
42
+
43
+ opts.on("--verbose", "Verbose mode - displays additional diagnostic information") do |file|
44
+ ManBook.logger = Logger.new(STDERR)
45
+ ManBook.logger.formatter = ManBook::LogFormatter.new
46
+ ManBook.logger.level = Logger::INFO
47
+ end
48
+
49
+ opts.on("--trace", "Trace (debug) mode - displays debug information and stack traces") do |file|
50
+ ManBook.logger = Logger.new(STDERR)
51
+ ManBook.logger.formatter = ManBook::LogFormatter.new
52
+ ManBook.logger.level = Logger::DEBUG
53
+ end
54
+
55
+ opts.on("--version", "Display current version") do
56
+ puts "#{File.basename(__FILE__)} " + ManBook::VERSION
57
+ exit 0
58
+ end
59
+
60
+ opts.on("--title STRING", "Use TITLE as book title") do |title|
61
+ ManBook.logger.info "Setting book title to '#{title}'"
62
+ @book_title = title
63
+ end
64
+
65
+ opts.on("--cover-image FILE", "Reference a cover image") do |cover_image|
66
+ ManBook.logger.info "Cover image set to #{cover_image}"
67
+ @cover_image = cover_image
68
+ end
69
+
70
+ opts.on("--no-cover-image", "Do not reference a cover image") do
71
+ @cover_image = nil
72
+ end
73
+ end
74
+
75
+ def render(template, my_binding = binding)
76
+ ERB.new(File.new(File.join(File.dirname(__FILE__), '..', 'templates', template)), 0, "%<>").result(my_binding)
77
+ end
78
+
79
+ begin
80
+ opts.parse!
81
+
82
+ raise "Directory argument missing" if ARGV.empty?
83
+ src_dir = ARGV.first
84
+ ManBook.logger.debug("Operating in directory #{src_dir}")
85
+
86
+ if @cover_image.nil?
87
+ ManBook.logger.debug("No cover image will be used")
88
+ else
89
+ ManBook.logger.debug("Using cover image #{@cover_image}")
90
+ raise "Could not find cover image" unless File.exist?(@cover_image)
91
+ FileUtils.cp(@cover_image, src_dir)
92
+
93
+ # continue working with the copy
94
+ @cover_image = File.basename(@cover_image)
95
+ end
96
+
97
+ # We generate about.html first so it is going to be picked up by the file finder
98
+ File.open(File.join(src_dir, ABOUT_HTML), 'w') {|f|
99
+ # Override page title. Would love to use a local here, but calling render with binding at this stage fails.
100
+ @title = "About this book"
101
+
102
+ f.write(render('application.html.erb'){
103
+ render('about.html.erb')
104
+ })
105
+
106
+ # undefine title
107
+ remove_instance_variable(:@title)
108
+ }
109
+
110
+ # find pages
111
+ @pages = Dir.glob(File.join(src_dir, "*.html")).reject{|f| INDEX_HTML == File.basename(f)}.collect{|html_file|
112
+ ManBook::Parser.parse(html_file)
113
+ }.sort{|l,r| l[:title] <=> r[:title]}
114
+
115
+ # index.html
116
+ File.open(File.join(src_dir, INDEX_HTML), 'w') {|f|
117
+ @title = "Table Of Contents"
118
+ f.write(render('application.html.erb'){
119
+ render('index.html.erb'){
120
+ @pages.collect{|page|
121
+ begin
122
+ render('_page.html.erb', binding)
123
+ rescue
124
+ ManBook.logger.error $!.message
125
+ ManBook.logger.debug "Backtrace:\n#{$!.backtrace.join("\n")}"
126
+ end
127
+ }.join
128
+ }
129
+ })
130
+ remove_instance_variable(:@title)
131
+ }
132
+
133
+ # opf file
134
+ # TODO add index.html so that the pseudo toc shows index.html, but index.html does not link to itself
135
+ File.open(File.join(src_dir, INDEX_OPF), 'w') {|f|
136
+ f.write(render('manbook.opf.erb'))
137
+ }
138
+
139
+ # ncx file
140
+ File.open(File.join(src_dir, INDEX_NCX), 'w') {|f|
141
+ f.write(render('manbook.ncx.erb'))
142
+ }
143
+
144
+ # print message how to call kindlegen
145
+ ManBook.logger.info "Successfully finished building the book in #{src_dir}"
146
+ ManBook.logger.info 'Call the following command in order to convert your book into the Kindle format:'
147
+ ManBook.logger.info
148
+ ManBook.logger.info " kindlegen #{File.join(src_dir, INDEX_OPF)} -o #{OUTPUT_FILE}"
149
+ ManBook.logger.info
150
+ ManBook.logger.info "After that, the book will appear as #{File.join(src_dir, OUTPUT_FILE)}. You can"
151
+ ManBook.logger.info "then open it with the Kindle app or mail it to your kindle."
152
+ rescue
153
+ ManBook.logger.error $!.message
154
+ ManBook.logger.debug "Backtrace:\n#{$!.backtrace.join("\n")}"
155
+ ManBook.logger.info usage
156
+ exit(1)
157
+ end