11

I would like to replace every backslash \ inside a macro (string) with a forwardslash /.

The macro is intended to contain a filename in Windows notation which should be replaced by a valid (La)TeX compatible filename. I know that it is preferable to process such strings before using them in a source file, but: is it possible to do it with (La)TeX?

My MWE is:

\documentclass{article}
\usepackage{etoolbox}

% The following macro is a placeholder.
% It should replace '\' by '/'
% #1: input
% #2: output
\newcommand{\replaceBS}[2]{%
  \edef\x{\noexpand\edef\noexpand#2{\noexpand\detokenize{\expandonce#1}}}%
  \x%
}

\begin{document}

\def\WindowsFilename{c:\files\examples\pictures\myfile.png}

\replaceBS{\WindowsFilename}{\TeXFilename}

Current result: \texttt{\TeXFilename}

Expected result: \texttt{c:/files/examples/pictures/myfile.png}

\end{document}

A solution for \replaceBS should be compilable with pdflatex.

I've tried things with the xstring package so far without success. Any solution with TeX, LaTeX3, special packages,... is welcome.

And just to be sure: Yes, I know how to do a replacement with an editor or an external tool ;-)

  • I think, xstring will also help – user31729 Nov 24 '14 at 17:40
  • Why do you want to replace the string? Wouldn't it be enough if it hadn't catcode 0? – Ulrike Fischer Nov 24 '14 at 17:40
  • @UlrikeFischer I want to use the resulting string to include an image to the document. – Thomas F. Sturm Nov 24 '14 at 17:57
  • @ChristianHupfer I could'nt figure out how. But David came up with a very short and nice TeX solution. – Thomas F. Sturm Nov 24 '14 at 17:58
12
\documentclass{article}

\makeatletter
\newcommand{\replaceBS}[2]{{\escapechar=`/ 
  \xdef#2{\expandafter\zap@space\detokenize\expandafter{#1} \@empty}}}
\makeatother

\begin{document}

\def\WindowsFilename{c:\files\examples\pictures\myfile.png}

\replaceBS{\WindowsFilename}{\TeXFilename}

Current result: \texttt{\TeXFilename}

Expected result: \texttt{c:/files/examples/pictures/myfile.png}

\end{document}
  • Yes, that's it! I just tested successfully that the resulting \TeXFilename can be used to include images (or whatever). Thank you: that was fast :-) – Thomas F. Sturm Nov 24 '14 at 17:49
  • @ThomasF.Sturm I'm fairly sure that for that use you wouldn't have to change \ to / just detokenize it. – David Carlisle Nov 24 '14 at 17:51
  • Hmm... maybe, but that resulted in errors because detokenizing inserted spaces and the file could not be found. – Thomas F. Sturm Nov 24 '14 at 17:56
  • 1
    Spaces in the path will be zapped as well, but they shouldn't be used anyway. – egreg Nov 24 '14 at 18:38
  • @egreg yes there's a hint in the \zap@space command name:-) – David Carlisle Nov 24 '14 at 19:25
5

As far as I know, both MiKTeX and TeX Live for Windows accept paths where \ is replaced by /, so if you define your \WindowsFilename as

c:/files/examples/pictures/myfile.png

to begin with, you shouldn't have any problem.

However, I understand that the casual user might not know this and be used to DOS style paths.

If you don't plan to define the paths in the argument to other commands, you can use some expl3 features:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\setWindowsPath}{mv}
 {
  \cs_new:Npn #1 { #2 }
 }
\NewDocumentCommand{\replaceBS}{mm}
 {
  \tl_set_eq:NN #2 #1
  \tl_replace_all:NVn #2 \c_backslash_other_tl { / }
 }
\tl_const:Nx \c_backslash_other_tl { \cs_to_str:N \\ }
\cs_generate_variant:Nn \tl_replace_all:Nnn { NV }
\ExplSyntaxOff

\setWindowsPath{\WindowsFilename}{c:\files\examples\pictures\myfile.png}

\replaceBS{\WindowsFilename}{\TeXFilename}

\show\WindowsFilename
\show\TeXFilename

\setWindowsPath{\WindowsFilenameS}{c:\files\example spaced\pictures\myfile.png}

\replaceBS{\WindowsFilenameS}{\TeXFilenameS}

\show\WindowsFilenameS
\show\TeXFilenameS

Note that this preserves spaces in paths. Note also that the backslashes in the Windows filenames have been “neutralized”, because they have category code 12.

> \WindowsFilename=\long macro:
->c:\files\examples\pictures\myfile.png.
l.22 \show\WindowsFilename

? 
> \TeXFilename=macro:
->c:/files/examples/pictures/myfile.png.
l.23 \show\TeXFilename

? 
> \WindowsFilenameS=\long macro:
->c:\files\example spaced\pictures\myfile.png.
l.29 \show\WindowsFilenameS

? 
> \TeXFilenameS=macro:
->c:/files/example spaced/pictures/myfile.png.
l.30 \show\TeXFilenameS
  • +1 Thank you for that answer which preserves spaces (and umlauts as I have tested). The intended use is for some Windows-generated data which may not be able to be filtered before input. Unfortunately, this would need the replacement to be inside another macros argument. Further, \WindowsFilename would have to be re-used many times which is not possible with the current code. – Thomas F. Sturm Nov 25 '14 at 12:10
  • I will investigate if I can do the replacement somehow automatically before LaTeX comes into play. – Thomas F. Sturm Nov 25 '14 at 12: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.