2

I'm using \ifdefstring as part of a conditional definition which depends on an environment variable, as indicated in this question.

It works mostly fine, except that inside the blocks defined by \ifdefstring, if I have a \lstinline containing backslashes, I need to escape them, otherwise it won't work.

I'd like to be able to add \ifdefstring blocks without having to escape/unescape what's inside, especially because the error message is not very clear: missing backslashes lead to cryptic error messages at the end of the block. Is there a way to do so?

Here's an MVE, where in each case (both inside and outside the \ifdefstring) a single backslash must be printed.

\documentclass{article}
\usepackage{listings}
\usepackage{etoolbox}
% catchfile block copied from other question
\usepackage{catchfile}
\newcommand{\getenv}[2][]{%
  \CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{\endlinechar=-1\relax}%
  \if\relax\detokenize{#1}\relax\temp\else\edef#1{\temp}\fi}
\getenv[\VAR]{VAR}%

\begin{document}
\ifdefstring{\VAR}{yes}{
  \lstinline|\\must_be_escaped_yes|
}{
  \lstinline|\\must_be_escaped_not_yes|
}

\lstinline|\must_not_be_escaped|

\end{document}

The output (here, with VAR != yes) is:

MVE for ifdefstring with lstinline inside

But to make it parsable, I had to manually add the extra \ inside the \lstinline parts inside the \ifdefstring blocks, which I'd like to avoid.

3
  • Can you show examples of how and why VAR should be somehow escaped and what you mean by that?
    – egreg
    Nov 15, 2016 at 17:01
  • I tried to clarify the example. I do not want to escape VAR, I would like to have LaTeX code that is the same whether it is inside an \ifdefstring block or not.
    – anol
    Nov 15, 2016 at 18:13
  • You can't: \lstinline is a verbatim like command; it has features that allow putting it in the argument to a command, but you need some escapes, in this case.
    – egreg
    Nov 15, 2016 at 18:15

1 Answer 1

2

\lstinline is a bit different from other verbatim commands, so it can go in the argument to another command, but with limitations.

You can define an \else\fi form of \ifdefstring so you can use the unescaped version.

\documentclass{article}
\usepackage{listings}
\usepackage{etoolbox}
% catchfile block copied from other question
\usepackage{catchfile}
\newcommand{\getenv}[2][]{%
  \CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{\endlinechar=-1\relax}%
  \if\relax\detokenize{#1}\relax\temp\else\edef#1{\temp}\fi}

\newcommand{\defstring}[2]{%
  TT\fi
  \ifdefstring{#1}{#2}{\iftrue}{\iffalse}%
  \ignorespaces
}

\getenv[\VAR]{VAR}

\begin{document}
\if\defstring{\VAR}{yes}
  \lstinline|\must_be_escaped_yes|
\else
  \lstinline|\must_be_escaped_not_yes|
\fi

\lstinline|\must_not_be_escaped|

\end{document}

Output with VAR unset

enter image description here

Output with VAR set to yes

enter image description here

You must log in to answer this question.

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