rpub 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec CHANGED
@@ -1,5 +1,6 @@
1
1
  --format progress
2
2
  --color
3
+ --order rand
3
4
  -Ilib
4
5
  -Ispec
5
6
  -r spec_helper
data/.yardopts CHANGED
@@ -1,6 +1,8 @@
1
1
  --no-private
2
2
  --title "Rpub, a simple ePub generator library in Ruby"
3
3
  --readme README.md
4
+ --markup markdown
5
+ --markup-provider kramdown
4
6
  -
5
7
  HISTORY.md
6
8
  LICENSE
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rpub (0.3.0)
4
+ rpub (0.4.0)
5
5
  builder
6
6
  kramdown
7
7
  nokogiri
@@ -17,35 +17,43 @@ GEM
17
17
  diff-lcs (1.1.3)
18
18
  ffi (1.0.11)
19
19
  growl (1.0.3)
20
- guard (1.0.1)
21
- ffi (>= 0.5.0)
22
- thor (~> 0.14.6)
23
- guard-rspec (0.7.0)
24
- guard (>= 0.10.0)
25
- kramdown (0.13.5)
26
- multi_json (1.3.2)
27
- nokogiri (1.5.2)
20
+ guard (1.1.1)
21
+ listen (>= 0.4.2)
22
+ thor (>= 0.14.6)
23
+ guard-rspec (1.0.0)
24
+ guard (>= 1.1)
25
+ kramdown (0.13.7)
26
+ listen (0.4.3)
27
+ rb-fchange (~> 0.0.5)
28
+ rb-fsevent (~> 0.9.1)
29
+ rb-inotify (~> 0.8.8)
30
+ multi_json (1.3.6)
31
+ nokogiri (1.5.3)
28
32
  rake (0.9.2.2)
33
+ rb-fchange (0.0.5)
34
+ ffi
29
35
  rb-fsevent (0.9.1)
30
- rspec (2.9.0)
31
- rspec-core (~> 2.9.0)
32
- rspec-expectations (~> 2.9.0)
33
- rspec-mocks (~> 2.9.0)
34
- rspec-core (2.9.0)
35
- rspec-expectations (2.9.1)
36
+ rb-inotify (0.8.8)
37
+ ffi (>= 0.5.0)
38
+ rspec (2.10.0)
39
+ rspec-core (~> 2.10.0)
40
+ rspec-expectations (~> 2.10.0)
41
+ rspec-mocks (~> 2.10.0)
42
+ rspec-core (2.10.1)
43
+ rspec-expectations (2.10.0)
36
44
  diff-lcs (~> 1.1.3)
37
- rspec-mocks (2.9.0)
45
+ rspec-mocks (2.10.1)
38
46
  rubypants (0.2.0)
39
47
  rubyzip (0.9.8)
40
- simplecov (0.6.2)
41
- multi_json (~> 1.3)
48
+ simplecov (0.6.4)
49
+ multi_json (~> 1.0)
42
50
  simplecov-html (~> 0.5.3)
43
51
  simplecov-html (0.5.3)
44
52
  textstats (0.0.2)
45
- thor (0.14.6)
53
+ thor (0.15.2)
46
54
  typogruby (1.0.15)
47
55
  rubypants
48
- yard (0.7.5)
56
+ yard (0.8.2)
49
57
 
50
58
  PLATFORMS
51
59
  ruby
data/HISTORY.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # History
2
2
 
3
+ ## 0.4.0
4
+
5
+ * Generate ePub table of contents from markdown headings
6
+ * Expanded documentation with configuration reference
7
+ * Enhanced .mobi compatibility (convert your .epub with kindlegen)
8
+
3
9
  ## 0.3.0
4
10
 
5
11
  * Only run simplecov on demand
data/README.md CHANGED
@@ -1,4 +1,4 @@
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)
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) [![Gemnasium dependency status](https://gemnasium.com/avdgaag/rpub.png)](https://gemnasium.com/avdgaag/rpub)
2
2
 
3
3
  ## Introduction
4
4
 
@@ -10,6 +10,7 @@ make working with ePub files a little easier:
10
10
  * Packaging your eBook in an archive with additional README file
11
11
  * Embedding fonts
12
12
  * Easy previewing as you write
13
+ * .mobi compatibility
13
14
 
14
15
  ## Installation
15
16
 
@@ -53,7 +54,8 @@ in a special configuration file called `config.yml`:
53
54
  title: My new book
54
55
  version: 0.1.0
55
56
 
56
- This file is written in [YAML](http://yaml.org) and sets basic properties of your book project.
57
+ This file is written in [YAML](http://yaml.org) and sets basic properties of
58
+ your book project.
57
59
 
58
60
  Since regenerating your ePub file and opening it in a suitable reader
59
61
  application is cumbersome, Rpub can generate a simple preview document for you:
@@ -67,6 +69,24 @@ easy viewing in any browser.
67
69
  [Markdown]: http://daringfireball.net/projects/markdown
68
70
  [John gruber]: http://daringfireball.net
69
71
 
72
+ ### Generating a .mobi file
73
+
74
+ Since the ePub and Mobipocket file formats are very (_very_) similar it is
75
+ quite easy to create a `.mobi` version of your book, suitable for reading on
76
+ Amazon's Kindle. To do so, you will need to install the [kindlegen program
77
+ Amazon provides][kindlegen].
78
+
79
+ Here's how it works:
80
+
81
+ 1. Install `kindlegen` ([download it here][kindlegen])
82
+ 2. Compile your book as usual using `rpub compile`
83
+ 3. Compile `my-book.epub` to `my-book.mobi`: `kindlegen my-book.epub`.
84
+
85
+ Optionally, include your `my-book.mobi` in your package by adding it to your
86
+ list of packaged files (see "Packaging for distribution").
87
+
88
+ [kindlegen]: http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211
89
+
70
90
  ### Advanced features
71
91
 
72
92
  #### Packaging for distribution
@@ -104,6 +124,15 @@ configuration to your `config.yml` file:
104
124
 
105
125
  toc: true
106
126
 
127
+ Note that this only affects the human-readable table of contents, represented
128
+ as a page in your book. Rpub will alway generate the .epub table of contents
129
+ for you, which contains the machine-readable references to your chapters. It
130
+ will, by default, reference all chapter titles and subheadings for you, but
131
+ you can customize the number of levels that will be included using the
132
+ following in your `config.yml` file:
133
+
134
+ max_level: 3
135
+
107
136
  #### Custom layout and styles
108
137
 
109
138
  When you compile a set of Markdown files to an ePub file, rpub uses a default
@@ -113,15 +142,22 @@ inclined.
113
142
 
114
143
  Simply define a `layout.html` and/or `styles.css` in your project directory.
115
144
  Your HTML file will be parsed with Erb, an so you can include your writing
116
- using the `yield` method:
145
+ using the `@body` instance variable:
117
146
 
118
147
  <html>
119
148
  <body>
120
- <%= yield %>
149
+ <%= @body %>
121
150
  </body>
122
151
  </html>
123
152
 
124
- **Note**: despite the name 'html' and `.html` extension, your file actually has
153
+ **Note 1**: this feature is actually provided by the [Kramdown gem][kramdown],
154
+ so have a look at [the standard Kramdown document template][doc] to see some
155
+ nifty tricks.
156
+
157
+ [kramdown]: http://kramdown.rubyforge.org
158
+ [doc]: https://github.com/gettalong/kramdown/blob/master/data/kramdown/document.html
159
+
160
+ **Note 2**: despite the name 'html' and `.html` extension, your file actually has
125
161
  to be XHTML-compliant.
126
162
 
127
163
  You can also provide custom layouts or styles to use when invoking the `compile`
@@ -136,16 +172,66 @@ those files into your project using the `generate` subcommand:
136
172
 
137
173
  ### Command reference
138
174
 
139
- * `rpub compile` -- generate .epub file
140
- * `rpub package` -- create zip file with compiled book and other listed files
141
- * `rpub preview` -- generate preview HTML file
142
- * `rpub generate` -- copy default layout.html, styles.css and config.yml
143
- * `rpub help` -- get help on subcommands
144
- * `rpub clean` -- remove generated files
175
+ `rpub compile`
176
+ : generate .epub file
177
+
178
+ `rpub package`
179
+ : create zip file with compiled book and other listed files
180
+
181
+ `rpub preview`
182
+ : generate preview HTML file
183
+
184
+ `rpub generate`
185
+ : copy default layout.html, styles.css and config.yml
186
+
187
+ `rpub help`
188
+ : get help on subcommands
189
+
190
+ `rpub clean`
191
+ : remove generated files
192
+
193
+ ### Configuration reference
194
+
195
+ `title`
196
+ : the book title (string)
197
+
198
+ `descrption`
199
+ : one-line summary of the book (string)
200
+
201
+ `creator`
202
+ : author name (string)
203
+
204
+ `publisher`
205
+ : publisher name (string)
206
+
207
+ `subject`
208
+ : book subject/category (string)
209
+
210
+ `language`
211
+ : language code of the book contents, e.g. 'en' (string)
212
+
213
+ `rights`
214
+ : copyright line (string)
215
+
216
+ `version`
217
+ : version number of the book to include in the .epub filename (string)
218
+
219
+ `toc`
220
+ : whether to generate a table of contents as book page (boolean, default false)
221
+
222
+ `max_level`
223
+ : the maximum depth of the .epub table of contents (number, default 2)
224
+
225
+ `ignore`
226
+ : list of files not to include in the epub, that otherwise would (array)
227
+
228
+ `package`
229
+ : list of files to be included in the archive created by the package task (array)
230
+
145
231
 
146
232
  ### Examples
147
233
 
148
- See the [examples directory](https://github.com/avdgaag/rpub/example) for two example projects.
234
+ See the [examples directory](https://github.com/avdgaag/rpub/tree/master/example) for two example projects.
149
235
 
150
236
  ### Documentation
151
237
 
@@ -171,7 +257,7 @@ tracker](https://github.com/avdgaag/rpub/issues).
171
257
 
172
258
  ### What has changed?
173
259
 
174
- See the [HISTORY](https://github.com/avdgaag/rpub/HISTORY) file for a detailed changelog.
260
+ See the [HISTORY](https://github.com/avdgaag/rpub/blob/master/HISTORY.md) file for a detailed changelog.
175
261
 
176
262
  ### Credits
177
263
 
@@ -17,6 +17,11 @@ module Rpub
17
17
  @content, @number, @layout = content, number, layout
18
18
  @document = Kramdown::Document.new(content, KRAMDOWN_OPTIONS.merge(:template => layout))
19
19
  end
20
+
21
+ # @return [Kramdown::Element] Toc elements hierarchy
22
+ def toc
23
+ Kramdown::Converter::Toc.convert(@document.root).first
24
+ end
20
25
 
21
26
  # @return [String] Unique identifier for this chapter.
22
27
  def uid
@@ -71,9 +71,14 @@ module Rpub
71
71
  end
72
72
  end
73
73
 
74
- if book.has_cover?
74
+ if book.has_cover? || book.has_toc?
75
75
  xml.guide do
76
- xml.reference :type => 'cover', :title => 'Cover', :href => 'cover.html'
76
+ if book.has_cover?
77
+ xml.reference :type => 'cover', :title => 'Cover', :href => 'cover.html'
78
+ end
79
+ if book.has_toc?
80
+ xml.reference :type => 'toc', :title => 'Table of Contents', :href => 'toc.html'
81
+ end
77
82
  end
78
83
  end
79
84
  end
@@ -4,7 +4,9 @@ module Rpub
4
4
  attr_reader :book
5
5
 
6
6
  def initialize(book)
7
- @book = book
7
+ @book = book
8
+ @play_order = -1
9
+ @max_level = book.config.fetch(:max_level) { 2 }
8
10
  super()
9
11
  end
10
12
 
@@ -13,23 +15,45 @@ module Rpub
13
15
  xml.declare! :DOCTYPE, :ncx, :PUBLIC, "-//W3C//DTD XHTML 1.1//EN", 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'
14
16
  xml.ncx :xmlns => 'http://www.daisy.org/z3986/2005/ncx/', :version => '2005-1' do
15
17
  xml.head do
16
- xml.meta :name => 'dtb:uid', :content => book.uid
17
- xml.meta :name => 'dtb:depth', :content => '1'
18
+ xml.meta :name => 'dtb:uid', :content => book.uid
19
+ xml.meta :name => 'dtb:depth', :content => @max_level
18
20
  xml.meta :name => 'dtb:totalPageCount', :content => '0'
19
- xml.meta :name => 'dtb:maxPageNumber', :content => '0'
21
+ xml.meta :name => 'dtb:maxPageNumber', :content => '0'
20
22
  end
21
23
  xml.docTitle { xml.text book.title }
22
24
  xml.navMap do
23
- book.chapters.each_with_index do |chapter, n|
24
- xml.navPoint :id => chapter.xml_id, :playOrder => n do
25
- xml.navLabel { xml.text chapter.title }
26
- xml.content :src => chapter.filename
27
- end
25
+ book.chapters.each do |chapter|
26
+ nav_points_nested_by_level chapter.toc, chapter.filename
28
27
  end
29
28
  end
30
29
  end
31
30
  end
31
+
32
+ private
33
+
34
+ def next_play_order
35
+ @play_order += 1
36
+ end
37
+
38
+ def nav_points_nested_by_level(heading, filename, level = 1)
39
+ heading.children.each do |heading|
40
+ html_id = heading.attr[:id]
41
+ source = filename+'#'+html_id
42
+ if heading.value.options[:level] <= @max_level
43
+ nav_point html_id, next_play_order, heading.value.options[:raw_text], source do
44
+ nav_points_nested_by_level heading, filename, level + 1
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def nav_point(id, play_order, text, filename)
51
+ xml.navPoint :id => id, :playOrder => play_order do
52
+ xml.navLabel { xml.text text }
53
+ xml.content :src => filename
54
+ yield if block_given?
55
+ end
56
+ end
32
57
  end
33
58
  end
34
59
  end
35
-
@@ -1,3 +1,3 @@
1
1
  module Rpub
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -58,6 +58,7 @@ describe Rpub::Epub::Content do
58
58
  context 'when the book has a ToC' do
59
59
  before { book.stub! :has_toc? => true }
60
60
  it { should have_xpath('/xmlns:package/xmlns:manifest/xmlns:item[@id="toc"][@href="toc.html"][@media-type="application/xhtml+xml"]') }
61
+ it { should have_xpath('/xmlns:package/xmlns:guide/xmlns:reference[@type="toc"][@title="Table of Contents"][@href="toc.html"]') }
61
62
  end
62
63
 
63
64
  context 'when the book has images' do
@@ -2,12 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  describe Rpub::Epub::Toc do
4
4
  let(:chapters) { [] }
5
- let(:book) { double('book', :uid => 'foo', :title => 'title', :chapters => chapters) }
5
+ let(:config) { {} }
6
+ let(:book) { double('book', :uid => 'foo', :title => 'title', :chapters => chapters, :config => config) }
6
7
  let(:subject) { described_class.new(book).render }
7
8
 
8
9
  it { should have_xpath('/xmlns:ncx') }
9
10
  it { should have_xpath('/xmlns:ncx/xmlns:head/xmlns:meta[@name="dtb:uid"][@content="foo"]') }
10
- it { should have_xpath('/xmlns:ncx/xmlns:head/xmlns:meta[@name="dtb:depth"][@content="1"]') }
11
+ it { should have_xpath('/xmlns:ncx/xmlns:head/xmlns:meta[@name="dtb:depth"][@content="2"]') }
11
12
  it { should have_xpath('/xmlns:ncx/xmlns:head/xmlns:meta[@name="dtb:totalPageCount"][@content="0"]') }
12
13
  it { should have_xpath('/xmlns:ncx/xmlns:head/xmlns:meta[@name="dtb:maxPageNumber"][@content="0"]') }
13
14
  it { should have_xpath('/xmlns:ncx/xmlns:docTitle/xmlns:text[text()="title"]') }
@@ -17,9 +18,23 @@ describe Rpub::Epub::Toc do
17
18
  end
18
19
 
19
20
  context 'with chapters' do
20
- let(:chapters) { [double('chapter', :title => 'chapter title', :filename => 'filename', :xml_id => 'id')] }
21
- it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint[@id="id"]') }
21
+ let(:heading1) { double('heading', :children => [heading2], :value => double('value', :options => { :level => 1, :raw_text => 'chapter title' }), :attr => { :id => 'foo' }) }
22
+ let(:heading2) { double('heading', :children => [], :value => double('value', :options => { :level => 2, :raw_text => 'chapter title 2' }), :attr => { :id => 'bar' }) }
23
+ let(:toc) { double('toc', :children => [heading1])}
24
+ let(:chapters) { [double('chapter', :title => 'chapter title', :filename => 'filename', :xml_id => 'id', :toc => toc)] }
25
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint[@id="foo"]') }
22
26
  it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:navLabel/xmlns:text[text()="chapter title"]') }
23
- it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:content[@src="filename"]') }
27
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:content[@src="filename#foo"]') }
28
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:navPoint[@id="bar"]') }
29
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:navPoint/xmlns:navLabel/xmlns:text[text()="chapter title 2"]') }
30
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:navPoint/xmlns:content[@src="filename#bar"]') }
31
+
32
+ context 'with low max_level' do
33
+ let(:config) { { :max_level => 1 } }
34
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint[@id="foo"]') }
35
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:navLabel/xmlns:text[text()="chapter title"]') }
36
+ it { should have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:content[@src="filename#foo"]') }
37
+ it { should_not have_xpath('/xmlns:ncx/xmlns:navMap/xmlns:navPoint/xmlns:navPoint') }
38
+ end
24
39
  end
25
40
  end
@@ -8,6 +8,7 @@ language: 'en'
8
8
  rights: 'public comain'
9
9
  version: '0.0.0'
10
10
  toc: true
11
+ max_level: 2
11
12
  ignore:
12
13
  - README.md
13
14
  package:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rpub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-06 00:00:00.000000000 Z
12
+ date: 2012-06-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: typogruby
@@ -349,7 +349,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
349
349
  version: '0'
350
350
  segments:
351
351
  - 0
352
- hash: 883141922978996594
352
+ hash: 2837060171432617966
353
353
  required_rubygems_version: !ruby/object:Gem::Requirement
354
354
  none: false
355
355
  requirements:
@@ -358,10 +358,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
358
358
  version: '0'
359
359
  segments:
360
360
  - 0
361
- hash: 883141922978996594
361
+ hash: 2837060171432617966
362
362
  requirements: []
363
363
  rubyforge_project:
364
- rubygems_version: 1.8.23
364
+ rubygems_version: 1.8.24
365
365
  signing_key:
366
366
  specification_version: 3
367
367
  summary: ! 'rPub is a command-line tool that generates a collection of plain text