Implement support for references with --open-at

This commit is contained in:
Kovid Goyal 2019-12-09 17:02:30 +05:30
parent 6a540b8b98
commit e6044fae91
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 44 additions and 3 deletions

View File

@ -168,7 +168,8 @@ View an e-book.
'at the location of the first Table of Contents entry that contains ' 'at the location of the first Table of Contents entry that contains '
'the string "something". The form toc-href:something will match the ' 'the string "something". The form toc-href:something will match the '
'href (internal link destination) of toc nodes. The matching is exact, ' 'href (internal link destination) of toc nodes. The matching is exact, '
'If you want to match a substring, use the form toc-href-contains:something. ')) 'If you want to match a substring, use the form toc-href-contains:something. '
'The form ref:something will use Reference mode references.'))
a('--continue', default=False, action='store_true', dest='continue_reading', a('--continue', default=False, action='store_true', dest='continue_reading',
help=_('Continue reading at the previously opened book')) help=_('Continue reading at the previously opened book'))
@ -192,7 +193,7 @@ def main(args=sys.argv):
oat = opts.open_at oat = opts.open_at
if oat and not ( if oat and not (
oat.startswith('toc:') or oat.startswith('toc-href:') or oat.startswith('toc-href-contains:') or oat.startswith('toc:') or oat.startswith('toc-href:') or oat.startswith('toc-href-contains:') or
oat.startswith('epubcfi(/') or is_float(oat)): oat.startswith('epubcfi(/') or is_float(oat) or oat.startswith('ref:')):
raise SystemExit('Not a valid --open-at value: {}'.format(opts.open_at)) raise SystemExit('Not a valid --open-at value: {}'.format(opts.open_at))
listener = None listener = None

View File

@ -416,6 +416,8 @@ class EbookViewer(MainWindow):
initial_position = {'type': 'toc', 'data': initial_toc_node} initial_position = {'type': 'toc', 'data': initial_toc_node}
elif open_at.startswith('epubcfi(/'): elif open_at.startswith('epubcfi(/'):
initial_position = {'type': 'cfi', 'data': open_at} initial_position = {'type': 'cfi', 'data': open_at}
elif open_at.startswith('ref:'):
initial_position = {'type': 'ref', 'data': open_at[len('ref:'):]}
elif is_float(open_at): elif is_float(open_at):
initial_position = {'type': 'bookpos', 'data': float(open_at)} initial_position = {'type': 'bookpos', 'data': float(open_at)}
self.web_view.start_book_load(initial_position=initial_position) self.web_view.start_book_load(initial_position=initial_position)

View File

@ -29,7 +29,9 @@ from read_book.paged_mode import (
scroll_by_page as paged_scroll_by_page, scroll_to_elem, scroll_by_page as paged_scroll_by_page, scroll_to_elem,
scroll_to_fraction as paged_scroll_to_fraction, snap_to_selection scroll_to_fraction as paged_scroll_to_fraction, snap_to_selection
) )
from read_book.referencing import end_reference_mode, start_reference_mode from read_book.referencing import (
elem_for_ref, end_reference_mode, start_reference_mode
)
from read_book.resources import finalize_resources, unserialize_html from read_book.resources import finalize_resources, unserialize_html
from read_book.settings import ( from read_book.settings import (
apply_colors, apply_font_size, apply_settings, apply_stylesheet, opts, apply_colors, apply_font_size, apply_settings, apply_stylesheet, opts,
@ -92,6 +94,7 @@ class IframeBoss:
'initialize':self.initialize, 'initialize':self.initialize,
'display': self.display, 'display': self.display,
'scroll_to_anchor': self.on_scroll_to_anchor, 'scroll_to_anchor': self.on_scroll_to_anchor,
'scroll_to_ref': self.on_scroll_to_ref,
'scroll_to_frac': self.on_scroll_to_frac, 'scroll_to_frac': self.on_scroll_to_frac,
'next_screen': self.on_next_screen, 'next_screen': self.on_next_screen,
'change_font_size': self.change_font_size, 'change_font_size': self.change_font_size,
@ -275,6 +278,8 @@ class IframeBoss:
self.to_scroll_fraction(ipos.frac) self.to_scroll_fraction(ipos.frac)
elif ipos.type is 'anchor': elif ipos.type is 'anchor':
self.scroll_to_anchor(ipos.anchor) self.scroll_to_anchor(ipos.anchor)
elif ipos.type is 'ref':
self.scroll_to_ref(ipos.refnum)
elif ipos.type is 'cfi': elif ipos.type is 'cfi':
self.jump_to_cfi(ipos.cfi) self.jump_to_cfi(ipos.cfi)
elif ipos.type is 'search': elif ipos.type is 'search':
@ -466,6 +471,17 @@ class IframeBoss:
else: else:
scroll_viewport.scroll_to(0, 0) scroll_viewport.scroll_to(0, 0)
def scroll_to_ref(self, refnum):
refnum = int(refnum)
elem = elem_for_ref(refnum)
if elem:
scroll_to_elem(elem)
def on_scroll_to_ref(self, data):
refnum = data.refnum
if refnum?:
self.scroll_to_ref(refnum)
def find(self, data, from_load): def find(self, data, from_load):
if data.searched_in_spine: if data.searched_in_spine:
window.getSelection().removeAllRanges() window.getSelection().removeAllRanges()

View File

@ -6,6 +6,12 @@ from __python__ import bound_methods, hash_literals
from read_book.globals import get_boss from read_book.globals import get_boss
def elem_for_ref(refnum):
refnum = int(refnum)
p = document.getElementsByTagName('p')[refnum - 1]
return p
def on_mouse_over(ev): def on_mouse_over(ev):
p = this p = this
if p.dataset.calibreRefNum: if p.dataset.calibreRefNum:

View File

@ -655,6 +655,8 @@ class View:
elif initial_position.type is 'bookpos': elif initial_position.type is 'bookpos':
navigated = True navigated = True
self.goto_book_position(initial_position.data) self.goto_book_position(initial_position.data)
elif initial_position.type is 'ref':
navigated = self.goto_reference(initial_position.data)
if navigated: if navigated:
self.hide_loading() self.hide_loading()
else: else:
@ -769,6 +771,20 @@ class View:
return True return True
return False return False
def goto_reference(self, reference):
if not self.book or not self.book.manifest:
return
index, refnum = reference.split('.')
index, refnum = int(index), int(refnum)
chapter_name = self.book.manifest.spine[index]
if not chapter_name:
return False
if self.currently_showing.name is chapter_name:
self.iframe_wrapper.send_message('scroll_to_ref', refnum=refnum)
else:
self.show_name(chapter_name, initial_position={'type':'ref', 'refnum':refnum, 'replace_history':True})
return True
def goto_named_destination(self, name, frag): def goto_named_destination(self, name, frag):
if self.currently_showing.name is name: if self.currently_showing.name is name:
self.iframe_wrapper.send_message('scroll_to_anchor', frag=frag) self.iframe_wrapper.send_message('scroll_to_anchor', frag=frag)