|
From: <jo...@us...> - 2009-11-13 19:23:03
|
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.
|