diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua | 117 |
1 files changed, 115 insertions, 2 deletions
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua index 13e1e092241..af8b1651e9a 100644 --- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua +++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua @@ -264,6 +264,33 @@ function number.signed(i) end end +local zero = P("0")^1 / "" +local plus = P("+") / "" +local minus = P("-") +local separator = S(".") +local digit = R("09") +local trailing = zero^1 * #S("eE") +local exponent = (S("eE") * (plus + Cs((minus * zero^0 * P(-1))/"") + minus) * zero^0 * (P(-1) * Cc("0") + P(1)^1)) +local pattern_a = Cs(minus^0 * digit^1 * (separator/"" * trailing + separator * (trailing + digit)^0) * exponent) +local pattern_b = Cs((exponent + P(1))^0) + +function number.sparseexponent(f,n) + if not n then + n = f + f = "%e" + end + local tn = type(n) + if tn == "string" then -- cast to number + local m = tonumber(n) + if m then + return lpegmatch((f == "%e" or f == "%E") and pattern_a or pattern_b,format(f,m)) + end + elseif tn == "number" then + return lpegmatch((f == "%e" or f == "%E") and pattern_a or pattern_b,format(f,n)) + end + return tostring(n) +end + local preamble = [[ local type = type local tostring = tostring @@ -281,6 +308,8 @@ local tracedchar = string.tracedchar local autosingle = string.autosingle local autodouble = string.autodouble local sequenced = table.sequenced +local formattednumber = number.formatted +local sparseexponent = number.sparseexponent ]] local template = [[ @@ -375,6 +404,16 @@ local format_E = function(f) return format("format('%%%sE',a%s)",f,n) end +local format_j = function(f) + n = n + 1 + return format("sparseexponent('%%%se',a%s)",f,n) +end + +local format_J = function(f) + n = n + 1 + return format("sparseexponent('%%%sE',a%s)",f,n) +end + local format_x = function(f) n = n + 1 return format("format('%%%sx',a%s)",f,n) @@ -520,6 +559,68 @@ local format_W = function(f) -- handy when doing depth related indent return format("nspaces[%s]",tonumber(f) or 0) end +-- maybe to util-num + +local digit = patterns.digit +local period = patterns.period +local three = digit * digit * digit + +local splitter = Cs ( + (((1 - (three^1 * period))^1 + C(three)) * (Carg(1) * three)^1 + C((1-period)^1)) + * (P(1)/"" * Carg(2)) * C(2) +) + +patterns.formattednumber = splitter + +function number.formatted(n,sep1,sep2) + local s = type(s) == "string" and n or format("%0.2f",n) + if sep1 == true then + return lpegmatch(splitter,s,1,".",",") + elseif sep1 == "." then + return lpegmatch(splitter,s,1,sep1,sep2 or ",") + elseif sep1 == "," then + return lpegmatch(splitter,s,1,sep1,sep2 or ".") + else + return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") + end +end + +-- print(number.formatted(1)) +-- print(number.formatted(12)) +-- print(number.formatted(123)) +-- print(number.formatted(1234)) +-- print(number.formatted(12345)) +-- print(number.formatted(123456)) +-- print(number.formatted(1234567)) +-- print(number.formatted(12345678)) +-- print(number.formatted(12345678,true)) +-- print(number.formatted(1234.56,"!","?")) + +local format_m = function(f) + n = n + 1 + if not f or f == "" then + f = "," + end + return format([[formattednumber(a%s,%q,".")]],n,f) +end + +local format_M = function(f) + n = n + 1 + if not f or f == "" then + f = "." + end + return format([[formattednumber(a%s,%q,",")]],n,f) +end + +-- + +local format_z = function(f) + n = n + (tonumber(f) or 1) + return "''" -- okay, not that efficient to append '' but a special case anyway +end + +-- + local format_rest = function(s) return format("%q",s) -- catches " and \n and such end @@ -546,6 +647,8 @@ local format_extension = function(extensions,f,name) end end +-- aA b cC d eE f gG hH iI jJ lL mM N o p qQ r sS tT uU wW xX z + local builder = Cs { "start", start = ( ( @@ -569,11 +672,13 @@ local builder = Cs { "start", + V("t") + V("T") + V("l") + V("L") + V("I") - + V("h") -- new + V("w") -- new + V("W") -- new + V("a") -- new + V("A") -- new + + V("j") + V("J") -- stripped e E + + V("m") + V("M") -- new + + V("z") -- new -- + V("*") -- ignores probably messed up % ) @@ -617,6 +722,14 @@ local builder = Cs { "start", ["w"] = (prefix_any * P("w")) / format_w, -- %w => n spaces (optional prefix is added) ["W"] = (prefix_any * P("W")) / format_W, -- %W => mandate prefix, no specifier -- + ["j"] = (prefix_any * P("j")) / format_j, -- %j => %e (float) stripped exponent (irrational) + ["J"] = (prefix_any * P("J")) / format_J, -- %J => %E (float) stripped exponent (irrational) + -- + ["m"] = (prefix_tab * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .) + ["M"] = (prefix_tab * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,) + -- + ["z"] = (prefix_any * P("z")) / format_z, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,) + -- ["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring) ["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring) -- @@ -647,7 +760,7 @@ local function make(t,str) p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n if n > 0 then p = format(template,preamble,t._preamble_,arguments[n],p) --- print("builder>",p) +-- print("builder>",p) f = loadstripped(p)() else f = function() return str end |