Source code for ipypublish.scripts.pdfexport

#!/usr/bin/env python
""" a module for exporting latex file to pdf

"""
import logging
import os
import shutil
import tempfile
from subprocess import Popen, PIPE, STDOUT

# python 3 to 2 compatibility
try:
    from shutil import which as exe_exists
except ImportError:
    from distutils.spawn import find_executable as exe_exists

VIEW_PDF = r"""
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
    <meta http-equiv="content-type" content="text/html; charset=windows-1252">
    <title>View PDF</title>

    <script type="text/javascript">
 	   var filepath = "{pdf_name}";
       var timer = null;

       function refresh(){{
          var d = document.getElementById("pdf"); // gets pdf-div
          d.innerHTML = '<iframe style="position: absolute; height: 100%; border: none" id="ipdf" src='+window.filepath+'  width="100%"></iframe>';
       }}

       function autoRefresh(){{
          timer = setTimeout("autoRefresh()", 20000);
          refresh();
       }}

       function manualRefresh(){{
          clearTimeout(timer);
          refresh();
       }}
	   function check_pdf() {{
	     var newfile = document.f.userFile.value;
	     ext = newfile.substring(newfile.length-3,newfile.length);
	     ext = ext.toLowerCase();
	     if(ext != 'pdf') {{
	       alert('You selected a .'+ext+
	             ' file; please select a .pdf file instead!'+filepath);
	       return false; }}
	     else
			 alert(newfile);
		     window.filepath = newfile;
			 alert(filepath);
			 refresh();
	       return true; }}
    </script>

</head>
<body>
	<!-- <form name=f onsubmit="return check_pdf();"
	    action='' method='POST' enctype='multipart/form-data'>
	    <input type='submit' name='upload_btn' value='upload'>
		<input type='file' name='userFile' accept="application/pdf">
	</form> -->
	<button onclick="manualRefresh()">manual refresh</button>
   <button onclick="autoRefresh()">auto refresh</button>
   <div id="pdf"></div>
</body>
<script type="text/javascript">refresh();</script>
</html>
"""


[docs]class change_dir: """Context manager for changing the current working directory""" def __init__(self, new_path): self.newPath = os.path.expanduser(new_path) def __enter__(self): self.savedPath = os.getcwd() os.chdir(self.newPath) def __exit__(self, etype, value, traceback): os.chdir(self.savedPath)
# python 3 to 2 compatibility try: import pathlib except ImportError: import pathlib2 as pathlib try: basestring except NameError: basestring = str
[docs]def export_pdf(texpath, outdir, files_path=None, convert_in_temp=False, html_viewer=True, debug_mode=False): if isinstance(texpath, basestring): texpath = pathlib.Path(texpath) if not texpath.exists() or not texpath.is_file(): logging.error('the tex file path does not exist: {}'.format(texpath)) raise IOError('the tex file path does not exist: {}'.format(texpath)) texname = os.path.splitext(texpath.name)[0] if files_path is not None: if isinstance(files_path, basestring): files_path = pathlib.Path(files_path) if not files_path.exists() or not files_path.is_dir(): logging.error('the external folder path does not exist: {}'.format(texpath)) raise IOError('the external folder path does not exist: {}'.format(texpath)) if not exe_exists('latexmk'): logging.error('requires the latexmk executable to run. See http://mg.readthedocs.io/latexmk.html#installation') raise RuntimeError( 'requires the latexmk executable to run. See http://mg.readthedocs.io/latexmk.html#installation') if convert_in_temp: out_folder = tempfile.mkdtemp() try: exitcode = run_conversion(texpath, out_folder, files_path, debug_mode) if exitcode == 0: shutil.copyfile(os.path.join(out_folder, texname + '.pdf'), os.path.join(outdir, texname + '.pdf')) finally: shutil.rmtree(out_folder) else: exitcode = run_conversion(texpath, outdir, files_path, debug_mode) if exitcode == 0: logging.info('pdf conversion complete') if html_viewer: view_pdf = VIEW_PDF.format(pdf_name=texname.replace(' ', '%20') + '.pdf') with open(os.path.join(outdir, texname + '.view_pdf.html'), 'w') as f: f.write(view_pdf) return True else: logging.error('pdf conversion failed: ' 'Try running with pdf_debug=True') return False
[docs]def run_conversion(texpath, out_folder, files_folder=None, debug_mode=False): """ run latexmk conversion """ # make sure tex file in right place outpath = os.path.join(out_folder, texpath.name) if os.path.dirname(str(texpath)) != str(out_folder): logging.debug('copying tex file to: {}'.format(os.path.join(str(out_folder), texpath.name))) shutil.copyfile(str(texpath), os.path.join(str(out_folder), texpath.name)) # make sure the external files folder is in right place if files_folder is not None: logging.debug('external files folder set') outfilespath = os.path.join(out_folder, str(files_folder.name)) if str(files_folder) != str(outfilespath): logging.debug('copying external files to: {}'.format(outfilespath)) if os.path.exists(outfilespath): shutil.rmtree(outfilespath) shutil.copytree(str(files_folder), str(outfilespath)) # run latexmk in correct folder with change_dir(out_folder): latexmk = ['latexmk', '-xelatex', '-bibtex', '-pdf'] latexmk += [] if debug_mode else ["--interaction=batchmode"] logging.info('running: ' + ' '.join(latexmk + ['<outpath>'])) latexmk += [outpath] def log_latexmk_output(pipe): for line in iter(pipe.readline, b''): logging.info('latexmk: {}'.format(line.decode("utf-8").strip())) process = Popen(latexmk, stdout=PIPE, stderr=STDOUT) with process.stdout: log_latexmk_output(process.stdout) exitcode = process.wait() # 0 means success return exitcode