PDF Output: Fix balanced parentheses in the text of items in the Table of Contents not being rendered properly by some PDF viewers. Fixes #1358443 [PDF ToC omitting entries in parentheses](https://bugs.launchpad.net/calibre/+bug/1358443)

This commit is contained in:
Kovid Goyal 2014-08-19 15:22:56 +05:30
parent aa31b724b9
commit b03e0c6eb0

View File

@ -93,24 +93,44 @@ class Name(unicode):
in raw]
stream.write(b'/'+b''.join(buf))
def escape_unbalanced_parantheses(bytestring):
indices = []
bad = []
ba = bytearray(bytestring)
for i, num in enumerate(ba):
if num == 40: # (
indices.append(i)
elif num == 41: # )
if indices:
indices.pop()
else:
bad.append(i)
bad = sorted(list(indices) + bad, reverse=True)
if not bad:
return bytestring
for i in bad:
ba.insert(i, 92) # \
return bytes(ba)
class String(unicode):
def pdf_serialize(self, stream):
s = self.replace('\\', '\\\\').replace('(', r'\(').replace(')', r'\)')
s = self.replace('\\', '\\\\')
try:
raw = s.encode('latin1')
if raw.startswith(codecs.BOM_UTF16_BE):
raw = codecs.BOM_UTF16_BE + s.encode('utf-16-be')
except UnicodeEncodeError:
raw = codecs.BOM_UTF16_BE + s.encode('utf-16-be')
stream.write(b'('+raw+b')')
stream.write(b'('+escape_unbalanced_parantheses(raw)+b')')
class UTF16String(unicode):
def pdf_serialize(self, stream):
s = self.replace('\\', '\\\\').replace('(', r'\(').replace(')', r'\)')
s = self.replace('\\', '\\\\')
raw = codecs.BOM_UTF16_BE + s.encode('utf-16-be')
stream.write(b'('+raw+b')')
stream.write(b'('+escape_unbalanced_parantheses(raw)+b')')
class Dictionary(dict):