mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
ca1fdf47b8
commit
0301890d59
45
src/calibre/ebooks/oeb/polish/opf.py
Normal file
45
src/calibre/ebooks/oeb/polish/opf.py
Normal 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)
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user