Revision: 7964 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7964&view=rev Author: jouni Date: 2009-11-13 19:22:52 +0000 (Fri, 13 Nov 2009)
Log Message: ----------- Expose the pdf information dictionary Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/doc/api/api_changes.rst trunk/matplotlib/examples/pylab_examples/multipage_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Property Changed: ---------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2009-11-13 00:44:11 UTC (rev 7963) +++ trunk/matplotlib/CHANGELOG 2009-11-13 19:22:52 UTC (rev 7964) @@ -1,3 +1,6 @@ +2009-11-13 The pdf backend now allows changing the contents of + a pdf file's information dictionary via PdfPages.infodict. - JKS + 2009-11-12 font_manager.py should no longer cause EINTR on Python 2.6 (but will on the 2.5 version of subprocess). Also the fc-list command in that file was fixed so now it should Modified: trunk/matplotlib/doc/api/api_changes.rst =================================================================== --- trunk/matplotlib/doc/api/api_changes.rst 2009-11-13 00:44:11 UTC (rev 7963) +++ trunk/matplotlib/doc/api/api_changes.rst 2009-11-13 19:22:52 UTC (rev 7964) @@ -10,7 +10,8 @@ Changes beyond 0.99.x ===================== -* You can now print several figures to one pdf file. See the docstrings +* You can now print several figures to one pdf file and modify the + document information dictionary of a pdf file. See the docstrings of the class :class:`matplotlib.backends.backend_pdf.PdfPages` for more information. Modified: trunk/matplotlib/examples/pylab_examples/multipage_pdf.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/multipage_pdf.py 2009-11-13 00:44:11 UTC (rev 7963) +++ trunk/matplotlib/examples/pylab_examples/multipage_pdf.py 2009-11-13 19:22:52 UTC (rev 7964) @@ -1,5 +1,6 @@ # This is a demo of creating a pdf file with several pages. +import datetime import numpy as np import matplotlib from matplotlib.backends.backend_pdf import PdfPages @@ -29,5 +30,14 @@ pdf.savefig(fig) # or you can pass a Figure object to pdf.savefig close() +# We can also set the file's metadata via the PdfPages object: +d = pdf.infodict() +d['Title'] = 'Multipage PDF Example' +d['Author'] = u'Jouni K. Sepp\xe4nen' +d['Subject'] = 'How to create a multipage pdf file and set its metadata' +d['Keywords'] = 'PdfPages multipage keywords author title subject' +d['CreationDate'] = datetime.datetime(2009,11,13) +d['ModDate'] = datetime.datetime.today() + # Remember to close the object - otherwise the file will not be usable pdf.close() Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-11-13 00:44:11 UTC (rev 7963) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-11-13 19:22:52 UTC (rev 7964) @@ -5,6 +5,7 @@ """ from __future__ import division +import codecs import os import re import sys @@ -149,6 +150,16 @@ elif isinstance(obj, (int, long)): return "%d" % obj + # Unicode strings are encoded in UTF-16BE with byte-order mark. + elif isinstance(obj, unicode): + try: + # But maybe it's really ASCII? + s = obj.encode('ASCII') + return pdfRepr(s) + except UnicodeEncodeError: + s = codecs.BOM_UTF16_BE + obj.encode('UTF-16BE') + return pdfRepr(s) + # Strings are written in parentheses, with backslashes and parens # escaped. Actually balanced parens are allowed, but it is # simpler to escape them all. TODO: cut long strings into lines; @@ -374,7 +385,6 @@ fh.write("%\254\334 \253\272\n") self.rootObject = self.reserveObject('root') - self.infoObject = self.reserveObject('info') self.pagesObject = self.reserveObject('pages') self.pageList = [] self.fontObject = self.reserveObject('fonts') @@ -388,14 +398,13 @@ 'Pages': self.pagesObject } self.writeObject(self.rootObject, root) - info = { 'Creator': 'matplotlib ' + __version__ \ - + ', http://matplotlib.sf.net', - 'Producer': 'matplotlib pdf backend', - 'CreationDate': datetime.today() } + revision = '$Rev$'.strip('$').split(':')[1].strip() + self.infoDict = { + 'Creator': 'matplotlib %s, http://matplotlib.sf.net' % __version__, + 'Producer': 'matplotlib pdf backend r%s' % revision, + 'CreationDate': datetime.today() + } - # Possible TODO: Title, Author, Subject, Keywords - self.writeObject(self.infoObject, info) - self.fontNames = {} # maps filenames to internal font names self.nextFont = 1 # next free internal font name self.dviFontInfo = {} # information on dvi fonts @@ -471,6 +480,7 @@ { 'Type': Name('Pages'), 'Kids': self.pageList, 'Count': len(self.pageList) }) + self.writeInfoDict() # Finalize the file self.writeXref() @@ -1280,6 +1290,31 @@ if borken: raise AssertionError, 'Indirect object does not exist' + def writeInfoDict(self): + """Write out the info dictionary, checking it for good form""" + + is_date = lambda x: isinstance(x, datetime) + check_trapped = lambda x: isinstance(x, Name) and x.name in \ + ('True', 'False', 'Unknown') + keywords = {'Title': is_string_like, + 'Author': is_string_like, + 'Subject': is_string_like, + 'Keywords': is_string_like, + 'Creator': is_string_like, + 'Producer': is_string_like, + 'CreationDate': is_date, + 'ModDate': is_date, + 'Trapped': check_trapped} + for k in self.infoDict.keys(): + if k not in keywords: + warnings.warn('Unknown infodict keyword: %s' % k) + else: + if not keywords[k](self.infoDict[k]): + warnings.warn('Bad value for infodict keyword %s' % k) + + self.infoObject = self.reserveObject('info') + self.writeObject(self.infoObject, self.infoDict) + def writeTrailer(self): """Write out the PDF trailer.""" @@ -2052,6 +2087,14 @@ self._file.close() self._file = None + def infodict(self): + """ + Return a modifiable information dictionary object + (see PDF reference section 10.2.1 'Document Information + Dictionary'). + """ + return self._file.infoDict + def savefig(self, figure=None, **kwargs): """ Save the Figure instance *figure* to this file as a new page. Property changes on: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py ___________________________________________________________________ Added: svn:keywords + Rev This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Matplotlib-checkins mailing list Matplotlib-checkins@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins