5

I would like to get an environment's body, store it inside a lua variable, in order to use it later in my document if needed. My code is actually working as long as I don't use any command with a } or any environment :

%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}

As I understand the problem, the compiler is trying to interpret the code inside the environment even if it's not needed, and it triggers an error due to the }.

I've come with two differents approaches to fix the problem :

%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}
  • The first fix isn't satisfying, because I'd like to write with the usual syntax inside this environment.

  • The second fix isn't satisfying either because I need another symbol to close the environment. I couldn't find a way to restore the \ catcode before the environment's end.

Well, I'm looking for a fresh eye on this problem, so if anyone has another idea, or did manage to do something similar in any other way let me know !

2 Answers 2

6

Instead of expanding the macro into the \directlua block only to escape it again, you can avoid the expansion and escaping by just reading the value of the macro directly:

%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}

The same without environ, using LaTeX core functionality instead:

%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
  • Thank you very much !
    – Vince
    Feb 21 at 18:38
  • Believe it or not, I was thinking of asking a question like that, but thought, "Aw, that cannot be done, and who else would ever use it?"
    – rallg
    Feb 21 at 20:10
5

You need to prevent expansion on the way in to Lua

enter image description here

\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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .