@@ -688,27 +688,7 @@ def individual_latex_image_conversion(latex_image, outformat, dest_dir, method):
688688 log .debug ("tex executable: {}" .format (tex_executable_cmd [0 ]))
689689 latex_cmd = tex_executable_cmd + ["-interaction=nonstopmode" , "-halt-on-error" , latex_image ]
690690 log .info ("converting {} to {}" .format (latex_image , latex_image_pdf ))
691- # Run LaTeX on the image file, usual console transcript is stdout.
692- # "result" is a "CompletedProcess" object. Specifying an encoding
693- # causes captured output to be a string, which is convenient.
694- result = subprocess .run (latex_cmd , stdout = subprocess .PIPE , encoding = "utf-8" )
695-
696- # It may be that the image needs to be compiled twice. If the .log file contains
697- # the string `Rerun to get`, then the document should be compiled again.
698-
699- # We keep track of how many times we've tried to compile the document and
700- # bail if it looks like we're stuck in a loop.
701- loop_count = 0
702- MAX_LOOPS = 10
703- while result .returncode == 0 and "Rerun to get" in open (latex_image_log ).read () and loop_count < MAX_LOOPS :
704- msg = "File {} needs to be processed with LaTeX again. Rerunning LaTeX for pass number {}."
705- log .info (msg .format (latex_image , loop_count + 2 ))
706- result = subprocess .run (latex_cmd , stdout = subprocess .PIPE , encoding = "utf-8" )
707- loop_count += 1
708-
709- if loop_count == MAX_LOOPS :
710- log .error ("Detected infinite loop while compiling {}. Aborting." .format (latex_image ))
711- result .returncode = 1
691+ result = _latex_compile (latex_cmd , latex_image_log , latex_image , capture_output = True )
712692
713693 if result .returncode != 0 :
714694 # failed to compile the LaTeX image
@@ -5154,6 +5134,31 @@ def latex(xml, pub_file, stringparams, extra_xsl, out_file, dest_dir):
51545134###################
51555135
51565136
5137+ def _latex_compile (latex_cmd , log_file , source_name , max_passes = 10 , capture_output = False ):
5138+ """Compile a LaTeX file, rerunning until cross-references settle.
5139+
5140+ Runs the initial pass, then reruns while the log file requests
5141+ "Rerun to get" and the pass limit has not been reached.
5142+
5143+ Returns the CompletedProcess from the final pass. Sets returncode
5144+ to 1 if the pass limit is reached without convergence.
5145+ """
5146+ run_kwargs = {"stdout" : subprocess .PIPE , "encoding" : "utf-8" } if capture_output else {}
5147+ result = subprocess .run (latex_cmd , ** run_kwargs )
5148+ pass_count = 1
5149+ while (result .returncode == 0
5150+ and os .path .isfile (log_file )
5151+ and "Rerun to get" in open (log_file ).read ()
5152+ and pass_count < max_passes ):
5153+ log .info ("Rerunning LaTeX for {} (pass {})" .format (source_name , pass_count + 1 ))
5154+ result = subprocess .run (latex_cmd , ** run_kwargs )
5155+ pass_count += 1
5156+ if pass_count == max_passes and result .returncode == 0 :
5157+ log .warning ("LaTeX compilation of {} required {} passes and may not have converged." .format (source_name , max_passes ))
5158+ result .returncode = 1
5159+ return result
5160+
5161+
51575162def pdf (xml , pub_file , stringparams , extra_xsl , out_file , dest_dir , method , outputs ):
51585163 """
51595164 Generate a PDF from an XML source using LaTeX as an intermediate format.
@@ -5237,21 +5242,7 @@ def pdf(xml, pub_file, stringparams, extra_xsl, out_file, dest_dir, method, outp
52375242 # matching the strategy used for standalone latex-image compilation.
52385243 latex_cmd = latex_exec_cmd + ["-halt-on-error" , sourcename ]
52395244 logname = basename + ".log"
5240- MAX_PASSES = 10
5241- result = subprocess .run (latex_cmd )
5242- for _ in range (2 , MAX_PASSES + 1 ):
5243- result = subprocess .run (latex_cmd )
5244- if result .returncode != 0 :
5245- break
5246- if os .path .isfile (logname ):
5247- with open (logname ) as f :
5248- log_contents = f .read ()
5249- if "Rerun to get" not in log_contents :
5250- break
5251- else :
5252- break
5253- else :
5254- log .warning ("LaTeX compilation of {} required {} passes and may not have converged." .format (sourcename , MAX_PASSES ))
5245+ result = _latex_compile (latex_cmd , logname , sourcename )
52555246
52565247 # If we want all outputs, we copy the entire build directory now that the PDF is built
52575248 # so we can get the *.log, *.aux, etc build files.
0 commit comments