「Lua の実行途中で TeX コードを実行する」ための「tangle モジュール」(以前の記事を参照)の改良の話。
従来(ixbase0 パッケージ、IXbase バンドル)の tangle では、大本の Lua コードを開始するときに、
\directlua{ tangle.execute(function() % 実行するコード end) }
のように起動する約束になっていた。この tangle.execute()
が、コルーチン中断後に必要な処理(Lua コード再開のための \directlua
を吐き出す、等)を行う。この起動プロトコルの部分に TeX の処理を絡めることで、Lua コード再開の \directlua
実行が「書出コード」を抜けた後で起こるようにした。TeX コードが絡むので、開始部分に(単なる \directlua
や luacode* 環境でなくて)独自の命令・環境を用いることになる。
……全く説明の体を成していないが、実際のパッケージの使い方を見れば判ると思う。BXluatool バンドルの bxluatangle パッケージが tangle モジュールの改良版にあたる。「途中で TeX を実行したい」Lua コードがある場合は \directlua
や luacode* の代わりに以下のようにして Lua コードを記述する。*1
% \directlua の代わり \tangleluaexec{ % 実行するコード } % luacode* 環境の代わり \begin{tangleluacode*} -- 実行するコード \end{tangleluacode*}
Lua コード中で TeX コードの実行を完了させるには、bxlt.run_tex()
を実行する。((BXluatool バンドルを通じて Lua モジュールの名前は bxlt としている。ixbase0 では tangle.run_tex()
であった。))
以前の記事で落ちていた例をこのパッケージで実装すると次のようになる。
% 文字コードは UTF-8 \documentclass[a4paper]{article} \usepackage{bxluatangle,luacode,bxluafacade} \begin{luacode*} function truncate_to_width(str) local wdt = bxlt.length.ttwTarget.width local max = str:len() for l = 1, str:len() do -- あえて線形探索を使う texio.write("("..l..")") -- デバッグ出力(*) -- str:sub(1,l) を組版しその幅を \ttwMeasured に代入する tex.print([[\settowidth{\ttwMeasured}{]]..str:sub(1, l)..[[}%]]) bxlt.run_tex() -- TeX の実行を完了させる local wdm = bxlt.length.ttwMeasured.width if wdm > wdt then max = l - 1; break end end tex.print(str:sub(1, max)) end \end{luacode*} \newlength{\ttwTarget} \newlength{\ttwMeasured} \newcommand*{\truncatetowidth}[2]{% \setlength{\ttwTarget}{#1}% \tangleluaexec{ truncate_to_width(\luastring{#2}) }% } \begin{document} \begin{itemize} \item \truncatetowidth {10pt}{I never feel like saying hello to world!} \item \truncatetowidth {50pt}{I never feel like saying hello to world!} \item \truncatetowidth {90pt}{I never feel like saying hello to world!} \item \truncatetowidth{130pt}{I never feel like saying hello to world!} \item \truncatetowidth{170pt}{I never feel like saying hello to world!} \end{itemize} \end{document}
今度は、ループ回数が増えても TeX の制限に引っかかることなく正常に動作している。
This is LuaTeX, Version beta-0.70.2-2012052919 (TeX Live 2012/W32TeX) restricted \write18 enabled. ……(中略)…… (./test.aux) (c:/usr/local/share/texmf/tex/latex/base/omscmr.fd)(1)(2)(3)(1)(2) (3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13 )(14)(15)(16)(17)(18)(19)(20)(21)(22)(23)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12 )(13)(14)(15)(16)(17)(18)(19)(20)(21)(22)(23)(24)(25)(26)(27)(28)(29)(30)(31)(3 2)(33)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)(15)(16)(17)(18)(19)(20)(2 1)(22)(23)(24)(25)(26)(27)(28)(29)(30)(31)(32)(33)(34)(35)(36)(37)(38)(39)(40) [1{c:/usr/local/share/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux) ) 263 words of node memory still in use: 2 hlist, 1 vlist, 1 rule, 2 glue, 40 glue_spec, 1 write nodes avail lists: 1:1,2:12,3:16,4:123,5:12,6:106,7:1,9:24,10:2 <c:/usr/local/share/texmf/fonts/type1/public/amsfonts/cm/cmr10.pfb><c:/usr/loca l/share/texmf/fonts/type1/public/amsfonts/cm/cmsy10.pfb> Output written on test.pdf (1 page, 21625 bytes). Transcript written on test.log.
*1:これを「tangle 付で実行する」という。