mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -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)
|
toc.remove(child)
|
||||||
return toc
|
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):
|
def add_id(container, name, loc):
|
||||||
root = container.parsed(name)
|
root = container.parsed(name)
|
||||||
body = root.xpath('//*[local-name()="body"]')[0]
|
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.container import get_container, AZW3Container
|
||||||
from calibre.ebooks.oeb.polish.toc import (
|
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 import Application, error_dialog, gprefs
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
from calibre.gui2.toc.location import ItemEdit
|
from calibre.gui2.toc.location import ItemEdit
|
||||||
@ -126,6 +126,7 @@ class ItemView(QFrame): # {{{
|
|||||||
go_to_root = pyqtSignal()
|
go_to_root = pyqtSignal()
|
||||||
create_from_xpath = pyqtSignal(object)
|
create_from_xpath = pyqtSignal(object)
|
||||||
create_from_links = pyqtSignal()
|
create_from_links = pyqtSignal()
|
||||||
|
create_from_files = pyqtSignal()
|
||||||
flatten_toc = pyqtSignal()
|
flatten_toc = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
@ -183,6 +184,15 @@ class ItemView(QFrame): # {{{
|
|||||||
)))
|
)))
|
||||||
l.addWidget(b)
|
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'))
|
self.xpb = b = QPushButton(_('Generate ToC from &XPath'))
|
||||||
b.clicked.connect(self.create_from_user_xpath)
|
b.clicked.connect(self.create_from_user_xpath)
|
||||||
b.setToolTip(textwrap.fill(_(
|
b.setToolTip(textwrap.fill(_(
|
||||||
@ -577,6 +587,7 @@ class TOCView(QWidget): # {{{
|
|||||||
i.add_new_item.connect(self.add_new_item)
|
i.add_new_item.connect(self.add_new_item)
|
||||||
i.create_from_xpath.connect(self.create_from_xpath)
|
i.create_from_xpath.connect(self.create_from_xpath)
|
||||||
i.create_from_links.connect(self.create_from_links)
|
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_item.connect(self.flatten_item)
|
||||||
i.flatten_toc.connect(self.flatten_toc)
|
i.flatten_toc.connect(self.flatten_toc)
|
||||||
i.go_to_root.connect(self.go_to_root)
|
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)
|
_('No links were found that could be added to the Table of Contents.'), show=True)
|
||||||
self.insert_toc_fragment(toc)
|
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): # {{{
|
class TOCEditor(QDialog): # {{{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user