From 5082a7b07239988fa025e8d25a131a280eae2fb3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 28 May 2010 21:46:50 -0600 Subject: [PATCH] Replace genshi with lxml when generating NCX files --- resources/templates/ncx.xml | 35 --------------- src/calibre/ebooks/metadata/toc.py | 69 ++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 43 deletions(-) delete mode 100644 resources/templates/ncx.xml diff --git a/resources/templates/ncx.xml b/resources/templates/ncx.xml deleted file mode 100644 index bcbcb432d4..0000000000 --- a/resources/templates/ncx.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - Table of Contents - - - ${'%*s'%(4*level,'')} - ${'%*s'%(4*level,'')} - ${'%*s'%(4*level,'')}${re.sub(r'\s+', ' ', np.text)} - ${'%*s'%(4*level,'')} - ${'%*s'%(4*level,'')} - ${'%*s'%(4*level,'')}${np.author} - ${'%*s'%(4*level,'')}${np.description} - ${navpoint(np2, level+1)} - ${'%*s'%(4*level,'')} - - - ${navpoint(np, 0)} - - diff --git a/src/calibre/ebooks/metadata/toc.py b/src/calibre/ebooks/metadata/toc.py index 5099b820d0..8c6f3f6baf 100644 --- a/src/calibre/ebooks/metadata/toc.py +++ b/src/calibre/ebooks/metadata/toc.py @@ -1,14 +1,31 @@ #!/usr/bin/env python __license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal ' +__copyright__ = '2010, Kovid Goyal ' + import os, glob, re from urlparse import urlparse from urllib import unquote +from uuid import uuid4 -from calibre import __appname__ +from lxml import etree +from lxml.builder import ElementMaker + +from calibre.constants import __appname__, __version__ from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, BeautifulSoup from calibre.ebooks.chardet import xml_to_unicode +NCX_NS = "http://www.daisy.org/z3986/2005/ncx/" +CALIBRE_NS = "http://calibre.kovidgoyal.net/2009/metadata" +NSMAP = { + None: NCX_NS, + 'calibre':CALIBRE_NS + } + + +E = ElementMaker(namespace=NCX_NS, nsmap=NSMAP) + +C = ElementMaker(namespace=CALIBRE_NS, nsmap=NSMAP) + class NCXSoup(BeautifulStoneSoup): NESTABLE_TAGS = {'navpoint':[]} @@ -208,10 +225,46 @@ class TOC(list): self.add_item(href, fragment, txt) def render(self, stream, uid): - from calibre.utils.genshi.template import MarkupTemplate - ncx_template = open(P('templates/ncx.xml'), 'rb').read() - doctype = ('ncx', "-//NISO//DTD ncx 2005-1//EN", "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd") - template = MarkupTemplate(ncx_template) - raw = template.generate(uid=uid, toc=self, __appname__=__appname__) - raw = raw.render(doctype=doctype) + root = E.ncx( + E.head( + E.meta(name='dtb:uid', content=str(uid)), + E.meta(name='dtb:depth', content=str(self.depth())), + E.meta(name='dtb:generator', content='%s (%s)'%(__appname__, + __version__)), + E.meta(name='dtb:totalPageCount', content='0'), + E.meta(name='dtb:maxPageNumber', content='0'), + ), + E.docTitle(E.text('Table of Contents')), + ) + navmap = E.navMap() + root.append(navmap) + root.set('{http://www.w3.org/XML/1998/namespace}lang', 'en') + + def navpoint(parent, np): + text = np.text + if not text: + text = '' + elem = E.navPoint( + E.navLabel(E.text(re.sub(r'\s+', ' ', text))), + E.content(src=unicode(np.href)+(('#' + unicode(np.fragment)) + if np.fragment else '')), + id=str(uuid4()), + playOrder=str(np.play_order) + ) + au = getattr(np, 'author', None) + if au: + au = re.sub(r'\s+', ' ', au) + elem.append(C.meta(au, name='author')) + desc = getattr(np, 'description', None) + if desc: + desc = re.sub(r'\s+', ' ', desc) + elem.append(C.meta(desc, name='description')) + parent.append(elem) + for np2 in np: + navpoint(elem, np2) + + for np in self: + navpoint(navmap, np) + raw = etree.tostring(root, encoding='utf-8', xml_declaration=True, + pretty_print=True) stream.write(raw)