Как рандомизировать размер текста каждого слова в ConTeXT?

Как рандомизировать размер текста каждого слова в ConTeXT?

Начинаем с такого отрывка текста:

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}}

Во всех случаях обращайте внимание на наличие лишних пробелов после списка.

Связанный контент