[Tex/LaTex] How to use string.find from Lua in ConTeXt

contextlua

I am trying to make some conditionals with Lua, which check if some text is found within a string. Unfortunately, when I compile it, I get:

! LuaTeX error <main ctx instance>:4: bad argument #1 to 'find' (string expected, got nil)
stack traceback:
    [C]: in function 'find'
    <main ctx instance>:4: in function 'hasnumber'
    <main ctx instance>:1: in main chunk.

I thought my code must have a problem with Lua, but I confirmed at Stack Overflow (How to check if matching text is found in a string in Lua?) that I have used the write code to use string.find inside a conditional, so I consider the posibility that I have made some error in incorporating this code into a Lua function within ConTeXt.

Here is an overly simplified version of my code, but which has the same error:

\startluacode
    userdata = userdata or {}
    function userdata.hasnumber()
        if string.find(str, "2") then
            str = "Has 2."
        elseif string.find(str, "1") then
            str = "Has 1."
        else
            str = "Has none."
        end
        context(str)
    end
\stopluacode

\starttext
    \ctxlua{userdata.hasnumber("The number 1 is here, as is 2")}
    \ctxlua{userdata.hasnumber("This has no numbers.")}
    \ctxlua{userdata.hasnumber("This only has 1")}
\stoptext

Why is string.find reporting that it did not receive any string?

Best Answer

string.find() needs at least two arguments, the string to search and the pattern. You give the two arguments, but the first one is nil (that is the error message). Why? Because in the line 4 (if string.find(str, "2") then) the variable str is not defined.

Here is the entry in the Lua reference manual: http://www.lua.org/manual/5.1/manual.html#pdf-string.find

Untested:

\startluacode
    userdata = userdata or {}
    function userdata.hasnumber(str)
        if string.find(str, "2") then
            str = "Has 2."
        elseif string.find(str, "1") then
            str = "Has 1."
        else
            str = "Has none."
        end
        context(str)
    end
\stopluacode

\starttext
    \ctxlua{userdata.hasnumber("The number 1 is here, as is 2")}
    \ctxlua{userdata.hasnumber("This has no numbers.")}
    \ctxlua{userdata.hasnumber("This only has 1")}
\stoptext

The function hasnumber gets one parameter (str) that is used in the string.find() function.

Related Question