这听起来很蠢,但对我很有用。我想随机化单词。输入一段文本,然后以随机顺序输出相同的单词。不过,我不知道该如何开始。因此,我甚至无法提供 MWE。
有人能告诉我使用哪个包来执行以下操作吗:
- 不必以逗号分隔的列表形式引入文本
- 获得真正随机的文本
- 序列
word,
和一般情况下word[punctuation-sign]
也可以随机分离
答案1
这是使用 LuaTeX 的一个小演示,希望它能作为进一步探索的起点。
- 代码改变了一些命令,例如
\bf
为了\textbf
更快地进行文本操作(%b
Lua 中的运算符),因为我希望在 TeX 级别格式化一些单词。 - 它还将空格更改为
} \command
格式化代码中的序列,例如,我们从一个序列中获取\textbf{1 2 3}
一个新的序列\text{1} \text{2} \text{3}
。 - 之后,代码按空格分割整个字符串并将术语保存到 Lua 表中。
- 该表是散列表,因此打印单词时其顺序看起来是随机的。更新 1:我不能 100% 确定散列等于(伪)随机选择,因此我使用了一种借助函数的经典算法
math.random
,并从表中删除项目,直到该表为空。 - 在 TeX 级别有一个
\randomize
命令,我们在需要时调用它。 - 更新 2:我还对标点符号实现了一些基本的操作:它们(只有。,!?)表现得像单词一样,并且在后处理阶段我们删除了一些多余的空格。
我附上了代码和结果预览,第一段经过处理并着色以便于阅读,第二段是原始文本。我们运行lualatex mal-text.tex
。
% lualatex mal-text.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage{luacode}
\usepackage{xcolor}
\begin{document}
\begin{luacode*}
math.randomseed(321) -- Are we getting the some output?
-- Preparations for minor changes.
format={ "\\textbf", "\\textit" }
change={ ["it"]="\\textit", ["bf"]="\\textbf" }
malcomma="[%.,!%?]+"
-- The core function we call every time when
-- we use the \randomize command in TeX.
function random()
text=tex.toks[0] -- Take parameter from TeX.
words={} -- initialize/clear the variable with previously parsed words
print("Processing: "..text)
-- Change \bf to \textbf for faster searching at a Lua level.
for search, modify in pairs(change) do
text=unicode.utf8.gsub(text, "{\\"..search.." ", modify.."{")
end -- for, modify
-- Let punctuations behave like words.
-- I am choosing only some basic ones for demonstration.
text=unicode.utf8.gsub(text, "("..malcomma..")", " %1")
-- Let's delete spaces after commands.
text=unicode.utf8.gsub(text, "(\\[%a]-) ", "%1")
for _,term in pairs(format) do -- Focus on defined terms only.
text=unicode.utf8.gsub(text, term.."(%b{})", -- Find that part.
function(s) -- Change spaces to commands, e.g. \textbf{a b c} to \textbf{a} \textf{b} \textbf{c}.
s=unicode.utf8.gsub(s, "%s+", "} "..term.."{")
toreturn=term..s -- Add original command to the string,
-- print(toreturn) -- print byproduct, if necessary,
return toreturn -- and return it to the gsub.
end -- function, s
) -- end of gsub
end -- for, term
-- Store data, they will be hashed at a Lua level.
for word in unicode.utf8.gmatch(text, "[%S]+") do
-- print("..."..word.."...") -- Words we process.
-- words[word]=word -- Is hashed equal to randomized? I assume not, therefore there is a classical example.
table.insert(words,word) -- Storing one text element.
end -- for, word
-- Print all words back in TeX, even with punctuation,
-- but the terms are hashed, therefore it looks like
-- randomly choosen data.
-- An old example...
--[[ for _, selected in pairs(words) do
tex.print(selected)
end -- for, selected]]
-- A new example, that's almost a classical algorithm...
backup=words -- backuping data, just in case
malstring=""
while #words~=0 do -- print table until that is empty
selected=math.random(#words) -- randomly pick number between 1 and number of elements in the table words
malstring=malstring..words[selected].." " -- print that element
table.remove(words,selected) -- and delete it
end -- repeat that process until that table is empty
-- Postprocessing due to punctuations, e.g. > . . <. Delete that extra space.
malstring=unicode.utf8.gsub(malstring, " ("..malcomma..")", "%1") -- unformatted punctuations
malstring=unicode.utf8.gsub(malstring, " (\\%a+{"..malcomma.."})", "%1") -- formatted punctuations
malstring=unicode.utf8.gsub(malstring, "%s+$", "") -- remove ending spaces
-- print(malstring)
-- Print the result in a document.
tex.sprint(malstring)
end -- function, random
\end{luacode*}
% Some background in TeX, send parameter to Lua.
% Let's change colour of the randomized text for easier checking the results.
\def\randomize#1{%
\toks0{#1}% Saving parameter for later load.
\begingroup\color{blue}% Change a colour within a group.
\directlua{random()}% Calling Lua.
\endgroup% End of the group, change of colour.
}% End of the command \randomize.
% An example of use.
% Definition of text + printing it.
\def\maltext{%
Regular text. \randomize{Text to be randomized. Next sentence to be used.} Common text, the middle part. \randomize{Next section \textit{of the text, middle part,} ending word.} The paragraph ends here. \randomize{1 2 {\bf 3 4 5 6 7 8} 9 0}. One last change: \randomize{a b c d e f g h A B C D E F G H}.}
\maltext
% Show me the original text.
\def\randomize#1{#1}
\maltext
\end{document}