如何在 ConTeXt 中迭代逗号分隔列表中的项目?

如何在 ConTeXt 中迭代逗号分隔列表中的项目?

我有一个非常简单的列表,如下所示:

cat, fish, dog, rabbit

(这是用逗号分隔的,但如果数据以其他方式存储也是可以的,但它需要允许将任意数量的项目添加到列表中)

我想将列表存储在某个地方。然后将一个简单的宏,例如\droptext放置在文档中。第一次显示时,它会打印“cat”,第二次显示“fish”等。第五次和第九次返回“cat”,重复循环。

\starttext
    \define\mylist{cat, fish, dog, rabbit}

    The \droptext\ is a nice animal. So is the \droptext.
    Once upon a time, a \droptext\ came to the garden
    and ate a \droptext. Everyone was so angry
    but then the \droptext came by and brought everyone
    a \droptext.

\stoptext

这将打印在页面上:

The cat is a nice animal. So is the fish.
Once upon a time, a dog came to the garden
and ate a rabbit. Everyone was so angry
but then the cat came by and brought everyone
a fish.
  • 我尝试了该\doloop命令,因为从描述来看它似乎可以做到这一点,但是添加该命令后文档甚至无法编译。

在 ConTeXt 中,每次文档中出现宏时,是否有办法打印列表中的项目并遍历所有项目?

答案1

编辑:我以前的答案仅适用于 ConTeXt LMTX。有一个替代方案,它同时适用于 LMTX 和 MkIV。

\startluacode

userdata = userdata or {}
userdata.my_lists = {}

interfaces.implement{
    name = "registercyclelist",
    public = true,
    arguments = {"string", "string"},
    actions = {
        function (name, t)
            userdata.my_lists[name] = utilities.parsers.settings_to_array(t)
        end
    }
}

interfaces.implement{
    name = "usecyclelist",
    public = true,
    arguments = {"string"},
    actions = {
        function (name)
            local first = userdata.my_lists[name][1]
            table.remove(userdata.my_lists[name], 1)
            table.insert(userdata.my_lists[name], first)
            return first 
        end,
        context
    }
}

\stopluacode

%Notice the braces 
\registercyclelist{firstlist}{cat, fish, dog, rabbit}
\def\droptext{\usecyclelist{firstlist}}

\starttext

The \droptext\ is a nice animal. So is the \droptext.
Once upon a time, a \droptext\ came to the garden
and ate a \droptext. Everyone was so angry
but then the \droptext\ came by and brought everyone
a \droptext.

\stoptext

答案2

您想要的行为正是上下文在转换内置转换集中处理脚注标记等的方式。请参阅此维基页面但内置了转换集演示。这些转换集用于指示页面中的脚注标记(在某些文章样式中)。

因此,这里有一个通过搭载计数器机制来实现预期效果的解决方案:

\defineconversion[animal][cat,fish,dog,rabbit]
\definecounter[myanimals][numberconversion=animal]

\define\droptext{\incrementcounter[myanimals]\convertedcounter[myanimals]}

基本上,定义一个名为 的新转换animal,它指定您想要的转换集。然后定义一个名为 的计数器myanimal,其 numberconversion 等于animal。然后,droptext只需增加计数器并显示其“转换值”。ConTeXt 负责在内部遍历列表。

相关内容