我希望计算出的数字能够自动格式化,这样我的学生就可以轻松地阅读演示文稿中的长数字。我发现setupunits
与单位结合使用非常方便,但它们仅在数字已经用点格式化时才有效,并且您无法在此宏中传递对 tex.print 的调用,如本 MWE 所示
\setcharacterspacing[frenchpunctuation]
\mainlanguage[fr]
\language[fr]
\setupunits [method=3,order=reverse]
\starttext
\unit{1.000.333}
\unit{1000333}
{\directlua{tex.print(333*999)}}
\unit{\directlua{tex.print(333*999)}}
\stoptext
我想要的是第四行看起来像 332 667(最终是 332.667,这在法语印刷中也是正确的)。
在网上快速搜索后,我发现这个lua函数可以将其分配为变量,然后传递给units
function comma_value(n) -- credit http://richard.warburton.it
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
问题是我不懂 Lua 技能。据我所知,这样的函数应该在环境中声明\startluacode
\stopluacode
,但即便如此,我仍然遇到一个问题:
\unit{\directlua(comma_value(tex.print(333*999))}
没有任何输出。
所以,
- 有没有办法实现这一点
unit
并comma_value
协同tex.print
工作? - 我怎样才能调整 comma_value 函数以获得法语输出,例如 332.667 而不是 333,667(我理解
(num:reverse():gsub('(%d%d%d)','%1.')
应该对整数执行这项工作,但如果涉及小数怎么办?) - 最后但同样重要的是,我猜想 ConTeXt 内部已经有一个 lua 函数可以完成这个任务。你知道吗?
答案1
您可以\unit
从 lua 内部调用context.unit
并在那里进行所有格式化:
\setcharacterspacing[frenchpunctuation]
\mainlanguage[fr]
\language[fr]
\startluacode
userdata = userdata or { }
function userdata.comma_value(n) -- credit http://richard.warburton.it
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
function userdata.formatted_number(n)
context.unit(userdata.comma_value(n))
end
\stopluacode
\setupunits [method=3]
\starttext
A formatted number: \directlua{userdata.formatted_number(333.3*999.9)}
\stoptext
您还可以创建一个 ConTeXt 命令来包裹您的 lua 代码:
\def\formattednumber#1%
{\directlua{userdata.formatted_number(#1)}}
现在你可以像这样使用它:\formattednumber{333.3*999.9}
答案2
如果要使用\unit
,则必须\directlua
首先扩展对 的调用。我正在使用\cldcontext
这实际上是 的快捷方式\directlua{tex.sprint(...)}
(带有额外的花哨功能)。在使用\cldcontext
之前先进行扩展。\unit
\expanded
\setcharacterspacing[frenchpunctuation]
\mainlanguage[fr]
\language[fr]
\setupunits [method=3]
\startluacode
function userdata.comma_value(n) -- credit http://richard.warburton.it
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
\stopluacode
\starttext
\expanded{\unit{\cldcontext{userdata.comma_value(333.3*999.9)}}}
\stoptext