例如我\fpeval
在 Plain LuaTeX 中定义:
\begingroup
\catcode`\%=12
\directlua{
function math.round_int ( x )
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
function math.round ( x , n )
return math.round_int ( x*10^n ) / 10^n
end
function gobblezero(x)
local y = math.round ( x , 8 )
if y == math.floor(y) then
return string.format ( "%.0f", y )
else
return math.round(y, 7)
end
end}
\endgroup
\def\fpeval#1{\directlua{tex.print(gobblezero(#1))}}
\directlua{%
p = 68
P = 80}
You have \fpeval{p} of \fpeval{P} points, this makes $\fpeval{p * 100/P}\,\%$.
\bye
但我想要一个名为的宏,\fpexpr
其行为类似于\numexpr
,以便我可以写道:
You have \fpexpr p of \fpexpr P points, this makes $\fpexpr p * 100/P \,\%$.
第一种情况\fpexpr
应该只接受p
作为参数,因为of
从来没有被定义为数字或函数\directlua{of = ...}
。第二种和第三种情况类似,因为points
在\,
Lua 解释器中未定义。
因此\fpexpr
应该将所有内容添加到 lua 代码中,直到添加的内容导致错误。
这可能吗?
答案1
这还远远未完成,但确实存在一些情况。
终端上的内容很丰富:
token is p
variable found 68 p
token is of
stop at of collected: 68
2: eval result is 68 x
token is P
variable found 80 P
token is points,
stop at points, collected: 80
2: eval result is 80 x
token is p
variable found 68 p
token is *
token is 100
token is /
token is P
variable found 80 P
token is ?
1: eval result is 85.0
代码是
\begingroup
\catcode`\%=12
\directlua{
function math.round_int ( x )
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
function math.round ( x , n )
return math.round_int ( x*10^n ) / 10^n
end
function gobblezero(x)
local y = math.round ( x , 8 )
if y == math.floor(y) then
return string.format ( "%.0f", y )
else
return math.round(y, 7)
end
end}
\endgroup
\def\fpeval#1{\directlua{tex.print(gobblezero(#1))}}
{\catcode`\%=12
\xdef\pc{%}
}
\directlua{
function zz (s)
local t = token.scan_string()
print ('token is ' .. (t or '?'))
if (t == nil) then
local f = loadstring('r= ' .. s)
f()
print('1: eval result is ' .. (r or '?'))
tex.print(r)
else
% t is local variable or operator or number (inexact pattern)
if (_G[t] \string~= nil) then
% recurse with value
print ('variable found ' .. _G[t] .. ' ' .. t)
zz(s .. _G[t])
else if(string.find(t,'^[+-/*().]?\pc d*$')) then
% recurse
zz(s .. t)
else
% evaluate string so far and retrun result and the rejected token
print('stop at ' .. t .. ' collected: ' .. s)
local f = loadstring('r= ' .. s)
f()
print('2: eval result is ' .. (r or '?') .. ' x')
tex.print(r .. ' ' .. t )
end
end
end
end
}
\def\fpzz{\directlua{zz('')}}
\directlua{%
p = 68
P = 80}
You have \fpzz p of \fpzz P points, this makes $\fpzz p * 100 / P \,\%$.
\bye