-- tkz_elements_utils.lua -- date 2025/05/25 -- version 4.00c -- Copyright 2025 Alain Matthes -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3 -- of this license or (at your option) any later version. -- The latest version of this license is in -- http://www.latex-project.org/lppl.txt -- and version 1.3 or later is part of all distributions of LaTeX -- version 2005/12/01 or later. -- This work has the LPPL maintenance status “maintained”. -- The Current Maintainer of this work is Alain Matthes. -- path-utils.lua utils = {} -- Parse a string of the form "(x,y)" into two numbers. function utils.parse_point(str) local x, y = str:match("^%s*%(?%s*([%+%-%.%deE]+)%s*,%s*([%+%-%.%deE]+)%s*%)%s*$") if not x or not y then error("Invalid point string: " .. tostring(str)) end return tonumber(x), tonumber(y) end -- Format a number with a specified number of decimal places. function utils.format_number(x, decimals) decimals = decimals or 5 local n = tonumber(x) if n then return string.format("%." .. decimals .. "f", n) else error("Invalid input to format_number: " .. tostring(x)) end end function utils.format_coord(x, decimals) decimals = decimals or 5 return string.format("%." .. decimals .. "f", x) end function utils.checknumber(x, decimals) decimals = decimals or 5 local n = tonumber(x) if n then return string.format("%." .. decimals .. "f", n) else error("Invalid number: " .. tostring(x)) end end -- Format a complex number (table with .re and .im) as a coordinate string. function utils.format_point(z, decimals) if type(z) ~= "table" or type(z.re) ~= "number" or type(z.im) ~= "number" then error("format_point expects a table with fields 're' and 'im'") end decimals = decimals or 5 local x = utils.format_number(z.re, decimals) local y = utils.format_number(z.im, decimals) return "(" .. x .. "," .. y .. ")" end -- Compare two numbers with tolerance. function utils.almost_equal(a, b, eps) eps = eps or tkz_epsilon return math.abs(a - b) < eps end -- Print formatted message to terminal and log. function utils.w(...) texio.write_nl("term and log", "[tkz-elements] " .. string.format(...)) end -- Print formatted message to log only. function utils.wlog(...) texio.write_nl("log", "[tkz-elements] " .. string.format(...)) end -- Optional: Clamp a number between min and max. function utils.clamp(x, min_val, max_val) return math.max(min_val, math.min(max_val, x)) end -- Optional: Return the sign of a number. function utils.sign(x) return (x > 0 and 1) or (x < 0 and -1) or 0 end -- Optional: Convert a number or string to a fixed-point string. function utils.to_decimal_string(x, decimals) decimals = decimals or 5 local n = tonumber(x) if n then return string.format("%." .. decimals .. "f", n) else error("Invalid input to to_decimal_string: " .. tostring(x)) end end function utils.table_getn(t) if type(t) ~= "table" then error("bad argument #1 to 'getn' (table expected)", 2) end local i = 0 while t[i + 1] ~= nil do i = i + 1 end return i end return utils