Multiple levels of TOC + meta info.
This commit is contained in:
131
src/epub.js
131
src/epub.js
@@ -101,15 +101,30 @@ class EpubOpf{
|
|||||||
<dc:rights>Please read the legal notice included in this e-book and/or check the copyright status in your country.</dc:rights>
|
<dc:rights>Please read the legal notice included in this e-book and/or check the copyright status in your country.</dc:rights>
|
||||||
<dc:identifier id="pub-id">${m.metadata.book_id}</dc:identifier>
|
<dc:identifier id="pub-id">${m.metadata.book_id}</dc:identifier>
|
||||||
<dc:title>${m.metadata.title}</dc:title>
|
<dc:title>${m.metadata.title}</dc:title>
|
||||||
<dc:language>${m.metadata.language}</dc:language>\n`
|
<dc:language>${m.metadata.language}</dc:language>
|
||||||
|
`
|
||||||
|
|
||||||
|
if (m.metadata.description){
|
||||||
|
cnt += ` <dc:description>${m.metadata.description}</dc:description>\n`
|
||||||
|
}
|
||||||
|
if (m.metadata.isbn){
|
||||||
|
cnt += ` <dc:identifier id="isbn">${m.metadata.isbn}</dc:identifier>\n`
|
||||||
|
let onixcode = m.metadata.isbn.length > 10 ? '15' : '02'
|
||||||
|
cnt += ` <meta refines="#isbn" property="identifier-type" scheme="onix:codelist5">${onixcode}</meta>\n`
|
||||||
|
}
|
||||||
if (m.metadata.publisher){
|
if (m.metadata.publisher){
|
||||||
cnt += ` <dc:publisher>${m.metadata.publisher}</dc:publisher>\n`
|
cnt += ` <dc:publisher>${m.metadata.publisher}</dc:publisher>\n`
|
||||||
}
|
}
|
||||||
if (m.metadata.cover_image){
|
if (m.metadata.cover_image){
|
||||||
cnt += ` <meta content="cover-image" name="${m.metadata.cover_image}"/>\n`
|
cnt += ` <meta content="cover-image" name="${m.metadata.cover_image}"/>\n`
|
||||||
}
|
}
|
||||||
// <dc:creator opf:file-as="Greatness, Georgia's" opf:role="aut">Lauren Baratz-Logsted</dc:creator>
|
for (let s in m.metadata.subject){
|
||||||
|
cnt += ` <dc:subject>${m.metadata.subject[s]}</dc:subject>\n`
|
||||||
|
}
|
||||||
|
for (let a in m.metadata.author){
|
||||||
|
cnt += ` <dc:creator id="creator-${a}">${m.metadata.author[a]}</dc:creator>\n`
|
||||||
|
cnt += ` <meta refines="#creator-${a}" property="role" schema="marc:relators">aut</meta>\n`
|
||||||
|
}
|
||||||
|
|
||||||
cnt +=' </metadata>\n <manifest>\n'
|
cnt +=' </metadata>\n <manifest>\n'
|
||||||
|
|
||||||
@@ -141,11 +156,37 @@ class EpubNcx{
|
|||||||
|
|
||||||
generate(){
|
generate(){
|
||||||
let m = this.meta
|
let m = this.meta
|
||||||
let cnt = `<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
let max_depth = 0;
|
||||||
|
let toc = ''
|
||||||
|
for (let i = 0; i < m.toc.length; ++i) {
|
||||||
|
let toc_item = m.toc[i]
|
||||||
|
toc +=
|
||||||
|
` <navPoint class="chapter" id="navpoint-${i}" playOrder="${i}">\n`
|
||||||
|
+` <navLabel><text>${toc_item.label}</text></navLabel>\n`
|
||||||
|
+` <content src="${toc_item.href}"/>\n`
|
||||||
|
|
||||||
|
if (max_depth < toc_item.depth) {
|
||||||
|
max_depth = toc_item.depth
|
||||||
|
}
|
||||||
|
|
||||||
|
let next_depth = 1
|
||||||
|
if (i+1 < m.toc.length) {
|
||||||
|
next_depth = m.toc[i+1].depth
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let current_dept = toc_item.depth;
|
||||||
|
current_dept >= next_depth;
|
||||||
|
current_dept--) {
|
||||||
|
toc += ' </navPoint>\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" xml:lang="en" version="2005-1">
|
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" xml:lang="en" version="2005-1">
|
||||||
<head>
|
<head>
|
||||||
<meta name="dtb:uid" content="${m.metadata.book_id}"/>
|
<meta name="dtb:uid" content="${m.metadata.book_id}"/>
|
||||||
<meta name="dtb:depth" content="2"/>
|
<meta name="dtb:depth" content="${max_depth}"/>
|
||||||
<meta name="dtb:totalPageCount" content="0"/>
|
<meta name="dtb:totalPageCount" content="0"/>
|
||||||
<meta name="dtb:maxPageNumber" content="0"/>
|
<meta name="dtb:maxPageNumber" content="0"/>
|
||||||
</head>
|
</head>
|
||||||
@@ -153,18 +194,10 @@ class EpubNcx{
|
|||||||
<text>${m.metadata.title}</text>
|
<text>${m.metadata.title}</text>
|
||||||
</docTitle>
|
</docTitle>
|
||||||
<navMap>
|
<navMap>
|
||||||
|
${toc}
|
||||||
|
</navMap>
|
||||||
|
</ncx>
|
||||||
`
|
`
|
||||||
for (let i in this.meta.toc){
|
|
||||||
let toc_item = this.meta.toc[i]
|
|
||||||
cnt +=
|
|
||||||
` <navPoint class="chapter" id="navpoint-${i}" playOrder="${i}">\n`
|
|
||||||
+` <navLabel><text>${toc_item.label}</text></navLabel>\n`
|
|
||||||
+` <content src="${toc_item.filename}"/>\n`
|
|
||||||
+' </navPoint>\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt += ' </navMap>\n</ncx>\n'
|
|
||||||
return cnt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +210,35 @@ class EpubNav{
|
|||||||
|
|
||||||
generate(){
|
generate(){
|
||||||
let m = this.meta
|
let m = this.meta
|
||||||
let cnt = `<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
|
||||||
|
let toc = ''
|
||||||
|
for (let i = 0; i < m.toc.length; ++i){
|
||||||
|
let toc_item = m.toc[i]
|
||||||
|
toc += ` <li><a href="${toc_item.href}">${toc_item.label}</a>`
|
||||||
|
|
||||||
|
let next_depth = 1
|
||||||
|
if (i+1 < m.toc.length){
|
||||||
|
next_depth = m.toc[i+1].depth
|
||||||
|
}
|
||||||
|
let current_dept = toc_item.depth
|
||||||
|
|
||||||
|
if (current_dept == next_depth){
|
||||||
|
toc += ' </li>\n'
|
||||||
|
}
|
||||||
|
else if (current_dept < next_depth){
|
||||||
|
for (; current_dept < next_depth; current_dept++){
|
||||||
|
toc += ' <ol>\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (current_dept > next_depth){
|
||||||
|
for (; current_dept > next_depth; current_dept--){
|
||||||
|
toc += ' </li></ol>\n'
|
||||||
|
}
|
||||||
|
toc += ' </li>\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xmlns:epub="http://www.idpf.org/2007/ops">
|
xmlns:epub="http://www.idpf.org/2007/ops">
|
||||||
@@ -189,14 +250,12 @@ class EpubNav{
|
|||||||
<nav epub:type="toc" id="toc">
|
<nav epub:type="toc" id="toc">
|
||||||
<h2>Table Of Content</h2>
|
<h2>Table Of Content</h2>
|
||||||
<ol>
|
<ol>
|
||||||
|
${toc}
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
`
|
`
|
||||||
for (let i in this.meta.toc){
|
|
||||||
let toc_item = this.meta.toc[i]
|
|
||||||
cnt += ` <li><a href="${toc_item.filename}">${toc_item.label}</a></li>\n`
|
|
||||||
}
|
|
||||||
|
|
||||||
cnt += ' </ol>\n </nav>\n</body>\n</html>\n'
|
|
||||||
return cnt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,11 +263,14 @@ class EpubMeta{
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.metadata = {
|
this.metadata = {
|
||||||
book_id: 'book_id',
|
book_id: 'book_id',
|
||||||
|
isbn: null,
|
||||||
title: 'title',
|
title: 'title',
|
||||||
language: 'en',
|
language: 'en',
|
||||||
author: 'author',
|
author: [],
|
||||||
publisher: 'publisher',
|
publisher: null,
|
||||||
cover_image: 'cover.img'
|
cover_image: null,
|
||||||
|
subject: [],
|
||||||
|
description: null
|
||||||
}
|
}
|
||||||
this.manifest = {}
|
this.manifest = {}
|
||||||
this.spine = []
|
this.spine = []
|
||||||
@@ -228,14 +290,23 @@ class EpubMeta{
|
|||||||
this.metadata.title = title
|
this.metadata.title = title
|
||||||
}
|
}
|
||||||
addAuthor(author){
|
addAuthor(author){
|
||||||
this.metadata.author = author
|
this.metadata.author.push(author)
|
||||||
}
|
}
|
||||||
addPublisher(publisher){
|
addPublisher(publisher){
|
||||||
this.metadata.publisher = publisher
|
this.metadata.publisher = publisher
|
||||||
}
|
}
|
||||||
|
addSubject(subject){
|
||||||
|
this.metadata.subject.push(subject)
|
||||||
|
}
|
||||||
addLanguage(lang){
|
addLanguage(lang){
|
||||||
this.metadata.language = lang
|
this.metadata.language = lang
|
||||||
}
|
}
|
||||||
|
addDescription(description){
|
||||||
|
this.metadata.description = description
|
||||||
|
}
|
||||||
|
addIsbn(isbn){
|
||||||
|
this.metadata.isbn = isbn
|
||||||
|
}
|
||||||
|
|
||||||
addMetaData(){
|
addMetaData(){
|
||||||
}
|
}
|
||||||
@@ -275,11 +346,8 @@ class EpubMeta{
|
|||||||
}
|
}
|
||||||
|
|
||||||
addToc(filename, label, depth){
|
addToc(filename, label, depth){
|
||||||
if (filename in this.override){
|
|
||||||
filename = this.override[filename].filename
|
|
||||||
}
|
|
||||||
this.toc.push({
|
this.toc.push({
|
||||||
filename: filename,
|
href: filename,
|
||||||
label: label,
|
label: label,
|
||||||
depth: depth
|
depth: depth
|
||||||
})
|
})
|
||||||
@@ -327,7 +395,6 @@ class EpubWriter{
|
|||||||
|
|
||||||
if (filename in this.meta.override){
|
if (filename in this.meta.override){
|
||||||
let o = this.meta.override[filename]
|
let o = this.meta.override[filename]
|
||||||
filename = o.filename
|
|
||||||
content = o.convert(content)
|
content = o.convert(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,21 +210,30 @@ function fillMetadata(epub, book)
|
|||||||
{
|
{
|
||||||
epub.meta.addTitle(book.book_info.title)
|
epub.meta.addTitle(book.book_info.title)
|
||||||
epub.meta.addLanguage(book.book_info.language)
|
epub.meta.addLanguage(book.book_info.language)
|
||||||
|
if (book.book_info.isbn){
|
||||||
epub.meta.addBookId(book.book_info.isbn)
|
epub.meta.addBookId(book.book_info.isbn)
|
||||||
|
}
|
||||||
|
if (book.book_info.description){
|
||||||
|
epub.meta.addDescription(book.book_info.description)
|
||||||
|
}
|
||||||
|
epub.meta.addIsbn(book.book_info.isbn)
|
||||||
for (let i in book.book_info.authors){
|
for (let i in book.book_info.authors){
|
||||||
let author = book.book_info.authors[i]
|
let author = book.book_info.authors[i]
|
||||||
epub.meta.addAuthor(author)
|
epub.meta.addAuthor(author.name)
|
||||||
}
|
}
|
||||||
for (let i in book.book_info.publishers){
|
for (let i in book.book_info.publishers){
|
||||||
let publisher = book.book_info.publishers[i]
|
let publisher = book.book_info.publishers[i]
|
||||||
epub.meta.addPublisher(publisher.name)
|
epub.meta.addPublisher(publisher.name)
|
||||||
}
|
}
|
||||||
|
for (let i in book.book_info.subjects){
|
||||||
|
let subject = book.book_info.subjects[i]
|
||||||
|
epub.meta.addSubject(subject.name)
|
||||||
|
}
|
||||||
|
|
||||||
// # The metadata element or deprecated dc-metadata element contains
|
// # The metadata element or deprecated dc-metadata element contains
|
||||||
// # at least one identifier element, at least one title element,
|
// # at least one identifier element, at least one title element,
|
||||||
// # and at least one language element drawn from the Dublin Core tag
|
// # and at least one language element drawn from the Dublin Core tag
|
||||||
// # set.
|
// # set.
|
||||||
// epub.set_title('Test Title')
|
|
||||||
// epub.set_language('en')
|
|
||||||
// epub.set_direction('ltr')
|
// epub.set_direction('ltr')
|
||||||
// # epub.set_cover(file_name, content, create_page=True):
|
// # epub.set_cover(file_name, content, create_page=True):
|
||||||
// # epub.add_author(author, file_as=None, role=None, uid='creator'):
|
// # epub.add_author(author, file_as=None, role=None, uid='creator'):
|
||||||
@@ -259,14 +268,20 @@ function fillHtmlComponents(epub, book)
|
|||||||
|
|
||||||
function fillToc(epub, book)
|
function fillToc(epub, book)
|
||||||
{
|
{
|
||||||
for (let i in book.book_toc){
|
let helper = function(epub, book_toc){
|
||||||
let toc_item = book.book_toc[i]
|
for (let i in book_toc){
|
||||||
|
let toc_item = book_toc[i]
|
||||||
epub.meta.addToc(
|
epub.meta.addToc(
|
||||||
toc_item.filename,
|
toc_item.href,
|
||||||
toc_item.label,
|
toc_item.label,
|
||||||
toc_item.depth)
|
toc_item.depth)
|
||||||
|
if ('children' in toc_item) {
|
||||||
|
helper(epub, toc_item.children)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
helper(epub,book.book_toc)
|
||||||
|
}
|
||||||
|
|
||||||
function fillSpine(epub, book)
|
function fillSpine(epub, book)
|
||||||
{
|
{
|
||||||
@@ -277,23 +292,21 @@ function fillSpine(epub, book)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillGuide(epub, book)
|
function createEpubStructure(book, epub){
|
||||||
{}
|
|
||||||
|
|
||||||
function createEpub(book, epub){
|
|
||||||
epub.addMetaInfoFile("book.json", JSON.stringify(book, null, '\t'))
|
epub.addMetaInfoFile("book.json", JSON.stringify(book, null, '\t'))
|
||||||
|
|
||||||
// OPF file info.
|
// OPF file info.
|
||||||
fillManifest(epub, book)
|
fillManifest(epub, book)
|
||||||
fillSpine(epub, book)
|
fillSpine(epub, book)
|
||||||
fillGuide(epub, book)
|
|
||||||
fillMetadata(epub, book)
|
fillMetadata(epub, book)
|
||||||
|
|
||||||
// NCX and NAV files.
|
// NCX and NAV files.
|
||||||
fillToc(epub, book)
|
fillToc(epub, book)
|
||||||
|
|
||||||
fillHtmlComponents(epub, book)
|
fillHtmlComponents(epub, book)
|
||||||
|
}
|
||||||
|
|
||||||
|
function createEpub(book, epub){
|
||||||
for (let url in book.book_files){
|
for (let url in book.book_files){
|
||||||
file = book.book_files[url]
|
file = book.book_files[url]
|
||||||
epub.addFile(file.filename, file.body)
|
epub.addFile(file.filename, file.body)
|
||||||
@@ -316,6 +329,7 @@ function onDownloadBookClicked(){
|
|||||||
// .then(() => { return page.renderChapterList(book); })
|
// .then(() => { return page.renderChapterList(book); })
|
||||||
.then(() => { return book.downloadMetaContent(); })
|
.then(() => { return book.downloadMetaContent(); })
|
||||||
.then(() => { return book.downloadContent(); })
|
.then(() => { return book.downloadContent(); })
|
||||||
|
.then(() => { return createEpubStructure(book, epub); })
|
||||||
.then(() => { return createEpub(book, epub); })
|
.then(() => { return createEpub(book, epub); })
|
||||||
.then(() => { return epub.generateAsync(); })
|
.then(() => { return epub.generateAsync(); })
|
||||||
.then((file) => {
|
.then((file) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user