Add per-book covers
This commit is contained in:
parent
a700e29299
commit
354fb46819
7 changed files with 52 additions and 12 deletions
BIN
covers/ward/cover.jpg
Normal file
BIN
covers/ward/cover.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 768 KiB |
22
covers/ward/cover.xhtml
Normal file
22
covers/ward/cover.xhtml
Normal 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>
|
||||||
|
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
|
|
@ -6,6 +6,8 @@
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
@ -7,16 +7,16 @@ const BOOK_PUBLISHER = "Domenic Denicola";
|
||||||
|
|
||||||
const NCX_FILENAME = "toc.ncx";
|
const NCX_FILENAME = "toc.ncx";
|
||||||
|
|
||||||
const COVER_IMG_FILENAME = "cover.png";
|
module.exports = async (scaffoldingPath, coverPath, bookPath, contentPath, chaptersPath, manifestPath, bookInfo) => {
|
||||||
const COVER_XHTML_FILENAME = "cover.xhtml";
|
|
||||||
const COVER_MIMETYPE = "image/png";
|
|
||||||
|
|
||||||
module.exports = async (scaffoldingPath, bookPath, contentPath, chaptersPath, manifestPath, bookInfo) => {
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
cpr(scaffoldingPath, bookPath, { overwrite: true, confirm: true, filter: noThumbs }),
|
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([
|
return Promise.all([
|
||||||
writeOPF(chapters, contentPath, bookInfo),
|
writeOPF(chapters, contentPath, coverFiles, bookInfo),
|
||||||
writeNcx(chapters, contentPath, bookInfo)
|
writeNcx(chapters, contentPath, bookInfo)
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
|
|
@ -28,7 +28,7 @@ function noThumbs(filePath) {
|
||||||
return path.basename(filePath) !== "Thumbs.db";
|
return path.basename(filePath) !== "Thumbs.db";
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeOPF(chapters, contentPath, bookInfo) {
|
function writeOPF(chapters, contentPath, coverFiles, bookInfo) {
|
||||||
const manifestChapters = chapters.map(c => {
|
const manifestChapters = chapters.map(c => {
|
||||||
return `<item id="${c.id}" href="${c.href}" media-type="application/xhtml+xml"/>`;
|
return `<item id="${c.id}" href="${c.href}" media-type="application/xhtml+xml"/>`;
|
||||||
}).join("\n");
|
}).join("\n");
|
||||||
|
|
@ -52,8 +52,8 @@ function writeOPF(chapters, contentPath, bookInfo) {
|
||||||
|
|
||||||
<manifest>
|
<manifest>
|
||||||
<item id="ncx" href="${NCX_FILENAME}" media-type="application/x-dtbncx+xml"/>
|
<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" href="${coverFiles.xhtml}" media-type="application/xhtml+xml"/>
|
||||||
<item id="cover-image" href="${COVER_IMG_FILENAME}" media-type="${COVER_MIMETYPE}"/>
|
<item id="cover-image" properties="cover-image" href="${coverFiles.image}" media-type="${coverFiles.imageMimeType}"/>
|
||||||
${manifestChapters}
|
${manifestChapters}
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ ${spineChapters}
|
||||||
</spine>
|
</spine>
|
||||||
|
|
||||||
<guide>
|
<guide>
|
||||||
<reference type="cover" title="Cover" href="${COVER_XHTML_FILENAME}"/>
|
<reference type="cover" title="Cover" href="${coverFiles.xhtml}"/>
|
||||||
</guide>
|
</guide>
|
||||||
</package>`;
|
</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] };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ const cachePath = path.resolve(argv.cache, argv.book);
|
||||||
const manifestPath = path.resolve(cachePath, "manifest.json");
|
const manifestPath = path.resolve(cachePath, "manifest.json");
|
||||||
|
|
||||||
const scaffoldingPath = path.resolve(__dirname, "../scaffolding");
|
const scaffoldingPath = path.resolve(__dirname, "../scaffolding");
|
||||||
|
const coverPath = path.resolve(__dirname, "../covers", argv.book);
|
||||||
const stagingPath = path.resolve(argv.staging, argv.book);
|
const stagingPath = path.resolve(argv.staging, argv.book);
|
||||||
const contentPath = path.resolve(stagingPath, "OEBPS");
|
const contentPath = path.resolve(stagingPath, "OEBPS");
|
||||||
const chaptersPath = path.resolve(contentPath, "chapters");
|
const chaptersPath = path.resolve(contentPath, "chapters");
|
||||||
|
|
@ -90,7 +91,9 @@ if (argv._.includes("convert")) {
|
||||||
|
|
||||||
if (argv._.includes("scaffold")) {
|
if (argv._.includes("scaffold")) {
|
||||||
const bookInfo = books[argv.book];
|
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")) {
|
if (argv._.includes("zip")) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"repository": "domenic/worm-scraper",
|
"repository": "domenic/worm-scraper",
|
||||||
"bin": "lib/worm-scraper.js",
|
"bin": "lib/worm-scraper.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
"covers/",
|
||||||
"lib/",
|
"lib/",
|
||||||
"scaffolding/",
|
"scaffolding/",
|
||||||
"npm-shrinkwrap.json"
|
"npm-shrinkwrap.json"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue