Erstellen einer Token-Liste in Lua

Erstellen einer Token-Liste in Lua

In TeX wird ein Schreibknoten beispielsweise folgendermaßen eingefügt:

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

Mit reinem Luatex könnte ein Knoten mit Folgendem erstellt werden:

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

Laut Handbuch handelt es <token-list>sich um eine Tabelle, die die zu schreibende Tokenliste darstellt (mit einer Liste von Tripletts). Ich konnte keine Dokumentation darüber finden, wie diese Liste erstellt wird. Ich habe festgestellt, dass eine Zeichenfolge akzeptiert wird, aber in eine Zeichenfolgenliste von Zeichen umgewandelt wird (ähnlich wie \meaning), also \the\lastyposwörtlich geschrieben und nicht ausgewertet wird.

Ich habe einen Workaround gefunden, der im folgenden Codeausschnitt dargestellt ist:

\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

}

Ich definiere eine Box mit einem \writeund untersuche dann den Knoten. Im echten Code übergebe ich ihn, anstatt ihn auszudrucken, an n.dataund Primitive funktionieren wie erwartet (mit einigen Problemen in benutzerdefinierten Makros).

Meine Frage ist: Wie erstelle ich in Lua die Token-Liste zum Füllen des dataFelds? [Bearbeiten. Bitte beachten Sie, dass es in meinen Fragen nicht um geht \lastypos, sondern um das Erstellen einer beliebigen Tokenliste für das dataFeld. Bedenken Sie auch, dass aufgrund der asynchronen Natur von TeX Seitenzahlen und dergleichen nicht bekannt sind, wenn der „Schreib“-Knoten erstellt wird, sondern erst, wenn der „Schreib“-Knoten tatsächlich ausgegeben wird.]

Hier ist eine Latex-Datei für einige Experimente mit einer Lua-Datei namens 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}

Die Lua-Datei:

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

Antwort1

LuaTeX verfügt über die token.createFunktion, einen Token-Benutzerwert zu erstellen. Diese können zu einer Token-Liste zusammengefasst werden, indem man sie in eine Tabelle einträgt. \string\donothing{\the\lastvpos}Dies wäre beispielsweise:

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

Normalerweise meinen die Verweise auf Tokenlisten in der LuaTeX-Dokumentation diese Art von Tabelle, aber Sie benötigen eine andere Art: Eine Tabelle mit Zahlentabellen. Diese Zahlen zu finden ist nicht einfach, aber Sie können Tokenlisten im obigen Format in dieses andere Format konvertieren (hier verwende ich einen kleinen Trick: {0, v.tok}wird auf die gleiche Weise interpretiert, als ob wir sie ordentlich in drei Teile aufgeteilt hätten 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

Ergebnisse in der Ausgabe

\donothing{0}
\donothing{0}

verwandte Informationen