I would like to use \immediate\write18 (encoded in the \OuputToFileA macro) to output a string containing a single quote. If I replace the single quote with another character, such as X
\StrSubstitute{\@CurrentString}{'}%
{X}% <---- Replace the single quote
[\@CurrentString]%
things work fine. But, I need the single quote in the output. Anything else I tried, such as escaping the single quote:
\StrSubstitute{\@CurrentString}{'}%
{\@backslashchar\@backslashchar'}% <---- Attempt to escape the single quote
[\@CurrentString]%
all result in an empty file.
Using \immediate\write (see \OuputToFileB macro) instead seems to work fine. How do I get this to work with \immediate\write18 instead?
Desired Output:
Afer pdflatex, the file foo.tex should contain
Notes:
- Do not run this if you have
foo.texin the current directory as that will be overwritten.
Code:
\documentclass{article}
\usepackage{xparse}
\usepackage{xstring}
\immediate\write18{printf "\n" > foo.tex }% Initialize File
\makeatletter
\NewDocumentCommand{\OuputToFileA}{%
m% string to output
}{%
Output A to pdf: #1
\def@CurrentString{#1}%
%% Using the first \StrSubstitute works. But, I don't want to replace the single quote
%\StrSubstitute{@CurrentString}{'}%
% {X}% <---- Replace the single quote
% [@CurrentString]%
\StrSubstitute{@CurrentString}{'}%
{@backslashchar@backslashchar'}% <---- Attempt to escape the single quote
[@CurrentString]%
%% ---------------------------------
\immediate\write18{printf 'string = "@CurrentString"' >> foo.tex }%
\immediate\write18{printf "\n" >> foo.tex }%
}
\NewDocumentCommand{\OuputToFileB}{%
m% string to output
}{%
Output B to pdf: #1
\def@CurrentString{#1}% No escaping required with \immediate
%% ---------------------------------
\newwrite\MyFile
\immediate\openout\MyFile=foo.tex
\immediate\write\MyFile{@CurrentString}%
\immediate\closeout\MyFile%
}
\makeatother
\begin{document}
\OuputToFileA{\detokenize{Einstein's Formula $E = mc^2$}}%
%\OuputToFileB{\detokenize{Einstein's Formula $E = mc^2$}}% <-- Works!
\end{document}

printf 'string = "Einstein'"'"'s Formula $E = mc^2$"\n'(see https://stackoverflow.com/a/1250279/6015190). The beautiful\StrSubstitute{\@CurrentString}{'}{'"'"'}[\@CurrentString]seems to work :) Or precede the whole single-quoted string with$and use sane escape sequences:printf $'string = "Einstein\'s Formula $E = mc^2$"\n'(https://stackoverflow.com/a/16605140/6015190) – Phelype Oleinik Jan 05 '22 at 18:58bashand shell escaping seems to usesh, so that won't work. I'll stop commenting now :-) – Phelype Oleinik Jan 05 '22 at 19:04{'"'"'}seems to work in the small test case. WIll test on my actual use case – Peter Grill Jan 05 '22 at 19:08$[\](https://tex.stackexchange.com/q/525424/250119) other – user202729 Jan 06 '22 at 08:33