ebookie 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }