Add per-book covers

This commit is contained in:
Domenic Denicola 2020-07-01 15:50:34 -04:00
commit 354fb46819
7 changed files with 52 additions and 12 deletions

BIN
covers/ward/cover.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

22
covers/ward/cover.xhtml Normal file
View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cover</title>
<style>
body {
text-align: center;
margin: 0;
padding: 0;
}
img {
max-width: 100%;
height: 100%;
margin: 0 auto;
}
</style>
</head>
<body>
<img src="cover.jpg" alt=""/>
</body>
</html>

View file

Before

Width:  |  Height:  |  Size: 332 KiB

After

Width:  |  Height:  |  Size: 332 KiB

Before After
Before After

View file

@ -6,6 +6,8 @@
<style>
body {
text-align: center;
margin: 0;
padding: 0;
}
img {
max-width: 100%;

View file

@ -7,16 +7,16 @@ const BOOK_PUBLISHER = "Domenic Denicola";
const NCX_FILENAME = "toc.ncx";
const COVER_IMG_FILENAME = "cover.png";
const COVER_XHTML_FILENAME = "cover.xhtml";
const COVER_MIMETYPE = "image/png";
module.exports = async (scaffoldingPath, bookPath, contentPath, chaptersPath, manifestPath, bookInfo) => {
module.exports = async (scaffoldingPath, coverPath, bookPath, contentPath, chaptersPath, manifestPath, bookInfo) => {
await Promise.all([
cpr(scaffoldingPath, bookPath, { overwrite: true, confirm: true, filter: noThumbs }),
getChapters(contentPath, chaptersPath, manifestPath).then(chapters => {
cpr(coverPath, path.resolve(bookPath, "OEBPS"), { overwrite: true, confirm: true, filter: noThumbs }),
Promise.all([
getChapters(contentPath, chaptersPath, manifestPath),
getCoverFiles(coverPath)
]).then(([chapters, coverFiles]) => {
return Promise.all([
writeOPF(chapters, contentPath, bookInfo),
writeOPF(chapters, contentPath, coverFiles, bookInfo),
writeNcx(chapters, contentPath, bookInfo)
]);
})
@ -28,7 +28,7 @@ function noThumbs(filePath) {
return path.basename(filePath) !== "Thumbs.db";
}
function writeOPF(chapters, contentPath, bookInfo) {
function writeOPF(chapters, contentPath, coverFiles, bookInfo) {
const manifestChapters = chapters.map(c => {
return `<item id="${c.id}" href="${c.href}" media-type="application/xhtml+xml"/>`;
}).join("\n");
@ -52,8 +52,8 @@ function writeOPF(chapters, contentPath, bookInfo) {
<manifest>
<item id="ncx" href="${NCX_FILENAME}" media-type="application/x-dtbncx+xml"/>
<item id="cover" href="${COVER_XHTML_FILENAME}" media-type="application/xhtml+xml"/>
<item id="cover-image" href="${COVER_IMG_FILENAME}" media-type="${COVER_MIMETYPE}"/>
<item id="cover" href="${coverFiles.xhtml}" media-type="application/xhtml+xml"/>
<item id="cover-image" properties="cover-image" href="${coverFiles.image}" media-type="${coverFiles.imageMimeType}"/>
${manifestChapters}
</manifest>
@ -63,7 +63,7 @@ ${spineChapters}
</spine>
<guide>
<reference type="cover" title="Cover" href="${COVER_XHTML_FILENAME}"/>
<reference type="cover" title="Cover" href="${coverFiles.xhtml}"/>
</guide>
</package>`;
@ -123,3 +123,15 @@ async function getChapters(contentPath, chaptersPath, manifestPath) {
};
});
}
async function getCoverFiles(coverPath) {
const filenames = await fs.readdir(coverPath);
const images = filenames.filter(f => [".png", ".jpg"].includes(path.extname(f)));
if (images.length !== 1) {
throw new Error(`Expected one cover image in ${coverPath}; found ${images.length}`);
}
const imageMimeType = path.extname(images[0]) === ".png" ? "image/png" : "image/jpeg";
return { xhtml: "cover.xhtml", imageMimeType, image: images[0] };
}

View file

@ -69,6 +69,7 @@ const cachePath = path.resolve(argv.cache, argv.book);
const manifestPath = path.resolve(cachePath, "manifest.json");
const scaffoldingPath = path.resolve(__dirname, "../scaffolding");
const coverPath = path.resolve(__dirname, "../covers", argv.book);
const stagingPath = path.resolve(argv.staging, argv.book);
const contentPath = path.resolve(stagingPath, "OEBPS");
const chaptersPath = path.resolve(contentPath, "chapters");
@ -90,7 +91,9 @@ if (argv._.includes("convert")) {
if (argv._.includes("scaffold")) {
const bookInfo = books[argv.book];
commands.push(() => scaffold(scaffoldingPath, stagingPath, contentPath, chaptersPath, manifestPath, bookInfo));
commands.push(() => scaffold(
scaffoldingPath, coverPath, stagingPath, contentPath, chaptersPath, manifestPath, bookInfo
));
}
if (argv._.includes("zip")) {

View file

@ -13,6 +13,7 @@
"repository": "domenic/worm-scraper",
"bin": "lib/worm-scraper.js",
"files": [
"covers/",
"lib/",
"scaffolding/",
"npm-shrinkwrap.json"