|
|
#1 |
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
Multi-level TOC broken in epub->epub conversion
Hi,
I'm taking the sample xhtml code from the calibre manual at http://calibre-ebook.com/user_manual...le-of-contents and save it as a html file, add the file to calibre as an ebook (which results in a zip file), enable "Force use of auto-generated Table of Contents", set level1 and level2 toc values as described and convert to epub. The resulting epub contains a two-level TOC as expected, but if I convert this epub again to epub using the same setting, the TOC of the new epub contains only the level1 headings. Bummer. Ciao, Steffen |
|
|
|
|
|
#2 |
|
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 3,130
Karma: 91256
Join Date: Feb 2008
Location: Germany
Device: Cybook Gen3
|
I'm guessing you'll have to adjust the level 2 detection XPath to account for changes occuring during conversion. Have a look at the XHTML inside the ePub to see what the relevant headings are tagged like.
|
|
|
|
|
|
#3 | |
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
Quote:
Ciao, Steffen |
|
|
|
|
|
|
#4 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
the level 2 expression only matches if a leve1 expression matched in the same html file.
Why are you forcing use of auto generated toc twice anyway? |
|
|
|
|
|
#5 | ||
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
Quote:
Is there a way to have calibre merge the html files again? Quote:
Ciao, Steffen |
||
|
|
|
|
|
#6 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
No calibre doesn't do merging.
|
|
|
|
|
|
#7 |
|
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 3,130
Karma: 91256
Join Date: Feb 2008
Location: Germany
Device: Cybook Gen3
|
|
|
|
|
|
|
#8 |
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
|
|
|
|
|
|
#9 | |
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
That's a pity. But it should be possible to implement, or does calibre discard some information it won't be able to recover?
Quote:
Ciao, Steffen |
|
|
|
|
|
|
#10 | ||
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Quote:
Quote:
|
||
|
|
|
|
|
#11 | ||
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
Quote:
Quote:
Ciao, Steffen |
||
|
|
|
|
|
#12 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Then feel free to submit a patch
|
|
|
|
|
|
#13 |
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
Ok, here it is:
Code:
diff --git a/src/calibre/ebooks/oeb/transforms/structure.py b/src/calibre/ebooks/oeb/transforms/structure.py
index 0db9b15..90de41d 100644
--- a/src/calibre/ebooks/oeb/transforms/structure.py
+++ b/src/calibre/ebooks/oeb/transforms/structure.py
@@ -95,10 +95,8 @@ class DetectStructure(object):
self.log.exception('Failed to mark chapter')
def create_level_based_toc(self):
- if self.opts.level1_toc is None:
- return
- for item in self.oeb.spine:
- self.add_leveled_toc_items(item)
+ if self.opts.level1_toc is not None:
+ self.add_leveled_toc_items()
def create_toc_from_chapters(self):
counter = self.oeb.toc.next_play_order()
@@ -145,14 +143,15 @@ class DetectStructure(object):
return text, href
- def add_leveled_toc_items(self, item):
- level1 = XPath(self.opts.level1_toc)(item.data)
+ def add_leveled_toc_items(self):
level1_order = []
- document = item
-
+ added = {}
+ added2 = {}
counter = 1
- if level1:
- added = {}
+ for item in self.oeb.spine:
+ level1 = XPath(self.opts.level1_toc)(item.data)
+ document = item
+
for elem in level1:
text, _href = self.elem_to_link(document, elem, counter)
counter += 1
@@ -163,14 +162,18 @@ class DetectStructure(object):
added[elem] = node
#node.add(_('Top'), _href)
if self.opts.level2_toc is not None:
- added2 = {}
level2 = list(XPath(self.opts.level2_toc)(document.data))
for elem in level2:
level1 = None
for item in document.data.iterdescendants():
if item in added.keys():
level1 = added[item]
- elif item == elem and level1 is not None:
+ elif item == elem:
+ if level1 is None:
+ if added == {}:
+ continue
+ else:
+ level1 = added[added.keys()[-1]]
text, _href = self.elem_to_link(document, elem, counter)
counter += 1
if text:
@@ -183,11 +186,15 @@ class DetectStructure(object):
for item in document.data.iterdescendants():
if item in added2.keys():
level2 = added2[item]
- elif item == elem and level2 is not None:
+ elif item == elem:
+ if level2 is None:
+ if added2 == {}:
+ continue
+ else:
+ level2 = added2[added2.keys()[-1]]
text, _href = \
self.elem_to_link(document, elem, counter)
counter += 1
if text:
level2.add(text, _href,
- play_order=self.oeb.toc.next_play_order())
-
+ play_order=self.oeb.toc.next_play_order())
Steffen |
|
|
|
|
|
#14 |
|
creator of calibre
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 45,609
Karma: 28549044
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Your patch will not work for the following reasons:
1) You need to use an OrderedDict not {} 2) if a file contains an <h2> as the first element and an <h1> after it, then the <h2> will be added to the <h1> from that file instead of the the <h1> from the previous file I have fixed both issues, but I haven't really tested my fix, so let me know if there are any problems. |
|
|
|
|
|
#15 | |||
|
Developer
![]() ![]() ![]() Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
It worked at least for my test documents and the real book I wanted to convert in the first place.
![]() Quote:
Quote:
I've now created such an epub with sigil and your implementation creates the correct TOC, while mine misplaces the <h2> as described. Quote:
Ciao, Steffen |
|||
|
|
|
![]() |
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Classic Can Nook read Multi-level TOC? | jhempel24 | Barnes & Noble NOOK | 13 | 12-10-2010 12:55 AM |
| Multi-Level TOC | edbro | Calibre | 4 | 09-16-2010 07:54 PM |
| Multi level TOC | PAQUITO | Bookeen | 1 | 12-23-2009 04:57 AM |
| Opus Multi-Level TOC's in ePub | AnemicOak | Bookeen | 1 | 11-08-2009 05:14 PM |
| ePub, 505 and multi-level ToC | JSWolf | Calibre | 4 | 06-04-2009 03:12 PM |