rpub 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +5 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +6 -0
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +51 -0
  7. data/Guardfile +5 -0
  8. data/HISTORY.md +5 -0
  9. data/LICENSE +0 -0
  10. data/README.md +182 -0
  11. data/Rakefile +11 -0
  12. data/bin/rpub +6 -0
  13. data/example/advanced/README +1 -0
  14. data/example/advanced/config.yml +11 -0
  15. data/example/advanced/layout.html +0 -0
  16. data/example/advanced/styles.css +0 -0
  17. data/example/simple/01-introduction.md +3 -0
  18. data/example/simple/02-foo.md +4 -0
  19. data/example/simple/03-bar.md +4 -0
  20. data/example/simple/config.yml +8 -0
  21. data/lib/rpub.rb +53 -0
  22. data/lib/rpub/book.rb +70 -0
  23. data/lib/rpub/chapter.rb +84 -0
  24. data/lib/rpub/commander.rb +14 -0
  25. data/lib/rpub/commands/base.rb +33 -0
  26. data/lib/rpub/commands/clean.rb +55 -0
  27. data/lib/rpub/commands/compile.rb +56 -0
  28. data/lib/rpub/commands/help.rb +37 -0
  29. data/lib/rpub/commands/main.rb +45 -0
  30. data/lib/rpub/commands/package.rb +45 -0
  31. data/lib/rpub/commands/preview.rb +56 -0
  32. data/lib/rpub/compilation_helpers.rb +43 -0
  33. data/lib/rpub/compressor.rb +46 -0
  34. data/lib/rpub/epub.rb +37 -0
  35. data/lib/rpub/epub/container.rb +14 -0
  36. data/lib/rpub/epub/content.rb +80 -0
  37. data/lib/rpub/epub/cover.rb +27 -0
  38. data/lib/rpub/epub/html_toc.rb +25 -0
  39. data/lib/rpub/epub/toc.rb +35 -0
  40. data/lib/rpub/hash_delegation.rb +23 -0
  41. data/lib/rpub/subclass_tracker.rb +53 -0
  42. data/lib/rpub/version.rb +3 -0
  43. data/lib/rpub/xml_file.rb +14 -0
  44. data/rpub.gemspec +52 -0
  45. data/spec/fixtures/clean/config.yml +2 -0
  46. data/spec/fixtures/clean/example.epub +0 -0
  47. data/spec/fixtures/clean/preview.html +0 -0
  48. data/spec/fixtures/no_files/config.yml +0 -0
  49. data/spec/fixtures/preview/a.md +1 -0
  50. data/spec/fixtures/preview/b.md +1 -0
  51. data/spec/fixtures/preview/config.yml +2 -0
  52. data/spec/rpub/book_spec.rb +62 -0
  53. data/spec/rpub/chapter_spec.rb +61 -0
  54. data/spec/rpub/commands/clean_spec.rb +46 -0
  55. data/spec/rpub/commands/main_spec.rb +26 -0
  56. data/spec/rpub/commands/preview_spec.rb +42 -0
  57. data/spec/rpub_spec.rb +7 -0
  58. data/spec/spec_helper.rb +21 -0
  59. data/support/layout.html +22 -0
  60. data/support/styles.css +66 -0
  61. metadata +310 -0
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ doc
2
+ .yardoc
3
+ bin/*
4
+ !bin/rpub
5
+ .bundle
6
+ .DS_Store
7
+ *~
8
+ pkg
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --format progress
2
+ --color
3
+ -Ilib
4
+ -Ispec
5
+ -r spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --no-private
2
+ --title "rPub, a simple ePub generator library in Ruby"
3
+ --readme README.md
4
+ -
5
+ HISTORY.md
6
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rpub (0.1.0)
5
+ builder
6
+ kramdown
7
+ rubyzip
8
+ typogruby
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ builder (3.0.0)
14
+ diff-lcs (1.1.3)
15
+ ffi (1.0.11)
16
+ growl (1.0.3)
17
+ guard (1.0.1)
18
+ ffi (>= 0.5.0)
19
+ thor (~> 0.14.6)
20
+ guard-rspec (0.7.0)
21
+ guard (>= 0.10.0)
22
+ kramdown (0.13.5)
23
+ rake (0.9.2.2)
24
+ rb-fsevent (0.9.1)
25
+ rspec (2.9.0)
26
+ rspec-core (~> 2.9.0)
27
+ rspec-expectations (~> 2.9.0)
28
+ rspec-mocks (~> 2.9.0)
29
+ rspec-core (2.9.0)
30
+ rspec-expectations (2.9.1)
31
+ diff-lcs (~> 1.1.3)
32
+ rspec-mocks (2.9.0)
33
+ rubypants (0.2.0)
34
+ rubyzip (0.9.7)
35
+ thor (0.14.6)
36
+ typogruby (1.0.15)
37
+ rubypants
38
+ yard (0.7.5)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ growl
45
+ guard
46
+ guard-rspec
47
+ rake
48
+ rb-fsevent
49
+ rpub!
50
+ rspec
51
+ yard
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/HISTORY.md ADDED
@@ -0,0 +1,5 @@
1
+ # History
2
+
3
+ ## 0.1.0
4
+
5
+ * Initial gem release
data/LICENSE ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # rPub -- an ePub generator in Ruby [![Build Status](https://secure.travis-ci.org/avdgaag/rpub.png?branch=master)](http://travis-ci.org/avdgaag/rpub)
2
+
3
+ **Note** this project is still in development and not yet ready for general use.
4
+
5
+ ## Introduction
6
+
7
+ rPub is a command-line tool that generates a collection of plain text input
8
+ files into an eBook in ePub format. It provides several related functions to
9
+ make working with ePub files a little easier:
10
+
11
+ * Generation of table of contents
12
+ * Tracking of references to tables or figures
13
+ * Validation of output file
14
+ * Packaging your eBook in an archive with additional README file
15
+
16
+ ## Installation
17
+
18
+ rPub is distributed as a Ruby gem, which should be installed on most Macs and
19
+ Linux systems. Once you have ensured you have a working installation of Ruby
20
+ and Ruby gems, install the gem as follows from the command line:
21
+
22
+ $ gem install rpub
23
+
24
+ You can verify the gem has installed correctly by checking its version number:
25
+
26
+ $ rpub -v
27
+
28
+ If this generates an error, something has gone wrong. You should see something
29
+ along the lines of `rpub 1.0.0`.
30
+
31
+ ## Usage
32
+
33
+ ### Basics
34
+
35
+ ePubs are basically collections of HTML files, combined in a single archive
36
+ according to a set of predefined rules. rPub generates these files for you from
37
+ simple text files written in [Markdown][], a very readable markup language created
38
+ by [John Gruber][]. This very README file is an example of a Markdown document.
39
+
40
+ The idea is you write several Markdown files using your favourite text editor,
41
+ and save them as plain text in your project directory. Usually you would write
42
+ one file per chapter. By invoking the `rpub` program you convert those files to
43
+ HTML and combine them in an ePub archive:
44
+
45
+ $ rpub compile
46
+ Generating my-new-book-0.1.0.epub... Done!
47
+
48
+ After you have run the `rpub compile` command, you will find a new `.epub` file
49
+ in your project directory. The name of this file depends on the title of your
50
+ book, and its version number. You can set these values, as well as a few others,
51
+ in a special configuration file called `config.yml`:
52
+
53
+ ---
54
+ author: Your Name
55
+ title: My new book
56
+ version: 0.1.0
57
+
58
+ This file is written in [YAML](http://yaml.org) and sets basic properties of your book project.
59
+
60
+ To make sure the book you generated is _valid_ -- meaning it is likely that most
61
+ readers out there will be able to read it -- you can use the special `validate`
62
+ command:
63
+
64
+ $ rpub validate
65
+
66
+ rPub will report any errors it finds. No output means everything is alright.
67
+
68
+ Since regenerating your ePub file and opening it in a suitable reader
69
+ application is cumbersome, rPub can generate a simple preview document for you:
70
+
71
+ $ rpub preview
72
+
73
+ This will generate a new HTML file in your project directory with a name similar
74
+ to your ePub file. This is the entire text of your book as a single web page for
75
+ easy viewing in any browser.
76
+
77
+ [Markdown]: http://daringfireball.net/projects/markdown
78
+ [John gruber]: http://daringfireball.net
79
+
80
+ ### Advanced features
81
+
82
+ #### Packaging for distribution
83
+
84
+ Often you want to distribute your ebook over the internet, along with some
85
+ extra files. You'll probably want to include a README file, a license or
86
+ references to extra online resources. A `package` task is defined to generate a
87
+ single compressed archive file from your generated ebook along with such
88
+ additional files.
89
+
90
+ You list the files to include with your ebook in your `config.yml` file, along
91
+ with the resulting packaged file name:
92
+
93
+ ---
94
+ package_file: mybook.zip
95
+ package:
96
+ - README
97
+ - license.txt
98
+ - code-samples.rb
99
+
100
+ All the filenames listed under `package` are looked up in the root of your
101
+ project directory. These files will be combined with the ebook in the
102
+ `mybook.zip` file in your project directory.
103
+
104
+ #### Automatic table of contents
105
+
106
+ Rpub automatically generates a table of contents for you, if you want it to. It
107
+ does this by scanning all your markdown files for headings and listing them on
108
+ a single page in the ebook. Each entry in the table of contents is linked to
109
+ its appropriate heading in the chapter, and has various hooks for your
110
+ stylesheet to determine its formatting.
111
+
112
+ To enable the automatic generation of a table of contents, add the following
113
+ configuration to your `config.yml` file:
114
+
115
+ toc: true
116
+
117
+ #### Custom layout and styles
118
+
119
+ When you compile a set of Markdown files to an ePub file, rpub uses a default
120
+ HTML layout and set of styles to determine the look and feel of the book. These
121
+ will do fine for most cases, but you can provide your own, if you are so
122
+ inclined.
123
+
124
+ Simply define a `layout.html` and/or `styles.css` in your project directory.
125
+ Your HTML file will be parsed with Erb, an so you can include your writing
126
+ using the `yield` method:
127
+
128
+ <html>
129
+ <body>
130
+ <%= yield %>
131
+ </body>
132
+ </html>
133
+
134
+ **Note**: despite the name 'html' and `.html` extension, your file actually has
135
+ to be XHTML-compliant.
136
+
137
+ You can also provide custom layouts or styles to use when invoking the `compile`
138
+ or `preview` commands, using the `-l` or `-s` options:
139
+
140
+ $ rpub compile -l /tmp/my-layout.html
141
+
142
+ ### Command reference
143
+
144
+ * `rpub compile` -- generate .epub file
145
+ * `rpub package` -- create zip file with compiled book and other listed files
146
+ * `rpub preview` -- generate preview HTML file
147
+ * `rpub help` -- get help on subcommands
148
+ * `rpub clean` -- remove generated files
149
+
150
+ ### Examples
151
+
152
+ See the [examples directory](https://github.com/avdgaag/rpub/example) for two example projects.
153
+
154
+ ## Other
155
+
156
+ ### Note on Patches/Pull Requests
157
+
158
+ 1. Fork the project.
159
+ 2. Make your feature addition or bug fix.
160
+ 3. Add tests for it. This is important so I don't break it in a future version
161
+ unintentionally.
162
+ 4. Commit, do not mess with rakefile, version, or history. (if you want to have
163
+ your own version, that is fine but bump version in a commit by itself I can
164
+ ignore when I pull)
165
+ 5. Send me a pull request. Bonus points for topic branches.
166
+
167
+ ### Issues
168
+
169
+ Please report any issues, defects or suggestions in the [Github issue
170
+ tracker](https://github.com/avdgaag/rpub/issues).
171
+
172
+ ### What has changed?
173
+
174
+ See the [HISTORY](https://github.com/avdgaag/rpub/HISTORY) file for a detailed changelog.
175
+
176
+ ### Credits
177
+
178
+ Created by: Arjan van der Gaag
179
+ URL: [http://arjanvandergaag.nl](http://arjanvandergaag.nl)
180
+ Project homepage: [http://avdgaag.github.com/rpub](http://avdgaag.github.com/rpub)
181
+ Date: april 2012
182
+ License: [MIT-license](https://github.com/avdgaag/rpub/LICENSE) (same as Ruby)
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ Bundler.setup
4
+
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc 'Default: run specs.'
8
+ task :default => :spec
9
+
10
+ desc 'Run specs'
11
+ RSpec::Core::RakeTask.new
data/bin/rpub ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../../lib', __FILE__)
4
+ require 'rpub'
5
+
6
+ Rpub::Commander.invoke(ARGV)
@@ -0,0 +1 @@
1
+ Example readme file
@@ -0,0 +1,11 @@
1
+ ---
2
+ creator: Arjan van der Gaag
3
+ language: en
4
+ title: My awesome ebook
5
+ publisher: Me!
6
+ subject: Some subject
7
+ rights: none
8
+ description: foo bar
9
+ package_file: 'ebook.zip'
10
+ package:
11
+ - README
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ # Introduction
2
+
3
+ Lorem ipsum dolor sit amet.
@@ -0,0 +1,4 @@
1
+ # Introduction
2
+
3
+ Lorem ipsum dolor sit amet.
4
+
@@ -0,0 +1,4 @@
1
+ # Introduction
2
+
3
+ Lorem ipsum dolor sit amet.
4
+
@@ -0,0 +1,8 @@
1
+ ---
2
+ creator: Arjan van der Gaag
3
+ language: en
4
+ title: My awesome ebook
5
+ publisher: Me!
6
+ subject: Some subject
7
+ rights: none
8
+ description: foo bar
data/lib/rpub.rb ADDED
@@ -0,0 +1,53 @@
1
+ require 'optparse'
2
+ require 'fileutils'
3
+ require 'yaml'
4
+ require 'digest'
5
+ require 'ostruct'
6
+ require 'erb'
7
+
8
+ require 'builder'
9
+ require 'kramdown'
10
+ require 'zip/zip'
11
+
12
+ require 'rpub/version'
13
+ require 'rpub/subclass_tracker'
14
+ require 'rpub/commander'
15
+ require 'rpub/compilation_helpers'
16
+ require 'rpub/commands/base'
17
+ require 'rpub/commands/main'
18
+ require 'rpub/commands/compile'
19
+ require 'rpub/commands/clean'
20
+ require 'rpub/commands/preview'
21
+ require 'rpub/commands/package'
22
+ require 'rpub/commands/help'
23
+ require 'rpub/hash_delegation'
24
+ require 'rpub/book'
25
+ require 'rpub/chapter'
26
+ require 'rpub/compressor'
27
+ require 'rpub/epub'
28
+ require 'rpub/xml_file'
29
+ require 'rpub/epub/container'
30
+ require 'rpub/epub/toc'
31
+ require 'rpub/epub/content'
32
+ require 'rpub/epub/html_toc'
33
+ require 'rpub/epub/cover'
34
+
35
+ module Rpub
36
+ GEM_ROOT = File.expand_path('../../', __FILE__)
37
+
38
+ NoConfiguration = Class.new(StandardError)
39
+
40
+ class InvalidSubcommand < StandardError
41
+ def initialize(subcommand)
42
+ super "Unknown subcommand: #{subcommand}"
43
+ end
44
+ end
45
+
46
+ def self.support_file(path)
47
+ File.join(GEM_ROOT, 'support', path)
48
+ end
49
+
50
+ KRAMDOWN_OPTIONS = {
51
+ :coderay_line_numbers => nil
52
+ }
53
+ end
data/lib/rpub/book.rb ADDED
@@ -0,0 +1,70 @@
1
+ module Rpub
2
+ # The Book object wraps a collection of chapter objects and knows about its
3
+ # ordering, the book metadata from the configuration file and the book output
4
+ # filename.
5
+ class Book
6
+ include Enumerable
7
+ include HashDelegation
8
+
9
+ delegate_to_hash :config
10
+
11
+ # @return [Hash] The hash of configuration options read from the config.yml file.
12
+ attr_reader :config
13
+
14
+ # @return [Array] List of chapters, one for every input markdown file.
15
+ attr_reader :chapters
16
+
17
+ # @return [String] the path the layout HTML file to use to wrap the chapter in.
18
+ attr_reader :layout
19
+
20
+ def initialize(layout, config = {})
21
+ @chapters, @config, @layout = [], config, layout
22
+ end
23
+
24
+ def each(&block)
25
+ chapters.each(&block)
26
+ end
27
+
28
+ def toc?
29
+ !!config.fetch('toc') { false }
30
+ end
31
+
32
+ def cover?
33
+ !!config.fetch('cover_image') { false }
34
+ end
35
+
36
+ def outline
37
+ inject([]) { |all, chapter| all << [chapter.filename, chapter.outline] }
38
+ end
39
+
40
+ def images
41
+ map { |chapter| chapter.images }.flatten.uniq
42
+ end
43
+
44
+ # Add textual content as a new Chapter to this book.
45
+ #
46
+ # This method returns the `Book` object iself, so you can chain multiple calls:
47
+ #
48
+ # @example Chaining mutliple calls
49
+ # book << 'foo' << 'bar'
50
+ #
51
+ # @param [String] content is chapter text to add
52
+ def add_chapter(content)
53
+ chapters << Chapter.new(content, chapters.size, layout)
54
+ self
55
+ end
56
+ alias_method :<<, :add_chapter
57
+
58
+ # @return [String] Unique identifier for this entire book to be used in the
59
+ # epub manifest files.
60
+ def uid
61
+ @uid ||= Digest::SHA1.hexdigest [config.inspect, map(&:uid)].join
62
+ end
63
+
64
+ # @return [String] output filename for epub, based on the book title and
65
+ # version number.
66
+ def filename
67
+ @filename ||= [config['title'], config['version']].join('-').gsub(/[^\w\.]/i, '-').squeeze('-').downcase.chomp('-') + '.epub'
68
+ end
69
+ end
70
+ end