diff --git a/core/settings.lua b/core/settings.lua index c5e8a45e0..ee0e6a512 100644 --- a/core/settings.lua +++ b/core/settings.lua @@ -28,6 +28,8 @@ function settings:_init () ]]):format(language, language, language, language)) end fluent:set_locale(language) + os.setlocale(language) + SU.setenv("LANG", language) end, help = "Locale for localized language support", }) diff --git a/core/utilities/init.lua b/core/utilities/init.lua index 2a9adf714..6619466bd 100644 --- a/core/utilities/init.lua +++ b/core/utilities/init.lua @@ -507,6 +507,34 @@ function utilities.rationWidth (target, width, ratio) return target end +--- System +-- @section system + +local function which_setenv () + if type(_G._rusty_funcs) == "table" then + return _G._rusty_funcs.setenv + elseif pcall(require, "posix") then + return require("posix").stdlib.setenv + elseif pcall(require, "winapi") then + return require("winapi").setenv + else + return function (key, _) + utilities.warn(([[Failed to set environment variable '%s' using legacy Lua based CLI + + Please use the Rust based CLI. Meanwhile expect anything depending on + this variable not to work. Alternatively installing the luaposix or + winapi LuaRocks modules will enable this from the Lua side. + + ]]):format(key)) + end + end +end + +--- Set environment variable to take effect when executing subprocesses +-- @tparam string key Name of environment variable, typically in all caps. +-- @tparam string value Value to set. +utilities.setenv = which_setenv() + --- Text handling -- @section text diff --git a/sile.rockspec.in b/sile.rockspec.in index c69e74ef4..d6a3e6d0d 100644 --- a/sile.rockspec.in +++ b/sile.rockspec.in @@ -46,6 +46,12 @@ dependencies = { "vstruct == 2.1.1-1", } +-- Optional deps to enable the legacy Lua CLI to have features from the Rust one +--[[ +table.insert(dependencies, "luaposix == 36.2.1-1") -- for Unix +table.insert(dependencies, "winapi == 1.4.2-1") -- for Windows +]] + build = { type = "builtin", modules = {}, diff --git a/spec/languages_spec.lua b/spec/languages_spec.lua index 2264e9470..3d5b422f4 100644 --- a/spec/languages_spec.lua +++ b/spec/languages_spec.lua @@ -1,6 +1,13 @@ SILE = require("core.sile") describe("Language module", function () + + it("should set env locale", function () + SILE.call("language", { main = "tr" }) + local syslang = os.getenv("LANG") + assert.is.equal("tr", syslang) + end) + describe("Norwegian", function () local hyphenate = SILE.showHyphenationPoints diff --git a/spec/utilities_spec.lua b/spec/utilities_spec.lua index fbb0191d7..e3a84813d 100644 --- a/spec/utilities_spec.lua +++ b/spec/utilities_spec.lua @@ -18,7 +18,7 @@ describe("SILE.utilities", function () end) end) - describe("utf8_to_utf16be_hexencoded ", function () + describe("utf8_to_utf16be_hexencoded", function () it("should hex encode input", function () local str = "foo" local out = "feff0066006f006f" @@ -26,6 +26,16 @@ describe("SILE.utilities", function () end) end) + describe("setenv", function () + it("should effectively set variables before executing system commands", function () + local before = os.getenv("FOO") + assert.is.equal(type(before), "nil") + SU.setenv("FOO", "bar") + local after = os.getenv("FOO") + assert.is.equal(after, "bar") + end) + end) + describe("formatNumber", function () local icu = require("justenoughicu") local icu73plus = tostring(icu.version()) >= "73.0" diff --git a/src/lib.rs b/src/lib.rs index ae6a911ed..996f54e79 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ pub fn start_luavm() -> crate::Result { #[cfg(feature = "static")] crate::embed::inject_embedded_loader(&lua); inject_paths(&lua); + inject_rusty_funcs(&lua); load_sile(&lua); inject_version(&lua); Ok(lua) @@ -50,6 +51,18 @@ pub fn inject_paths(lua: &Lua) { } } +pub fn inject_rusty_funcs(lua: &Lua) { + let rusty_funcs: LuaTable = lua.create_table().unwrap(); + let setenv: LuaFunction = lua + .create_function(|_, (key, value): (String, String)| { + env::set_var(key, value); + Ok(()) + }) + .unwrap(); + rusty_funcs.set("setenv", setenv).unwrap(); + lua.globals().set("_rusty_funcs", rusty_funcs).unwrap(); +} + pub fn inject_version(lua: &Lua) { let sile: LuaTable = lua.globals().get("SILE").unwrap(); let mut full_version: String = sile.get("full_version").unwrap();