2

I'm trying to implement \luaescapestring in plain e-TeX. My solution needs to be fully expandable, so that \immediate\write\luascript{ local file = "\luaescapestring{\something}" } works. The following code is almost there, but it consumes space characters:

\def\luaescapestring#1{%
  \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
  \expandafter\next\expandafter\expandafter\expandafter\gobbleone
  \expandafter\detokenize\expandafter{\csname#1\endcsname}\relax}%
\def\gobbleone#1{}%
\begingroup
  \catcode`\"=12%
  \catcode`\|=0%
  \catcode`\\=12%
  |gdef|next#1{%
    |if#1|relax|else
      |if#1"%
        \"|expandafter|expandafter|expandafter
          |next
      |else
        |if#1\%
          \\|expandafter|expandafter|expandafter|expandafter
            |expandafter|expandafter|expandafter|next
        |else
          #1|expandafter|expandafter|expandafter|expandafter
            |expandafter|expandafter|expandafter|next
        |fi
      |fi
    |fi}%
|endgroup

A code similar to the one used in the letterspacing.tex package takes into account the spaces, but \futurelet spoils the party.

  • 2
    I don't get what you are trying to do. The luatex format enables all the extra primitives of LuaTeX on loading, so \luaescapestring is already there. – Henri Menke May 31 '16 at 10:57
  • 1
    Indeed, I'm trying to implement a similar macro outside luatex. – Witiko May 31 '16 at 11:00
4

I used OPmac trick 0153, so I needed to define the \eapply macro only:

\def\tmp#1{}\edef\nb{\expandafter\tmp\string\\}  % \nb is normal backslash

\def\luaescapestring#1{\etoksA #1{\end}}
\def\etoksA#1#{\etokssB#1 {\end} }
\def\etokssB#1 #2 {\etoksC#1\end 
    \ifx\end#2\empty\expandafter\etoksD\else\space\fihere{\etokssB#2 }\fi}
\def\etoksC#1{\ifx\end#1\else\eapply{#1}\expandafter\etoksC\fi}
\def\etoksD#1{\ifx\end#1\empty\else\fihere{{\luaescapestring{#1}}\etoksA}\fi}
\def\fihere#1\fi{\fi#1}

\def\eapply#1{\ifx"#1\nb"\else\bbstring#1\fi}
\def\bbstring#1{\expandafter\bbstringA\string#1}
\def\bbstringA#1{\expandafter\ifx\nb#1\nb\fi#1}

%test:
\message{...\luaescapestring{"a"\ hah ah \a}}

\end

The \message command expands its parameter and prints ...\"a\"\\ hah ah \\a in our example.

Note that you need not any special eTeX primitive. All is done by classical TeX.

  • That is a neat and useful trick. With your permission, I am going to use it in ctan.org/pkg/markdown to perform the escaping of strings (after I have dissected and fully understood it). – Witiko Jun 10 '16 at 20:19
  • I think you meant: \def\etoksD#1{\ifx\end#1\empty\else\fihere{{\etoksA #1{\end}}\etoksA}\fi} ? – David Carlisle Jun 10 '16 at 20:32
  • @DavidCarlisle Than you, I corrected it. – wipet Jun 10 '16 at 23:02
  • @Witiko Of course, you can use this. But keep in the mind some limitations. The tokenized string is processed. If the token is \foo then we don't know if we have to put a space after it or no. My implementation says no. So, \foo1 or \foo 1 (both inputs are tokenized to the same token list, so it is undistinguishable by TeX) is converted to \\foo1. Second problem: I didn't solve that \\ must converted to \\\\. I leave this as an exercise. – wipet Jun 10 '16 at 23:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.