# Multiple Page PDF Export Issue With pylatex

Multiple page issue:

I am trying to export a multiple page pdf and there seems to be an error. I cannot find the source...

I suppose that it is because of the text " âchemical exchangeâ " where non standard letters are used, but in theory I included the utf8 package so this should not be a problem...

Here is the pylatex code:

import pylatex as pl
from pylatex.utils import NoEscape
from pylatex import Command
from pylatex import Package
from pylatex import Figure
import os

videoNumber = 1
slideNumber = 5

class Form(pl.base_classes.Environment):
"""A class to wrap hyperref's form environment."""

_latex_name = 'Form'

packages = [pl.Package('hyperref')]
escape = False
content_separator = "\n"

def pdf(i):

dirname = os.getcwd()
filename = os.path.join(dirname, 'Text_And_Slides\\' + str(videoNumber) + '\\Slides\\' + str(i)) +".jpg"
print(filename)

with doc.create(Figure(position='h!')) as slide_pic:

doc.append(NoEscape(r"\noindent"))
doc.append(NoEscape(r"\rule{\linewidth}{1pt}"))
doc.append(NoEscape(r"\linebreak"))

dirname = os.getcwd()
filename = os.path.join(dirname, 'Text And Slides\\' + str(videoNumber) + '\\Text\\' + str(i))
with open(filename+".txt", 'r',encoding="utf8") as myfile:

doc.append(text)

doc.append(NoEscape(r"\newline"))
doc.append(NoEscape(r"\noindent"))
doc.append(NoEscape(r"\rule{\textwidth}{1pt}"))
doc.append(NoEscape(r"\newline"))
doc.append("Notes: ")
doc.append(NoEscape(r"\newline"))

doc.append(NoEscape(r"\newcommand\measurepage{\the\dimexpr\pagegoal-\pagetotal-\baselineskip\relax}"))
doc.append(NoEscape(r"\par")) # <---- This line added
with doc.create(Form()):
doc.append(Command('noindent'))
doc.append(Command('TextField',
options=["name=multilinetextbox", "multiline=true",
NoEscape("width=\linewidth"),NoEscape("height=\measurepage")],
arguments=''))

doc.append(NoEscape(r"\newpage"))

geometry_options = {
"margin": "0.3in",
"bottom": "0.3in",
doc = pl.Document('basic',geometry_options=geometry_options)
doc.preamble.append(Command('usepackage', 'helvet'))
doc.preamble.append(Package ('inputenc', options = ['utf8']))
doc.preamble.append(Package('needspace'))

for i in range(1,3):
pdf(i)

doc.generate_pdf('pdf_test')


And here is the generated LaTeX file:

\documentclass{article}%
\usepackage[T1]{fontenc}%
\usepackage[utf8]{inputenc}%
\usepackage{lmodern}%
\usepackage{textcomp}%
\usepackage{lastpage}%
\usepackage{graphicx}%
\usepackage{hyperref}%
%
\usepackage{helvet}%
\usepackage[utf8]{inputenc}%
\usepackage{needspace}%
%
\begin{document}%
\normalsize%

\begin{figure}[h!]%
\centering%
\includegraphics[width=\linewidth]{1.jpg}%
\end{figure}

%
\noindent%
\rule{\linewidth}{1pt}%
\linebreak%
Welcome to our MOOC our Massively Online Open Course on Basic Steps in Magnetic Resonance. That is the subject of chapter 4 of Peter Hore's book. The author has chosen an example of chemical exchange for the title page of his book so it is safe to assume that he found this subject particularly interesting. Like many other basic aspects of magnetic resonance the effects of chemical exchange were discovered in the 1950s. The name of Herbert Gutowsky is often associated with this discovery. The theory was developed by Felix Bloch and Harden McConnell. As we shall see chemical reactions that occur during the observation of NMR spectra lead to characteristic effects: line broadening coalescence and line narrowing all of which allow us to determine the rates of reactions. Typically one can study rates that are comparable with differences in chemical shifts. The range of applications is truly staggering. From simple conformational equilibria to internal mobility of biomolecules such as proteins.%
\newline%
\noindent%
\rule{\textwidth}{1pt}%
\newline%
Notes: %
\newline%
\newcommand\measurepage{\the\dimexpr\pagegoal-\pagetotal-\baselineskip\relax}%
\par%
\begin{Form}
\noindent
\TextField[name=multilinetextbox,multiline=true,width=\linewidth,height=\measurepage]{}
\end{Form}%
\newpage%

\begin{figure}[h!]%
\centering%
\includegraphics[width=\linewidth]{1.jpg}%
\end{figure}

%
\noindent%
\rule{\linewidth}{1pt}%
\linebreak%
So the word âchemical exchangeâ has a particular meaning for NMR spectroscopists which is not shared by the entire community of chemists. To explain this point let's consider some simple examples. All of us in first year chemistry must have learned that cyclohexane normally looks like this if it is drawn as a static molecule and that we have protons or generally speaking substituents sticking out from the ring in axial positions and other ones that are in equatorial positions. Now we also know that these can interchange to give another conformation which again has axial and equatorial positions. Now what is curious is that in the static molecule if we could stop it from exchanging we would expect a different chemical shift for the axial position and the equatorial position. One would expect them to have different chemical shifts. Let's not talk about the fact that they are also coupled which is not of interest here. Now it turns out that the chemical shift of the axial proton will be transformed into the chemical shift of an equatorial proton. Whereas the equatorial proton will find itself in the position of an axial proton. Consequently there is an interchange between their chemical shifts. It turns out that this process is extremely fast and therefore difficult to measure with NMR unless we find some way of slowing it down which is actually still a topic of interest. I can take another example of a true chemical reaction. Let's consider some carboxylic acid which looks like this in the acid form. And we have all learned that this can be transformed into the conjugate base by giving a proton to the environment. Now if we think of this carbon{-}13 we can expect its chemical shift to be different from the chemical shift in the conjugate base. And indeed it is. Again such a process tends to be very fast and therefore not easy to measure by NMR. But it turns out that such processes can be slowed down considerably. For example if this carboxylic acid is hidden in the heart of a protein if it belongs to the side{-}chain of a protein to one of the amino{-}acids in the protein the exchange can be slowed down and can become measurable which is of great interest to NMR spectroscopy.%
\newline%
\noindent%
\rule{\textwidth}{1pt}%
\newline%
Notes: %
\newline%
\newcommand\measurepage{\the\dimexpr\pagegoal-\pagetotal-\baselineskip\relax}%
\par%
\begin{Form}
\noindent
\TextField[name=multilinetextbox,multiline=true,width=\linewidth,height=\measurepage]{}
\end{Form}%
\newpage%
\end{document}


This is the error:

CalledProcessError Traceback (most recent call last) in () 70 pdf(i) 71 ---> 72 doc.generate_pdf('pdf_test')

~\Anaconda3\lib\site-packages\pylatex\document.py in generate_pdf(self, filepath, clean, clean_tex, compiler, compiler_args, silent) 231 try: 232 output = subprocess.check_output(command, --> 233 stderr=subprocess.STDOUT) 234 except (OSError, IOError) as e: 235 # Use FileNotFoundError when python 2 is dropped

~\Anaconda3\lib\subprocess.py in check_output(timeout, *popenargs, **kwargs) 334 335 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, --> 336 **kwargs).stdout 337 338

~\Anaconda3\lib\subprocess.py in run(input, timeout, check, *popenargs, **kwargs) 416 if check and retcode: 417 raise CalledProcessError(retcode, process.args, --> 418 output=stdout, stderr=stderr) 419 return CompletedProcess(process.args, retcode, stdout, stderr) 420

CalledProcessError: Command '['latexmk', '--pdf', '--interaction=nonstopmode', 'pdf_test.tex']' returned non-zero exit status 12.

EDIT:

I just realized that if I run the Python script multiple times, after the second or third run, it will output the pdf... Very strange!

Any help is highly appreciated!!

EDIT 2:

Here is the updated code based on the comments. It still does not work, though...

import pylatex as pl
from pylatex.utils import NoEscape
from pylatex import Command
from pylatex import Package
from pylatex import Figure
import os

videoNumber = 1
slideNumber = 5

class Form(pl.base_classes.Environment):
"""A class to wrap hyperref's form environment."""

_latex_name = 'Form'

packages = [pl.Package('hyperref')]
escape = False
content_separator = "\n"

def pdf(i):

dirname = os.getcwd()
filename = os.path.join(dirname, 'Text_And_Slides\\' + str(videoNumber) + '\\Slides\\' + str(i)) +".jpg"
print(filename)

with doc.create(Figure(position='h!')) as slide_pic:

doc.append(NoEscape(r"\noindent"))
doc.append(NoEscape(r"\rule{\linewidth}{1pt}"))
doc.append(NoEscape(r"\linebreak"))

dirname = os.getcwd()
filename = os.path.join(dirname, 'Text And Slides\\' + str(videoNumber) + '\\Text\\' + str(i))
with open(filename+".txt", 'r',encoding="utf8") as myfile:

doc.append(text)

doc.append(NoEscape(r"\newline"))
doc.append(NoEscape(r"\noindent"))
doc.append(NoEscape(r"\rule{\textwidth}{1pt}"))
doc.append(NoEscape(r"\newline"))
doc.append("Notes: ")
doc.append(NoEscape(r"\newline"))

doc.append(NoEscape(r"\setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}"))
doc.append(NoEscape(r"\par")) # <---- This line added
with doc.create(Form()):
doc.append(Command('noindent'))
doc.append(Command('TextField',
options=["name=multilinetextbox", "multiline=true",
NoEscape("width=\linewidth"),NoEscape("height=\measurepage")],
arguments=''))

doc.append(NoEscape(r"\newpage"))

geometry_options = {
"margin": "0.3in",
"bottom": "0.3in",
doc = pl.Document('basic',geometry_options=geometry_options)
doc.preamble.append(Command('usepackage', 'helvet'))
doc.preamble.append(Package ('inputenc', options = ['utf8']))
doc.preamble.append(Package('needspace'))
doc.preamble.append(NoEscape(r"\newlength{\measurepage}"))

for i in range(1,3):
pdf(i)

doc.generate_tex('pdf_test')


Here is the generated LaTeX output:

\documentclass{article}%
\usepackage[T1]{fontenc}%
\usepackage[utf8]{inputenc}%
\usepackage{lmodern}%
\usepackage{textcomp}%
\usepackage{lastpage}%
\usepackage{graphicx}%
\usepackage{hyperref}%
%
\usepackage{helvet}%
\usepackage[utf8]{inputenc}%
\usepackage{needspace}%
\newlength{\measurepage}%
%
\begin{document}%
\normalsize%

\begin{figure}[h!]%
\centering%
\includegraphics[width=\linewidth]{1.jpg}%
\end{figure}

%
\noindent%
\rule{\linewidth}{1pt}%
\linebreak%
Welcome to our MOOC our Massively Online Open Course on Basic Steps in Magnetic Resonance. That is the subject of chapter 4 of Peter Hore's book. The author has chosen an example of chemical exchange for the title page of his book so it is safe to assume that he found this subject particularly interesting. Like many other basic aspects of magnetic resonance the effects of chemical exchange were discovered in the 1950s. The name of Herbert Gutowsky is often associated with this discovery. The theory was developed by Felix Bloch and Harden McConnell. As we shall see chemical reactions that occur during the observation of NMR spectra lead to characteristic effects: line broadening coalescence and line narrowing all of which allow us to determine the rates of reactions. Typically one can study rates that are comparable with differences in chemical shifts. The range of applications is truly staggering. From simple conformational equilibria to internal mobility of biomolecules such as proteins.%
\newline%
\noindent%
\rule{\textwidth}{1pt}%
\newline%
Notes: %
\newline%
\setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}%
\par%
\begin{Form}
\noindent
\TextField[name=multilinetextbox,multiline=true,width=\linewidth,height=\measurepage]{}
\end{Form}%
\newpage%

\begin{figure}[h!]%
\centering%
\includegraphics[width=\linewidth]{1.jpg}%
\end{figure}

%
\noindent%
\rule{\linewidth}{1pt}%
\linebreak%
So the word âchemical exchangeâ has a particular meaning for NMR spectroscopists which is not shared by the entire community of chemists. To explain this point let's consider some simple examples. All of us in first year chemistry must have learned that cyclohexane normally looks like this if it is drawn as a static molecule and that we have protons or generally speaking substituents sticking out from the ring in axial positions and other ones that are in equatorial positions. Now we also know that these can interchange to give another conformation which again has axial and equatorial positions. Now what is curious is that in the static molecule if we could stop it from exchanging we would expect a different chemical shift for the axial position and the equatorial position. One would expect them to have different chemical shifts. Let's not talk about the fact that they are also coupled which is not of interest here. Now it turns out that the chemical shift of the axial proton will be transformed into the chemical shift of an equatorial proton. Whereas the equatorial proton will find itself in the position of an axial proton. Consequently there is an interchange between their chemical shifts. It turns out that this process is extremely fast and therefore difficult to measure with NMR unless we find some way of slowing it down which is actually still a topic of interest. I can take another example of a true chemical reaction. Let's consider some carboxylic acid which looks like this in the acid form. And we have all learned that this can be transformed into the conjugate base by giving a proton to the environment. Now if we think of this carbon{-}13 we can expect its chemical shift to be different from the chemical shift in the conjugate base. And indeed it is. Again such a process tends to be very fast and therefore not easy to measure by NMR. But it turns out that such processes can be slowed down considerably. For example if this carboxylic acid is hidden in the heart of a protein if it belongs to the side{-}chain of a protein to one of the amino{-}acids in the protein the exchange can be slowed down and can become measurable which is of great interest to NMR spectroscopy.%
\newline%
\noindent%
\rule{\textwidth}{1pt}%
\newline%
Notes: %
\newline%
\setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}%
\par%
\begin{Form}
\noindent
\TextField[name=multilinetextbox,multiline=true,width=\linewidth,height=\measurepage]{}
\end{Form}%
\newpage%
\end{document}

• Off-topic: If the \measurepage won't change I would put it in the preamble to avoid a "command already defined" error, otherwise I would use \def instead of \newcommand. – Phelype Oleinik Sep 24 '18 at 11:29
• @PhelypeOleinik Thanks for the notice. However, in my case it changes quite a lot depending on the amount of text. I tried using \def , but it does not change anything. – james Sep 24 '18 at 11:40
• The problem using \newcommand more than once is that it raises an error the second time, while \def ifnores that. Also, I just noticed you use a command to store a length... In this case it would be preferable, in terms of performance and logic, if you used \newlength{\measurepage} in the preamble and then, at each page, used \setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}. – Phelype Oleinik Sep 24 '18 at 11:45
• @PhelypeOleinik I included all your comments, but it still does not work. :( Please have a look at my new edit. – james Sep 24 '18 at 12:09
• @PhelypeOleinik I think redefining the \measurepage macro is the wrong way to go (as well as using a length). Instead he should define the macro to be \newcommand\measurepage{\the\dimexpr\pagegoal-\pagetotal-\baselineskip\relax} in the preamble once and then use it as the argument for the height key. This way it gets calculated exactly where it is needed. This is not a length but code to calculate one ad hoc. Still a \par prior to the calculation would be necessary (so putting it in front of the Form environments). – Skillmon Sep 24 '18 at 12:36

You have to use \setlength after the \par. The following LaTeX code seems to produce the correct output:

\documentclass{article}%
\usepackage[T1]{fontenc}%
\usepackage[utf8]{inputenc}%
\usepackage{lmodern}%
\usepackage{textcomp}%
\usepackage{lastpage}%
\usepackage{graphicx}%
\usepackage{hyperref}%
%
\usepackage{helvet}%
\usepackage[utf8]{inputenc}%
\usepackage{needspace}%
\newlength{\measurepage}%
%
\begin{document}%
\normalsize%

\begin{figure}[h!]%
\centering%
\includegraphics[width=\linewidth]{example-image-duck}%
\end{figure}

%
\noindent%
\rule{\linewidth}{1pt}%
\linebreak%
Welcome to our MOOC our Massively Online Open Course on Basic Steps in Magnetic Resonance. That is the subject of chapter 4 of Peter Hore's book. The author has chosen an example of chemical exchange for the title page of his book so it is safe to assume that he found this subject particularly interesting. Like many other basic aspects of magnetic resonance the effects of chemical exchange were discovered in the 1950s. The name of Herbert Gutowsky is often associated with this discovery. The theory was developed by Felix Bloch and Harden McConnell. As we shall see chemical reactions that occur during the observation of NMR spectra lead to characteristic effects: line broadening coalescence and line narrowing all of which allow us to determine the rates of reactions. Typically one can study rates that are comparable with differences in chemical shifts. The range of applications is truly staggering. From simple conformational equilibria to internal mobility of biomolecules such as proteins.%
\newline%
\noindent%
\rule{\textwidth}{1pt}%
\newline%
Notes: %
\newline%
\par%
\setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}%
\begin{Form}
\noindent
\TextField[name=multilinetextbox,multiline=true,width=\linewidth,height=\measurepage]{}
\end{Form}%
\newpage%

\begin{figure}[h!]%
\centering%
\includegraphics[width=\linewidth]{example-image-duck}%
\end{figure}

%
\noindent%
\rule{\linewidth}{1pt}%
\linebreak%
So the word âchemical exchangeâ has a particular meaning for NMR spectroscopists which is not shared by the entire community of chemists. To explain this point let's consider some simple examples. All of us in first year chemistry must have learned that cyclohexane normally looks like this if it is drawn as a static molecule and that we have protons or generally speaking substituents sticking out from the ring in axial positions and other ones that are in equatorial positions. Now we also know that these can interchange to give another conformation which again has axial and equatorial positions. Now what is curious is that in the static molecule if we could stop it from exchanging we would expect a different chemical shift for the axial position and the equatorial position. One would expect them to have different chemical shifts. Let's not talk about the fact that they are also coupled which is not of interest here. Now it turns out that the chemical shift of the axial proton will be transformed into the chemical shift of an equatorial proton. Whereas the equatorial proton will find itself in the position of an axial proton. Consequently there is an interchange between their chemical shifts. It turns out that this process is extremely fast and therefore difficult to measure with NMR unless we find some way of slowing it down which is actually still a topic of interest. I can take another example of a true chemical reaction. Let's consider some carboxylic acid which looks like this in the acid form. And we have all learned that this can be transformed into the conjugate base by giving a proton to the environment. Now if we think of this carbon{-}13 we can expect its chemical shift to be different from the chemical shift in the conjugate base. And indeed it is. Again such a process tends to be very fast and therefore not easy to measure by NMR. But it turns out that such processes can be slowed down considerably. For example if this carboxylic acid is hidden in the heart of a protein if it belongs to the side{-}chain of a protein to one of the amino{-}acids in the protein the exchange can be slowed down and can become measurable which is of great interest to NMR spectroscopy.%
\newline%
\noindent%
\rule{\textwidth}{1pt}%
\newline%
Notes: %
\newline%
\par%
\setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}%
\begin{Form}
\noindent
\TextField[name=multilinetextbox,multiline=true,width=\linewidth,height=\measurepage]{}
\end{Form}%
\newpage%
\end{document}


The only changes I made was replacing the image file I don't have and changing the order of \par and \setlength{\measurepage}.

If you want to include this snippet multiple times, it might be a good idea to define a command such like:

\newcommand*\MeasurePage{\par\setlength{\measurepage}{\dimexpr\pagegoal-\pagetotal-\baselineskip}}


And then use that one instead of the same code all over again.

• Thank you very much ! I still have a problem. I changed the python code accordingly, but I don't understand it... When I execute the python code, I get an error. If however, I keep executing the python code 2 or 3 times, eventually it will work and output the pdf. – james Sep 24 '18 at 12:28
• @james I can't really help you on the python code as I can't test anything there. Did you make sure to always use raw strings if your TeX code contains backslashes? Also: What are the error messages you get? TeX ones or python ones? What exactly is the message. If the problem lies in your python code and not the generated TeX code then it might be better to ask in a forum with more python users (of which some might have a working pylatex installation), like e.g. Stackoverflow. If you don't show the error messages I can't help you. – Skillmon Sep 24 '18 at 12:32