Franck Pommereau

added Makefile, minor fixes

*~
/with-shell
/without-shell
*.pyc
all:
test: clean test-with-shell test-without-shell
clean:
rm -rf with-shell without-shell
test-with-shell:
mkdir with-shell
cp test.tex pytex.sty Makefile with-shell/
cp pytex.py with-shell/pytex
chmod +x with-shell/pytex
PATH=.:$$PATH make -C with-shell run-test-with-shell
run-test-with-shell:
pdflatex -shell-escape test
test-without-shell:
mkdir without-shell
cp test.tex pytex.sty Makefile without-shell/
cp pytex.py without-shell/pytex
chmod +x without-shell/pytex
PATH=.:$$PATH make -C without-shell run-test-without-shell
run-test-without-shell:
pdflatex test
pytex test
pdflatex test
......@@ -9,6 +9,10 @@ try :
except :
pygments = None
def log (message) :
sys.stdout.write(message)
sys.stdout.flush()
class Interpreter (object) :
def __init__ (self, jobname) :
self._t = []
......@@ -163,7 +167,7 @@ class Handler (SocketServer.BaseRequestHandler) :
self.client_address)
return
sock.sendto(repr({"status" : "ok",
"message" : "file proceeded successfully"}),
"message" : "<%(method)s %(path)s>" % req}),
self.client_address)
class Server (multiprocessing.Process) :
......@@ -172,14 +176,14 @@ class Server (multiprocessing.Process) :
child = cls(port, jobname)
child.start()
multiprocessing.process._current_process._children.discard(child)
print("<server started at %s>" % child.pid)
log("<server started at %s>" % child.pid)
def __init__ (self, port, jobname) :
multiprocessing.Process.__init__(self)
self.port = port
self.jobname = jobname
def run (self) :
self.server = SocketServer.UDPServer(("", self.port), Handler)
self.py = Interpreter(self.jobname)
self.server.py = Interpreter(self.jobname)
self.server.serve_forever()
@classmethod
def quit (cls, port) :
......@@ -228,56 +232,61 @@ def main () :
args = parser.parse_args([a.strip("{}") for a in sys.argv[1:]])
if args.listen :
if len(args.args) != 1 :
print("usage: pytex [-b BASE] --listen PORT JOBNAME")
log("usage: pytex [-b BASE] --listen PORT JOBNAME")
sys.exit(1)
Server.daemonize(args.listen, *args.args)
return
elif args.call :
if len(args.args) != 2 :
print("usage: pytex [-b BASE] --call PORT MODE FILE")
log("usage: pytex [-b BASE] --call PORT MODE FILE")
sys.exit(1)
elif args.args[0] not in ("eval", "exec") :
print("pytex: expected 'exec' or 'eval', but got %r" % args.args[0])
log("pytex: expected 'exec' or 'eval', but got %r" % args.args[0])
sys.exit(1)
print Server.process(args.call, *args.args)
resp = Server.process(args.call, *args.args)
try :
resp = ast.literal_eval(resp)
except :
resp = {"message": "<invalid answer from server>"}
log(resp.get("message", "<invalid answer from server>"))
return
elif args.shutdown :
if len(args.args) > 0 :
print("usage: pytex [-b BASE] --shutdown PORT")
log("usage: pytex [-b BASE] --shutdown PORT")
sys.exit(1)
try :
resp = Server.quit(args.shutdown)
except socket.timeout :
print("<could not reach server to shutdown>")
log("<could not reach server to shutdown>")
sys.exit(1)
try :
resp = ast.literal_eval(resp)
pid = int(resp["pid"])
except :
print("<invalid answer from server>")
log("<invalid answer from server>")
sys.exit(1)
child = psutil.Process(pid)
try :
child.wait(1)
print("<server at %s has sutdown>" % child.pid)
log("<server at %s has shutdown>" % child.pid)
return
except :
child.terminate()
try :
child.wait(1)
print("<server at %s terminated>" % child.pid)
log("<server at %s terminated>" % child.pid)
return
except :
child.kill()
print("<server at %s killed>" % child.pid)
log("<server at %s killed>" % child.pid)
return
elif len(args.args) != 1 :
print("usage: pytex [-b BASE] [--clean] JOBNAME")
log("usage: pytex [-b BASE] [--clean] JOBNAME")
sys.exit(1)
try :
jobname, jobs = getjobs(args.args[0])
except :
print("pytex: invalid file %r" % args.args[0])
log("pytex: invalid file %r" % args.args[0])
sys.exit(2)
if args.base is None :
if jobs :
......@@ -303,14 +312,14 @@ def main () :
py = Interpreter(jobname)
for mode, path in jobs :
if not os.path.exists(path) :
print("not found: %s" % path)
log("not found: %s" % path)
elif mode in ("eval", "exec") :
print("%s: %s" % (mode, path))
log("%s: %s" % (mode, path))
py(path, mode)
elif mode == "code" :
print("skip: %s" % path)
log("skip: %s" % path)
else :
print("pytex: invalid mode %r in file %r" % (mode, jobname + ".pytex"))
log("pytex: invalid mode %r in file %r" % (mode, jobname + ".pytex"))
if __name__ == "__main__" :
main()
......
\ProvidesPackage{pytex}
\RequirePackage{pgfopts}
\RequirePackage{sverb}
\RequirePackage{fancyvrb}
......@@ -12,21 +11,15 @@
\edef\py@port{12345}
\edef\py@base{\jobname.pytmp}
\pgfkeys{
/pytex/.cd,
base/.store in=\py@base,
port/.store in=\py@port,
}
\ProcessPgfOptions{/pytex}
\immediate\write18{pytex -b {\py@base} --listen {\py@port} {\jobname}}
\AtEndDocument{\immediate\write18{pytex -b {\py@base} --quit {\py@port}}}
\immediate\write18{pytex --clean {\jobname}}
\IfFileExists{\py@base/\jobname}
{\global\edef\py@base{\py@base/}}
{\global\edef\py@base{\py@base.}}
\immediate\write18{pytex -b {\py@base} --listen {\py@port} {\jobname}}
\AtEndDocument{\immediate\write18{pytex -b {\py@base} --shutdown {\py@port}}}
%%
%%
......
......@@ -3,6 +3,8 @@
\usepackage{pytex}
\parindent=0pt
\def\hello{NOT DEFINED}
\begin{document}
***\pyv{" ".join(s.capitalize() for s in "hello world!".split())}***
......@@ -38,6 +40,4 @@ def fact (n) :
return f
\end{pycode}
\IfFileExists{pytex.tmp}{found}{NO}.
\end{document}
......