Создание списка токенов в lua

Создание списка токенов в lua

В TeX узел «запись» вставляется, например, так:

\write1{\string\doit{\the\lastypos}}

С помощью чистого luatex узел можно создать с помощью:

local n = node.new(8, 1)
n.stream = 1
n.data = <token-list>

Согласно руководству, <token-list>это таблица, представляющая список токенов, который нужно записать (со списком триплетов). Я не смог найти никакой документации о том, как этот список строится. Я обнаружил, что строка принимается, но преобразуется в строковый список символов (очень похожий на \meaning), поэтому \the\lastyposзаписывается дословно, а не оценивается.

Я нашел обходной путь, показанный в следующем фрагменте кода:

\setbox0\hbox{\write1{\the\lastxpos}}

\directlua{

  for _,d in ipairs(tex.box[0].head.data) do
    texio.write(' ** ' .. d[1] .. '/' .. d[2] .. '/' .. d[3])
  end

}

Я определяю ящик с помощью \writeи затем проверяю узел. В реальном коде вместо того, чтобы печатать его, я передаю его в n.dataи примитивы работают так, как и ожидалось (с некоторыми проблемами в определяемых пользователем макросах).

У меня вопрос: как сгенерировать в lua список токенов для подачиdata поля? [Редактировать. Пожалуйста, обратите внимание, что мой вопрос не о \lastypos, а о построении произвольного списка токенов для dataполя. Помните также, что из-за асинхронной природы TeX номера страниц и тому подобное неизвестны, когда создается узел «write», а известны только когда «write» фактически выводится.]

Вот файл latex для проведения некоторых экспериментов с файлом lua с именем extra.lua:

\documentclass{article}

\def\donothing#1{}

\directlua{
  require'extra'
}

\setbox0\hbox{\write1{\string\donothing{\the\lastypos}}}

\begin{document}

\directlua{

for _,d in ipairs(tex.box[0].head.data) do
  texio.write(' +++ ' .. d[1] .. '/' .. d[2] .. '/' .. d[3])
end

}

\copy0
\copy0
\copy0

\end{document}

Файл lua:

local n = node.new(8, 1)
n.stream = 1
n.data =  'abcd#&\\the\\lastxpos' 

for _,d in ipairs(n.data) do
  texio.write(' *** ' .. d[1] .. '/' .. d[2] .. '/' .. d[3])
end

решение1

LuaTeX имеет token.createфункцию создания токена uservalue. Их можно объединить в список токенов, поместив их в таблицу. Для \string\donothing{\the\lastvpos}этого будет:

tl = {
  token.create'string',
  token.create'donothing',
  token.create(string.byte'{'),
    token.create'the',
    token.create'lastypos',
  token.create(string.byte'}')
}

Обычно ссылки на списки токенов в документации LuaTeX подразумевают этот тип таблицы, но вам нужен другой тип: таблица таблиц чисел. Найти эти числа непросто, но вы можете преобразовать списки токенов в формате выше в этот другой формат (здесь я использую небольшой трюк: {0, v.tok}интерпретируется так же, как если бы мы v.tokправильно разделили их на три части):

\directlua{
local function convert_tl(list)
  local new = {}
  for i,v in ipairs(list) do
    new[i] = {0, v.tok}
  end
  return new
end

local n = node.new(8, 1)
n.stream = 3
n.data = convert_tl{
  token.create'string',
  token.create'donothing',
  token.create(string.byte'{'),
    token.create'the',
    token.create'lastypos',
  token.create(string.byte'}')
}

tex.box[0] = node.hpack(n)
}
\copy0
\copy0

результаты в выводе

\donothing{0}
\donothing{0}

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