Multiple levels of TOC + meta info.

This commit is contained in:
Vahagn Khachatryan
2019-01-16 01:18:14 +00:00
parent 6b8a60d8c0
commit e7e723f1cf
2 changed files with 129 additions and 48 deletions

View File

@@ -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)
} }

View File

@@ -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) => {