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