
Начинаем с такого отрывка текста:
This is a sample passage.
Как сделать так, чтобы каждое слово отображалось случайным образом в разном размере из списка из 3-4 возможных размеров?
Например, в выходных данных «This» может быть большим, «is» может быть маленьким, «a» может быть средним и т. д.
- При каждом отображении документа они могут иметь разные размеры.
решение1
Помимо двух команд, упомянутых Адитьей и Анри, ConTeXt также предоставляет команды \applytosplitstringwordspaced
и \applytosplitstringcharspaced
для применения команды к каждому word
или character
в заданном аргументе.
\startluacode
function userdata.randomwordsize(str)
local sizes = { "10pt", "12pt", "14pt", "16pt", "18pt", "20pt" }
local size = sizes[math.random(1,6)]
context.startfont{ string.formatters["Serif at %s"](size) }
context(str)
context.stopfont()
end
\stopluacode
\starttext
\defineexpandable[1]\RandomWordSize
{\ctxlua{userdata.randomwordsize("#1")}}
\applytosplitstringwordspaced\RandomWordSize
{The fraction of fossil olfactory receptor genes is significantly
higher in all species with full color vision. This suggests that
the evolution of trichromatic vision --- which allows these
primates to detect food, mates, and danger with visual cues ---
has reduced their reliance on the sense of smell.}
\blank
\applytosplitstringcharspaced\RandomWordSize
{The fraction of fossil olfactory receptor genes is significantly
higher in all species with full color vision. This suggests that
the evolution of trichromatic vision --- which allows these
primates to detect food, mates, and danger with visual cues ---
has reduced their reliance on the sense of smell.}
\stoptext
решение2
Самая сложная часть — выделить слова из отрывка и применить произвольный макрос к каждому слову. ConTeXt предоставляет команду, \processwords
которая это делает. Чтобы использовать эту команду, сначала нужно определить макрос \processword
, который будет действовать на определенное слово.
В качестве примера предположим, что вы хотите нарисовать рамку вокруг каждого слова. Затем определите:
\def\processword{\inframed}
\starttext
Normal text \processwords{This is a simple passage.} Normal text
\stoptext
который дает
Теперь следующим шагом будет создание макроса, который выбирает случайный размер шрифта и применяет его.
решение3
Ответ Адитьи в принципе правильный, но наивный макрос для рандомизации размера шрифта работать не будет. Это потому, что по умолчанию \processwords
используется«старый призыв»где каждое слово помещается в поле, а \processword
макрос оценивается только один раз. Чтобы смягчить это, нам придется вручную переключиться на«Вызов MetaFun»которому также не нужно вызывать Lua.
\def\processword#1{{\switchtobodyfont[\randomnumber{5}{15}pt]#1}}
\starttext
Normal text \processwords{This is a simple passage.} Normal text
\unprotect
\def\processwords#1%
{\syst_helpers_process_word#1 \_e_o_w_}% no \unskip
\protect
Normal text \processwords{This is a simple passage.}Normal text
\stoptext
В качестве альтернативы вы можете использовать \processseparatedlist
, что позволяет использовать произвольный разделитель:
\processseparatedlist
[This is a simple passage.]
[ ]
{\groupedcommand{\bgroup\switchtobodyfont[\randomnumber{5}{15}pt]}{\space\egroup}}
Во всех случаях обращайте внимание на наличие лишних пробелов после списка.