mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-31 14:33:54 -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()
|
_parser = Parser()
|
||||||
return _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
|
import unittest
|
||||||
from future_builtins import map
|
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):
|
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):
|
def test_parsing(self):
|
||||||
p = parser()
|
p = parser()
|
||||||
def step(x):
|
def step(x):
|
||||||
|
@ -173,9 +173,10 @@ class BookmarkManager(QWidget):
|
|||||||
self.edited.emit(bm)
|
self.edited.emit(bm)
|
||||||
|
|
||||||
def sort_by_pos(self):
|
def sort_by_pos(self):
|
||||||
|
from calibre.ebooks.epub.cfi.parse import cfi_sort_key
|
||||||
def pos_key(b):
|
def pos_key(b):
|
||||||
if b.get('type', None) == 'cfi':
|
if b.get('type', None) == 'cfi':
|
||||||
return b['spine'], b['pos']
|
return b['spine'], cfi_sort_key(b['pos'])
|
||||||
return (None, None)
|
return (None, None)
|
||||||
bm = self.get_bookmarks()
|
bm = self.get_bookmarks()
|
||||||
bm.sort(key=pos_key)
|
bm.sort(key=pos_key)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user