将环境主体存储在 LUA 字符串中

将环境主体存储在 LUA 字符串中

我想获取环境的主体,将其存储在 lua 变量中,以便稍后在需要时在我的文档中使用它。只要我不使用任何带有 a}或任何环境的命令,我的代码实际上就可以正常工作:

%Uncomment the differents lines and see the error for \hspace{2cm}
\documentclass{article}

\usepackage{luacode}
\usepackage{environ}

\NewEnviron{latextolua}{
  \directlua{
    STR = [[\BODY]]
  }
}
\newcommand{\luatolatex}{
  \directlua{tex.sprint(STR)}
}

\begin{document}

Before.

\begin{latextolua}
  Some text.
  %Some \hfill text.
  %Some \hspace{2cm} text.
\end{latextolua}

After.

\luatolatex

\end{document}

据我了解,问题是,编译器试图解释环境内的代码,即使不需要,也会由于 而触发错误}

我提出了两种不同的方法来解决这个问题:

%First possible fix : escape the \ inside the environment
\documentclass{article}

\usepackage{luacode}
\usepackage{environ}

\NewEnviron{latextolua}{
  \directlua{
    STR = [[\BODY]]
    STR = string.gsub(STR,"\\\\","\\")
  }
}
\newcommand{\luatolatex}{
  \directlua{tex.sprint(STR)}
}

\begin{document}

Before.

\begin{latextolua}
  Some text.
  Some \\hfill text.
  Some \\hspace{2cm} text.
\end{latextolua}

After.

\luatolatex

\end{document}

%Second possible fix : deactivate the \ inside the environment and use § as the new \
\documentclass{article}

\usepackage{luacode}
\usepackage{environ}

\NewEnviron{latextolua}{
  \directlua{
    STR = [[\BODY]]
  }
}
\newcommand{\luatolatex}{
  \directlua{tex.sprint(STR)}
}

\AtBeginEnvironment{latextolua}{\catcode`\§ \active\catcode`\§=0\catcode`\\=12}

\begin{document}

Before.

\begin{latextolua}
  Some text.
  Some \hfill text.
  Some \hspace{2cm} text.
§end{latextolua}

After.

\luatolatex

\end{document}
  • 第一个修复并不令人满意,因为我想在这个环境中使用通常的语法来编写。

  • 第二个修复也不令人满意,因为我需要另一个符号来关闭环境。我找不到\在环境结束前恢复 catcode 的方法。

好吧,我正在寻找一个全新的视角来看待这个问题,所以如果有人有其他想法,或者确实以其他方式做了类似的事情,请告诉我!

答案1

您不必将宏扩展至\directlua块中然后再次将其转义,而是可以通过直接读取宏的值来避免扩展和转义:

%Uncomment the differents lines and see the error for \hspace{2cm}
\documentclass{article}

% You could use \NewDocumentEnvironment instead, but let's keep it for now.
\usepackage{environ}

\NewEnviron{latextolua}{%
  \directlua{
    STR = token.get_macro'BODY'
  }%
}
\newcommand{\luatolatex}{%
  \directlua{tex.sprint(STR)}%
}

\begin{document}

Before.

\begin{latextolua}
  Some text.
  Some \hfill text.
  Some \hspace{2cm} text.
\end{latextolua}

After.

\luatolatex

\end{document}

相同但不使用environ,而是使用 LaTeX 核心功能:

%Uncomment the differents lines and see the error for \hspace{2cm}
\documentclass{article}

\NewDocumentEnvironment{latextolua}{+b}{%
  \directlua{
    STR = token.scan_argument(false)
  }{#1}%
}{}
\newcommand{\luatolatex}{%
  \directlua{tex.sprint(STR)}%
}

\begin{document}

Before.

\begin{latextolua}
  Some text.
  Some \hfill text.
  Some \hspace{2cm} text.
\end{latextolua}

After.

\luatolatex

\end{document}

答案2

你需要防止进入 Lua 的扩展

在此处输入图片描述

\documentclass{article}

% not needed \usepackage{luacode}
% not needed \usepackage{environ}

\NewDocumentEnvironment{latextolua}{+b}{%
  \directlua{
    STR = [[\detokenize{#1}]]
  }%
}{}

\newcommand{\luatolatex}{%
  \directlua{tex.sprint(STR)}%
}

\begin{document}

Before.

\begin{latextolua}
  Some text.
  Some \hfill text.
  Some \hspace{2cm} text.
\end{latextolua}

After.

\luatolatex

\end{document}

相关内容