ToC Editor: Allow generating the ToC directly from individual files inside the ebook. Useful for EPUBs that have individual chapters in single files. Fixes #1163520 (Request for new method to generate entries in ToC editor)

This commit is contained in:
Kovid Goyal 2013-04-03 09:58:58 +05:30
parent 7076d8c2f5
commit fe1f2c7925
2 changed files with 49 additions and 1 deletions

View File

@ -262,6 +262,35 @@ def from_links(container):
toc.remove(child)
return toc
def find_text(node):
LIMIT = 200
pat = re.compile(r'\s+')
for child in node:
if isinstance(child, etree._Element):
text = xml2text(child).strip()
text = pat.sub(' ', text)
if len(text) < 1:
continue
if len(text) > LIMIT:
# Look for less text in a child of this node, recursively
ntext = find_text(child)
return ntext or (text[:LIMIT] + '...')
else:
return text
def from_files(container):
toc = TOC()
for spinepath in container.spine_items:
name = container.abspath_to_name(spinepath)
root = container.parsed(name)
body = XPath('//h:body')(root)
if not body:
continue
text = find_text(body[0])
if text:
toc.add(text, name)
return toc
def add_id(container, name, loc):
root = container.parsed(name)
body = root.xpath('//*[local-name()="body"]')[0]

View File

@ -18,7 +18,7 @@ from PyQt4.Qt import (QPushButton, QFrame, QVariant, QMenu, QInputDialog,
from calibre.ebooks.oeb.polish.container import get_container, AZW3Container
from calibre.ebooks.oeb.polish.toc import (
get_toc, add_id, TOC, commit_toc, from_xpaths, from_links)
get_toc, add_id, TOC, commit_toc, from_xpaths, from_links, from_files)
from calibre.gui2 import Application, error_dialog, gprefs
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.gui2.toc.location import ItemEdit
@ -126,6 +126,7 @@ class ItemView(QFrame): # {{{
go_to_root = pyqtSignal()
create_from_xpath = pyqtSignal(object)
create_from_links = pyqtSignal()
create_from_files = pyqtSignal()
flatten_toc = pyqtSignal()
def __init__(self, parent):
@ -183,6 +184,15 @@ class ItemView(QFrame): # {{{
)))
l.addWidget(b)
self.cfb = b = QPushButton(_('Generate ToC from &files'))
b.clicked.connect(self.create_from_files)
b.setToolTip(textwrap.fill(_(
'Generate a Table of Contents from individual files in the book.'
' Each entry in the ToC will point to the start of the file, the'
' text of the entry will be the "first line" of text from the file.'
)))
l.addWidget(b)
self.xpb = b = QPushButton(_('Generate ToC from &XPath'))
b.clicked.connect(self.create_from_user_xpath)
b.setToolTip(textwrap.fill(_(
@ -577,6 +587,7 @@ class TOCView(QWidget): # {{{
i.add_new_item.connect(self.add_new_item)
i.create_from_xpath.connect(self.create_from_xpath)
i.create_from_links.connect(self.create_from_links)
i.create_from_files.connect(self.create_from_files)
i.flatten_item.connect(self.flatten_item)
i.flatten_toc.connect(self.flatten_toc)
i.go_to_root.connect(self.go_to_root)
@ -778,6 +789,14 @@ class TOCView(QWidget): # {{{
_('No links were found that could be added to the Table of Contents.'), show=True)
self.insert_toc_fragment(toc)
def create_from_files(self):
toc = from_files(self.ebook)
if len(toc) == 0:
return error_dialog(self, _('No items found'),
_('No files were found that could be added to the Table of Contents.'), show=True)
self.insert_toc_fragment(toc)
# }}}
class TOCEditor(QDialog): # {{{