bookmaker 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ module Bookmaker
2
+ module TOC
3
+ autoload :HTML, "bookmaker/toc/html"
4
+ autoload :Epub, "bookmaker/toc/epub"
5
+ end
6
+ end
@@ -0,0 +1,41 @@
1
+ module Bookmaker
2
+ module TOC
3
+ class Epub
4
+ attr_accessor :navigation
5
+
6
+ def initialize(navigation)
7
+ @navigation = navigation
8
+ end
9
+
10
+ def to_html
11
+ ERB.new(template).result OpenStruct.new(:navigation => navigation).instance_eval{ binding }
12
+ end
13
+
14
+ def template
15
+ <<-HTML.strip_heredoc.force_encoding("utf-8")
16
+ <?xml version="1.0" encoding="utf-8" ?>
17
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
18
+ <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
19
+ <head>
20
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
21
+ <link rel="stylesheet" type="text/css" href="epub.css"/>
22
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
23
+ <title>Table of Contents</title>
24
+ </head>
25
+ <body>
26
+ <div id="toc">
27
+ <ul>
28
+ <% navigation.each do |nav| %>
29
+ <li>
30
+ <a href="<%= nav[:content] %>"><%= nav[:label] %></a>
31
+ </li>
32
+ <% end %>
33
+ </ul>
34
+ </div>
35
+ </body>
36
+ </html>
37
+ HTML
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,78 @@
1
+ module Bookmaker
2
+ module TOC
3
+ class HTML
4
+ # Return the table of contents in hash format.
5
+ #
6
+ attr_reader :toc
7
+
8
+ private_class_method :new
9
+ attr_reader :buffer # :nodoc:
10
+ attr_reader :attrs # :nodoc:
11
+ attr_accessor :content # :nodoc:
12
+
13
+ # Traverse every title and add a +id+ attribute.
14
+ # Return the modified content.
15
+ #
16
+ def self.normalize(content)
17
+ counter = {}
18
+ html = Nokogiri::HTML.parse(content)
19
+ html.search("h1, h2, h3, h4, h5, h6").each do |tag|
20
+ title = tag.inner_text
21
+ permalink = title.to_permalink
22
+
23
+ counter[permalink] ||= 0
24
+ counter[permalink] += 1
25
+
26
+ permalink = "#{permalink}-#{counter[permalink]}" if counter[permalink] > 1
27
+
28
+ tag.set_attribute("id", permalink)
29
+ end
30
+
31
+ html.css("body").to_xhtml.gsub(/<body>(.*?)<\/body>/m, "\\1")
32
+ end
33
+
34
+ # Traverse every title normalizing its content as a permalink.
35
+ #
36
+ def self.generate(content)
37
+ content = normalize(content)
38
+ listener = new
39
+ listener.content = content
40
+ Stream.new(content, listener).parse
41
+ listener
42
+ end
43
+
44
+ def initialize # :nodoc:
45
+ @toc = []
46
+ @counters = {}
47
+ end
48
+
49
+ def tag(node) # :nodoc:
50
+ toc << {
51
+ :level => node.name.gsub(/[^\d]/, "").to_i,
52
+ :text => node.text,
53
+ :permalink => node["id"]
54
+ }
55
+ end
56
+
57
+ # Return a hash with all normalized attributes.
58
+ #
59
+ def to_hash
60
+ {
61
+ :content => content,
62
+ :html => to_html,
63
+ :toc => toc
64
+ }
65
+ end
66
+
67
+ # Return the table of contents in HTML format.
68
+ #
69
+ def to_html
70
+ String.new.tap do |html|
71
+ toc.each do |options|
72
+ html << %[<div class="level#{options[:level]} #{options[:permalink]}"><a href="##{options[:permalink]}"><span>#{CGI.escape_html(options[:text])}</span></a></div>]
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module Bookmaker
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,51 @@
1
+ # The book's title. Will be used everywhere!
2
+ title: "<%= @title %>"
3
+
4
+ # The book's language.
5
+ language: en
6
+
7
+ # Your book copyright info.
8
+ # Here's some examples:
9
+ #
10
+ # Copyright <%= @year %> by <%= @name %>.
11
+ # Copyright <%= @year %> by <%= @name %>. This work is licensed under MIT License.
12
+ # This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
13
+ # This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
14
+ # This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
15
+ #
16
+ copyright: "Copyright (C) <%= @year %> <%= @name %>."
17
+
18
+ # Who's publishing this book.
19
+ publisher: "<%= @name %>"
20
+
21
+ # When this book was published.
22
+ published_at: "<%= Date.today %>"
23
+
24
+ # Some book description.
25
+ subject: "[Your book description]"
26
+
27
+ # Some keywords that identify this book.
28
+ keywords: "[Your book keywords (comma-separated)]"
29
+
30
+ # Some unique identification. Works great with your domain
31
+ # like `http://yourbook.example.com`.
32
+ uid: "<%= @uid %>"
33
+
34
+ # Your book identification like ISBN or ISSN.
35
+ identifier:
36
+ id: "9-87654-3231-0123"
37
+ type: "ISBN-13" # can be ISBN, ISSN or URL
38
+
39
+ # This book authors.
40
+ authors:
41
+ - "<%= @name %>"
42
+
43
+ # The base URL from your source code.
44
+ base_url: http://example.com
45
+
46
+ #==========
47
+ # Book Manifest
48
+ sections:
49
+ - 01-Welcome.md
50
+
51
+
@@ -0,0 +1,500 @@
1
+ /*! normalize.css v1.0.0 | MIT License | git.io/normalize */
2
+
3
+ /* ==========================================================================
4
+ HTML5 display definitions
5
+ ========================================================================== */
6
+
7
+ /*
8
+ * Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3.
9
+ */
10
+
11
+ article,
12
+ aside,
13
+ details,
14
+ figcaption,
15
+ figure,
16
+ footer,
17
+ header,
18
+ hgroup,
19
+ nav,
20
+ section,
21
+ summary {
22
+ display: block;
23
+ }
24
+
25
+ /*
26
+ * Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
27
+ */
28
+
29
+ audio,
30
+ canvas,
31
+ video {
32
+ display: inline-block;
33
+ *display: inline;
34
+ *zoom: 1;
35
+ }
36
+
37
+ /*
38
+ * Prevents modern browsers from displaying `audio` without controls.
39
+ * Remove excess height in iOS 5 devices.
40
+ */
41
+
42
+ audio:not([controls]) {
43
+ display: none;
44
+ height: 0;
45
+ }
46
+
47
+ /*
48
+ * Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3,
49
+ * and Safari 4.
50
+ * Known issue: no IE 6 support.
51
+ */
52
+
53
+ [hidden] {
54
+ display: none;
55
+ }
56
+
57
+ /* ==========================================================================
58
+ Base
59
+ ========================================================================== */
60
+
61
+ /*
62
+ * 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using
63
+ * `em` units.
64
+ * 2. Prevents iOS text size adjust after orientation change, without disabling
65
+ * user zoom.
66
+ */
67
+
68
+ html {
69
+ font-size: 100%; /* 1 */
70
+ -webkit-text-size-adjust: 100%; /* 2 */
71
+ -ms-text-size-adjust: 100%; /* 2 */
72
+ }
73
+
74
+ /*
75
+ * Addresses `font-family` inconsistency between `textarea` and other form
76
+ * elements.
77
+ */
78
+
79
+ html,
80
+ button,
81
+ input,
82
+ select,
83
+ textarea {
84
+ font-family: sans-serif;
85
+ }
86
+
87
+ /*
88
+ * Addresses margins handled incorrectly in IE 6/7.
89
+ */
90
+
91
+ body {
92
+ margin: 0;
93
+ }
94
+
95
+ /* ==========================================================================
96
+ Links
97
+ ========================================================================== */
98
+
99
+ /*
100
+ * Addresses `outline` inconsistency between Chrome and other browsers.
101
+ */
102
+
103
+ a:focus {
104
+ outline: thin dotted;
105
+ }
106
+
107
+ /*
108
+ * Improves readability when focused and also mouse hovered in all browsers.
109
+ */
110
+
111
+ a:active,
112
+ a:hover {
113
+ outline: 0;
114
+ }
115
+
116
+ /* ==========================================================================
117
+ Typography
118
+ ========================================================================== */
119
+
120
+ /*
121
+ * Addresses font sizes and margins set differently in IE 6/7.
122
+ * Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5,
123
+ * and Chrome.
124
+ */
125
+
126
+ h1 {
127
+ font-size: 2em;
128
+ margin: 0.67em 0;
129
+ }
130
+
131
+ h2 {
132
+ font-size: 1.5em;
133
+ margin: 0.83em 0;
134
+ }
135
+
136
+ h3 {
137
+ font-size: 1.17em;
138
+ margin: 1em 0;
139
+ }
140
+
141
+ h4 {
142
+ font-size: 1em;
143
+ margin: 1.33em 0;
144
+ }
145
+
146
+ h5 {
147
+ font-size: 0.83em;
148
+ margin: 1.67em 0;
149
+ }
150
+
151
+ h6 {
152
+ font-size: 0.75em;
153
+ margin: 2.33em 0;
154
+ }
155
+
156
+ /*
157
+ * Addresses styling not present in IE 7/8/9, Safari 5, and Chrome.
158
+ */
159
+
160
+ abbr[title] {
161
+ border-bottom: 1px dotted;
162
+ }
163
+
164
+ /*
165
+ * Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.
166
+ */
167
+
168
+ b,
169
+ strong {
170
+ font-weight: bold;
171
+ }
172
+
173
+ blockquote {
174
+ margin: 1em 40px;
175
+ }
176
+
177
+ /*
178
+ * Addresses styling not present in Safari 5 and Chrome.
179
+ */
180
+
181
+ dfn {
182
+ font-style: italic;
183
+ }
184
+
185
+ /*
186
+ * Addresses styling not present in IE 6/7/8/9.
187
+ */
188
+
189
+ mark {
190
+ background: #ff0;
191
+ color: #000;
192
+ }
193
+
194
+ /*
195
+ * Addresses margins set differently in IE 6/7.
196
+ */
197
+
198
+ p,
199
+ pre {
200
+ margin: 1em 0;
201
+ }
202
+
203
+ /*
204
+ * Corrects font family set oddly in IE 6, Safari 4/5, and Chrome.
205
+ */
206
+
207
+ code,
208
+ kbd,
209
+ pre,
210
+ samp {
211
+ font-family: monospace, serif;
212
+ _font-family: 'courier new', monospace;
213
+ font-size: 1em;
214
+ }
215
+
216
+ /*
217
+ * Improves readability of pre-formatted text in all browsers.
218
+ */
219
+
220
+ pre {
221
+ white-space: pre;
222
+ white-space: pre-wrap;
223
+ word-wrap: break-word;
224
+ }
225
+
226
+ /*
227
+ * Addresses CSS quotes not supported in IE 6/7.
228
+ */
229
+
230
+ q {
231
+ quotes: none;
232
+ }
233
+
234
+ /*
235
+ * Addresses `quotes` property not supported in Safari 4.
236
+ */
237
+
238
+ q:before,
239
+ q:after {
240
+ content: '';
241
+ content: none;
242
+ }
243
+
244
+ small {
245
+ font-size: 75%;
246
+ }
247
+
248
+ /*
249
+ * Prevents `sub` and `sup` affecting `line-height` in all browsers.
250
+ */
251
+
252
+ sub,
253
+ sup {
254
+ font-size: 75%;
255
+ line-height: 0;
256
+ position: relative;
257
+ vertical-align: baseline;
258
+ }
259
+
260
+ sup {
261
+ top: -0.5em;
262
+ }
263
+
264
+ sub {
265
+ bottom: -0.25em;
266
+ }
267
+
268
+ /* ==========================================================================
269
+ Lists
270
+ ========================================================================== */
271
+
272
+ /*
273
+ * Addresses margins set differently in IE 6/7.
274
+ */
275
+
276
+ dl,
277
+ menu,
278
+ ol,
279
+ ul {
280
+ margin: 1em 0;
281
+ }
282
+
283
+ dd {
284
+ margin: 0 0 0 40px;
285
+ }
286
+
287
+ /*
288
+ * Addresses paddings set differently in IE 6/7.
289
+ */
290
+
291
+ menu,
292
+ ol,
293
+ ul {
294
+ padding: 0 0 0 40px;
295
+ }
296
+
297
+ /*
298
+ * Corrects list images handled incorrectly in IE 7.
299
+ */
300
+
301
+ nav ul,
302
+ nav ol {
303
+ list-style: none;
304
+ list-style-image: none;
305
+ }
306
+
307
+ /* ==========================================================================
308
+ Embedded content
309
+ ========================================================================== */
310
+
311
+ /*
312
+ * 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3.
313
+ * 2. Improves image quality when scaled in IE 7.
314
+ */
315
+
316
+ img {
317
+ border: 0; /* 1 */
318
+ -ms-interpolation-mode: bicubic; /* 2 */
319
+ }
320
+
321
+ /*
322
+ * Corrects overflow displayed oddly in IE 9.
323
+ */
324
+
325
+ svg:not(:root) {
326
+ overflow: hidden;
327
+ }
328
+
329
+ /* ==========================================================================
330
+ Figures
331
+ ========================================================================== */
332
+
333
+ /*
334
+ * Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11.
335
+ */
336
+
337
+ figure {
338
+ margin: 0;
339
+ }
340
+
341
+ /* ==========================================================================
342
+ Forms
343
+ ========================================================================== */
344
+
345
+ /*
346
+ * Corrects margin displayed oddly in IE 6/7.
347
+ */
348
+
349
+ form {
350
+ margin: 0;
351
+ }
352
+
353
+ /*
354
+ * Define consistent border, margin, and padding.
355
+ */
356
+
357
+ fieldset {
358
+ border: 1px solid #c0c0c0;
359
+ margin: 0 2px;
360
+ padding: 0.35em 0.625em 0.75em;
361
+ }
362
+
363
+ /*
364
+ * 1. Corrects color not being inherited in IE 6/7/8/9.
365
+ * 2. Corrects text not wrapping in Firefox 3.
366
+ * 3. Corrects alignment displayed oddly in IE 6/7.
367
+ */
368
+
369
+ legend {
370
+ border: 0; /* 1 */
371
+ padding: 0;
372
+ white-space: normal; /* 2 */
373
+ *margin-left: -7px; /* 3 */
374
+ }
375
+
376
+ /*
377
+ * 1. Corrects font size not being inherited in all browsers.
378
+ * 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5,
379
+ * and Chrome.
380
+ * 3. Improves appearance and consistency in all browsers.
381
+ */
382
+
383
+ button,
384
+ input,
385
+ select,
386
+ textarea {
387
+ font-size: 100%; /* 1 */
388
+ margin: 0; /* 2 */
389
+ vertical-align: baseline; /* 3 */
390
+ *vertical-align: middle; /* 3 */
391
+ }
392
+
393
+ /*
394
+ * Addresses Firefox 3+ setting `line-height` on `input` using `!important` in
395
+ * the UA stylesheet.
396
+ */
397
+
398
+ button,
399
+ input {
400
+ line-height: normal;
401
+ }
402
+
403
+ /*
404
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
405
+ * and `video` controls.
406
+ * 2. Corrects inability to style clickable `input` types in iOS.
407
+ * 3. Improves usability and consistency of cursor style between image-type
408
+ * `input` and others.
409
+ * 4. Removes inner spacing in IE 7 without affecting normal text inputs.
410
+ * Known issue: inner spacing remains in IE 6.
411
+ */
412
+
413
+ button,
414
+ html input[type="button"], /* 1 */
415
+ input[type="reset"],
416
+ input[type="submit"] {
417
+ -webkit-appearance: button; /* 2 */
418
+ cursor: pointer; /* 3 */
419
+ *overflow: visible; /* 4 */
420
+ }
421
+
422
+ /*
423
+ * Re-set default cursor for disabled elements.
424
+ */
425
+
426
+ button[disabled],
427
+ input[disabled] {
428
+ cursor: default;
429
+ }
430
+
431
+ /*
432
+ * 1. Addresses box sizing set to content-box in IE 8/9.
433
+ * 2. Removes excess padding in IE 8/9.
434
+ * 3. Removes excess padding in IE 7.
435
+ * Known issue: excess padding remains in IE 6.
436
+ */
437
+
438
+ input[type="checkbox"],
439
+ input[type="radio"] {
440
+ box-sizing: border-box; /* 1 */
441
+ padding: 0; /* 2 */
442
+ *height: 13px; /* 3 */
443
+ *width: 13px; /* 3 */
444
+ }
445
+
446
+ /*
447
+ * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
448
+ * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
449
+ * (include `-moz` to future-proof).
450
+ */
451
+
452
+ input[type="search"] {
453
+ -webkit-appearance: textfield; /* 1 */
454
+ -moz-box-sizing: content-box;
455
+ -webkit-box-sizing: content-box; /* 2 */
456
+ box-sizing: content-box;
457
+ }
458
+
459
+ /*
460
+ * Removes inner padding and search cancel button in Safari 5 and Chrome
461
+ * on OS X.
462
+ */
463
+
464
+ input[type="search"]::-webkit-search-cancel-button,
465
+ input[type="search"]::-webkit-search-decoration {
466
+ -webkit-appearance: none;
467
+ }
468
+
469
+ /*
470
+ * Removes inner padding and border in Firefox 3+.
471
+ */
472
+
473
+ button::-moz-focus-inner,
474
+ input::-moz-focus-inner {
475
+ border: 0;
476
+ padding: 0;
477
+ }
478
+
479
+ /*
480
+ * 1. Removes default vertical scrollbar in IE 6/7/8/9.
481
+ * 2. Improves readability and alignment in all browsers.
482
+ */
483
+
484
+ textarea {
485
+ overflow: auto; /* 1 */
486
+ vertical-align: top; /* 2 */
487
+ }
488
+
489
+ /* ==========================================================================
490
+ Tables
491
+ ========================================================================== */
492
+
493
+ /*
494
+ * Remove most spacing between table cells.
495
+ */
496
+
497
+ table {
498
+ border-collapse: collapse;
499
+ border-spacing: 0;
500
+ }