03-08-2011, 12:58 PM | #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 |
03-08-2011, 01:05 PM | #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.
|
Advert | |
|
03-08-2011, 01:16 PM | #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 |
|
03-08-2011, 01:30 PM | #4 |
creator of calibre
Posts: 44,380
Karma: 23766374
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? |
03-08-2011, 01:53 PM | #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 |
||
Advert | |
|
03-08-2011, 01:56 PM | #6 |
creator of calibre
Posts: 44,380
Karma: 23766374
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
No calibre doesn't do merging.
|
03-08-2011, 02:18 PM | #7 |
Wizard
Posts: 3,130
Karma: 91256
Join Date: Feb 2008
Location: Germany
Device: Cybook Gen3
|
|
03-08-2011, 04:02 PM | #8 |
Developer
Posts: 155
Karma: 280
Join Date: Nov 2010
Device: Kindle 3 (Keyboard) 3G / iPad 9 WiFi / Google Pixel 6a (Android)
|
|
03-08-2011, 04:07 PM | #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 |
|
03-08-2011, 04:12 PM | #10 | ||
creator of calibre
Posts: 44,380
Karma: 23766374
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Quote:
Quote:
|
||
03-08-2011, 04:24 PM | #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 |
||
03-08-2011, 04:53 PM | #12 |
creator of calibre
Posts: 44,380
Karma: 23766374
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
|
Then feel free to submit a patch
|
03-09-2011, 11:41 AM | #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 |
03-09-2011, 01:13 PM | #14 |
creator of calibre
Posts: 44,380
Karma: 23766374
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. |
03-09-2011, 05:38 PM | #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-09-2010 11:55 PM |
Multi-Level TOC | edbro | Calibre | 4 | 09-16-2010 06:54 PM |
Multi level TOC | PAQUITO | Bookeen | 1 | 12-23-2009 03:57 AM |
Opus Multi-Level TOC's in ePub | AnemicOak | Bookeen | 1 | 11-08-2009 04:14 PM |
ePub, 505 and multi-level ToC | JSWolf | Calibre | 4 | 06-04-2009 02:12 PM |