Create synthetic bookmarks for index field entries

This commit is contained in:
Kovid Goyal 2014-03-31 16:00:51 +05:30
parent 530112799e
commit 7ea8e2abc5
2 changed files with 27 additions and 5 deletions

View File

@ -6,9 +6,10 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
import re import re, os, uuid
from calibre.ebooks.docx.names import XPath, get from calibre.ebooks.docx.names import XPath, get, namespaces
TEST_INDEX = 'CALIBRE_TEST_INDEX' in os.environ
class Field(object): class Field(object):
@ -42,6 +43,9 @@ scanner = re.Scanner([
null = object() null = object()
def WORD(x):
return '{%s}%s' % (namespaces['w'], x)
def parser(name, field_map, default_field_name=None): def parser(name, field_map, default_field_name=None):
field_map = dict((x.split(':') for x in field_map.split())) field_map = dict((x.split(':') for x in field_map.split()))
@ -84,6 +88,8 @@ class Fields(object):
def __init__(self): def __init__(self):
self.fields = [] self.fields = []
self.bookmark_counter = 0
self.bookmark_prefix = str(uuid.uuid4())
def __call__(self, doc, log): def __call__(self, doc, log):
stack = [] stack = []
@ -144,13 +150,30 @@ class Fields(object):
def parse_xe(self, field, parse_func, log): def parse_xe(self, field, parse_func, log):
# Parse XE fields # Parse XE fields
if not TEST_INDEX:
return
if None in (field.start, field.end):
return
xe = parse_func(field.instructions, log) xe = parse_func(field.instructions, log)
if xe: if xe:
# TODO: parse the field contents # We insert a synthetic bookmark around this index item so that we
# can link to it later
self.bookmark_counter += 1
bmark = xe['anchor'] = '%s-%d' % (self.bookmark_prefix, self.bookmark_counter)
p = field.start.getparent()
bm = p.makeelement(WORD('bookmarkStart'))
bm.set(WORD('id'), bmark), bm.set(WORD('name'), bmark)
p.insert(p.index(field.start), bm)
p = field.end.getparent()
bm = p.makeelement(WORD('bookmarkEnd'))
bm.set(WORD('id'), bmark)
p.insert(p.index(field.end) + 1, bm)
self.xe_fields.append(xe) self.xe_fields.append(xe)
def parse_index(self, field, parse_func, log): def parse_index(self, field, parse_func, log):
# Parse Index fields # Parse Index fields
if not TEST_INDEX:
return
idx = parse_func(field.instructions, log) idx = parse_func(field.instructions, log)
# TODO: parse the field contents # TODO: parse the field contents
self.index_fields.append(idx) self.index_fields.append(idx)

View File

@ -26,13 +26,12 @@ from calibre.ebooks.docx.footnotes import Footnotes
from calibre.ebooks.docx.cleanup import cleanup_markup from calibre.ebooks.docx.cleanup import cleanup_markup
from calibre.ebooks.docx.theme import Theme from calibre.ebooks.docx.theme import Theme
from calibre.ebooks.docx.toc import create_toc from calibre.ebooks.docx.toc import create_toc
from calibre.ebooks.docx.fields import Fields from calibre.ebooks.docx.fields import Fields, TEST_INDEX
from calibre.ebooks.docx.settings import Settings from calibre.ebooks.docx.settings import Settings
from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.metadata.opf2 import OPFCreator
from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1 from calibre.utils.localization import canonicalize_lang, lang_as_iso639_1
NBSP = '\xa0' NBSP = '\xa0'
TEST_INDEX = 'CALIBRE_TEST_INDEX' in os.environ
class Text: class Text: