Construindo uma lista de tokens em lua

Construindo uma lista de tokens em lua

No TeX, um nó 'write' é inserido com, digamos:

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

Com luatex puro, um nó poderia ser criado com:

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

De acordo com o manual, <token-list>é uma tabela que representa a lista de tokens a ser escrita (com uma lista de trigêmeos). Não consegui encontrar nenhuma documentação sobre como esta lista é construída. Descobri que uma string é aceita, mas é convertida em uma lista de caracteres com string (muito parecido com \significado), portanto \the\lastyposé escrita literalmente, não avaliada.

Encontrei uma solução alternativa, mostrada no seguinte trecho de código:

\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

}

Defino uma caixa com a \writee inspeciono o nó. No código real, em vez de imprimi-lo, eu o passo n.datae as primitivas funcionam conforme o esperado (com alguns problemas nas macros definidas pelo usuário).

Minha dúvida é: como gerar em lua a lista de tokens para alimentar o datacampo? [Editar. Por favor, observe que minhas perguntas não são sobre \lastypos, mas sobre a construção de uma lista arbitrária de tokens para o datacampo. Lembre-se também que, devido à natureza assíncrona do TeX, os números de página e similares não são conhecidos quando o nó 'write' é criado, apenas quando o nó 'write' é realmente produzido.]

Aqui está um arquivo latex para fazer alguns experimentos, com um arquivo lua chamado 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}

O arquivo 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

Responder1

LuaTeX tem a token.createfunção de criar um token uservalue. Eles podem ser combinados em uma lista de tokens, colocando-os em uma tabela. Para \string\donothing{\the\lastvpos}isso seria:

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

Normalmente as referências a tokenlists na documentação do LuaTeX significam este tipo de tabela, mas você precisa de um tipo diferente: Uma tabela de tabelas de números. Encontrar esses números não é fácil, mas você pode converter listas de tokens no formato acima para este outro formato (aqui estou usando um pequeno truque: {0, v.tok}é interpretado da mesma maneira como se tivéssemos dividido v.tokcorretamente em três partes):

\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

resulta na saída

\donothing{0}
\donothing{0}

informação relacionada