Lua でトークン リストを作成する

Lua でトークン リストを作成する

TeX では、次のようにして 'write' ノードが挿入されます。

\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' が実際に出力されたときにのみわかることにも注意してください。

以下は、extra.lua という名前の lua ファイルを使用して、いくつかの実験を行うための LaTeX ファイルです。

\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トークン ユーザー値を作成する機能があります。トークン ユーザー値をテーブルに入れることで、トークン リストにまとめることができます。\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 ドキュメントのトークンリストへの参照は、この種類のテーブルを意味しますが、必要なのは別の種類です: 数値のテーブルのテーブルです。これらの数値を見つけるのは簡単ではありませんが、上記の形式のトークンリストをこの別の形式に変換できます (ここでは、ちょっとしたトリックを使用しています: は、 3 つの部分に適切に{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}

関連情報