5

The function I'm trying to create is one that takes two numbers and prints the result with some math. The following is my code:

\documentclass[12pt,a4paper]{article}

\begin{document}
    \directlua{
        function prod(a,b)
            tex.print(a "$\times$" b "$=$" a*c)
        end
    }

    The product of 2 and 3: \directlua{prod(2,3)}.
\end{document}

I can't make it print the whole statement correctly. How to solve it?

3
  • 3
    Try tex.print("$" .. a .. "\string\\times" .. b .. "=" .. a*b .. "$")
    – moewe
    Commented Apr 5, 2019 at 19:32
  • 1
    Unlike TeX, to which everything is (by default) a token to be typeset so you can simply write "hello world" and have those words appear in the typeset output, Lua is a general-purpose programming language in which something like a b is a syntax error (assuming a and b are variables). Here, tex.print is a Lua function that takes a single string as input, so you need to give it a single string. (There are other forms of tex.print too, that you can read in the LuaTeX manual, but those are probably not what you want.) Lua uses .. to concatenate strings. Commented Apr 5, 2019 at 19:39
  • 2
    BTW instead of concatenating different strings with .., you can also use string.format to build a string, e.g. in a file test.lua put function prod(a,b) tex.print(string.format([[$%d \times %d = %d$]], a, b, a*b)) end and in your file do \directlua{dofile('test.lua')} -- here the [[ instead of " is to avoid needing to escape the backslash in \times. Commented Apr 5, 2019 at 19:46

3 Answers 3

7
\documentclass[12pt,a4paper]{article}

\directlua{
  function prod(a,b)
    tex.print("$" .. a .. "\string\\times" .. b .. "=" ..  a*b .. "$")
  end
}

\begin{document}    
  The product of 2 and 3: \directlua{prod(2,3)}.
\end{document}

The product of 2 and 3: 2 × 3 = 6.

One tricky thing is getting the backslash escaping game right: LuaTeX: How to handle a Lua function that prints TeX macros. directlua expands macros before passing them on to Lua, so \times gets messed up. But something like \string\times, which should stop that expansion does not quite work as intended because \t is a special escape for the tab in Lua. Hence we need to escape the backslash there. In Lua you would have to type \\times, but in TeX we need to stop the \\ from being expanded, so we need \string\\times. That is one of the reasons why it is often recommended to use the luacode package or externalise Lua functions into their own .lua files and then load them with dofile or require (see for example How to do a 'printline' in LuaTeX, a bit on dofile and require can be found at LuaLatex: Difference between `dofile` and `require` when loading lua files).

Another thing is that you need .. to concatenate strings.

Finally, you probably want the entire expression in math mode and not just certain bits.

Also moved the \directlua function definition into the preamble. (Thanks to Mico for the suggestion.)

2
  • That's what I was looking for. It worked here. Thank you!
    – Levy
    Commented Apr 5, 2019 at 19:40
  • And the explanation was really helpful!
    – Levy
    Commented Apr 5, 2019 at 19:40
6
\documentclass[12pt,a4paper]{article}

\begin{document}
    \directlua{
        function prod(a,b)
            tex.print(a.. "$\string\\times$".. b.. "$=$".. a*b)
        end
    }

    The product of 2 and 3: \directlua{prod(2,3)}.
\end{document}

enter image description here

6

Just for completeness, here's a solution that shows how to (a) write the Lua code to an external file, (b) load the Luacode via a \directlua{dofile("...")} directive, and (c) set up a LaTeX "wrapper" macro (called \showprod in the example below) whose function (pun intended) is to invoke the Lua function.

Note that with this setup, one can write \\ rather than \string\\ to denote a single backslash character. (This is also the case for the luacode and luacode* environments that are provided by the luacode package.)

enter image description here

\RequirePackage{filecontents}
\begin{filecontents*}{show_prod.lua}
function show_prod ( a , b )
  tex.sprint ( "$"..a.."\\times"..b.."="..a*b.."$" )
end
\end{filecontents*}

\documentclass{article}
%% Load Lua code from external file and define a LaTeX "wrapper" macro
\directlua{dofile("show_prod.lua")}
\newcommand\showprod[2]{\directlua{show_prod(#1,#2)}}

\begin{document}
The product of 2 and 3: \showprod{2}{3}.
\end{document}

You must log in to answer this question.

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