ebookie 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,60 @@
1
+ require "epzip"
2
+ require "epub_validator"
3
+
4
+ module Ebookie
5
+ module Rendering
6
+ class Epub < Base
7
+
8
+ set :paths, %w(OEBPS OEBPS/images META-INF)
9
+ set :files, %w(mimetype OEBPS/epub.css OEBPS/content.opf.erb OEBPS/toc.ncx.erb META-INF/container.xml)
10
+ set :images_dir, 'OEBPS/images'
11
+
12
+ def copy_cover
13
+ if File.extname(document.cover) != '.png'
14
+ raise "Cover file is not a valid png"
15
+ end
16
+
17
+ borrow document.cover.to_s, to: tmp_dir.join("OEBPS/images/cover.png")
18
+ end
19
+
20
+ def process!
21
+ copy_cover if document.cover
22
+
23
+ document.chapters.each do |chapter|
24
+ render_erb_to_file template_file("OEBPS/chapter.erb"), tmp_dir.join("OEBPS/#{chapter.slug}.html"), chapter: chapter
25
+ end
26
+
27
+ unless Ebookie.logger.debug?
28
+ Epzip.class_variable_set("@@zip_cmd_path", "zip -q")
29
+ end
30
+
31
+ zip = Epzip.zip( tmp_dir, output_path )
32
+
33
+ validation = EpubValidator.check( output_path )
34
+ if validation.valid?
35
+ Ebookie.logger.info "Successfully compiled #{document.title} to epub"
36
+ else
37
+ Ebookie.logger.warn "Errors when compiling #{document.title} to epub"
38
+ validation.messages.each do |m|
39
+ Ebookie.logger.warn "~> #{m}"
40
+ end
41
+ end
42
+ end
43
+
44
+ def sanitize(html)
45
+ html = html.dup
46
+ {
47
+ "<figure>" => "<span class=\"figure\">",
48
+ "</figure>" => "</span>",
49
+ "<figcaption>" => "<span class=\"figcaption\">",
50
+ "</figcaption>" => "</span>"
51
+ }.each do |k,v|
52
+ html.gsub! k, v
53
+ end
54
+
55
+ sanitize_html clean_images(html, Pathname.new("images"))
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,31 @@
1
+ require "kindlegen"
2
+
3
+ module Ebookie
4
+ module Rendering
5
+ class Mobi < Base
6
+
7
+ def process!
8
+ epub = "#{document.destination}/#{document.slug}.epub"
9
+
10
+ if !File.exists?(epub)
11
+ Epub.new(document).render
12
+ end
13
+
14
+ command = "#{Kindlegen.command} #{epub} -c2 -verbose -o #{document.slug}.mobi"
15
+ converted = `#{command}`
16
+
17
+ warnings = converted.split("\n").keep_if do |line|
18
+ line.include?("Warning")
19
+ end
20
+
21
+ if warnings.length > 0
22
+ Ebookie.logger.warn "Warnings when compiling #{document.title} to mobi"
23
+ warnings.each do |m|
24
+ Ebookie.logger.warn "~> #{m}"
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,104 @@
1
+ require "combine_pdf"
2
+ require "pdf-reader"
3
+
4
+ module Ebookie
5
+ module Rendering
6
+ class Pdf < Base
7
+
8
+ set :files, %w(pdf.css document.html.erb)
9
+ set :paths, %w(images)
10
+ set :images_dir, 'images'
11
+
12
+ def after_initialize
13
+ @wkhtmltopdf_path = Gem.bin_path("wkhtmltopdf-binary-edge")
14
+
15
+ @ghostscript_path = `which gs`.chomp
16
+ raise "GhostScript not installed" unless @ghostscript_path
17
+
18
+ @tmp_path = tmp_dir.join("document.pdf")
19
+ @pages = []
20
+
21
+ settings[:files] << 'cover.html.erb' if convert_cover?
22
+ end
23
+
24
+ def process!
25
+ convert_page(tmp_dir.join('document.html'), @tmp_path)
26
+
27
+ ::PDF::Reader.new(@tmp_path).pages.each_with_index do |page, idx|
28
+ prune_blank_page(idx)
29
+ end
30
+
31
+ if document.cover
32
+ if File.extname(document.cover) != '.pdf'
33
+ cover_path = convert_cover
34
+ @pages.unshift cover_path
35
+ else
36
+ borrow document.cover.to_s, to: tmp_dir.join('cover.pdf')
37
+ @pages.unshift tmp_dir.join('cover.pdf')
38
+ end
39
+ end
40
+
41
+ pdf = CombinePDF.new
42
+ @pages.compact.each do |page|
43
+ pdf << CombinePDF.new(page)
44
+ end
45
+ pdf.save output_path
46
+ end
47
+
48
+ def sanitize(html)
49
+ html = html.dup
50
+ {
51
+ "—" => "&mdash;"
52
+ }.each do |k,v|
53
+ html.gsub! k, v
54
+ end
55
+
56
+ sanitize_html clean_images(html, tmp_dir.join("images"))
57
+ end
58
+
59
+ def convert_page(input_path, output_path, args=[])
60
+ args << "--quiet"
61
+ args << "--page-size Letter"
62
+ args << "--title '#{document.title}'"
63
+ command = [@wkhtmltopdf_path] + args
64
+ command << input_path
65
+ command << output_path
66
+ system command.join(' ')
67
+ end
68
+
69
+ def convert_cover?
70
+ document.cover && File.extname(document.cover) != '.pdf'
71
+ end
72
+
73
+ def convert_cover
74
+ borrow document.cover.to_s, to: tmp_dir.join('images', File.basename(document.cover))
75
+ cover_path = tmp_dir.join("cover.pdf")
76
+
77
+ margins = ['--margin-top 0', '--margin-bottom 0', '--margin-left 0', '--margin-right 0']
78
+ convert_page(tmp_dir.join('cover.html'), cover_path, margins)
79
+
80
+ return cover_path
81
+ end
82
+
83
+ def prune_blank_page(index)
84
+ output_file = tmp_dir.join("page-#{index}.pdf")
85
+ options = ["-q",
86
+ "-dBATCH",
87
+ "-dNOPAUSE",
88
+ "-sDEVICE=pdfwrite",
89
+ "-dFirstPage=#{index+1}",
90
+ "-dLastPage=#{index+1}",
91
+ "-sOutputFile=#{output_file}"]
92
+
93
+ system [@ghostscript_path, options.join(' '), @tmp_path].join(' ')
94
+
95
+ colors = `#{@ghostscript_path} -q -o - -sDEVICE=inkcov #{output_file}`
96
+ colors = colors.split(" ").uniq[0..-3]
97
+ unless colors.length == 1 && colors.first == "0.00000"
98
+ @pages << tmp_dir.join("page-#{index}.pdf")
99
+ end
100
+ end
101
+
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0"?>
2
+ <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
3
+ <rootfiles>
4
+ <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
5
+ </rootfiles>
6
+ </container>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <link href='epub.css' rel='stylesheet' />
5
+ <title><%= chapter.title %></title>
6
+ </head>
7
+ <body>
8
+ <div class='article'>
9
+ <%= renderer.sanitize chapter.content %>
10
+ </div>
11
+ </body>
12
+ </html>
@@ -0,0 +1,50 @@
1
+ <?xml version="1.0"?>
2
+ <package xmlns="http://www.idpf.org/2007/opf"
3
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+ unique-identifier="bookid"
5
+ version="2.0">
6
+
7
+ <metadata xmlns:opf="http://www.idpf.org/2007/opf"
8
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
9
+
10
+ <dc:identifier id="bookid">urn:uuid:33bf6f6c-3b3f-8f99-261d-33744f528720</dc:identifier>
11
+ <dc:title><%= document.title %></dc:title>
12
+ <% %w(creator publisher rights subject language source date).each do |option| %>
13
+ <% if document.send(option) %>
14
+ <dc:<%= option %>><%= document.send(option) %></dc:<%= option %>>
15
+ <% end %>
16
+ <% end %>
17
+
18
+ <% if document.cover %>
19
+ <meta name="cover" content="cover-image"/>
20
+ <% end %>
21
+ </metadata>
22
+
23
+ <manifest>
24
+ <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
25
+
26
+ <% if document.cover %>
27
+ <item id="cover-image" href="images/cover.png" media-type="image/png"/>
28
+ <% end %>
29
+
30
+ <item id="css" href="epub.css" media-type="text/css"/>
31
+
32
+ <!-- chapters -->
33
+ <% document.chapters.each do |chapter| %>
34
+ <item id="<%= chapter.slug %>" href="<%= chapter.slug + ".html" %>" media-type="application/xhtml+xml" />
35
+ <% end %>
36
+
37
+ <!-- images -->
38
+ <% document.images.each_with_index do |image, index| %>
39
+ <item id="image<%= index + 1 %>" href="images/<%= image.basename %>" media-type="image/png" />
40
+ <% end %>
41
+ </manifest>
42
+
43
+ <spine toc="ncx">
44
+ <!-- chapters -->
45
+ <% document.chapters.each do |chapter| %>
46
+ <itemref idref="<%= chapter.slug %>" />
47
+ <% end %>
48
+ </spine>
49
+
50
+ </package>
@@ -0,0 +1,68 @@
1
+ /* Styles */
2
+ body {
3
+ background: #ffffff;
4
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
5
+ color: #3f3f38;
6
+ }
7
+
8
+ pre,
9
+ code,
10
+ kbd,
11
+ samp,
12
+ tt {
13
+ font-family: monospace;
14
+ font-size: 108%;
15
+ line-height: 1;
16
+ }
17
+
18
+ h1,
19
+ h2,
20
+ h3,
21
+ dl,
22
+ dl dt {
23
+ font-weight: 700;
24
+ margin: 1em 0;
25
+ line-height: 1em;
26
+ }
27
+
28
+ h1 {
29
+ font-size: 2em;
30
+ }
31
+
32
+ h2 {
33
+ font-size: 1.5em;
34
+ }
35
+
36
+ h3 {
37
+ font-size: 1em;
38
+ }
39
+
40
+ p {
41
+ margin: 15px 0 15px;
42
+ color: #787975;
43
+ line-height: 1.4em;
44
+ }
45
+
46
+ p + h1,
47
+ p + h2,
48
+ p + h3,
49
+ p + dl dt,
50
+ dl p + dt,
51
+ p + h4,
52
+ p + h5,
53
+ p + h6 {
54
+ margin-top: 2em;
55
+ }
56
+
57
+ blockquote {
58
+ margin-left: 1em;
59
+ padding-left: 1em;
60
+ border-left: 1px solid #fff;
61
+ }
62
+
63
+ a,
64
+ a:visited {
65
+ color: #45bcd2;
66
+ font-weight: bold;
67
+ text-decoration: none;
68
+ }
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">
3
+ <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
4
+ <head>
5
+ <meta name="dtb:uid" content="urn:uuid:33bf6f6c-3b3f-8f99-261d-33744f528720"/>
6
+ <meta name="dtb:depth" content="1"/>
7
+ <meta name="dtb:totalPageCount" content="0"/>
8
+ <meta name="dtb:maxPageNumber" content="0"/>
9
+ </head>
10
+ <docTitle>
11
+ <text><%= document.title %></text>
12
+ </docTitle>
13
+ <navMap>
14
+ <% document.chapters.each_with_index do |chapter, index| %>
15
+ <navPoint id="<%= chapter.slug %>" playOrder="<%= index + 1 %>">
16
+ <navLabel><text><%= chapter.title %></text></navLabel>
17
+ <content src="<%= chapter.slug + ".html" %>" />
18
+ </navPoint>
19
+ <% end %>
20
+ </navMap>
21
+ </ncx>
@@ -0,0 +1 @@
1
+ application/epub+zip
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= document.title %></title>
5
+ </head>
6
+ <body>
7
+ <img src='<%= renderer.tmp_dir.join("images", File.basename(document.cover)) %>' width='100%' />
8
+ </body>
9
+ </html>
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= document.title %></title>
5
+ <link href='<%= renderer.tmp_dir.join("pdf.css") %>' rel='stylesheet' />
6
+ </head>
7
+ <body>
8
+ <div class='chapters'>
9
+ <% document.chapters.each do |chapter| %>
10
+ <article>
11
+ <%= renderer.sanitize(chapter.content) %>
12
+ </article>
13
+ <% end %>
14
+ </div>
15
+ </body>
16
+ </html>
@@ -0,0 +1,642 @@
1
+ /*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */
2
+ /* =============================================================================
3
+ HTML5 display definitions
4
+ ========================================================================== */
5
+ /*
6
+ * Corrects block display not defined in IE6/7/8/9 & FF3
7
+ */
8
+
9
+ article,
10
+ aside,
11
+ details,
12
+ figcaption,
13
+ figure,
14
+ footer,
15
+ header,
16
+ hgroup,
17
+ nav,
18
+ section,
19
+ summary {
20
+ display: block;
21
+ }
22
+
23
+ /*
24
+ * Corrects inline-block display not defined in IE6/7/8/9 & FF3
25
+ */
26
+
27
+ audio,
28
+ canvas,
29
+ video {
30
+ display: inline-block;
31
+ *display: inline;
32
+ *zoom: 1;
33
+ }
34
+
35
+ /*
36
+ * Prevents modern browsers from displaying 'audio' without controls
37
+ * Remove excess height in iOS5 devices
38
+ */
39
+
40
+ audio:not([controls]) {
41
+ display: none;
42
+ height: 0;
43
+ }
44
+
45
+ /*
46
+ * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
47
+ * Known issue: no IE6 support
48
+ */
49
+
50
+ [hidden] {
51
+ display: none;
52
+ }
53
+
54
+ /* =============================================================================
55
+ Base
56
+ ========================================================================== */
57
+ /*
58
+ * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
59
+ * http://clagnut.com/blog/348/#c790
60
+ * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
61
+ * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
62
+ */
63
+
64
+ html {
65
+ font-size: 100%;
66
+ /* 1 */
67
+ -webkit-text-size-adjust: 100%;
68
+ /* 2 */
69
+ -ms-text-size-adjust: 100%;
70
+ /* 2 */
71
+ }
72
+
73
+ /*
74
+ * Addresses font-family inconsistency between 'textarea' and other form elements.
75
+ */
76
+
77
+ html,
78
+ button,
79
+ input,
80
+ select,
81
+ textarea {
82
+ font-family: sans-serif;
83
+ }
84
+
85
+ /*
86
+ * Addresses margins handled incorrectly in IE6/7
87
+ */
88
+
89
+ body {
90
+ margin: 0;
91
+ }
92
+
93
+ /* =============================================================================
94
+ Links
95
+ ========================================================================== */
96
+ /*
97
+ * Addresses outline displayed oddly in Chrome
98
+ */
99
+
100
+ a:focus {
101
+ outline: thin dotted;
102
+ }
103
+
104
+ /*
105
+ * Improves readability when focused and also mouse hovered in all browsers
106
+ * people.opera.com/patrickl/experiments/keyboard/test
107
+ */
108
+
109
+ a:hover,
110
+ a:active {
111
+ outline: 0;
112
+ }
113
+
114
+ /* =============================================================================
115
+ Typography
116
+ ========================================================================== */
117
+ /*
118
+ * Addresses font sizes and margins set differently in IE6/7
119
+ * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
120
+ */
121
+
122
+ h1 {
123
+ font-size: 2em;
124
+ margin: 0.67em 0;
125
+ }
126
+
127
+
128
+ h2 {
129
+ font-size: 1.5em;
130
+ margin: 0.83em 0;
131
+ }
132
+
133
+
134
+ h3 {
135
+ font-size: 1.17em;
136
+ margin: 1em 0;
137
+ }
138
+
139
+
140
+ h4 {
141
+ font-size: 1em;
142
+ margin: 1.33em 0;
143
+ }
144
+
145
+
146
+ h5 {
147
+ font-size: 0.83em;
148
+ margin: 1.67em 0;
149
+ }
150
+
151
+
152
+ h6 {
153
+ font-size: 0.75em;
154
+ margin: 2.33em 0;
155
+ }
156
+
157
+ /*
158
+ * Addresses styling not present in IE7/8/9, S5, Chrome
159
+ */
160
+
161
+ abbr[title] {
162
+ border-bottom: 1px dotted;
163
+ }
164
+
165
+ /*
166
+ * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
167
+ */
168
+
169
+ b,
170
+ strong {
171
+ font-weight: bold;
172
+ }
173
+
174
+
175
+ blockquote {
176
+ margin: 1em 40px;
177
+ }
178
+
179
+ /*
180
+ * Addresses styling not present in S5, Chrome
181
+ */
182
+
183
+ dfn {
184
+ font-style: italic;
185
+ }
186
+
187
+ /*
188
+ * Addresses styling not present in IE6/7/8/9
189
+ */
190
+
191
+ mark {
192
+ background: #ff0;
193
+ color: #000;
194
+ }
195
+
196
+ /*
197
+ * Addresses margins set differently in IE6/7
198
+ */
199
+
200
+ p,
201
+ pre {
202
+ margin: 1em 0;
203
+ }
204
+
205
+ /*
206
+ * Corrects font family set oddly in IE6, S4/5, Chrome
207
+ * en.wikipedia.org/wiki/User:Davidgothberg/Test59
208
+ */
209
+
210
+ pre,
211
+ code,
212
+ kbd,
213
+ samp {
214
+ font-family: monospace, serif;
215
+ _font-family: 'courier new', monospace;
216
+ font-size: 1em;
217
+ }
218
+
219
+ /*
220
+ * Improves readability of pre-formatted text in all browsers
221
+ */
222
+
223
+ pre {
224
+ white-space: pre;
225
+ white-space: pre-wrap;
226
+ word-wrap: break-word;
227
+ }
228
+
229
+ /*
230
+ * 1. Addresses CSS quotes not supported in IE6/7
231
+ * 2. Addresses quote property not supported in S4
232
+ */
233
+ /* 1 */
234
+
235
+ q {
236
+ quotes: none;
237
+ }
238
+
239
+ /* 2 */
240
+
241
+ q:before,
242
+ q:after {
243
+ content: '';
244
+ content: none;
245
+ }
246
+
247
+
248
+ small {
249
+ font-size: 75%;
250
+ }
251
+
252
+ /*
253
+ * Prevents sub and sup affecting line-height in all browsers
254
+ * gist.github.com/413930
255
+ */
256
+
257
+ sub,
258
+ sup {
259
+ font-size: 75%;
260
+ line-height: 0;
261
+ position: relative;
262
+ vertical-align: baseline;
263
+ }
264
+
265
+
266
+ sup {
267
+ top: -0.5em;
268
+ }
269
+
270
+
271
+ sub {
272
+ bottom: -0.25em;
273
+ }
274
+
275
+ /* =============================================================================
276
+ Lists
277
+ ========================================================================== */
278
+ /*
279
+ * Addresses margins set differently in IE6/7
280
+ */
281
+
282
+ dl,
283
+ menu,
284
+ ol,
285
+ ul {
286
+ margin: 1em 0;
287
+ }
288
+
289
+
290
+ dd {
291
+ margin: 0 0 0 40px;
292
+ }
293
+
294
+ /*
295
+ * Addresses paddings set differently in IE6/7
296
+ */
297
+
298
+ menu,
299
+ ol,
300
+ ul {
301
+ padding: 0 0 0 40px;
302
+ }
303
+
304
+ /*
305
+ * Corrects list images handled incorrectly in IE7
306
+ */
307
+
308
+ nav ul,
309
+ nav ol {
310
+ list-style: none;
311
+ list-style-image: none;
312
+ }
313
+
314
+ /* =============================================================================
315
+ Embedded content
316
+ ========================================================================== */
317
+ /*
318
+ * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
319
+ * 2. Improves image quality when scaled in IE7
320
+ * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
321
+ */
322
+
323
+ img {
324
+ border: 0;
325
+ /* 1 */
326
+ -ms-interpolation-mode: bicubic;
327
+ /* 2 */
328
+ }
329
+
330
+ /*
331
+ * Corrects overflow displayed oddly in IE9
332
+ */
333
+
334
+ svg:not(:root) {
335
+ overflow: hidden;
336
+ }
337
+
338
+ /* =============================================================================
339
+ Figures
340
+ ========================================================================== */
341
+ /*
342
+ * Addresses margin not present in IE6/7/8/9, S5, O11
343
+ */
344
+
345
+ figure {
346
+ margin: 0;
347
+ }
348
+
349
+ /* =============================================================================
350
+ Forms
351
+ ========================================================================== */
352
+ /*
353
+ * Corrects margin displayed oddly in IE6/7
354
+ */
355
+
356
+ form {
357
+ margin: 0;
358
+ }
359
+
360
+ /*
361
+ * Define consistent border, margin, and padding
362
+ */
363
+
364
+ fieldset {
365
+ border: 1px solid #c0c0c0;
366
+ margin: 0 2px;
367
+ padding: 0.35em 0.625em 0.75em;
368
+ }
369
+
370
+ /*
371
+ * 1. Corrects color not being inherited in IE6/7/8/9
372
+ * 2. Corrects text not wrapping in FF3
373
+ * 3. Corrects alignment displayed oddly in IE6/7
374
+ */
375
+
376
+ legend {
377
+ border: 0;
378
+ /* 1 */
379
+ padding: 0;
380
+ white-space: normal;
381
+ /* 2 */
382
+ *margin-left: -7px;
383
+ /* 3 */
384
+ }
385
+
386
+ /*
387
+ * 1. Corrects font size not being inherited in all browsers
388
+ * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
389
+ * 3. Improves appearance and consistency in all browsers
390
+ */
391
+
392
+ button,
393
+ input,
394
+ select,
395
+ textarea {
396
+ font-size: 100%;
397
+ /* 1 */
398
+ margin: 0;
399
+ /* 2 */
400
+ vertical-align: baseline;
401
+ /* 3 */
402
+ *vertical-align: middle;
403
+ /* 3 */
404
+ }
405
+
406
+ /*
407
+ * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
408
+ */
409
+
410
+ button,
411
+ input {
412
+ line-height: normal;
413
+ /* 1 */
414
+ }
415
+
416
+ /*
417
+ * 1. Improves usability and consistency of cursor style between image-type 'input' and others
418
+ * 2. Corrects inability to style clickable 'input' types in iOS
419
+ * 3. Removes inner spacing in IE7 without affecting normal text inputs
420
+ * Known issue: inner spacing remains in IE6
421
+ */
422
+
423
+ button,
424
+ input[type="button"],
425
+ input[type="reset"],
426
+ input[type="submit"] {
427
+ cursor: pointer;
428
+ /* 1 */
429
+ -webkit-appearance: button;
430
+ /* 2 */
431
+ *overflow: visible;
432
+ /* 3 */
433
+ }
434
+
435
+ /*
436
+ * Re-set default cursor for disabled elements
437
+ */
438
+
439
+ button[disabled],
440
+ input[disabled] {
441
+ cursor: default;
442
+ }
443
+
444
+ /*
445
+ * 1. Addresses box sizing set to content-box in IE8/9
446
+ * 2. Removes excess padding in IE8/9
447
+ * 3. Removes excess padding in IE7
448
+ Known issue: excess padding remains in IE6
449
+ */
450
+
451
+ input[type="checkbox"],
452
+ input[type="radio"] {
453
+ box-sizing: border-box;
454
+ /* 1 */
455
+ padding: 0;
456
+ /* 2 */
457
+ *height: 13px;
458
+ /* 3 */
459
+ *width: 13px;
460
+ /* 3 */
461
+ }
462
+
463
+ /*
464
+ * 1. Addresses appearance set to searchfield in S5, Chrome
465
+ * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
466
+ */
467
+
468
+ input[type="search"] {
469
+ -webkit-appearance: textfield;
470
+ /* 1 */
471
+ -moz-box-sizing: content-box;
472
+ -webkit-box-sizing: content-box;
473
+ /* 2 */
474
+ box-sizing: content-box;
475
+ }
476
+
477
+ /*
478
+ * Removes inner padding and search cancel button in S5, Chrome on OS X
479
+ */
480
+
481
+ input[type="search"]::-webkit-search-decoration,
482
+ input[type="search"]::-webkit-search-cancel-button {
483
+ -webkit-appearance: none;
484
+ }
485
+
486
+ /*
487
+ * Removes inner padding and border in FF3+
488
+ * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
489
+ */
490
+
491
+ button::-moz-focus-inner,
492
+ input::-moz-focus-inner {
493
+ border: 0;
494
+ padding: 0;
495
+ }
496
+
497
+ /*
498
+ * 1. Removes default vertical scrollbar in IE6/7/8/9
499
+ * 2. Improves readability and alignment in all browsers
500
+ */
501
+
502
+ textarea {
503
+ overflow: auto;
504
+ /* 1 */
505
+ vertical-align: top;
506
+ /* 2 */
507
+ }
508
+
509
+ /* =============================================================================
510
+ Tables
511
+ ========================================================================== */
512
+ /*
513
+ * Remove most spacing between table cells
514
+ */
515
+
516
+ table {
517
+ border-collapse: collapse;
518
+ border-spacing: 0;
519
+ }
520
+
521
+ @page {
522
+ margin: 3cm 2.5cm;
523
+ }
524
+
525
+ body {
526
+ font-family: 'Helvetica Neue LT Std', 'Helvetica Neue', Arial, Helvetica, sans-serif;
527
+ padding: 52pt;
528
+ color: #222;
529
+ font-size: 10pt;
530
+ }
531
+
532
+ img {
533
+ max-width: 100%;
534
+ }
535
+
536
+ article {
537
+ page-break-after: always;
538
+ max-width: 640pt;
539
+ margin: 0 auto;
540
+ padding: 0 0 6em 0;
541
+ }
542
+ .chapters article:last-child {
543
+ page-break-after: avoid;
544
+ }
545
+ article .break {
546
+ page-break-after: always;
547
+ }
548
+ article img {
549
+ max-width: 100%;
550
+ }
551
+ article figure {
552
+ padding: 1em 0;
553
+ }
554
+ article figure figcaption {
555
+ padding: 1em 0 0 0;
556
+ }
557
+ article .footnotes {
558
+ list-style: none;
559
+ padding: 1em 0 0 0;
560
+ font-size: 8pt;
561
+ }
562
+ article .footnotes li {
563
+ padding: .5em 0;
564
+ }
565
+
566
+ ul {
567
+ padding-left: 1em;
568
+ }
569
+ ul li {
570
+ padding: .25em 0;
571
+ }
572
+
573
+ h1 {
574
+ color: #000;
575
+ font-size: 40pt;
576
+ border-top: 1pt solid #000;
577
+ padding: .25em 0 .125em 0;
578
+ margin: 0;
579
+ line-height: 100%;
580
+ }
581
+ h1 + h2 {
582
+ margin-top: 0;
583
+ padding-top: 0;
584
+ border-top: none;
585
+ }
586
+
587
+ h2 {
588
+ color: #000;
589
+ font-size: 16pt;
590
+ font-weight: 200;
591
+ margin: 2em 0 0 0;
592
+ padding: .5em 0 1.5em 0;
593
+ border-top: 1pt solid #000;
594
+ }
595
+ h2 + h1 {
596
+ border-top: none;
597
+ padding-top: 0;
598
+ margin-top: -.5em;
599
+ }
600
+
601
+ h3, h4, h5, h6 {
602
+ color: #000;
603
+ font-weight: bold;
604
+ font-size: 15pt;
605
+ margin: 2em 0 0 0;
606
+ }
607
+
608
+ .cs1 {
609
+ color: #336699;
610
+ }
611
+
612
+ .cs2 {
613
+ color: #cc6600;
614
+ }
615
+
616
+ p {
617
+ line-height: 150%;
618
+ -webkit-font-smoothing: antialiased;
619
+ }
620
+
621
+ a {
622
+ color: #45bcd2;
623
+ }
624
+
625
+ table {
626
+ border-collapse: collapse;
627
+ }
628
+
629
+ th {
630
+ background-color: #efefef;
631
+ padding: 15px;
632
+ text-align: left;
633
+ }
634
+
635
+ td {
636
+ padding: 15px;
637
+ vertical-align: top;
638
+ }
639
+
640
+ table, td, th {
641
+ border: 1px solid gainsboro;
642
+ }