I'm trying to open a tex file from within python, tell the tex editor to run (manually you would press ctrl + T) and finally close the program.

So far I can only figure out how to open and close the program.

this is what I have so far...

    os.spawnv(os.P_WAIT, r"C:\Program Files\MiKTeX 2.9\miktex\bin\miktex-texworks.exe", ('miktex-texworks' , dir_dst + temp3 + temp2 + '.tex'))

Dani AI

Generated

A short, practical addendum to 's thread.

Prefer invoking the LaTeX engine directly instead of driving the editor UI. Calling the engine (for example pdflatex/xelatex) from Python with the subprocess API gives a blocking call, a return code, and full stdout/stderr to inspect — no fragile sleep/SendKeys timing needed (this is the point was making). Example pattern:

import subprocess, shutil, os

texfile = r"C:\path\to\file.tex"
pdflatex = shutil.which("pdflatex") or r"C:\Program Files\MiKTeX 2.9\miktex\bin\pdflatex.exe"
if not os.path.exists(pdflatex):
    raise FileNotFoundError(pdflatex)

cmd = [pdflatex, "-interaction=nonstopmode", "-halt-on-error", "-output-directory", os.path.dirname(texfile), texfile]
res = subprocess.run(cmd, capture_output=True, text=True)
if res.returncode:
    print("compile failed:", res.stderr)
else:
    print("compile finished")

If the GUI must be used (Texworks opening and pressing Ctrl+T), note that many editors spawn the compiler as a separate process, so waiting on the editor process does not guarantee compilation finished. In that case monitor the output file or the .log file. A simple, robust check is to wait until the PDF file size is stable for a short interval:

import os, time

def wait_for_stable(path, timeout=30, interval=0.5):
    end = time.time() + timeout
    last = -1
    while time.time() < end:
        try:
            size = os.path.getsize(path)
        except OSError:
            size = -1
        if size == last and size != -1:
            return True
        last = size
        time.sleep(interval)
    return False

Notes: use -interaction=nonstopmode/-halt-on-error to avoid prompts, ensure MiKTeX binaries are on PATH, avoid SendKeys+fixed sleeps (fragile), and consider latexmk or a dedicated build tool for multi-pass builds. For GUI-level automation, use a window-automation library (pywinauto/pyautogui) rather than raw SendKeys.

Recommended Answers

All 4 Replies

If you're using a unix-based operating system (aka not windows), you can use the subprocess module to execute shell commands. In effect, you would run latex at the command line through Python.

http://docs.python.org/library/subprocess.html

Looks like you are using windows though so I'm not quite sure. Sorry

:( yeah, I'm using Windows. Nonetheless, I found a way to control an external windows program! However, I would like to program a way for the program to tell python that it is done with its process and then for python to close the program. So far I have this:

        shell = win32com.client.Dispatch("WScript.Shell")
        shell.Run(dir_dst '.tex')
        sleep(4)
        shell.SendKeys("^t", 1)
        sleep(8)
        shell.SendKeys("^q", 1)

The only problem with it is that some files take longer to process and python moves on before the external program is done. Any idea on how I could fix this?

If your goal is to run a program from Python as in your original post, the only way I think of that working is that you call the program from a script like I mentioned. This can be done in windows if you are able to somehow call latex from the cmd line. Once you do this, you should be able to write a script in whatever language windows cmd line scripts are written in, then have python call that script as you did in the original post.

Let me ask you this... what exactly are you doing this for? I use latex and may be able to help you get around having to write a script in the first place. Secondly, latex I beleive has its own macro language so you may be able to write this script within latex itself. Last, you may want to consider downloading ubuntuu and installing it side-by-side of your windows build. Operations like what you are trying to do as well as many other situations you will likely encounter are more elegantly handled in a unix-based system, and the solutions are more likely to be scattered around the web.

I also should point out that if you do end up finding a way to use the python package "subprocess" the subprocess.call method knows to wait until the process is finished automoatically.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.