Created
December 16, 2010 11:41
-
-
Save pmuellr/743312 to your computer and use it in GitHub Desktop.
Drop this file in an expanded .epub, it may create a page which can be saved as PDF and displayed nicely on a Kindle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<meta charset="utf-8" /> | |
<!-- | |
#------------------------------------------------------------------------------- | |
# Copyright (c) 2010 Patrick Mueller | |
# Licensed under the MIT license: | |
# http://www.opensource.org/licenses/mit-license.php | |
#------------------------------------------------------------------------------- | |
--> | |
<html> | |
<base href="OEBPS" /> | |
<head> | |
<title>some ePub</title> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script> | |
</head> | |
<body> | |
<div id="epub-to-kindle-html-div-status"> | |
starting... | |
</div> | |
<div id="epub-to-kindle-html-div-content"> | |
</div> | |
</body> | |
</html> | |
<!-- ======================================================================= --> | |
<style> | |
h1 { | |
font-size: 120%; | |
} | |
h1.title { | |
page-break-before: always; | |
} | |
body { | |
font-size: 180%; | |
font-family: Georgia; | |
margin: 0em; | |
padding: 0em; | |
} | |
pre { | |
font-size: 80%; | |
background-color: #EEE; | |
padding: 0.4em 0.5em; | |
border-style: solid; | |
border-width: thin; | |
border-radius: 0.5em; | |
-moz-border-radius: 0.5em; | |
page-break-inside: avoid; | |
} | |
.sidebar { | |
padding: 0.2em 0.5em; | |
border-style: solid; | |
border-width: thin; | |
border-radius: 0.5em; | |
-moz-border-radius: 0.5em; | |
background-color: #EEE; | |
} | |
.sidebar p.title { | |
font-weight: bold; | |
} | |
@import url("epub-to-kindle-html-overrides.css") | |
.epub-to-kindle-html-page-break-before { | |
page-break-before: always; | |
} | |
.epub-to-kindle-html-page-break-after { | |
page-break-after: always; | |
} | |
#epub-to-kindle-html-div-status { | |
background-color: #CCF; | |
border-style: solid; | |
padding: 0.25em 0.50em; | |
font-size: 120%; | |
font-weight: bold; | |
} | |
#epub-to-kindle-html-div-status .error { | |
background-color: #F77; | |
} | |
@media print { | |
#epub-to-kindle-html-div-button { | |
display: none; | |
} | |
#epub-to-kindle-html-div-status { | |
display: none; | |
} | |
} | |
</style> | |
<!-- ======================================================================= --> | |
<script> | |
var $content | |
var Manifest | |
//------------------------------------------------------------------------------ | |
function load() { | |
$content = $("#epub-to-kindle-html-div-content") | |
var containerXML = xhrLoadXML("META-INF/container.xml") | |
rootFileURLs = [] | |
$("rootfile", containerXML).each(function() { | |
var $this = $(this) | |
if ($this.attr("media-type") != "application/oebps-package+xml") return | |
rootFileURLs.push($this.attr("full-path")) | |
}) | |
updateStatus("root files: " + JSON.stringify(rootFileURLs)) | |
jQuery.each(rootFileURLs, function(i, rootFileURL) { | |
loadRootFile(rootFileURL) | |
}) | |
updateStatus() | |
} | |
//------------------------------------------------------------------------------ | |
function loadRootFile(rootFileURL) { | |
var doc = xhrLoadXML(rootFileURL) | |
// loadCover(doc) | |
loadFrontPage(doc) | |
loadManifest(doc) | |
loadPages(doc) | |
} | |
//------------------------------------------------------------------------------ | |
function loadCover(doc) { | |
var coverImageURL = $("#cover-image", doc).attr("href") | |
var imageContent = "<img src='OEBPS/" + coverImageURL + "' class='epub-to-kindle-html-page-break-after'>" | |
if (coverImageURL) appendContent(imageContent) | |
} | |
//------------------------------------------------------------------------------ | |
function loadFrontPage(doc) { | |
var dc = "http://purl.org/dc/elements/1.1/" | |
var dcIdentifier = $(gebtnNS(doc, dc, "identifier"), doc).text() | |
var dcTitle = $(gebtnNS(doc, dc, "title"), doc).text() | |
var dcRights = $(gebtnNS(doc, dc, "rights"), doc).text() | |
var dcPublisher = $(gebtnNS(doc, dc, "publisher"), doc).text() | |
var dcDate = $(gebtnNS(doc, dc, "date"), doc).text() | |
var dcDescription = $(gebtnNS(doc, dc, "description"), doc).text() | |
var dcCreator = $(gebtnNS(doc, dc, "creator"), doc).text() | |
if (dcIdentifier) dcIdentifier = dcIdentifier.escapeHTML() | |
if (dcTitle) dcTitle = dcTitle.escapeHTML() | |
if (dcRights) dcRights = dcRights.escapeHTML() | |
if (dcPublisher) dcPublisher = dcPublisher.escapeHTML() | |
if (dcDate) dcDate = dcDate.escapeHTML() | |
if (dcCreator) dcCreator = dcCreator.escapeHTML() | |
if (dcTitle) document.title = dcTitle | |
if (dcTitle) appendContent("<h1>" + dcTitle + "</h1>") | |
var html = [] | |
html.push("<table>") | |
if (dcCreator) html.push("<tr><td>Author:" + "<td>" + dcCreator) | |
if (dcPublisher) html.push("<tr><td>Publisher:" + "<td>" + dcPublisher) | |
if (dcDate) html.push("<tr><td>Date:" + "<td>" + dcDate) | |
if (dcIdentifier) html.push("<tr><td>Identifier:" + "<td>" + dcIdentifier) | |
if (dcRights) html.push("<tr><td>Rights:" + "<td>" + dcRights) | |
html.push("</table>") | |
appendContent(html.join("\n")) | |
if (dcDescription) appendContent("<p>" + dcDescription) | |
} | |
//------------------------------------------------------------------------------ | |
function loadManifest(doc) { | |
Manifest = {} | |
var items = $("manifest > item", doc) | |
items.each(function(i, item) { | |
item = $(item) | |
var id = item.attr("id") | |
var href = item.attr("href") | |
if (!id || !href) return | |
Manifest[id] = href | |
}) | |
} | |
//------------------------------------------------------------------------------ | |
function loadPages(doc) { | |
var pages = $("spine > itemref", doc) | |
pages.each(function(i, page) { | |
var idRef = $(page).attr("idref") | |
var href = Manifest[idRef] | |
if (!href) error("unable to find page for idref: " + idRef) | |
var page = xhrLoadText("OEBPS/" + href) | |
if (!page) error("unable to load page: " + href) | |
page = fixPage(page) | |
page = $(page) | |
$("img", page).each(function() { | |
var src = this.src.replace(/(.*)\/(.*)/, "$1/OEBPS/$2") | |
this.src = src | |
}) | |
appendContent("") | |
appendContent("<!-- from: " + href + " -->") | |
page.each(function() { | |
appendContent(this.innerHTML) | |
}) | |
updateStatus("added page: " + href) | |
}) | |
} | |
//------------------------------------------------------------------------------ | |
function fixPage(page) { | |
return page. | |
replace(/<\?xml(\n|.)*?>/i, "<!-- <?xml> -->"). | |
replace(/<!DOCTYPE(\n|.)*?>/i, "<!-- <!DOCTYPE> -->"). | |
replace(/<html(\n|.)*?>/i, "<!-- <html> --> "). | |
replace(/<\/html(\n|.)*?>/i, "<!-- </html> -->"). | |
replace(/<head(\n|.)*?>(\n|.)*<\/head(\n|.)*?>/i, "<!-- <head>...</head> -->"). | |
replace(/<body(\n|.)*?>/i, "<!-- <body> -->"). | |
replace(/<\/body(\n|.)*?>/i, "<!-- </body> -->") | |
} | |
//------------------------------------------------------------------------------ | |
function gebtnNS(context, ns, name) { | |
return context.getElementsByTagNameNS(ns, name) | |
} | |
//------------------------------------------------------------------------------ | |
function appendContent(content) { | |
$content.append(content) | |
} | |
//------------------------------------------------------------------------------ | |
function xhrLoadXML(url) { return _xhrLoad(url, true) } | |
function xhrLoadText(url) { return _xhrLoad(url, false) } | |
//------------------------------------------------------------------------------ | |
function _xhrLoad(url, xml) { | |
updateStatus("loading " + url) | |
var xhr = new XMLHttpRequest() | |
xhr.open("GET", url, false) | |
try { | |
xhr.send() | |
} | |
catch (e) { | |
throw error("error loading '" + url + "' during send(): " + e) | |
} | |
var status = xhr.status | |
if ((status != 200) && (status != 0)) { | |
throw error("error loading '" + url + "': " + status) | |
} | |
if (xml) { | |
if (xhr.responseXML) { | |
return xhr.responseXML | |
} | |
} | |
return xhr.responseText | |
} | |
//------------------------------------------------------------------------------ | |
function error(message) { | |
updateStatus(message, true) | |
throw new Error(message) | |
} | |
//------------------------------------------------------------------------------ | |
function updateStatus(message, error) { | |
var statusElement = $("#epub-to-kindle-html-div-status") | |
if (!message) { | |
statusElement.hide() | |
return | |
} | |
var className = "normal" | |
if (error) className = "error" | |
statusElement.append("<div class='" + className + "'>" + message.escapeHTML() + "</div>") | |
} | |
//------------------------------------------------------------------------------ | |
String.prototype.escapeHTML = function escapeHTML() { | |
return this. | |
replace("&", "&"). | |
replace("<", "<"). | |
replace(">", ">") | |
} | |
//------------------------------------------------------------------------------ | |
function main() { | |
$(load) | |
} | |
//------------------------------------------------------------------------------ | |
main() | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment