'use strict'; const core = require('@epubook/core'); const path = require('node:path'); function _interopNamespaceCompat(e) { if (e && typeof e === 'object' && 'default' in e) return e; const n = Object.create(null); if (e) { for (const k in e) { n[k] = e[k]; } } n.default = e; return n; } const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path); class Cover extends core.XHTML { static from(image, xhtml) { const cover = new Cover(xhtml.filename(), xhtml.meta(), xhtml.content()); cover._image = image; return cover; } image() { return this._image; } } class EpubookError extends Error { constructor(msg) { super(msg); } } const TextDir = "text"; const ImageDir = "images"; class Epubook { constructor(option) { this._spine = []; this._styles = []; this.counter = { image: 0 }; this._option = { title: "unknown", description: "unknown", language: "zh-CN", author: [{ name: "unknown" }], ...option }; this._container = new core.Epub({ creator: this._option.creator ?? this._option.author[0], contributor: this._option.contributor ?? this._option.author.slice(1), ...this._option }); } static async create(option) { const epubook = new Epubook(option); await epubook.loadTheme(option.theme); return epubook; } async loadTheme(theme) { if (theme) { this.theme = theme; } else { const { DefaultTheme } = await import('@epubook/theme-default'); this.theme = await DefaultTheme(); } this._styles = this.theme.styles.length === 1 ? [new core.Style(`styles/style.css`, this.theme.styles[0])] : this.theme.styles.map((s, idx) => new core.Style(`styles/style-${idx}.css`, s)); this._container.item(...this._styles); return this; } extend(theme) { this.theme.pages = { ...this.theme.pages, ...theme.pages }; return this; } epub() { return this._container; } meta(info) { if (info.language) { this._option.language = info.language; } this._container.main().update(info); return this; } async loadImage(file, img, ext) { let image; if (typeof img === "string") { ext = path__namespace.extname(img); image = await core.Image.read(file, img); } else if (ext) { const media = core.getImageMediaType(ext); if (media) { image = new core.Image(file, media, img); } } if (image) { this._container.item(image); } return image; } async image(img, ext) { if (typeof img === "string") { ext = path__namespace.extname(img).slice(1); } this.counter.image++; const image = typeof img === "string" ? await this.loadImage(`${ImageDir}/${path__namespace.basename(img)}`, img) : await this.loadImage(`${ImageDir}/image-${this.counter.image}.${ext}`, img, ext); return image; } async cover(img, ext) { if (typeof img === "string") { ext = path__namespace.extname(img).slice(1); } const image = typeof img === "string" ? await this.loadImage(`${ImageDir}/cover.${ext}`, img) : await this.loadImage(`${ImageDir}/cover.${ext}`, img, ext); if (image) { image.update({ properties: "cover-image" }); const builder = this.pageBuilder("cover", { image }, { file: `cover.xhtml` }); this._cover = Cover.from(image, builder.build()); this._container.item(this._cover); return this._cover; } else { throw new EpubookError("Can not load image"); } } /** * Do not forget adding the generate page to container * * @param template Use specify template to generate XHTML * @param props Generate props * @param option * @returns */ pageBuilder(template, props, option = {}) { const render = this.theme.pages[template]; const file = option.file ?? `${TextDir}/${template}-${this.counter[template] ?? 1}.xhtml`; if (!option.file) { if (!this.counter[template]) { this.counter[template] = 2; } else { this.counter[template]++; } } return render(file, props).style(...this._styles).language(this._option.language ?? "zh-CN"); } page(template, props) { const builder = this.pageBuilder(template, props); const xhtml = builder.build(); this._container.item(xhtml); return xhtml; } // TODO: add toc page self to toc toc(...items) { const nav = items.map( (i) => i instanceof core.XHTML ? { title: i.title(), page: i } : { title: i.title, list: i.list.map((i2) => ({ title: i2.title(), page: i2 })) } ); const option = {}; option.builder = this.pageBuilder("nav", { nav, option }, { file: "nav.xhtml" }); this._container.toc(nav, option); const spine = items.flatMap((i) => i instanceof core.XHTML ? [i] : i.list); this.spine(...spine); return this._toc = this._container.main().toc(); } spine(...items) { this._spine.splice(0, this._spine.length, ...items); this._container.spine(...this._spine); return this; } async bundle() { return this._container.bundle(); } async writeFile(file) { return this._container.writeFile(file); } } exports.Epubook = Epubook; Object.keys(core).forEach(function (k) { if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) exports[k] = core[k]; });