mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
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:
parent
7076d8c2f5
commit
fe1f2c7925
@ -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]
|
||||
|
@ -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): # {{{
|
||||
|
Loading…
x
Reference in New Issue
Block a user