0

I'm trying to check if a parameter is declared/empty using lua. So far I wrote the following MWE:

\documentclass{standalone}

\def\var#1{\def@var{#1}} %\var{Hello world}

\begin{document} @var --

\directlua{if string.len("\@var") == 0 then tex.print("empty") else tex.print("not empty") end}

\end{document}

If \var{Hello world} is uncommented the code runs with no errors, but if it's commented then it always returns error.

Is there a way to make this checking on a parameter/variable with LuaLaTeX?

Levy
  • 1,167
  • I don't know lua, but with regular latex, I would expect this to have all sorts of problems because https://tex.stackexchange.com/questions/8351/what-do-makeatletter-and-makeatother-do. Could that be the problem here? – Teepeemm Aug 03 '23 at 01:49
  • If I declare the command with no @ it would lead to errors too. – Levy Aug 03 '23 at 01:53
  • As is, I'm getting the output: "var -". If I uncomment that line, then I get the output: "Hello world - not empty". I'm not quite sure what you think is happening. Even if @ were a letter, I don't think this would work the way you want, because \@var -- would be the same (I think) as \@var{-}-. The only way to get an empty parameter is a literal {}. – Teepeemm Aug 03 '23 at 02:04
  • I commented \@var -- so it should print just the result of \directlua and the result is Process exited with error(s) after compiling. – Levy Aug 03 '23 at 02:08

2 Answers2

4

Your line

\@var --

prints var – because the macro \@ sets the spacefactor and then there are letters v a r and then space and the double -- which is converted to the ligature .

Your \directlua line works like this:

\directlua{if string.len("\spacefactor \@m {}var") == 0 then tex.print("empty") else tex.print("not empty") end}

because the \directlua primitive fully expands its argument before the argument is used.

If you use your macro \var (which is unused in your example), then the macro \@ is redefined as a macro with mandatory separator var.

There are three cases described above, I mean that none of these case were your intention.

I can only guess your intend. Maybe, you want to define \@var macro when the \var macro is used and you want to test if the \@var macro is defined. You can't do this test using \directlua because you cannot put an undefined macro to the \directlua parameter because \directlua expands its parameter. You can do:

\catcode`\@=11 % `@` is letter
\def\var#1{\def\@var{#1}}

%\var{Hello world} % this defines @var as a macro with body Hello world.

\ifx@var\undefined undefined var\else defined var \fi

wipet
  • 74,238
4

As wipet wrote you are missing \makeatletter. Apart from this you can get the content of a macro in lua with token.get_macro. Side remark: do not use standalone for such small examples. That is a complicated class with various side-effects. article is normally much better.

\documentclass{article}

\makeatletter \def\var#1{\def@var{#1}} \makeatother \var{Hello world}

\begin{document} \makeatletter @var -- \makeatother

\directlua{
  a=token.get_macro("@var")
  print("XXXXXXXXXX @var is: ",a) %for debugging on the terminal
  if string.len(a) == 0 then 
   tex.print("empty") 
  else 
    tex.print("not empty " .. string.len(a)) 
  end}

\var{}

  \directlua{
  a=token.get_macro("@var")
  print("XXXXXXXXXX @var is: ",a) 
  if string.len(a) == 0 then 
   tex.print("empty") 
  else 
    tex.print("not empty " .. string.len(a)) 
  end}



\end{document}

enter image description here

Ulrike Fischer
  • 327,261