Luaに改行を渡したい。

Luaに改行を渡したい。

- 西村 一輝 の投稿
返信数: 4
皆さまお世話になっております。
Luaで文字列を処理したく、以下のようなコードを書きました。

\documentclass{ltjsarticle}
\def\w#1{
\directlua{
 str="#1"
}
}
\begin{document}
hello
\w{
A
B
}
\end{document}

str="A B"となってしまいますが、
str="A\nB"のように
改行を\nとして渡す方法はありますでしょうか?


西村 一輝 への返信

Re: Luaに改行を渡したい。

- Z. R. の投稿
str="A B"となってしまいますが、

いや、この場合 str="␣A␣B␣"(5文字)になるはずです。

str="A\nB"のように

だとすると、質問の解釈として、「Aの前やBの後の改行はどうしたいのか」が問題になります。

Z. R. への返信

Re: Luaに改行を渡したい。

- 西村 一輝 の投稿
Z. R. 様
ご指摘ありがとうございます。
ひとまず、
str="\nA\nB\n"を得ることはできますでしょうか?。


よろしくお願い致します。

西村
西村 一輝 への返信

Re: Luaに改行を渡したい。

- Z. R. の投稿

(※TeX言語に基本的な知識を前提とします。)

ソース中の改行が空白と見なされるのは勿論TeX言語の規則に従った結果なので、TeX言語の字句解析を変更する 必要があります。

  • \endlinechar=10 で行末文字の解釈をCR(13)からLF(10)に変更します。TeXではLF(10)は通常の文字(カテゴリコード12)なので、\w の引数中の改行がLFの通常文字トークンとなって \directlua のコードの中に埋め込まれることになります。
  • ただしこの変更が有効な間、\w の引数の外の改行もLFとなってしまい、これは意図しない動作を引き起こします。なので、不要な改行文字は % で無効化する必要があります。
  • Luaの通常文字列リテラルは途中に改行を含めないので、このままではLuaの文法エラーになります。改行を \ でエスケープすると改行文字を含められるため、\luaescapestring でエスケープを適用します。
\documentclass{ltjsarticle}
\def\w#1{
  \directlua{
    str="\luaescapestring{#1}"
    % ↓文字コードを端末出力する
    print();print(str:byte(1,5))
  }
}
\begin{document}
hello
\begingroup
\endlinechar=10 %
\w{
A
B
}% ←この%に注意
\endgroup% ←
\end{document}

これを実行すると、期待通り、print文が次の出力を行います。

10      65      10      66      10

ただし \endlinechar による行末文字コード変更は(カテゴリコード変更などと同様に)字句解析時に有効になる性質のため、これを使うと「他のマクロの引数の中では使えない」という厄介な制限を抱え込むことになります。

\fbox{%←マクロの引数の中で同じことをしてもダメ
\begingroup
\endlinechar=10 %
\w{
A
B
}%
\endgroup%
}

\endlinechar の変更は常に引数の外で行う必要があります。

\begingroup
\endlinechar=10 %←外に出す
\fbox{%
\w{
A
B
}%
}%←ここにも%が要る
\endgroup%

結局、TeXの規則に逆らおうとすると色々と面倒なことが起こるわけです。

Z. R. への返信

Re: Luaに改行を渡したい。

- 西村 一輝 の投稿
Z.R.様

お忙しい中、大変詳しいご回答ありがとうございます。
私の力量では直ぐに理解できないので、もう少し時間を下さい。
一応、TeXBookとTexByTopicは読みましたが、ほとんど忘れました。

Web系でよくあるように、もはやプリプロセッサで処理した方が早いのではと思ってしまうのが悔しいところですが、私はやります。

西村