\luaexec は機能するのに、luacode 環境は機能しないのはなぜですか?

\luaexec は機能するのに、luacode 環境は機能しないのはなぜですか?

以下のコードは、(バージョン beta-0.70.1-2011061410 (rev 4277)) で正しくコンパイルできますlualatex。ただし、\begin{luacode} ... \end{luacode}環境を使用してコマンドを置き換えると\luaexec{...}、エラーが発生します。これはバグでしょうか?

! Extra }, or forgotten \endgroup.
<template> \unskip \hfil }
                          \hskip \tabcolsep \endtemplate 
l.19 \end{luacode}

? 
! Missing \endgroup inserted.
<inserted text> 
                \endgroup 
l.19 \end{luacode}

? 
! Missing } inserted.
<inserted text> 
                }
l.19 \end{luacode}

? 
! LaTeX Error: \begin{tabular} on input line 8 ended by \end{luacode}.
See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.19 \end{luacode}

? q

例を挙げてみましょう

\documentclass[]{article}
\usepackage{luacode}
\usepackage[left=1cm,right=1cm]{geometry}

\begin{document}

\begin{center}

\begin{tabular}{lllllllll}

\luaexec{
  num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
}

\end{tabular}
\end{center}

\end{document}

答え1

環境/マクロはそれぞれ異なります。それぞれ特殊文字を異なる方法で再定義します。

例えば、あなたのコード例では

\luaexec{
  num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
}

を使用します\\。LaTeXでは は\特殊文字です。LaTeXは、Luaがそれを見る前に、まずLuaコードブロックを処理します。これは、次のようなものがあった場合、

\directlua{print('\n')}

Latexはそれを解析し、\それを使って何かをしようとします。もし\nそれがLatexマクロであれば、それを展開しようとします。LatexがLuaコードを台無しにしないようにする1つの方法は、次のように展開しないように指示することです。

\directlua{print('\noexpand\n')}

その場合、ラテックスは\noexpandその後に続くものを展開しないことを認識します。

ここで、 の catcodes\とその他の特殊記号を変更すれば、LaTeX が Lua コードを混乱させるのを防ぐことができます。これは良いこともあれば、悪いこともあります。

例えば

\newcommand{\mylatexmacro}{my text}
\directlua{print('\mylatexmacro')}

my textラテックスが膨張するので印刷されます\mylatexmacro。しかし、

\newcommand{\mylatexmacro}{my text}
\luaexec{print('\mylatexmacro')} 

lua にある?latexmacroものは何でも where ? で出力されます。\m

私は、Lua コードをすべて LaTeX コードから分離しておく傾向があります。これは、Lua を使い始めると、通常、あまりにも多くの問題が関係してくるためです。非常に単純なものについては、インライン Lua コードを使用しますが、すべての関数を、LaTeX ファイルに含まれる別の Lua ファイルにコーディングします。

本質的には、lualatex は tex ファイルを前処理せず、単に latex にフックされた lua インタープリタを提供するだけであるという問題があります。latex の lua コードは、実際には lua インタープリタに渡される latex コードです。latex がコード ブロックを解析すると、lua が理解できないコードが混乱する可能性があります。例:

\directlua{print('\\')}

は印刷されません。\これは、LaTeX が を見つけて\\そこに新しい行を作成しようとするため、その新しいコードが Lua パーサーに渡され、最終的に Lua コードとして意味をなさなくなるためです。

答え2

次のように試してください:

\begin{tabular}{lllllllll}

\luacode
  num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
\endluacode

\end{tabular}

または代わりに

\documentclass{article}
\usepackage{luacode}

\begin{document}

\begin{luacode}
  tex.print("\\begin{tabular}{lllllllll}")
    num=6
  for i=1,num do  
    for j=1,num do
    ixj='$'..i..'\\times'..j..'='..i*j..'$';
    tex.print(ixj)
    if(j<num) then tex.sprint('&') else tex.sprint('\\\\') end 
    end 
  end 
  tex.print("\\end{tabular}")
\end{luacode}

\end{document}

関連情報