mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
ToC Editor: Allow creating ToC from links in the book
This commit is contained in:
parent
97e632168b
commit
1f93448791
@ -39,6 +39,10 @@ class TOC(object):
|
||||
c.parent = self
|
||||
return c
|
||||
|
||||
def remove(self, child):
|
||||
self.children.remove(child)
|
||||
child.parent = None
|
||||
|
||||
def __iter__(self):
|
||||
for c in self.children:
|
||||
yield c
|
||||
@ -191,6 +195,8 @@ def elem_to_toc_text(elem):
|
||||
text = elem.get('alt', '')
|
||||
text = re.sub(r'\s+', ' ', text.strip())
|
||||
text = text[:1000].strip()
|
||||
if not text:
|
||||
text = _('(Untitled)')
|
||||
return text
|
||||
|
||||
def from_xpaths(container, xpaths):
|
||||
@ -229,6 +235,33 @@ def from_xpaths(container, xpaths):
|
||||
|
||||
return tocroot
|
||||
|
||||
def from_links(container):
|
||||
toc = TOC()
|
||||
link_path = XPath('//h:a[@href]')
|
||||
seen_titles, seen_dests = set(), set()
|
||||
for spinepath in container.spine_items:
|
||||
name = container.abspath_to_name(spinepath)
|
||||
root = container.parsed(name)
|
||||
for a in link_path(root):
|
||||
href = a.get('href')
|
||||
if not href or not href.strip():
|
||||
continue
|
||||
dest = container.href_to_name(href, base=name)
|
||||
frag = href.rpartition('#')[-1] or None
|
||||
if (dest, frag) in seen_dests:
|
||||
continue
|
||||
seen_dests.add((dest, frag))
|
||||
text = elem_to_toc_text(a)
|
||||
if text in seen_titles:
|
||||
continue
|
||||
seen_titles.add(text)
|
||||
toc.add(text, dest, frag=frag)
|
||||
verify_toc_destinations(container, toc)
|
||||
for child in toc:
|
||||
if not child.dest_exists:
|
||||
toc.remove(child)
|
||||
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,
|
||||
|
||||
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)
|
||||
get_toc, add_id, TOC, commit_toc, from_xpaths, from_links)
|
||||
from calibre.gui2 import Application, error_dialog, gprefs
|
||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||
from calibre.gui2.toc.location import ItemEdit
|
||||
@ -33,6 +33,7 @@ class ItemView(QFrame): # {{{
|
||||
flatten_item = pyqtSignal()
|
||||
go_to_root = pyqtSignal()
|
||||
create_from_xpath = pyqtSignal(object)
|
||||
create_from_links = pyqtSignal()
|
||||
|
||||
def __init__(self, parent):
|
||||
QFrame.__init__(self, parent)
|
||||
@ -79,7 +80,15 @@ class ItemView(QFrame): # {{{
|
||||
' heading tags. Uses the <h1-6> tags.')))
|
||||
l.addWidget(b)
|
||||
|
||||
|
||||
self.lb = b = QPushButton(_('Generate ToC from &links'))
|
||||
b.clicked.connect(self.create_from_links)
|
||||
b.setToolTip(textwrap.fill(_(
|
||||
'Generate a Table of Contents from all the links in the book.'
|
||||
' Links that point to destinations that do not exist in the book are'
|
||||
' ignored. Also multiple links with the same destination or the same'
|
||||
' text are ignored.'
|
||||
)))
|
||||
l.addWidget(b)
|
||||
|
||||
l.addStretch()
|
||||
self.w1 = la = QLabel(_('<b>WARNING:</b> calibre only supports the '
|
||||
@ -270,6 +279,7 @@ class TOCView(QWidget): # {{{
|
||||
self.item_view.delete_item.connect(self.delete_current_item)
|
||||
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.flatten_item.connect(self.flatten_item)
|
||||
i.go_to_root.connect(self.go_to_root)
|
||||
l.addWidget(i, 0, 4, col, 1)
|
||||
@ -490,6 +500,13 @@ class TOCView(QWidget): # {{{
|
||||
_('No items were found that could be added to the Table of Contents.'), show=True)
|
||||
self.insert_toc_fragment(toc)
|
||||
|
||||
def create_from_links(self):
|
||||
toc = from_links(self.ebook)
|
||||
if len(toc) == 0:
|
||||
return error_dialog(self, _('No items found'),
|
||||
_('No links 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