mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
E-book viewer: More accurate sorting of bookmarks by position in book
This commit is contained in:
parent
caad45e8d8
commit
a0c4206477
@ -167,3 +167,32 @@ def parser():
|
||||
_parser = Parser()
|
||||
return _parser
|
||||
|
||||
def get_steps(pcfi):
|
||||
ans = tuple(pcfi['steps'])
|
||||
if 'redirect' in pcfi:
|
||||
ans += get_steps(pcfi['redirect'])
|
||||
return ans
|
||||
|
||||
def cfi_sort_key(cfi, only_path=True):
|
||||
p = parser()
|
||||
try:
|
||||
if only_path:
|
||||
pcfi = p.parse_path(cfi)[0]
|
||||
else:
|
||||
parent, start = p.parse_epubcfi(cfi)[:2]
|
||||
pcfi = start or parent
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return ()
|
||||
if not pcfi:
|
||||
import sys
|
||||
print ('Failed to parse CFI: %r' % pcfi, file=sys.stderr)
|
||||
return ()
|
||||
steps = get_steps(pcfi)
|
||||
step_nums = tuple(s.get('num', 0) for s in steps)
|
||||
step = steps[-1] if steps else {}
|
||||
offsets = (step.get('temporal_offset', 0), tuple(reversed(step.get('spatial_offset', (0, 0)))), step.get('text_offset', 0), )
|
||||
return (step_nums, offsets)
|
||||
|
||||
|
||||
|
@ -9,10 +9,20 @@ __copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import unittest
|
||||
from future_builtins import map
|
||||
|
||||
from calibre.ebooks.epub.cfi.parse import parser
|
||||
from calibre.ebooks.epub.cfi.parse import parser, cfi_sort_key
|
||||
|
||||
class Tests(unittest.TestCase):
|
||||
|
||||
def test_sorting(self):
|
||||
null_offsets = (0, (0, 0), 0)
|
||||
for path, key in [
|
||||
('/1/2/3', ((1, 2, 3), null_offsets)),
|
||||
('/1[id]:34[yyyy]', ((1,), (0, (0, 0), 34))),
|
||||
('/1@1:2', ((1,), (0, (2, 1), 0))),
|
||||
('/1~1.2', ((1,), (1.2, (0, 0), 0))),
|
||||
]:
|
||||
self.assertEqual(cfi_sort_key(path), key)
|
||||
|
||||
def test_parsing(self):
|
||||
p = parser()
|
||||
def step(x):
|
||||
|
@ -173,9 +173,10 @@ class BookmarkManager(QWidget):
|
||||
self.edited.emit(bm)
|
||||
|
||||
def sort_by_pos(self):
|
||||
from calibre.ebooks.epub.cfi.parse import cfi_sort_key
|
||||
def pos_key(b):
|
||||
if b.get('type', None) == 'cfi':
|
||||
return b['spine'], b['pos']
|
||||
return b['spine'], cfi_sort_key(b['pos'])
|
||||
return (None, None)
|
||||
bm = self.get_bookmarks()
|
||||
bm.sort(key=pos_key)
|
||||
|
Loading…
x
Reference in New Issue
Block a user