I try to build a throw-away script which automatically compiles my latex document after every change.
The relevant code:
class LatexCompiler(FileSystemEventHandler):
def on_modified(self, event):
if isinstance(event, watchdog.events.FileModifiedEvent):
print event
os.system("pdflatex Thesis.tex")
if __name__ == "__main__":
path = sys.argv[1] if len(sys.argv) > 1 else '.'
os.chdir("/path/to/my/tex/file")
observer = Observer()
observer.schedule(LatexCompiler(), path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
As soon as I add the os.system(...) line the on_modified() method starts to loop forever after triggering. To ensure that on_modified() is called only once I've omitted the call to os.system() and there it is, just one line got printed describing the event.
So what is going wrong?
The event handler on_modified()
is called whenever any existing file in the monitored directory is modified.
I'm guessing, but its likely that pdflatex
creates intermediate files which it then modifies. Or it could just be that the output pdf file exists from a previous run and is then modified by pdflatex
. Either way this would trigger the on_modified()
handler, which in turn runs pdflatex
again (modifying file(s)), which triggers another call to on_modified()
.... you get the idea.
You can monitor a specific set of files, your input tex files, and then trigger pdflatex
only if one of those files is modified. There are some details to clean up, but the following should give you an idea.
import os, time, sys
import watchdog.events
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
class LatexCompiler(FileSystemEventHandler):
def __init__(self, files, *args, **kwargs):
super(LatexCompiler, self).__init__(*args, **kwargs)
self._files = files
print "LatexCompiler(): monitoring files %r" % self._files
def on_modified(self, event):
if (isinstance(event, watchdog.events.FileModifiedEvent) and
event.src_path in self._files):
print event
os.system("pdflatex %s" % event.src_path)
if __name__ == "__main__":
path = sys.argv[1] if len(sys.argv) > 1 else '.'
observer = Observer()
files = [os.path.join(path, f) for f in ['Thesis.tex', 'Resume.tex']]
observer.schedule(LatexCompiler(files), path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()