diff --git a/src/calibre/ebooks/docx/fields.py b/src/calibre/ebooks/docx/fields.py
index df7b877e51..6c4a74d37e 100644
--- a/src/calibre/ebooks/docx/fields.py
+++ b/src/calibre/ebooks/docx/fields.py
@@ -84,6 +84,13 @@ parse_index = parser('index',
' f:entry-type g:page-range-separator h:heading k:crossref-separator'
' l:page-number-separator p:letter-range s:sequence-name r:run-together y:yomi z:langcode')
+parse_ref = parser('ref',
+ 'd:separator f:footnote h:hyperlink n:number p:position r:relative-number t:suppress w:number-full-context')
+
+parse_noteref = parser('noteref',
+ 'f:footnote h:hyperlink p:position')
+
+
class Fields(object):
def __init__(self):
@@ -117,7 +124,7 @@ class Fields(object):
if stack:
stack[-1].contents.append(elem)
- field_types = ('hyperlink', 'xe', 'index')
+ field_types = ('hyperlink', 'xe', 'index', 'ref', 'noteref')
parsers = {x.upper():getattr(self, 'parse_'+x) for x in field_types}
field_parsers = {f.upper():globals()['parse_%s' % f] for f in field_types}
@@ -131,28 +138,42 @@ class Fields(object):
if func is not None:
func(field, field_parsers[field.name], log)
+ def get_runs(self, field):
+ all_runs = []
+ current_runs = []
+ # We only handle spans in a single paragraph
+ # being wrapped in
+ for x in field.contents:
+ if x.tag.endswith('}p'):
+ if current_runs:
+ all_runs.append(current_runs)
+ current_runs = []
+ elif x.tag.endswith('}r'):
+ current_runs.append(x)
+ if current_runs:
+ all_runs.append(current_runs)
+ return all_runs
+
def parse_hyperlink(self, field, parse_func, log):
# Parse hyperlink fields
hl = parse_func(field.instructions, log)
if hl:
if 'target' in hl and hl['target'] is None:
hl['target'] = '_blank'
- all_runs = []
- current_runs = []
- # We only handle spans in a single paragraph
- # being wrapped in
- for x in field.contents:
- if x.tag.endswith('}p'):
- if current_runs:
- all_runs.append(current_runs)
- current_runs = []
- elif x.tag.endswith('}r'):
- current_runs.append(x)
- if current_runs:
- all_runs.append(current_runs)
- for runs in all_runs:
+ for runs in self.get_runs(field):
self.hyperlink_fields.append((hl, runs))
+ def parse_ref(self, field, parse_func, log):
+ ref = parse_func(field.instructions, log)
+ dest = ref.get(None, None)
+ if dest is not None and 'hyperlink' in ref:
+ for runs in self.get_runs(field):
+ self.hyperlink_fields.append(({'anchor':dest}, runs))
+ else:
+ self.log.warn('Unsupported reference field (%s), ignoring: %r' % (field.name, ref))
+
+ parse_noteref = parse_ref
+
def parse_xe(self, field, parse_func, log):
# Parse XE fields
if None in (field.start, field.end):