var cssFileName = 'ebook.css'; var ebookTitle = null; function getImagesIndex(allImages) { return allImages.reduce(function(prev, elem, index) { return prev + '\n' + ''; }, ''); } function getExternalLinksIndex() { // TODO return allExternalLinks.reduce(function(prev, elem, index) { return prev + '\n' + ''; }, ''); } function buildEbookFromChapters() { getEbookTitle(function (title) { ebookTitle = title; if (!ebookTitle || ebookTitle.trim().length === 0) { ebookTitle = 'eBook'; } getEbookPages(_buildEbook); }) } function buildEbook(allPages) { _buildEbook(allPages); } // http://ebooks.stackexchange.com/questions/1183/what-is-the-minimum-required-content-for-a-valid-epub function _buildEbook(allPages) { allPages = allPages.filter(function(page) { return page !== null; }); console.log('Prepare Content...'); var ebookFileName = 'eBook.epub'; if (ebookTitle) { // ~TODO a pre-processing function to apply escapeXMLChars to all page.titles ebookName = escapeXMLChars(ebookTitle); ebookFileName = getEbookFileName(ebookTitle) + '.epub'; } else { ebookName = escapeXMLChars(allPages[0].title); ebookFileName = getEbookFileName(allPages[0].title) + '.epub'; } var zip = new JSZip(); zip.file('mimetype', 'application/epub+zip'); var metaInfFolder = zip.folder("META-INF"); metaInfFolder.file('container.xml', '' + '' + '' + '' + '' + '' ); var oebps = zip.folder("OEBPS"); oebps.file('toc.xhtml', '' + '' + '' + 'toc.xhtml' + '' + '' + '' + '' + '' + '' ); oebps.file('toc.ncx', '' + '' + '' + '' + '' + '' + '' + '' + ebookName + '' + '' + '' + allPages.reduce(function(prev, page, index) { var tmpPageTitle = escapeXMLChars(page.title); return prev + '\n' + '' + '' + tmpPageTitle + '' + '' + ''; }, '') + '' + '' ); oebps.file(cssFileName, ''); //TODO var styleFolder = oebps.folder('style'); allPages.forEach(function(page) { styleFolder.file(page.styleFileName, page.styleFileContent); }); var pagesFolder = oebps.folder('pages'); allPages.forEach(function(page) { var tmpPageTitle = escapeXMLChars(page.title); pagesFolder.file(page.url, '' + '' + '' + '' + tmpPageTitle+ '' + '' + '' + page.content + '' ); }); oebps.file('content.opf', '' + '' + '' + ''+ ebookName + '' + 'isbn' + '' + new Date().toISOString().replace(/\.[0-9]+Z/i, 'Z') + '' + 'en' + '' + '' + '' + '' + '' + allPages.reduce(function(prev, page, index) { return prev + '\n' + ''; }, '') + allPages.reduce(function(prev, page, index) { return prev + '\n' + ''; }, '') + allPages.reduce(function(prev, page, index) { return prev + '\n' + getImagesIndex(page.images); }, '') + '' + '' + allPages.reduce(function(prev, page, index) { return prev + '\n' + ''; }, '') + '' + '' ); /////////////// var imgsFolder = oebps.folder("images"); allPages.forEach(function(page) { for (var i = 0; i < page.images.length; i++) { var tmpImg = page.images[i]; imgsFolder.file(tmpImg.filename, tmpImg.data, { base64: true }); } }); var done = false; zip.generateAsync({ type: "blob" }) .then(function(content) { done = true; console.log("done !"); saveAs(content, ebookFileName); }); setTimeout(function() { if (done) { return; } zip.generateAsync({ type: "blob" }) .then(function(content) { saveAs(content, ebookFileName); }); }, 60000); }