如何在 metafun 循环中自动转换数字?我试过使用,MPvar
但不起作用。
\starttext
\startMPpage
for i=1 upto 10:
label (i,(10i,0));
label ("\convertnumber{R}{\MPvar{i}}",(10i,30));
endfor;
\stopMPpage
\stoptext
我知道我可以用罗马数字创建一个数组并使用 这个答案来做到这一点,但了解一种自动完成的方法将会很有帮助。
编辑我没有标记这个问题,metapost
但如果它可能对 LaTeX+METAPOST 用户有用,我会改变它
答案1
如果您不想重新发明轮子,ConTeXt 为 Metafun 提供了 Lua 绑定,因此您至少有两种方法可以在 Lua 中进行转换,以避免出现 TeX 宏问题:
直接调用Lua进行转换
既然你使用的是 ConTeXt,那就使用一些 Lua 魔法吧。为了直接从 MetaPost 调用 Lua 函数,你可以使用拼写lua
和调用converters.Romannumerals
大写和converters.romannumerals
小写变体(完整的转换列表位于core-con.lua
):
%Modified original so numbers don't overlap
\starttext
\startMPpage
for i=1 step 7 until 50:
label (i,(4i,0));
label (lua("mp.string(converters.romannumerals(" & decimal i & "))"),(4i,30));
endfor;
\stopMPpage
\startMPpage
for i=1 step 9 until 100:
label (i,(0,-1.5i));
label (lua("mp.string(converters.Romannumerals(" & decimal i & "))"),(30,-1.5i));
endfor;
\stopMPpage
\stoptext
第一页:
第二页:
在 Lua 中定义 Metafun 函数
但是,如果调用 Lua 变得冗长且令人困惑,或者您想像roman
@Marijn 那样使用定义(或两者兼而有之),那么以下是可能的,并且在我看来更清晰:
\startluacode
--MP is a namespace reserved for Metafun functions
--This will be lua.MP.roman in Metafun
function MP.roman(n)
--You could use many others, but you shouldn't forget to
--send results to Metafun via mp.string or related functions.
mp.string(converters.Romannumerals(n))
end
\stopluacode
\startMPpage
vardef roman primary n =
lua.MP.roman(n)
enddef;
for i=1 step 37 until 1000:
label (i,(0,-i/3));
label (roman i,(50,-i/3));
endfor;
\stopMPpage
\stoptext
答案2
从转换函数开始https://tex.stackexchange.com/a/237400/我为罗马数字定义了一个递归转换函数:
\starttext
\startMPpage
vardef roman primary h =
if h=0: ""
elseif h<4: "I" & roman (h-1)
elseif h=4: "IV"
elseif h<9: "V" & roman (h-5)
elseif h=9: "IX"
elseif h<40: "X" & roman (h-10)
elseif h<50: "XL" & roman (h-40)
elseif h<90: "L" & roman (h-50)
elseif h<100: "XC" & roman (h-90)
elseif h<400: "C" & roman (h-100)
elseif h<500: "CD" & roman (h-400)
elseif h<900: "D" & roman (h-500)
elseif h<1000: "CM" & roman (h-900)
else: "M" & roman (h-1000)
fi
enddef;
for i=1 step 9 until 109:
label (decimal i & "\ " & roman i,(0,10-10i/9));
endfor;
\stopMPpage
\stoptext