##// END OF EJS Templates
Adding better logic to the PDF postprocessor.
Brian E. Granger -
Show More
@@ -30,23 +30,46 b' class PDFPostProcessor(PostProcessorBase):'
30 How many times pdflatex will be called.
30 How many times pdflatex will be called.
31 """)
31 """)
32
32
33 command = List(["pdflatex", "{filename}"], config=True, help="""
33 pdflatex_command = List(["pdflatex", "{filename}"], config=True, help="""
34 Shell command used to compile PDF.""")
34 Shell command used to compile PDF.""")
35
35
36 bibtex_command = List(["bibtex", "{filename}"], config=True, help="""
37 Shell command used to run bibtex.""")
38
36 verbose = Bool(False, config=True, help="""
39 verbose = Bool(False, config=True, help="""
37 Whether or not to display the output of the compile call.
40 Whether or not to display the output of the compile call.
38 """)
41 """)
39
42
40 def postprocess(self, input):
43 temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'],
41 """
44 config=True, help="""
42 Consume and write Jinja output a PDF.
45 Filename extensions of temp files to remove after running
43 See files.py for more...
46 """)
47
48 def run_command(self, command_list, filename, count, log_function):
49 """Run pdflatex or bibtext count times.
50
51 Parameters
52 ----------
53 command_list : list
54 A list of args to provide to Popen. Each element of this
55 list will be interpolated with the filename to convert.
56 filename : unicode
57 The name of the file to convert.
58 count : int
59 How many times to run the command.
60
61 Returns
62 -------
63 continue : bool
64 A boolean indicating if the command was successful (True)
65 or failed (False).
44 """
66 """
45 command = [c.format(filename=input) for c in self.command]
67 command = [c.format(filename=filename) for c in command_list]
46 self.log.info("Building PDF: %s", command)
68 times = 'time' if count == 1 else 'times'
69 self.log.info("Running %s %i %s: %s", command_list[0], count, times, command)
47 with open(os.devnull, 'rb') as null:
70 with open(os.devnull, 'rb') as null:
48 stdout = subprocess.PIPE if not self.verbose else None
71 stdout = subprocess.PIPE if not self.verbose else None
49 for index in range(self.iteration_count):
72 for index in range(count):
50 p = subprocess.Popen(command, stdout=stdout, stdin=null)
73 p = subprocess.Popen(command, stdout=stdout, stdin=null)
51 out, err = p.communicate()
74 out, err = p.communicate()
52 if p.returncode:
75 if p.returncode:
@@ -56,5 +79,52 b' class PDFPostProcessor(PostProcessorBase):'
56 out = u''
79 out = u''
57 else:
80 else:
58 out = out.decode('utf-8', 'replace')
81 out = out.decode('utf-8', 'replace')
59 self.log.critical(u"PDF conversion failed: %s\n%s", command, out)
82 log_function(command, out)
83 return False # failure
84 return True # success
85
86 def run_pdflatex(self, filename):
87 """Run pdflatex self.iteration_count times."""
88
89 def log_error(command, out):
90 self.log.critical(u"pdflatex failed: %s\n%s", command, out)
91
92 return self.run_command(self.pdflatex_command, filename,
93 self.iteration_count, log_error)
94
95 def run_bibtex(self, filename):
96 """Run bibtex self.iteration_count times."""
97 filename = filename.rstrip('.tex')
98
99 def log_error(command, out):
100 self.log.warn('bibtex had problems, most likely because there were no citations')
101 self.log.debug(u"bibtex output: %s\n%s", command, out)
102
103 return self.run_command(self.bibtex_command, filename, 1, log_error)
104
105 def clean_temp_files(self, filename):
106 """Remove temporary files created by pdflatex/bibtext."""
107 self.log.info("Removing temporary LaTeX files")
108 filename = filename.strip('.tex')
109 for ext in self.temp_file_exts:
110 try:
111 os.remove(filename+ext)
112 except OSError:
113 pass
114
115 def postprocess(self, filename):
116 """Build a PDF by running pdflatex and bibtex"""
117 self.log.info("Building PDF")
118 cont = self.run_pdflatex(filename)
119 if cont:
120 cont = self.run_bibtex(filename)
121 else:
122 self.clean_temp_files(filename)
60 return
123 return
124 if cont:
125 cont = self.run_pdflatex(filename)
126 self.clean_temp_files(filename)
127 if os.path.isfile(filename.rstrip('.tex')+'.pdf'):
128 self.log.info('PDF successfully created')
129 return
130
@@ -62,3 +62,7 b' class TestPDF(TestsBase):'
62
62
63 # Check that the PDF was created.
63 # Check that the PDF was created.
64 assert os.path.isfile('a.pdf')
64 assert os.path.isfile('a.pdf')
65
66 # Make sure that temp files are cleaned up
67 for ext in processor.temp_file_exts:
68 assert not os.path.isfile('a'+ext)
General Comments 0
You need to be logged in to leave comments. Login now