在 metafun 循环中将数字转换为罗马数字

在 metafun 循环中将数字转换为罗马数字

如何在 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

在此处输入图片描述

相关内容