前記事のちょとした補足です。
\begin{luacode*} function readFromPipe(cmd) local f = assert(io.popen(cmd, 'r')) local s = assert(f:read('*a')) f:close() return s end \end{luacode*}
とした場合,コマンド出力結果の最後に改行があると,それを空白として文字列 s
に取り込んでしまします。すると,それを tex.print()
で出力したときにも,スペーストークンが入ってきてしまうことになります。
【実例】
%#!lualatex -shell-escape \documentclass{jlreq} \usepackage{luacode} \begin{luacode*} function readFromPipe(cmd) local f = assert(io.popen(cmd, 'r')) local s = assert(f:read('*a')) f:close() return s end \end{luacode*} \newcommand\command[1]{\expandafter\detokenize\expandafter{\directlua{tex.print(readFromPipe('#1'))}}} \begin{document} \ttfamily % uname コマンドの結果を出力してみる [\command{uname -s}] [\command{uname -m}] \end{document}
【結果】
確かに,右側に余分なスペースが入ってきてしまっています。
そこで,s
に対してLuaの正規表現置換で末尾スペースを除去しようとして,こうしたとします。
【実例】
%#!lualatex -shell-escape \documentclass{jlreq} \usepackage{luacode} \begin{luacode*} function readFromPipe(cmd) local f = assert(io.popen(cmd, 'r')) local s = assert(f:read('*a')) f:close() return string.gsub(s, '%s+$', '') end \end{luacode*} \newcommand\command[1]{\expandafter\detokenize\expandafter{\directlua{tex.print(readFromPipe('#1'))}}} \begin{document} \ttfamily % uname コマンドの結果を出力してみる [\command{uname -s}] [\command{uname -m}] \end{document}
すると,今度は謎の1
が出力に入ってきてしまいました。
【結果】
これは,gsub
関数は置換後の文字列と置換回数という2つの返値を返し,return
でその両側が外側に伝えられてしまっているからです。
次のように,1つめの返値だけを受け取り,2つめの返値を捨ててしまえばOKです。
【実例】
%#!lualatex -shell-escape \documentclass{jlreq} \usepackage{luacode} \begin{luacode*} function readFromPipe(cmd) local f = assert(io.popen(cmd, 'r')) local s = assert(f:read('*a')) f:close() s = string.gsub(s, '%s+$', '') return s end \end{luacode*} \newcommand\command[1]{\expandafter\detokenize\expandafter{\directlua{tex.print(readFromPipe('#1'))}}} \begin{document} \ttfamily % uname コマンドの結果を出力してみる [\command{uname -s}] [\command{uname -m}] \end{document}
【結果】