Passing arguments from TeX to a Lua functionLuaLaTeX set a path in luaCannot access arguments in a lua blockPrint large macro block from Lua to TeXDoes Lua(La)TeX use external lua or built in?Accessing MySQL or SQLite from Lua(La)TeXPass macro to be parsed by lua function in directluaPrint TeX PDF page with luaPassing LaTeX blocks to LuaPassing arguments to LuaLaTeX with LuaSQLLuaTeX: Call a Lua function with two optional argumentsConTeXt passing current counter value to lua

Count rotary dial pulses in a phone number (including letters)

A steel cutting sword?

Simple fuzz pedal using breadboard

Using credit/debit card details vs swiping a card in a payment (credit card) terminal

Ticket to ride, 1910: What are the big cities

Defining the standard model of PA so that a space alien could understand

What kind of metaphor is "trees in the wind"?

What is the object moving across the ceiling in this stock footage?

how to grep in the output of ls -a

Why does Mjolnir fall down in Age of Ultron but not in Endgame?

Where have Brexit voters gone?

Simple function that simulates survey results based on sample size and probability

Line of lights moving in a straight line , with a few following

Is the field of q-series 'dead'?

How should I introduce map drawing to my players?

Writing with dry erase marker on Shabbos, is it permitted?

Why colon to denote that a value belongs to a type?

Employer demanding to see degree after poor code review

How strong are Wi-Fi signals?

What is quasi-aromaticity?

How to pull out the underlying query syntax being used by dataset?

Flying domestically in the US, is my State Issued ID all I need to get past security?

Why aren't space telescopes put in GEO?

Computing the matrix powers of a non-diagonalizable matrix



Passing arguments from TeX to a Lua function


LuaLaTeX set a path in luaCannot access arguments in a lua blockPrint large macro block from Lua to TeXDoes Lua(La)TeX use external lua or built in?Accessing MySQL or SQLite from Lua(La)TeXPass macro to be parsed by lua function in directluaPrint TeX PDF page with luaPassing LaTeX blocks to LuaPassing arguments to LuaLaTeX with LuaSQLLuaTeX: Call a Lua function with two optional argumentsConTeXt passing current counter value to lua













3















The following code is a simple example of passing arguments from TeX to Lua. Just passing the arguments directly (the version without luastringN) gives an error.



(./luafunction.aux)./luafunction.lua:2: attempt to concatenate local 's' (a nil value)
stack traceback:
./luafunction.lua:2: in function 'joinstring'
[directlua]:1: in main chunk.
joinstring #1#2-> directlua joinstring(#1, #2)

l.19 joinstringfoobar


I noticed that other code used the macro luastringN when passing arguments from TeX to Lua, so I did too. But this is completely Cargo Cult programming, because I have no idea why. The docunentation in the luacode manual isn't very enlightening. On section 1.2 on page 3 of the v1.2a manual where luastringN is documented, it talks about escaping special characters. But there are no special characters in my example. And I don't understand what special handling is required to pass from TeX to Lua. Explanations appreciated - feel free to dumb it down.



Additionally, this answer to the question "LuaLaTeX set a path in lua" mentioned that one should use token.get_macro instead. The documentation on pg 10.6.4 of the luatex v 1.10 manual says:




The get_macro function can be used to get the content of a macro




but I'm not sure what that means. Also, I did a search in TeX SE for token.get_macro, and got two hits.



So is that a better choice, and if so, why? And what does the get_macro function do, exactly?



documentclassarticle
usepackageluacode
usepackagefilecontents
beginfilecontents*luafunction2.lua
function joinstring (s, t)
tex.sprint(s .. t)
end

endfilecontents*
directluarequire "luafunction2.lua"
begindocument

newcommandjoinstring[2]

% directluajoinstring(#1, #2)
directluajoinstring(luastringN#1, luastringN#2)


joinstringfoobar

enddocument


Chat room discussion starts around here










share|improve this question
























  • your example runs without error in texlive 2019

    – David Carlisle
    11 hours ago











  • If all you are wondering about is how a TeX argument #1 or whatever should be passed to Lua, you are overthinking things: is that the core question?

    – Joseph Wright
    11 hours ago






  • 1





    @DavidCarlisle The version without luastringN gives the error. I'll edit to clarify.

    – Faheem Mitha
    11 hours ago











  • @JosephWright That's one of my questions, yes. I ask several related ones here. Why is that "overthinking"?

    – Faheem Mitha
    11 hours ago












  • @FaheemMitha Well for example get_macro is in an entirely different area

    – Joseph Wright
    11 hours ago















3















The following code is a simple example of passing arguments from TeX to Lua. Just passing the arguments directly (the version without luastringN) gives an error.



(./luafunction.aux)./luafunction.lua:2: attempt to concatenate local 's' (a nil value)
stack traceback:
./luafunction.lua:2: in function 'joinstring'
[directlua]:1: in main chunk.
joinstring #1#2-> directlua joinstring(#1, #2)

l.19 joinstringfoobar


I noticed that other code used the macro luastringN when passing arguments from TeX to Lua, so I did too. But this is completely Cargo Cult programming, because I have no idea why. The docunentation in the luacode manual isn't very enlightening. On section 1.2 on page 3 of the v1.2a manual where luastringN is documented, it talks about escaping special characters. But there are no special characters in my example. And I don't understand what special handling is required to pass from TeX to Lua. Explanations appreciated - feel free to dumb it down.



Additionally, this answer to the question "LuaLaTeX set a path in lua" mentioned that one should use token.get_macro instead. The documentation on pg 10.6.4 of the luatex v 1.10 manual says:




The get_macro function can be used to get the content of a macro




but I'm not sure what that means. Also, I did a search in TeX SE for token.get_macro, and got two hits.



So is that a better choice, and if so, why? And what does the get_macro function do, exactly?



documentclassarticle
usepackageluacode
usepackagefilecontents
beginfilecontents*luafunction2.lua
function joinstring (s, t)
tex.sprint(s .. t)
end

endfilecontents*
directluarequire "luafunction2.lua"
begindocument

newcommandjoinstring[2]

% directluajoinstring(#1, #2)
directluajoinstring(luastringN#1, luastringN#2)


joinstringfoobar

enddocument


Chat room discussion starts around here










share|improve this question
























  • your example runs without error in texlive 2019

    – David Carlisle
    11 hours ago











  • If all you are wondering about is how a TeX argument #1 or whatever should be passed to Lua, you are overthinking things: is that the core question?

    – Joseph Wright
    11 hours ago






  • 1





    @DavidCarlisle The version without luastringN gives the error. I'll edit to clarify.

    – Faheem Mitha
    11 hours ago











  • @JosephWright That's one of my questions, yes. I ask several related ones here. Why is that "overthinking"?

    – Faheem Mitha
    11 hours ago












  • @FaheemMitha Well for example get_macro is in an entirely different area

    – Joseph Wright
    11 hours ago













3












3








3








The following code is a simple example of passing arguments from TeX to Lua. Just passing the arguments directly (the version without luastringN) gives an error.



(./luafunction.aux)./luafunction.lua:2: attempt to concatenate local 's' (a nil value)
stack traceback:
./luafunction.lua:2: in function 'joinstring'
[directlua]:1: in main chunk.
joinstring #1#2-> directlua joinstring(#1, #2)

l.19 joinstringfoobar


I noticed that other code used the macro luastringN when passing arguments from TeX to Lua, so I did too. But this is completely Cargo Cult programming, because I have no idea why. The docunentation in the luacode manual isn't very enlightening. On section 1.2 on page 3 of the v1.2a manual where luastringN is documented, it talks about escaping special characters. But there are no special characters in my example. And I don't understand what special handling is required to pass from TeX to Lua. Explanations appreciated - feel free to dumb it down.



Additionally, this answer to the question "LuaLaTeX set a path in lua" mentioned that one should use token.get_macro instead. The documentation on pg 10.6.4 of the luatex v 1.10 manual says:




The get_macro function can be used to get the content of a macro




but I'm not sure what that means. Also, I did a search in TeX SE for token.get_macro, and got two hits.



So is that a better choice, and if so, why? And what does the get_macro function do, exactly?



documentclassarticle
usepackageluacode
usepackagefilecontents
beginfilecontents*luafunction2.lua
function joinstring (s, t)
tex.sprint(s .. t)
end

endfilecontents*
directluarequire "luafunction2.lua"
begindocument

newcommandjoinstring[2]

% directluajoinstring(#1, #2)
directluajoinstring(luastringN#1, luastringN#2)


joinstringfoobar

enddocument


Chat room discussion starts around here










share|improve this question
















The following code is a simple example of passing arguments from TeX to Lua. Just passing the arguments directly (the version without luastringN) gives an error.



(./luafunction.aux)./luafunction.lua:2: attempt to concatenate local 's' (a nil value)
stack traceback:
./luafunction.lua:2: in function 'joinstring'
[directlua]:1: in main chunk.
joinstring #1#2-> directlua joinstring(#1, #2)

l.19 joinstringfoobar


I noticed that other code used the macro luastringN when passing arguments from TeX to Lua, so I did too. But this is completely Cargo Cult programming, because I have no idea why. The docunentation in the luacode manual isn't very enlightening. On section 1.2 on page 3 of the v1.2a manual where luastringN is documented, it talks about escaping special characters. But there are no special characters in my example. And I don't understand what special handling is required to pass from TeX to Lua. Explanations appreciated - feel free to dumb it down.



Additionally, this answer to the question "LuaLaTeX set a path in lua" mentioned that one should use token.get_macro instead. The documentation on pg 10.6.4 of the luatex v 1.10 manual says:




The get_macro function can be used to get the content of a macro




but I'm not sure what that means. Also, I did a search in TeX SE for token.get_macro, and got two hits.



So is that a better choice, and if so, why? And what does the get_macro function do, exactly?



documentclassarticle
usepackageluacode
usepackagefilecontents
beginfilecontents*luafunction2.lua
function joinstring (s, t)
tex.sprint(s .. t)
end

endfilecontents*
directluarequire "luafunction2.lua"
begindocument

newcommandjoinstring[2]

% directluajoinstring(#1, #2)
directluajoinstring(luastringN#1, luastringN#2)


joinstringfoobar

enddocument


Chat room discussion starts around here







luatex






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 11 hours ago







Faheem Mitha

















asked 12 hours ago









Faheem MithaFaheem Mitha

3,39854064




3,39854064












  • your example runs without error in texlive 2019

    – David Carlisle
    11 hours ago











  • If all you are wondering about is how a TeX argument #1 or whatever should be passed to Lua, you are overthinking things: is that the core question?

    – Joseph Wright
    11 hours ago






  • 1





    @DavidCarlisle The version without luastringN gives the error. I'll edit to clarify.

    – Faheem Mitha
    11 hours ago











  • @JosephWright That's one of my questions, yes. I ask several related ones here. Why is that "overthinking"?

    – Faheem Mitha
    11 hours ago












  • @FaheemMitha Well for example get_macro is in an entirely different area

    – Joseph Wright
    11 hours ago

















  • your example runs without error in texlive 2019

    – David Carlisle
    11 hours ago











  • If all you are wondering about is how a TeX argument #1 or whatever should be passed to Lua, you are overthinking things: is that the core question?

    – Joseph Wright
    11 hours ago






  • 1





    @DavidCarlisle The version without luastringN gives the error. I'll edit to clarify.

    – Faheem Mitha
    11 hours ago











  • @JosephWright That's one of my questions, yes. I ask several related ones here. Why is that "overthinking"?

    – Faheem Mitha
    11 hours ago












  • @FaheemMitha Well for example get_macro is in an entirely different area

    – Joseph Wright
    11 hours ago
















your example runs without error in texlive 2019

– David Carlisle
11 hours ago





your example runs without error in texlive 2019

– David Carlisle
11 hours ago













If all you are wondering about is how a TeX argument #1 or whatever should be passed to Lua, you are overthinking things: is that the core question?

– Joseph Wright
11 hours ago





If all you are wondering about is how a TeX argument #1 or whatever should be passed to Lua, you are overthinking things: is that the core question?

– Joseph Wright
11 hours ago




1




1





@DavidCarlisle The version without luastringN gives the error. I'll edit to clarify.

– Faheem Mitha
11 hours ago





@DavidCarlisle The version without luastringN gives the error. I'll edit to clarify.

– Faheem Mitha
11 hours ago













@JosephWright That's one of my questions, yes. I ask several related ones here. Why is that "overthinking"?

– Faheem Mitha
11 hours ago






@JosephWright That's one of my questions, yes. I ask several related ones here. Why is that "overthinking"?

– Faheem Mitha
11 hours ago














@FaheemMitha Well for example get_macro is in an entirely different area

– Joseph Wright
11 hours ago





@FaheemMitha Well for example get_macro is in an entirely different area

– Joseph Wright
11 hours ago










3 Answers
3






active

oldest

votes


















3














All that luastringN does here is provide a wrapper for luaescapestring plus a few wrinkles. I'd just write that out, at least for a 'practice' file



documentclassarticle
usepackagefilecontents
beginfilecontents*luafunction2.lua
function joinstring (s, t)
tex.sprint(s .. t)
end
endfilecontents*
directluarequire "luafunction2.lua"
begindocument

newcommandjoinstring[2]
%
directluajoinstring(
"luaescapestringunexpanded#1",
"luaescapestringunexpanded#2")
%


joinstringfoobar

enddocument


Notice that luaescapestring carries out (e-type) expansion, so we need unexpanded to avoid strange stuff happening. Also notice the " characters, which are needed to tell Lua we are passing a string. We don't have to worry about any " in the TeX input as luaescapestring makes them safe.






share|improve this answer






























    2














    Since the Lua function tex.sprint expects to operate on strings (either string constants, variables of type string, or something that can be coerced into type string on the fly), defining the LaTeX-side macro as



    newcommandjoinstring[2]directluajoinstring(#1,#2)


    and then running



    joinstringfoobar


    is incorrect, because foo and bar are not automatically converted into what Lua recognizes as strings. Indeed, the error message you reproduced shows that Lua considers foo and bar to be of type nil. Variables of type nil are definitely going to trip up the string concatenation operation .. in the tex.sprint ( s .. t ) instruction.



    The two obvious remedies are




    1. Place explicit quotation marks around the arguments of joinstring, i.e., run



      joinstring"foo""bar"



    2. define the LaTeX macro as



      newcommandjoinstring[2]directluajoinstring("#1","#2")


      I suppose that one could say that luastring#1 and especially luastringN#1 are elaborations (say, to prohibit expansion of #1) of the "#1" approach. They are also more robust in the sense that they can handle unbalanced (single and double) quote marks in their arguments; unbalanced double-quote marks is something that would trip up the "#1" approach.




    A full MWE that implements the second idea -- notice that for the simple code at hand it's not necessary to load the luacode package:



    enter image description here



    documentclassarticle
    directluafunction joinstring (s,t) tex.sprint (s..t) end
    newcommandjoinstring[2]directluajoinstring("#1","#2")
    begindocument
    joinstringfoobar
    enddocument





    share|improve this answer




















    • 1





      Let us continue this discussion in chat.

      – Joseph Wright
      10 hours ago


















    1














    As an alternative to the luaescapestring based solution in the other answers, you can also use the token library to pass arguments from TeX to Lua. This leads to minor speed improvements, because LuaTeX doesn't have to escape the string only for Lua to parse it again. So you might consider it especially when you expect long strings. Also this avoids mixing TeX and Lua code which can help if you later decide to use your code with luafunction (or luadef).



    Anyway, you first have to decide if you want (e-type) expansion or not. The token functions always expand the arguments, so you have to apply unexpanded if you do not want this. Then you can use token.scan_argument to read a argument that is given directly after the whole Lua code. If you decide to read an expanded argument, you can also handle the argument reading entirely through Lua, but then slightly different scanning rules apply. Especially in simple cases no braces are required around string arguments.



    Here are some examples to see the actual effects of the different options:



    documentclassarticle
    usepackageluacode
    usepackagefilecontents
    beginfilecontents*luafunction2.lua
    function joinstring (s, t)
    tex.write(s, ', ' , t, ': ')
    tex.sprint(s .. t .. '.')
    end
    endfilecontents*
    directluarequire "luafunction2.lua"
    begindocument

    newcommandjoinstring[2]
    directluajoinstring(token.scan_argument(), token.scan_argument())%
    unexpanded#1unexpanded#2


    newcommandexpandedjoinstring[2]

    directluajoinstring(token.scan_argument(), token.scan_argument())%
    #1#2%


    newcommandotherexpandedjoinstring

    directluajoinstring(token.scan_argument(), token.scan_argument())%


    newcommandfoofoo
    newcommandBarbar
    verb|joinstringfoobar|: joinstringfoobar\
    verb|joinstringfooBar|: joinstringfooBar\
    verb|joinstring foo bar|: joinstring foo bar\
    verb|expandedjoinstringfoobar|: expandedjoinstringfoobar\
    verb|expandedjoinstringfooBar|: expandedjoinstringfooBar\
    verb|expandedjoinstring foo bar|: expandedjoinstring foo bar\
    verb|otherexpandedjoinstringfoobar|: otherexpandedjoinstringfoobar\
    verb|otherexpandedjoinstringfooBar|: otherexpandedjoinstringfooBar\
    verb|otherexpandedjoinstring foo bar|: otherexpandedjoinstring foo bar\
    enddocument


    enter image description here






    share|improve this answer























      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "85"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f492630%2fpassing-arguments-from-tex-to-a-lua-function%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      3














      All that luastringN does here is provide a wrapper for luaescapestring plus a few wrinkles. I'd just write that out, at least for a 'practice' file



      documentclassarticle
      usepackagefilecontents
      beginfilecontents*luafunction2.lua
      function joinstring (s, t)
      tex.sprint(s .. t)
      end
      endfilecontents*
      directluarequire "luafunction2.lua"
      begindocument

      newcommandjoinstring[2]
      %
      directluajoinstring(
      "luaescapestringunexpanded#1",
      "luaescapestringunexpanded#2")
      %


      joinstringfoobar

      enddocument


      Notice that luaescapestring carries out (e-type) expansion, so we need unexpanded to avoid strange stuff happening. Also notice the " characters, which are needed to tell Lua we are passing a string. We don't have to worry about any " in the TeX input as luaescapestring makes them safe.






      share|improve this answer



























        3














        All that luastringN does here is provide a wrapper for luaescapestring plus a few wrinkles. I'd just write that out, at least for a 'practice' file



        documentclassarticle
        usepackagefilecontents
        beginfilecontents*luafunction2.lua
        function joinstring (s, t)
        tex.sprint(s .. t)
        end
        endfilecontents*
        directluarequire "luafunction2.lua"
        begindocument

        newcommandjoinstring[2]
        %
        directluajoinstring(
        "luaescapestringunexpanded#1",
        "luaescapestringunexpanded#2")
        %


        joinstringfoobar

        enddocument


        Notice that luaescapestring carries out (e-type) expansion, so we need unexpanded to avoid strange stuff happening. Also notice the " characters, which are needed to tell Lua we are passing a string. We don't have to worry about any " in the TeX input as luaescapestring makes them safe.






        share|improve this answer

























          3












          3








          3







          All that luastringN does here is provide a wrapper for luaescapestring plus a few wrinkles. I'd just write that out, at least for a 'practice' file



          documentclassarticle
          usepackagefilecontents
          beginfilecontents*luafunction2.lua
          function joinstring (s, t)
          tex.sprint(s .. t)
          end
          endfilecontents*
          directluarequire "luafunction2.lua"
          begindocument

          newcommandjoinstring[2]
          %
          directluajoinstring(
          "luaescapestringunexpanded#1",
          "luaescapestringunexpanded#2")
          %


          joinstringfoobar

          enddocument


          Notice that luaescapestring carries out (e-type) expansion, so we need unexpanded to avoid strange stuff happening. Also notice the " characters, which are needed to tell Lua we are passing a string. We don't have to worry about any " in the TeX input as luaescapestring makes them safe.






          share|improve this answer













          All that luastringN does here is provide a wrapper for luaescapestring plus a few wrinkles. I'd just write that out, at least for a 'practice' file



          documentclassarticle
          usepackagefilecontents
          beginfilecontents*luafunction2.lua
          function joinstring (s, t)
          tex.sprint(s .. t)
          end
          endfilecontents*
          directluarequire "luafunction2.lua"
          begindocument

          newcommandjoinstring[2]
          %
          directluajoinstring(
          "luaescapestringunexpanded#1",
          "luaescapestringunexpanded#2")
          %


          joinstringfoobar

          enddocument


          Notice that luaescapestring carries out (e-type) expansion, so we need unexpanded to avoid strange stuff happening. Also notice the " characters, which are needed to tell Lua we are passing a string. We don't have to worry about any " in the TeX input as luaescapestring makes them safe.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 11 hours ago









          Joseph WrightJoseph Wright

          207k23568897




          207k23568897





















              2














              Since the Lua function tex.sprint expects to operate on strings (either string constants, variables of type string, or something that can be coerced into type string on the fly), defining the LaTeX-side macro as



              newcommandjoinstring[2]directluajoinstring(#1,#2)


              and then running



              joinstringfoobar


              is incorrect, because foo and bar are not automatically converted into what Lua recognizes as strings. Indeed, the error message you reproduced shows that Lua considers foo and bar to be of type nil. Variables of type nil are definitely going to trip up the string concatenation operation .. in the tex.sprint ( s .. t ) instruction.



              The two obvious remedies are




              1. Place explicit quotation marks around the arguments of joinstring, i.e., run



                joinstring"foo""bar"



              2. define the LaTeX macro as



                newcommandjoinstring[2]directluajoinstring("#1","#2")


                I suppose that one could say that luastring#1 and especially luastringN#1 are elaborations (say, to prohibit expansion of #1) of the "#1" approach. They are also more robust in the sense that they can handle unbalanced (single and double) quote marks in their arguments; unbalanced double-quote marks is something that would trip up the "#1" approach.




              A full MWE that implements the second idea -- notice that for the simple code at hand it's not necessary to load the luacode package:



              enter image description here



              documentclassarticle
              directluafunction joinstring (s,t) tex.sprint (s..t) end
              newcommandjoinstring[2]directluajoinstring("#1","#2")
              begindocument
              joinstringfoobar
              enddocument





              share|improve this answer




















              • 1





                Let us continue this discussion in chat.

                – Joseph Wright
                10 hours ago















              2














              Since the Lua function tex.sprint expects to operate on strings (either string constants, variables of type string, or something that can be coerced into type string on the fly), defining the LaTeX-side macro as



              newcommandjoinstring[2]directluajoinstring(#1,#2)


              and then running



              joinstringfoobar


              is incorrect, because foo and bar are not automatically converted into what Lua recognizes as strings. Indeed, the error message you reproduced shows that Lua considers foo and bar to be of type nil. Variables of type nil are definitely going to trip up the string concatenation operation .. in the tex.sprint ( s .. t ) instruction.



              The two obvious remedies are




              1. Place explicit quotation marks around the arguments of joinstring, i.e., run



                joinstring"foo""bar"



              2. define the LaTeX macro as



                newcommandjoinstring[2]directluajoinstring("#1","#2")


                I suppose that one could say that luastring#1 and especially luastringN#1 are elaborations (say, to prohibit expansion of #1) of the "#1" approach. They are also more robust in the sense that they can handle unbalanced (single and double) quote marks in their arguments; unbalanced double-quote marks is something that would trip up the "#1" approach.




              A full MWE that implements the second idea -- notice that for the simple code at hand it's not necessary to load the luacode package:



              enter image description here



              documentclassarticle
              directluafunction joinstring (s,t) tex.sprint (s..t) end
              newcommandjoinstring[2]directluajoinstring("#1","#2")
              begindocument
              joinstringfoobar
              enddocument





              share|improve this answer




















              • 1





                Let us continue this discussion in chat.

                – Joseph Wright
                10 hours ago













              2












              2








              2







              Since the Lua function tex.sprint expects to operate on strings (either string constants, variables of type string, or something that can be coerced into type string on the fly), defining the LaTeX-side macro as



              newcommandjoinstring[2]directluajoinstring(#1,#2)


              and then running



              joinstringfoobar


              is incorrect, because foo and bar are not automatically converted into what Lua recognizes as strings. Indeed, the error message you reproduced shows that Lua considers foo and bar to be of type nil. Variables of type nil are definitely going to trip up the string concatenation operation .. in the tex.sprint ( s .. t ) instruction.



              The two obvious remedies are




              1. Place explicit quotation marks around the arguments of joinstring, i.e., run



                joinstring"foo""bar"



              2. define the LaTeX macro as



                newcommandjoinstring[2]directluajoinstring("#1","#2")


                I suppose that one could say that luastring#1 and especially luastringN#1 are elaborations (say, to prohibit expansion of #1) of the "#1" approach. They are also more robust in the sense that they can handle unbalanced (single and double) quote marks in their arguments; unbalanced double-quote marks is something that would trip up the "#1" approach.




              A full MWE that implements the second idea -- notice that for the simple code at hand it's not necessary to load the luacode package:



              enter image description here



              documentclassarticle
              directluafunction joinstring (s,t) tex.sprint (s..t) end
              newcommandjoinstring[2]directluajoinstring("#1","#2")
              begindocument
              joinstringfoobar
              enddocument





              share|improve this answer















              Since the Lua function tex.sprint expects to operate on strings (either string constants, variables of type string, or something that can be coerced into type string on the fly), defining the LaTeX-side macro as



              newcommandjoinstring[2]directluajoinstring(#1,#2)


              and then running



              joinstringfoobar


              is incorrect, because foo and bar are not automatically converted into what Lua recognizes as strings. Indeed, the error message you reproduced shows that Lua considers foo and bar to be of type nil. Variables of type nil are definitely going to trip up the string concatenation operation .. in the tex.sprint ( s .. t ) instruction.



              The two obvious remedies are




              1. Place explicit quotation marks around the arguments of joinstring, i.e., run



                joinstring"foo""bar"



              2. define the LaTeX macro as



                newcommandjoinstring[2]directluajoinstring("#1","#2")


                I suppose that one could say that luastring#1 and especially luastringN#1 are elaborations (say, to prohibit expansion of #1) of the "#1" approach. They are also more robust in the sense that they can handle unbalanced (single and double) quote marks in their arguments; unbalanced double-quote marks is something that would trip up the "#1" approach.




              A full MWE that implements the second idea -- notice that for the simple code at hand it's not necessary to load the luacode package:



              enter image description here



              documentclassarticle
              directluafunction joinstring (s,t) tex.sprint (s..t) end
              newcommandjoinstring[2]directluajoinstring("#1","#2")
              begindocument
              joinstringfoobar
              enddocument






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 9 hours ago

























              answered 11 hours ago









              MicoMico

              292k32402789




              292k32402789







              • 1





                Let us continue this discussion in chat.

                – Joseph Wright
                10 hours ago












              • 1





                Let us continue this discussion in chat.

                – Joseph Wright
                10 hours ago







              1




              1





              Let us continue this discussion in chat.

              – Joseph Wright
              10 hours ago





              Let us continue this discussion in chat.

              – Joseph Wright
              10 hours ago











              1














              As an alternative to the luaescapestring based solution in the other answers, you can also use the token library to pass arguments from TeX to Lua. This leads to minor speed improvements, because LuaTeX doesn't have to escape the string only for Lua to parse it again. So you might consider it especially when you expect long strings. Also this avoids mixing TeX and Lua code which can help if you later decide to use your code with luafunction (or luadef).



              Anyway, you first have to decide if you want (e-type) expansion or not. The token functions always expand the arguments, so you have to apply unexpanded if you do not want this. Then you can use token.scan_argument to read a argument that is given directly after the whole Lua code. If you decide to read an expanded argument, you can also handle the argument reading entirely through Lua, but then slightly different scanning rules apply. Especially in simple cases no braces are required around string arguments.



              Here are some examples to see the actual effects of the different options:



              documentclassarticle
              usepackageluacode
              usepackagefilecontents
              beginfilecontents*luafunction2.lua
              function joinstring (s, t)
              tex.write(s, ', ' , t, ': ')
              tex.sprint(s .. t .. '.')
              end
              endfilecontents*
              directluarequire "luafunction2.lua"
              begindocument

              newcommandjoinstring[2]
              directluajoinstring(token.scan_argument(), token.scan_argument())%
              unexpanded#1unexpanded#2


              newcommandexpandedjoinstring[2]

              directluajoinstring(token.scan_argument(), token.scan_argument())%
              #1#2%


              newcommandotherexpandedjoinstring

              directluajoinstring(token.scan_argument(), token.scan_argument())%


              newcommandfoofoo
              newcommandBarbar
              verb|joinstringfoobar|: joinstringfoobar\
              verb|joinstringfooBar|: joinstringfooBar\
              verb|joinstring foo bar|: joinstring foo bar\
              verb|expandedjoinstringfoobar|: expandedjoinstringfoobar\
              verb|expandedjoinstringfooBar|: expandedjoinstringfooBar\
              verb|expandedjoinstring foo bar|: expandedjoinstring foo bar\
              verb|otherexpandedjoinstringfoobar|: otherexpandedjoinstringfoobar\
              verb|otherexpandedjoinstringfooBar|: otherexpandedjoinstringfooBar\
              verb|otherexpandedjoinstring foo bar|: otherexpandedjoinstring foo bar\
              enddocument


              enter image description here






              share|improve this answer



























                1














                As an alternative to the luaescapestring based solution in the other answers, you can also use the token library to pass arguments from TeX to Lua. This leads to minor speed improvements, because LuaTeX doesn't have to escape the string only for Lua to parse it again. So you might consider it especially when you expect long strings. Also this avoids mixing TeX and Lua code which can help if you later decide to use your code with luafunction (or luadef).



                Anyway, you first have to decide if you want (e-type) expansion or not. The token functions always expand the arguments, so you have to apply unexpanded if you do not want this. Then you can use token.scan_argument to read a argument that is given directly after the whole Lua code. If you decide to read an expanded argument, you can also handle the argument reading entirely through Lua, but then slightly different scanning rules apply. Especially in simple cases no braces are required around string arguments.



                Here are some examples to see the actual effects of the different options:



                documentclassarticle
                usepackageluacode
                usepackagefilecontents
                beginfilecontents*luafunction2.lua
                function joinstring (s, t)
                tex.write(s, ', ' , t, ': ')
                tex.sprint(s .. t .. '.')
                end
                endfilecontents*
                directluarequire "luafunction2.lua"
                begindocument

                newcommandjoinstring[2]
                directluajoinstring(token.scan_argument(), token.scan_argument())%
                unexpanded#1unexpanded#2


                newcommandexpandedjoinstring[2]

                directluajoinstring(token.scan_argument(), token.scan_argument())%
                #1#2%


                newcommandotherexpandedjoinstring

                directluajoinstring(token.scan_argument(), token.scan_argument())%


                newcommandfoofoo
                newcommandBarbar
                verb|joinstringfoobar|: joinstringfoobar\
                verb|joinstringfooBar|: joinstringfooBar\
                verb|joinstring foo bar|: joinstring foo bar\
                verb|expandedjoinstringfoobar|: expandedjoinstringfoobar\
                verb|expandedjoinstringfooBar|: expandedjoinstringfooBar\
                verb|expandedjoinstring foo bar|: expandedjoinstring foo bar\
                verb|otherexpandedjoinstringfoobar|: otherexpandedjoinstringfoobar\
                verb|otherexpandedjoinstringfooBar|: otherexpandedjoinstringfooBar\
                verb|otherexpandedjoinstring foo bar|: otherexpandedjoinstring foo bar\
                enddocument


                enter image description here






                share|improve this answer

























                  1












                  1








                  1







                  As an alternative to the luaescapestring based solution in the other answers, you can also use the token library to pass arguments from TeX to Lua. This leads to minor speed improvements, because LuaTeX doesn't have to escape the string only for Lua to parse it again. So you might consider it especially when you expect long strings. Also this avoids mixing TeX and Lua code which can help if you later decide to use your code with luafunction (or luadef).



                  Anyway, you first have to decide if you want (e-type) expansion or not. The token functions always expand the arguments, so you have to apply unexpanded if you do not want this. Then you can use token.scan_argument to read a argument that is given directly after the whole Lua code. If you decide to read an expanded argument, you can also handle the argument reading entirely through Lua, but then slightly different scanning rules apply. Especially in simple cases no braces are required around string arguments.



                  Here are some examples to see the actual effects of the different options:



                  documentclassarticle
                  usepackageluacode
                  usepackagefilecontents
                  beginfilecontents*luafunction2.lua
                  function joinstring (s, t)
                  tex.write(s, ', ' , t, ': ')
                  tex.sprint(s .. t .. '.')
                  end
                  endfilecontents*
                  directluarequire "luafunction2.lua"
                  begindocument

                  newcommandjoinstring[2]
                  directluajoinstring(token.scan_argument(), token.scan_argument())%
                  unexpanded#1unexpanded#2


                  newcommandexpandedjoinstring[2]

                  directluajoinstring(token.scan_argument(), token.scan_argument())%
                  #1#2%


                  newcommandotherexpandedjoinstring

                  directluajoinstring(token.scan_argument(), token.scan_argument())%


                  newcommandfoofoo
                  newcommandBarbar
                  verb|joinstringfoobar|: joinstringfoobar\
                  verb|joinstringfooBar|: joinstringfooBar\
                  verb|joinstring foo bar|: joinstring foo bar\
                  verb|expandedjoinstringfoobar|: expandedjoinstringfoobar\
                  verb|expandedjoinstringfooBar|: expandedjoinstringfooBar\
                  verb|expandedjoinstring foo bar|: expandedjoinstring foo bar\
                  verb|otherexpandedjoinstringfoobar|: otherexpandedjoinstringfoobar\
                  verb|otherexpandedjoinstringfooBar|: otherexpandedjoinstringfooBar\
                  verb|otherexpandedjoinstring foo bar|: otherexpandedjoinstring foo bar\
                  enddocument


                  enter image description here






                  share|improve this answer













                  As an alternative to the luaescapestring based solution in the other answers, you can also use the token library to pass arguments from TeX to Lua. This leads to minor speed improvements, because LuaTeX doesn't have to escape the string only for Lua to parse it again. So you might consider it especially when you expect long strings. Also this avoids mixing TeX and Lua code which can help if you later decide to use your code with luafunction (or luadef).



                  Anyway, you first have to decide if you want (e-type) expansion or not. The token functions always expand the arguments, so you have to apply unexpanded if you do not want this. Then you can use token.scan_argument to read a argument that is given directly after the whole Lua code. If you decide to read an expanded argument, you can also handle the argument reading entirely through Lua, but then slightly different scanning rules apply. Especially in simple cases no braces are required around string arguments.



                  Here are some examples to see the actual effects of the different options:



                  documentclassarticle
                  usepackageluacode
                  usepackagefilecontents
                  beginfilecontents*luafunction2.lua
                  function joinstring (s, t)
                  tex.write(s, ', ' , t, ': ')
                  tex.sprint(s .. t .. '.')
                  end
                  endfilecontents*
                  directluarequire "luafunction2.lua"
                  begindocument

                  newcommandjoinstring[2]
                  directluajoinstring(token.scan_argument(), token.scan_argument())%
                  unexpanded#1unexpanded#2


                  newcommandexpandedjoinstring[2]

                  directluajoinstring(token.scan_argument(), token.scan_argument())%
                  #1#2%


                  newcommandotherexpandedjoinstring

                  directluajoinstring(token.scan_argument(), token.scan_argument())%


                  newcommandfoofoo
                  newcommandBarbar
                  verb|joinstringfoobar|: joinstringfoobar\
                  verb|joinstringfooBar|: joinstringfooBar\
                  verb|joinstring foo bar|: joinstring foo bar\
                  verb|expandedjoinstringfoobar|: expandedjoinstringfoobar\
                  verb|expandedjoinstringfooBar|: expandedjoinstringfooBar\
                  verb|expandedjoinstring foo bar|: expandedjoinstring foo bar\
                  verb|otherexpandedjoinstringfoobar|: otherexpandedjoinstringfoobar\
                  verb|otherexpandedjoinstringfooBar|: otherexpandedjoinstringfooBar\
                  verb|otherexpandedjoinstring foo bar|: otherexpandedjoinstring foo bar\
                  enddocument


                  enter image description here







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 4 hours ago









                  Marcel KrügerMarcel Krüger

                  13.2k11636




                  13.2k11636



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f492630%2fpassing-arguments-from-tex-to-a-lua-function%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                      Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                      Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її