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.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +91 -0
- data/lib/ebookie.rb +16 -0
- data/lib/ebookie/cli.rb +20 -0
- data/lib/ebookie/document.rb +16 -0
- data/lib/ebookie/document/base.rb +49 -0
- data/lib/ebookie/document/chapter.rb +26 -0
- data/lib/ebookie/document/config.rb +43 -0
- data/lib/ebookie/document/image.rb +29 -0
- data/lib/ebookie/rendering.rb +10 -0
- data/lib/ebookie/rendering/base.rb +156 -0
- data/lib/ebookie/rendering/epub.rb +60 -0
- data/lib/ebookie/rendering/mobi.rb +31 -0
- data/lib/ebookie/rendering/pdf.rb +104 -0
- data/lib/ebookie/templates/epub/META-INF/container.xml +6 -0
- data/lib/ebookie/templates/epub/OEBPS/chapter.erb +12 -0
- data/lib/ebookie/templates/epub/OEBPS/content.opf.erb +50 -0
- data/lib/ebookie/templates/epub/OEBPS/epub.css +68 -0
- data/lib/ebookie/templates/epub/OEBPS/toc.ncx.erb +21 -0
- data/lib/ebookie/templates/epub/mimetype +1 -0
- data/lib/ebookie/templates/pdf/cover.html.erb +9 -0
- data/lib/ebookie/templates/pdf/document.html.erb +16 -0
- data/lib/ebookie/templates/pdf/pdf.css +642 -0
- data/lib/ebookie/version.rb +3 -0
- metadata +270 -0
@@ -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
|
+
"—" => "—"
|
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,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,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
|
+
}
|