使用 ConTeXt 自动格式化数字

使用 ConTeXt 自动格式化数字

我希望计算出的数字能够自动格式化,这样我的学生就可以轻松地阅读演示文稿中的长数字。我发现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))}

没有任何输出。

所以,

  • 有没有办法实现这一点unitcomma_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

在此处输入图片描述

相关内容