如何在 ConTeXt 中打印随机文本?

如何在 ConTeXt 中打印随机文本?

我经常需要在 ConTeXt 的文档中放置随机元素。例如,我在格式信函中添加了一些随机语言差异。

在每个实例中,都可以选择要显示的项目:

Print
   a
Or
   b
Or
   c
Done

在某些情况下,我需要嵌套随机性:

Print
   a
Or
   Print
       b
   Or
       c
   Done
Or
   d
Done

我创建了此代码来实现我需要的功能,但是语法效率不太高:

\starttext

    \define[2]\loadrandom{%
        \getrandomnumber \randomnumber {#1} {#2}%
    }

    \loadrandom{1}{10}%
    %
    \ifnum\randomnumber=1%
        This will print the first item.
    \fi%
    %
    \ifnum\randomnumber=2%
        This will print the second item.
    \fi%
    %
    \ifnum\randomnumber=3%
        This will print the third item.
    \fi%
    %
    \ifnum\randomnumber=4%
        This will print the fourth item.
    \fi%
    %
    \ifnum\randomnumber=5%
        This will print the fifth item.
    \fi%
    %
    \ifnum\randomnumber=6%
        This will print the sixth item.
    \fi%
    %
    \ifnum\randomnumber=7%
        This will print the seventh item.
    \fi%
    %
    \ifnum\randomnumber=8%
        This will print the eigth item.
    \fi%
    %
    \ifnum\randomnumber=9%
        This will print the ninth item.
    \fi%
    %
    \ifnum\randomnumber=10%
        This will print the tenth item.
    \fi%

\stoptext

有什么方法可以改进此代码,以便更容易快速地在页面中放置随机文本?

答案1

也许你需要这个。我的示例包括嵌套随机打印,如果第一个随机数等于 2。

\getrandomnumber \randomnumber {1} {10}
\ifcase\randomnumber \or
   print a
   \or
   \getrandomnumber \randomnumber {1} {2}
   \ifcase\randomnumber \or
       print ba
       \or
       print bb
   \fi
   \or
   print c
   \or
   print d
   \or
   print e
   \or
   print f
   \or
   print g
   \or
   print h
   \or
   print i
   \or
   print j
\fi

或者你可以定义一个宏\randomtext

\newcount\tmpnum
\def\randomtext#1{\def\tmpbuf{}\tmpnum=0\randomtextA#1;;}
\def\randomtextA#1;{\if;#1;\getrandomnumber\randomnumber{1}{\tmpnum}%
      \expandafter\ifcase\expandafter\randomnumber\tmpbuf\fi
   \else \expandafter\def\expandafter\tmpbuf\expandafter{\tmpbuf\or#1}%
      \advance\tmpnum by1
      \expandafter\randomtextA
   \fi
}

并使用它:

\randomtext{a;b;c;d;e;f}
or nested:
\randomtext{a;\randomtext{ba;bb};c;d;e}

抱歉,我没有测试它,因为我不使用 ConTeXt。但我希望它能工作...因为 ConTeXt 是基于 TeX 的。

编辑:因为 ConTeXt 使用伪随机生成器,所以您需要调用\randomtext多次才能看到效果:

\newcount\tmpnum
\def\randomtext#1{\def\tmpbuf{}\tmpnum=0\randomtextA#1;;}
\def\randomtextA#1;{\if;#1;\getrandomnumber\randomnumber{1}{\tmpnum}%
      \expandafter\ifcase\expandafter\randomnumber\tmpbuf\fi
   \else \expandafter\def\expandafter\tmpbuf\expandafter{\tmpbuf\or#1}%
      \advance\tmpnum by1
      \expandafter\randomtextA
   \fi
}

\starttext

\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}
\randomtext{a;\randomtext{(ba);(bb)};c;d;e}

\stoptext

答案2

设置文本的随机值的方法有很多种,第一种是低级\ifacse宏。

\define\RandomText
  {\getrandomnumber\randomnumber{1}{4}%
   \ifcase\randomnumber
     % 0
   \or
     First item.% 1
   \or
     Second item.% 2
   \or
     Third item.% 3
   \else
     Another item.% 4+
   \fi}

\starttext
\dorecurse{3}{\RandomText\par}
\stoptext

与此等效的 ConTeXt 是\processaction命令。该命令的第一个参数采用应在列表中搜索的参数,第二个参数采用由带有 的文本分隔的值=>。您还可以设置当搜索的值不在带有键的列表中时应使用的文本unknown

\define\RandomText
  {\getrandomnumber\randomnumber{1}{4}%
   \processaction
     [\randomnumber]
     [      1=>First item.,
            2=>Second item.,
            3=>Third item.,
      unknown=>Another item.]}

\starttext
\dorecurse{3}{\RandomText\par}
\stoptext

当您只想显示文本时,我建议使用另一种方法,这样更容易编写文本。有两种可能的方法非常相似,第一种使用环境setups(我使用它是rawsetups因为它保留了输入中每行末尾的空格),第二种buffer使用环境。

当您的文本不包含任何特殊内容(如逐字等)时,setups可以毫无问题地使用。

\startrawsetups[randomtext:1]
  First item.
\stoprawsetups

\startrawsetups[randomtext:2]
  Second item.
\stoprawsetups

\startrawsetups[randomtext:3]
  Third item.
\stoprawsetups

\startrawsetups[randomtext:unknown]
  Another item.
\stoprawsetups

\define\RandomText
  {\getrandomnumber\randomnumber{1}{4}%
   \doifsetupselse{randomtext:\randomnumber}
     {\directsetup{randomtext:\randomnumber}}
     {\directsetup{randomtext:unknown}}}

\starttext
\dorecurse{3}{\RandomText\par}
\stoptext

当您还有逐字文本或其他特殊内容时,TeXbuffers是更好的解决方案,因为它们不会出现问题。

\startbuffer[randomtext:1]
  First item.
\stopbuffer

\startbuffer[randomtext:2]
  Second item.
\stopbuffer

\startbuffer[randomtext:3]
  Third item.
\stopbuffer

\startbuffer[randomtext:unknown]
  Another item.
\stopbuffer

\define\RandomText
  {\getrandomnumber\randomnumber{1}{4}%
   \doifelsebuffer{randomtext:\randomnumber}
     {\getbuffer[randomtext:\randomnumber]}
     {\getbuffer[randomtext:unknown]}}

\starttext
\dorecurse{3}{\RandomText\par}
\stoptext

答案3

这是一段用 Lua 编写的代码,可从 LuaLaTeX 运行,只需对 TeX 结构进行少量修改,即可轻松在 ConTeXt 中运行。我们获取表中的元素数量,然后随机挑选一个项目并确定它是否是表类型。如果是,我们会再调用该函数一次,否则我们会打印所选项目。

在此示例中,我们运行该函数十次以检查它是否按预期工作。

% run: lualatex mal-random.tex
\documentclass{article}
\usepackage{luacode}

\begin{luacode*}
-- Some input data...
math.randomseed(0)
randomdata={
  "first",
  {"second-a", "second-b", "second-c"},
  "third",
  "fourth",
  "fifth",
  }
-- Repetition of the function...
function randomme (number)
for i=1,number do -- repetition
  randomcall(randomdata)
end --for i
end --function randomme

function randomcall (input)
randompick=math.random(#input)
randomcell=input[randompick]
print(#input, randompick, randomcell)
if type(randomcell)=="table" then  
  randomcall(randomcell)
    else
  print("Selected item ("..randompick..".): "..randomcell)
  tex.print(randomcell)
end -- if type
end --function randomcall
\end{luacode*}

\begin{document}
\directlua{randomme(10)}
\end{document}

运行后,lualatex mal-random.tex我们在终端中收到这些消息(它列出了实际级别的大小、所选项目的顺序以及项目本身):

5   2   table: 01524790
3   2   second-b
Selected item (2.): second-b
5   1   first
Selected item (1.): first
5   2   table: 01524790
3   2   second-b
Selected item (2.): second-b
5   2   table: 01524790
3   3   second-c
Selected item (3.): second-c
5   2   table: 01524790
3   3   second-c
Selected item (3.): second-c
5   1   first
Selected item (1.): first
5   5   fifth
Selected item (5.): fifth
5   1   first
Selected item (1.): first
5   1   first
Selected item (1.): first
5   4   fourth
Selected item (4.): fourth

我们将在 PDF 文件中看到选定的非表格项目:second-b first second-b second-c second-c first fifth first first fourth

相关内容