Reputation: 69
I would like to create a ToC with hyperlinks to another script and would like to understand how it works, but i can't get it to work with this example I found. Could you help me? I just get the Error message:
Unicode-objects must be encoded before hashing
This is the entire the example: https://www.reportlab.com/snippets/13/
#this function makes our headings
def doHeading(text,sty):
from hashlib import sha1
#create bookmarkname
bn=sha1(text+sty.name).hexdigest()
#modify paragraph text to include an anchor point with name bn
h=Paragraph(text+'<a name="%s"/>' % bn,sty)
#store the bookmark name on the flowable so afterFlowable can see this
h._bookmarkName=bn
story.append(h)
story.append(Paragraph('<b>Table of contents</b>', centered))
story.append(PageBreak())
doHeading('First heading', h1)
story.append(Paragraph('Text in first heading', PS('body')))
doHeading('First sub heading', h2)
story.append(Paragraph('Text in first sub heading', PS('body')))
story.append(PageBreak())
doHeading('Second sub heading', h2)
story.append(Paragraph('Text in second sub heading', PS('body')))
story.append(PageBreak())
doHeading('Last heading', h1)
story.append(Paragraph('Text in last heading', PS('body')))
doc = MyDocTemplate('mintoc.pdf')
doc.multiBuild(story)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-16-138d578aa6aa> in <module>
83 story.append(Paragraph('<b>Table of contents</b>', centered))
84 story.append(PageBreak())
---> 85 doHeading('First heading', h1)
86 story.append(Paragraph('Text in first heading', PS('body')))
87 doHeading('First sub heading', h2)
<ipython-input-16-138d578aa6aa> in doHeading(text, sty)
74 from hashlib import sha1
75 #create bookmarkname
---> 76 bn=sha1(text+sty.name).hexdigest()
77 #modify paragraph text to include an anchor point with name bn
78 h=Paragraph(text+'<a name="%s"/>' % bn,sty)
TypeError: Unicode-objects must be encoded before hashing
Upvotes: 0
Views: 262
Reputation: 5093
The example code is for Python 2. I can reproduce this error with Python 3. For reference, the full traceback is:
Traceback (most recent call last):
File "example.py", line 85, in <module>
doHeading('First heading', h1)
File "example.py", line 76, in doHeading
bn=sha1(text+sty.name).hexdigest()
TypeError: Unicode-objects must be encoded before hashing
The reason is that the method sha1()
expects bytes, not a string. Python 2 is less strict with string handling, that's why it doesn't give an exception.
So you have two choices: either use Python 2 (which is not recommended for new code), or you can update the code to work with Python 3. I could get this specific example working with two minor modifications:
At line 76, replace
bn=sha1(text+sty.name).hexdigest()
by
bn=sha1((text+sty.name).encode('ascii')).hexdigest()
At line 11, apply()
is being used, which is deprecated since Python 2.3. To update, replace
apply(BaseDocTemplate.__init__, (self, filename), kw)
by
BaseDocTemplate.__init__(*(self, filename), **kw)
Note that the example with these modifications runs fine in Python 2 and 3 (tested with 2.7 and 3.6).
Upvotes: 2