From 8a1f46a389322665d9450c3490e37ef848db2391 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 26 Aug 2013 15:14:09 +0530 Subject: [PATCH] EPUB metadata: Handle multiple title elements when setting titles EPUB metadata: When changing the title in an EPUB 2.0 file that has multiple titles, remove the extra titles. Fixes #1211949 [Private bug](https://bugs.launchpad.net/calibre/+bug/1211949) --- src/calibre/ebooks/metadata/opf2.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index 6ae40d157d..52b8238a8f 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -518,7 +518,6 @@ class OPF(object): # {{{ spine_path = XPath('descendant::*[re:match(name(), "spine", "i")]/*[re:match(name(), "itemref", "i")]') guide_path = XPath('descendant::*[re:match(name(), "guide", "i")]/*[re:match(name(), "reference", "i")]') - title = MetadataField('title', formatter=lambda x: re.sub(r'\s+', ' ', x)) publisher = MetadataField('publisher') comments = MetadataField('description') category = MetadataField('type') @@ -781,6 +780,29 @@ class OPF(object): # {{{ for item in self.iterguide(): item.set('href', get_href(item)) + @dynamic_property + def title(self): + # TODO: Add support for EPUB 3 refinements + + def fget(self): + for elem in self.title_path(self.metadata): + title = self.get_text(elem) + if title and title.strip(): + return re.sub(r'\s+', ' ', title.strip()) + + def fset(self, val): + val = (val or '').strip() + titles = self.title_path(self.metadata) + if not val or self.package_version < 3: + for title in titles: + title.getparent().remove(title) + if val: + titles = self.title_path(self.metadata) + title = titles[0] if titles else self.create_metadata_element('title') + title.text = re.sub(r'\s+', ' ', unicode(val)) + + return property(fget=fget, fset=fset) + @dynamic_property def authors(self): @@ -1132,10 +1154,7 @@ class OPF(object): # {{{ def get_metadata_element(self, name): matches = self.metadata_elem_path(self.metadata, name=name) if matches: - num = -1 - if self.package_version >= 3 and name == 'title': - num = 0 - return matches[num] + return matches[-1] def create_metadata_element(self, name, attrib=None, is_dc=True): if is_dc: