Skip to content

Instantly share code, notes, and snippets.

@pmuellr
Created December 16, 2010 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pmuellr/743312 to your computer and use it in GitHub Desktop.
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.
<!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("&", "&amp;").
replace("<", "&lt;").
replace(">", "&gt;")
}
//------------------------------------------------------------------------------
function main() {
$(load)
}
//------------------------------------------------------------------------------
main()
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment