mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
fix(import): import the cover image
The EPUB cover was discarded and replaced with the default generated cover. Locate the cover via the manifest cover-image property or the meta name="cover" reference, resolve it to a data URI, and import it as an image cover. Claude-Session: https://claude.ai/code/session_01RzTWrLiy4zGuw2hZSQGamk
This commit is contained in:
1 parent
983d8fd2c0
commit
5caf66a6fc
1 file changed
+27
-5
+27
-5
@@ -1,7 +1,7 @@
|
|||||||
import { invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
import { open } from "@tauri-apps/plugin-dialog";
|
import { open } from "@tauri-apps/plugin-dialog";
|
||||||
import type { JSONContent } from "@tiptap/core";
|
import type { JSONContent } from "@tiptap/core";
|
||||||
import { type Book, type BookMetadata, type Chapter, createCover } from "../model/book";
|
import { type Book, type BookMetadata, type Chapter, type Cover, createCover } from "../model/book";
|
||||||
|
|
||||||
export interface RawFile {
|
export interface RawFile {
|
||||||
path: string;
|
path: string;
|
||||||
@@ -357,6 +357,11 @@ function readNavTitles(
|
|||||||
return titles;
|
return titles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fileToDataUri(file: RawFile, mime: string): string {
|
||||||
|
const data = file.encoding === "base64" ? file.data : btoa(unescape(encodeURIComponent(file.data)));
|
||||||
|
return `data:${mime};base64,${data}`;
|
||||||
|
}
|
||||||
|
|
||||||
function resolveImages(
|
function resolveImages(
|
||||||
doc: Document,
|
doc: Document,
|
||||||
baseDir: string,
|
baseDir: string,
|
||||||
@@ -375,12 +380,29 @@ function resolveImages(
|
|||||||
img.removeAttribute("src");
|
img.removeAttribute("src");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const mime = mimeByPath.get(resolved) || mimeFromExt(resolved);
|
img.setAttribute("src", fileToDataUri(file, mimeByPath.get(resolved) || mimeFromExt(resolved)));
|
||||||
const data = file.encoding === "base64" ? file.data : btoa(unescape(encodeURIComponent(file.data)));
|
|
||||||
img.setAttribute("src", `data:${mime};base64,${data}`);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findCover(
|
||||||
|
opf: Document,
|
||||||
|
manifest: Map<string, ManifestItem>,
|
||||||
|
byPath: Map<string, RawFile>,
|
||||||
|
): Cover {
|
||||||
|
let item = Array.from(manifest.values()).find((m) => m.properties.split(/\s+/).includes("cover-image"));
|
||||||
|
if (!item) {
|
||||||
|
const metaCover = Array.from(opf.getElementsByTagName("*")).find(
|
||||||
|
(el) => el.localName === "meta" && el.getAttribute("name") === "cover",
|
||||||
|
);
|
||||||
|
const id = metaCover?.getAttribute("content");
|
||||||
|
if (id) item = manifest.get(id);
|
||||||
|
}
|
||||||
|
if (!item) return createCover();
|
||||||
|
const file = byPath.get(normalize(item.href));
|
||||||
|
if (!file) return createCover();
|
||||||
|
return { ...createCover(), kind: "image", image: fileToDataUri(file, item.mediaType || mimeFromExt(item.href)) };
|
||||||
|
}
|
||||||
|
|
||||||
function buildChapter(
|
function buildChapter(
|
||||||
file: RawFile,
|
file: RawFile,
|
||||||
baseDir: string,
|
baseDir: string,
|
||||||
@@ -455,7 +477,7 @@ export function filesToBook(files: RawFile[], fallbackName = "Imported book"): B
|
|||||||
metadata,
|
metadata,
|
||||||
theme: "quiet-press",
|
theme: "quiet-press",
|
||||||
settings: { trim: "6x9", bleed: true },
|
settings: { trim: "6x9", bleed: true },
|
||||||
cover: createCover(),
|
cover: findCover(opf, manifest, byPath),
|
||||||
chapters,
|
chapters,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user