我想获取环境的主体,将其存储在 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}