8

I have a ConTeXt document containing many special characters. I have followed the instructions at Which symbols need to be escaped in ConTeXt? to ensure they can all display properly in the document, however, as most of my text is processed by Lua, I found some problems. When \# appears in the document, because I want the symbol "#" to be displayed, Lua cannot compile. Also, when double quotes appear in the document, e.g. ", Lua cannot compile.

  • How can I get these symbols to be displayed in ConTeXt when used with Lua?
  • What other special characters need special treatment when used with Lua?

Update:

Here is some example code:

\define[2]\showtext{%
    \startlua
        if #1 < 2 then
            context("#2")
        end
    \stoplua%
}

\starttext
    \showtext{1}{This is text \#1.}
\stoptext
0

2 Answers 2

8

As @rdhs mentioned in his comment, you can use [[...]] for Lua strings. ConTeXt provides \!!bs ... \!!es macros that map to [===[ ... ]===] (this way your string can have literal [[ as well). So, the easiest way to define such a macro is:

\unprotect
\define[2]\showtext
  {\startlua
        if #1 < 2 then
            context(\!!bs#2\!!es)
        end
    \stoplua}
\protect

Another option is to use commands.doif series of Lua functions, which follow the same syntax as \doif series of ConTeXt macros:

\define[1]\showtext{\ctxcommand{doif(#1 < 2)}}

The latter has the advantage of being slightly faster (#2 is not scanned) and slightly more robust, e.g.,

\showtext {5}{\undefined}

works with the second definition but not the first.

10

There are at least two approaches here, but both relate to the way that TeX and Lua interact with respect to category code (see Can the Lua part of LuaTeX know about tokens? for more on this). What is happening is that \# escapes the # when TeX transfers the input to Lua, but when Lua transfers the result back to TeX you just have # with category code 6.

The first solution is to include an additional \ in the input, which itself will need to be escaped

\define[2]\showtext{%
    \startlua
        if #1 < 2 then
            context("#2")
        end
    \stoplua%
}
\starttext
    \showtext{1}{This is text \\\#1.}
\stoptext

This means that Lua receives the input This is text \#1. from TeX, which with normal category codes will be parse by TeX as you want.

The alternative is to deliberately transfer to TeX with safe category codes using the optional argument to tex.print:

\define[2]\showtext{%
    \startlua
        if #1 < 2 then
            tex.print(-2, "#2")
        end
    \stoplua%
}
\starttext
    \showtext{1}{This is text \#1.}
\stoptext

This works as the optional argument for tex.print sets the category code table used to transfer the tokens back to TeX, and table -2 is the 'detokenized' table.

Which solution is most appropriate will depend on your use case. For example, if you want other TeX category codes to apply in the input (say a protected macro can be present) then the first is best, but if you just want the text then the second is better as it keeps the TeX input clearer.

2
  • 5
    One other alternative is to call context() as context([[#2]]). This way, Lua doesn't assign any special meaning to \ so you can use arbitrary TeX control sequences.
    – Chel
    Apr 2, 2012 at 7:00
  • 1
    @rdhs I did say 'at least two'. You could add your approach as an answer, or if you prefer I can edit it into mine.
    – Joseph Wright
    Apr 2, 2012 at 7:22

You must log in to answer this question.

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