# LuaTeX: Call a Lua function with two optional arguments

I've read More than one optional argument for newcommand and I chose the answer with xargs. I would like to pass a second optional argument to the Lua function. But the first of the two commented \drawLUAline lines leads to the error:

./d.tex:39: Package pgfkeys Error: I do not know the key '/tikz/midway {A}' and I am going to ignore it. Perhaps you misspelled it.

Of course, I can here just add the second optional part as I did, but I want to know how to do this right for other cases. And for me the syntax with the double brackets for the optional arguments is not clear.

\documentclass[preview]{standalone}
\usepackage{xargs}
\usepackage{luacode}
\usepackage{tikz}

\begin{document}

\begin{luacode*}
function print_line (x, y, optA, optB)

-- optA: yes
if optA~=[[]] then
tex.sprint("\\draw["..optA.."] (0,0) -- ("..x..","..y..")")
end

-- optA: no
if optA==[[]]  then
tex.sprint("\\draw (0,0) -- ("..x..","..y..")")
end

-- optB: yes
if optB ~=[[]] then
tex.sprint(""..optB.."")
end

end
\end{luacode*}

\newcommandx{\drawLUAline}[4][1, 4]{%
\directlua{print_line(#2,#3,[[#1]],[[#4]])}
}

\begin{tikzpicture}
\draw (0,0) grid (3,4);
\drawLUAline{3}{1};
\drawLUAline[red]{3}{2};
\drawLUAline[blue]{3}{2.5} node[midway]{A};
%\drawLUAline[green]{3}{3}[node[midway]{A}];
%\drawLUAline{3}{4}[node[midway]{A}];
\end{tikzpicture}
\end{document}


• Just out of curiosity: Wouldn't it be easier/less cumbersome to specify a Lua function with 4 arguments, with tests for args 3 and/or 4 being empty (and supplying default values if the args are indeed empty)? This Lua function would be invoked by a LaTeX macro whose 3rd and/or 4th args could be empty, say, \drawLUAline{3}{1}{}{}, \drawLUAline{3}{2}{red}{}, and \drawLUAline{3}{3}{green}{"node[midway]{A}"}. – Mico May 13 '18 at 18:51
• Of course may be there are better ways. But I would like to be able to choose the best way. So I need information about the choices. That's why I asked my question. – Nik May 14 '18 at 9:54

The package xargs does not support nested brackets, so a optional arguments ends at the first ]. In your example this means, that for

\drawLUAline[green]{3}{3}[node[midway]{A}];
%                                    ^ This bracket ends the argument


the second optional argument is node[midway. Then the {A}] comes after the macro, so TikZ sees node[midway{A}] which leads to the error. You could avoid this by writing braces around the argument, so call the macro with

\drawLUAline[green]{3}{3}[{node[midway]{A}}];
%                         ^               ^ These "hide" the ].


If you want your macro to accept the argument without these additional braces, you can use xparse instead:

\documentclass[preview]{standalone}
\usepackage{xparse}
\usepackage{luacode}
\usepackage{tikz}

\begin{document}

\begin{luacode*}
function print_line (x, y, optA, optB)

-- optA: yes
if optA~=[[]] then
tex.sprint("\\draw["..optA.."] (0,0) -- ("..x..","..y..")")
end

-- optA: no
if optA==[[]]  then
tex.sprint("\\draw (0,0) -- ("..x..","..y..")")
end

-- optB: yes
if optB ~=[[]] then
tex.sprint(""..optB.."")
end

end
\end{luacode*}

\NewDocumentCommand{\drawLUAline}{O{} m m O{}}{%
\directlua{print_line(#2,#3,[[#1]],[[#4]])}
}

\begin{tikzpicture}
\draw (0,0) grid (3,4);
\drawLUAline{3}{1};
\drawLUAline[red]{3}{2};
\drawLUAline[blue]{3}{2.5} node[midway]{A};
\drawLUAline[green]{3}{3}[node[midway]{A}];
\drawLUAline{3}{4}[node[midway]{A}];
\end{tikzpicture}
\end{document}


While this works, there is another problem hidden in this code: Using [[#1]] etc. is unsafe. Especially if the argument could end with a ] or contain ]] this leads to weird errors. Use normal quotes and \luaescapestring instead:

\documentclass[preview]{standalone}
\usepackage{xparse}
\usepackage{luacode}
\usepackage{tikz}

\begin{document}

\begin{luacode*}
function print_line (x, y, optA, optB)

-- optA: yes
if optA~="" then
tex.sprint("\\draw["..optA.."] (0,0) -- ("..x..","..y..")")
end

-- optA: no
if optA==""  then
tex.sprint("\\draw (0,0) -- ("..x..","..y..")")
end

-- optB: yes
if optB ~= "" then
tex.sprint(""..optB.."")
end

end
\end{luacode*}

\NewDocumentCommand{\drawLUAline}{O{} m m O{}}{%
\directlua{print_line(#2,#3,"\luaescapestring{#1}","\luaescapestring{#4}")}%
}

\begin{tikzpicture}
\draw (0,0) grid (3,4);
\drawLUAline{3}{1};
\drawLUAline[red]{3}{2};
\drawLUAline[blue]{3}{2.5} node[midway]{A};
\drawLUAline[green]{3}{3}[node[midway]{A}];
\drawLUAline{3}{4}[node[midway]{A}];
\end{tikzpicture}
\end{document}

• Thank you. But what is the meaning of the double braces: [[#1]] ? – Nik May 14 '18 at 9:46
• @Nik You find more information about the double square brackets at lua.org/pil/2.4.html. They mark string literals, similar to quotation marks. In contrast to quotation marks, no escape sequences are interpreted between them and they can be used for multi-line string literals. – Marcel Krüger May 14 '18 at 14:56