summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/pyluatex/pyluatex.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/latex/pyluatex/pyluatex.lua')
-rw-r--r--macros/luatex/latex/pyluatex/pyluatex.lua73
1 files changed, 56 insertions, 17 deletions
diff --git a/macros/luatex/latex/pyluatex/pyluatex.lua b/macros/luatex/latex/pyluatex/pyluatex.lua
index d7e27bc6cb..6e9c6abb63 100644
--- a/macros/luatex/latex/pyluatex/pyluatex.lua
+++ b/macros/luatex/latex/pyluatex/pyluatex.lua
@@ -26,6 +26,7 @@ local json = require("pyluatex-json")
local socket = require("socket")
pyluatex = pyluatex or {
+ ignore_errors = false,
verbose = false,
session = "default"
}
@@ -38,10 +39,15 @@ local tcp = nil
local env_end = nil
local env_lines = nil
local parent_env = nil
+local env_repl_mode = false
local last_code = nil
local last_output = nil
+local function trim(s)
+ return (s:gsub("^%s*(.-)%s*$", "%1"))
+end
+
local function err_cmd(message)
return "\\PackageError{PyLuaTeX}{" .. message .. "}{}"
end
@@ -94,7 +100,7 @@ local function split_lines(str)
return t
end
-function pyluatex.execute(code, auto_print, write)
+function pyluatex.execute(code, auto_print, write, repl_mode)
local full_code
if auto_print then
full_code = "print(str(" .. code .. "), end='')"
@@ -104,12 +110,19 @@ function pyluatex.execute(code, auto_print, write)
if pyluatex.verbose then log_input(full_code) end
- local success, output = request({ session = pyluatex.session, code = full_code })
+ local success, output = request(
+ {
+ session = pyluatex.session,
+ code = full_code,
+ repl_mode = repl_mode,
+ ignore_errors = pyluatex.ignore_errors
+ }
+ )
last_code = split_lines(code)
last_output = split_lines(output)
- if success then
- if pyluatex.verbose then log_output(output) end
+ if success or pyluatex.ignore_errors then
+ if pyluatex.verbose or not success then log_output(output) end
if write then
tex.print(last_output)
@@ -135,10 +148,14 @@ local function record_line(line)
local s, e = line:find(env_end, 1, true)
if s ~= nil then
luatexbase.remove_from_callback("process_input_buffer", "pyluatex_record_line")
- table.insert(env_lines, line:sub(1, s - 1))
+ local code_in_line = line:sub(1, s - 1)
+ if trim(code_in_line):len() > 0 then
+ -- only include this line if it contains non-whitespace characters
+ table.insert(env_lines, code_in_line)
+ end
local code = table.concat(env_lines, "\n")
- local success = pyluatex.execute(code, false, false)
- if success then
+ local success = pyluatex.execute(code, false, false, env_repl_mode)
+ if success or pyluatex.ignore_errors then
return line:sub(s)
else
return env_end .. err_cmd("Python error (see above)") .. line:sub(e + 1)
@@ -149,20 +166,14 @@ local function record_line(line)
end
end
-function pyluatex.record_env(quiet)
- local name
+function pyluatex.record_env(name, repl_mode)
if parent_env ~= nil then
name = parent_env
parent_env = nil
- else
- if quiet then
- name = "pythonq"
- else
- name = "python"
- end
end
env_end = "\\end{" .. name .. "}"
env_lines = {}
+ env_repl_mode = repl_mode
luatexbase.add_to_callback("process_input_buffer", record_line, "pyluatex_record_line")
end
@@ -172,12 +183,18 @@ function pyluatex.set_parent_env(name)
end
end
-function pyluatex.run_file(path, write)
+function pyluatex.run_file(path, write, repl_mode)
local f = io.open(path, "r")
if f then
local code = f:read("*a")
f:close()
- pyluatex.execute(code, false, write)
+ -- ignore trailing new line if present
+ if code:sub(-2) == "\r\n" then
+ code = code:sub(0, -3)
+ elseif code:sub(-1) == "\n" then
+ code = code:sub(0, -2)
+ end
+ pyluatex.execute(code, false, write, repl_mode)
else
tex.sprint(err_cmd("File not found: " .. path))
end
@@ -191,4 +208,26 @@ function pyluatex.get_last_output()
return last_output
end
+local function parse_bool(name, value)
+ if value == "true" then
+ return true
+ elseif value == "false" then
+ return false
+ else
+ tex.sprint(
+ err_cmd("Invalid value '" .. value .. "' for option " .. name)
+ )
+ end
+end
+
+function pyluatex.set_option(name, value)
+ if name == "ignoreerrors" then
+ pyluatex.ignore_errors = parse_bool(name, value)
+ elseif name == "verbose" then
+ pyluatex.verbose = parse_bool(name, value)
+ else
+ tex.sprint(err_cmd("Unknown option '" .. name .. "'"))
+ end
+end
+
return pyluatex