5

Goal

I am attempting to redefine an existing command (\mintedinline) which takes a verbatim argument. I need to format this argument such that it can be passed to an outside program for processing; this requires some minor string substitution to ensure that some characters such as double quotes are properly escaped. For the substitution, I am using the xstring package.

Problem

I have discovered that the \StrSubstitute{}{}{}[] command provided by xstring does not seem to work with verbatim arguments in general, not just in my particular use case. I suspect that this is do to the verbatim text being tokenized differently/completely detokenized, but I am not enough of a LaTeXpert to fully understand the inner workings of verbatim arguments.

Minimum Working Example

\documentclass{article}
\usepackage{xstring}

% How the command needs to be formatted for my purposes
\NewDocumentCommand{\mwecmdactual}{v}{
    \StrSubstitute{#1}{a}{c}[\tmp]
    \tmp
}

% A test case showing the expected output using a mandatory argument instead of a verbatim one
\NewDocumentCommand{\mwecmdexpect}{m}{
    \StrSubstitute{#1}{a}{c}[\tmp]
    \tmp
}

\begin{document}

    Result of \verb+\mwecmdactual|abcde|+: \mwecmdactual|abcde|

    Result of \verb+\mwecmdexpect{abcde}+: \mwecmdexpect{abcde}

\end{document}

Results

The above MWE was compiled with pdflatex, and a screenshot of the output was taken:

A screenshot showing that the verbatim argument is no substituted while the normal argument is

The screenshot clearly shows the failure of \StrSubstitute to perform the substitution when it is given a verbatim argument from an encompassing command.

Request for Help

I am unfortunately bound to using the verbatim argument as I am ultimately redefining a preexisting command. Thus, any solution would need to use the verbatim argument as it is provided via the \mwecmdactual|| (in reality the \mintedinline[]{}||) command.

2 Answers 2

4

Try doing it like this:

\documentclass{article}
\usepackage{xstring}

% Redefine the command to handle verbatim arguments
\NewDocumentCommand{\mwecmdactual}{v}{%
    % Detokenize the verbatim input to ensure consistent catcodes
    \edef\tmp{\detokenize{#1}}%
    % Perform substitution with detokenized patterns
    \StrSubstitute{\tmp}{\detokenize{a}}{\detokenize{c}}[\result]%
    \result% Output the result
}

% Test command for comparison
\NewDocumentCommand{\mwecmdexpect}{m}{%
    \StrSubstitute{#1}{a}{c}[\tmp]%
    \tmp%
}

\begin{document}

    Result of \verb+\mwecmdactual|abcde|+: \mwecmdactual|abcde|
    
    Result of \verb+\mwecmdexpect{abcde}+: \mwecmdexpect{abcde}

\end{document}
1
  • This seems to have worked perfectly for both my MWE and my actual use case. Thanks! Commented Mar 22 at 14:53
4

You don't need xstring. The regular expression replacements provided in the LaTeX kernel suffice and they're category code agnostic.

\documentclass{article}
\usepackage{xstring} % for the check

% How the command needs to be formatted for my purposes
\ExplSyntaxOn
\NewDocumentCommand{\mwecmdactual}{v}
 {
  \tl_set:Nn \l_tmpa_tl {#1}
  \regex_replace_all:nnN {a}{c} \l_tmpa_tl
  \tl_use:N \l_tmpa_tl
 }
\ExplSyntaxOff

% A test case showing the expected output using a mandatory argument instead of a verbatim one
\NewDocumentCommand{\mwecmdexpect}{m}{%
    \StrSubstitute{#1}{a}{c}[\tmp]%
    \tmp
}

\begin{document}

Result of \verb+\mwecmdactual|abcde|+: \mwecmdactual|abcde|

Result of \verb+\mwecmdexpect{abcde}+: \mwecmdexpect{abcde}

\end{document}

output

More details are needed about the actual replacements you need to do.

1
  • 1
    Hi! Thanks for your answer. I am tempted to change the accepted answer to this one as it does provide a far more robust regex experience. However, the expl3 syntax may as well have been ancient Sumerian for as well as I could understand it before finding some introduction and full reference for it. I would suggest adding some links to the relevant docs as the expl3 layer is (at first) esoteric, even by TeX standards. Commented Mar 23 at 9:58

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.