use mlua::{Lua, MultiValue, Value};
use retex_engine::print::Selector;
use crate::with_engine;
pub fn install(lua: &Lua) -> mlua::Result<()> {
let t = lua.create_table()?;
t.set(
"write",
lua.create_function(|lua, args: MultiValue| write(lua, args, false))?,
)?;
t.set(
"write_nl",
lua.create_function(|lua, args: MultiValue| write(lua, args, true))?,
)?;
t.set("setescape", lua.create_function(|_, _v: Value| Ok(()))?)?;
t.set("closeinput", lua.create_function(|_, ()| Ok(()))?)?;
lua.globals().set("texio", t)?;
Ok(())
}
fn target(s: &[u8], current: Selector, log_open: bool) -> Option<Selector> {
match s {
b"term" => Some(Selector::TermOnly),
b"log" => Some(if log_open {
Selector::LogOnly
} else {
Selector::NoPrint
}),
b"term and log" => Some(if log_open {
Selector::TermAndLog
} else {
Selector::TermOnly
}),
_ => {
let _ = current;
None
}
}
}
fn write(lua: &Lua, args: MultiValue, nl: bool) -> mlua::Result<()> {
let mut v: Vec<Value> = args.into_iter().collect();
let mut sel_override = None;
if v.len() > 1
&& let Some(Value::String(s)) = v.first()
{
let b = s.as_bytes().to_vec();
let t = with_engine(lua, |e| {
target(&b, e.printer.selector, e.printer.log_opened())
})?;
if t.is_some() {
sel_override = t;
v.remove(0);
}
}
let mut texts: Vec<Vec<u8>> = Vec::new();
for x in &v {
match x {
Value::String(s) => texts.push(s.as_bytes().to_vec()),
Value::Integer(n) => texts.push(n.to_string().into_bytes()),
Value::Number(n) => texts.push(crate::texlib::lua_number_string(*n).into_bytes()),
_ => {}
}
}
with_engine(lua, |e| {
let old = e.printer.selector;
if let Some(s) = sel_override {
e.printer.selector = s;
} else if e.printer.selector == Selector::NoPrint && e.printer.log_opened() {
e.printer.selector = Selector::LogOnly;
}
if nl {
e.printer.begin_line();
}
for t in &texts {
e.printer.print_lua_bytes(t);
}
e.printer.update_terminal();
e.printer.selector = old;
})
}