Edit book: When generating inline Table of Contents, mark it as such in the guide section of the OPF. Fixes #1287018 [ebook-edit should add coresponding guide reference element <reference href="Text/toc.xhtml" type="toc" title="TOC" /> after adding inline toc.xhtml](https://bugs.launchpad.net/calibre/+bug/1287018)

This commit is contained in:
Kovid Goyal 2014-03-17 22:06:22 +05:30
parent ca1fdf47b8
commit 0301890d59
2 changed files with 56 additions and 1 deletions

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python
# vim:fileencoding=utf-8
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
from lxml import etree
from calibre.ebooks.oeb.polish.container import OPF_NAMESPACES
from calibre.utils.localization import canonicalize_lang
def get_book_language(container):
for lang in container.opf_xpath('//dc:language'):
raw = lang.text
if raw:
code = canonicalize_lang(raw.split(',')[0].strip())
if code:
return code
def set_guide_item(container, item_type, title, name, frag=None):
guides = container.opf_xpath('//opf:guide')
if not guides:
g = container.opf.makeelement('{%s}guide' % OPF_NAMESPACES['opf'], nsmap={'opf':OPF_NAMESPACES['opf']})
container.insert_into_xml(container.opf, g)
guides = [g]
ref_tag = '{%s}reference' % OPF_NAMESPACES['opf']
href = container.name_to_href(name, container.opf_name)
if frag:
href += '#' + frag
for guide in guides:
matches = []
for child in guide.iterchildren(etree.Element):
if child.tag == ref_tag and child.get('type', '').lower() == item_type.lower():
matches.append(child)
if not matches:
r = guide.makeelement(ref_tag, type=item_type, nsmap={'opf':OPF_NAMESPACES['opf']})
container.insert_into_xml(guide, r)
matches.append(r)
for m in matches:
m.set('title', title), m.set('href', href), m.set('type', item_type)
container.dirty(container.opf_name)

View File

@ -20,7 +20,9 @@ from calibre import __version__
from calibre.ebooks.oeb.base import XPath, uuid_id, xml2text, NCX, NCX_NS, XML, XHTML, XHTML_NS, serialize from calibre.ebooks.oeb.base import XPath, uuid_id, xml2text, NCX, NCX_NS, XML, XHTML, XHTML_NS, serialize
from calibre.ebooks.oeb.polish.errors import MalformedMarkup from calibre.ebooks.oeb.polish.errors import MalformedMarkup
from calibre.ebooks.oeb.polish.utils import guess_type from calibre.ebooks.oeb.polish.utils import guess_type
from calibre.ebooks.oeb.polish.opf import set_guide_item, get_book_language
from calibre.ebooks.oeb.polish.pretty import pretty_html_tree from calibre.ebooks.oeb.polish.pretty import pretty_html_tree
from calibre.translations.dynamic import translate
from calibre.utils.localization import get_lang, canonicalize_lang, lang_as_iso639_1 from calibre.utils.localization import get_lang, canonicalize_lang, lang_as_iso639_1
ns = etree.FunctionNamespace('calibre_xpath_extensions') ns = etree.FunctionNamespace('calibre_xpath_extensions')
@ -481,7 +483,12 @@ def find_inline_toc(container):
return name return name
def create_inline_toc(container, title=None): def create_inline_toc(container, title=None):
title = title or _('Table of Contents') lang = get_book_language(container)
default_title = 'Table of Contents'
if lang:
lang = lang_as_iso639_1(lang) or lang
default_title = translate(lang, default_title)
title = title or default_title
toc = get_toc(container) toc = get_toc(container)
if len(toc) == 0: if len(toc) == 0:
return None return None
@ -529,6 +536,8 @@ def create_inline_toc(container, title=None):
name = toc_name name = toc_name
for child in toc: for child in toc:
process_node(html[1][1], child) process_node(html[1][1], child)
if lang:
html.set('lang', lang)
pretty_html_tree(container, html) pretty_html_tree(container, html)
raw = serialize(html, 'text/html') raw = serialize(html, 'text/html')
if name is None: if name is None:
@ -540,5 +549,6 @@ def create_inline_toc(container, title=None):
else: else:
with container.open(name, 'wb') as f: with container.open(name, 'wb') as f:
f.write(raw) f.write(raw)
set_guide_item(container, 'toc', title, name, frag='calibre_generated_inline_toc')
return name return name