0

How do I change the path separator from \ to / ?

enter image description here

I use MikteX on Windows.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[abspath]{currfile}

\begin{document}

Absolute directory: \texttt{\currfileabsdir}

Absolute path: \texttt{\currfileabspath}

\end{document}

Edit : I'm looking to use currfileabsdir in an \input{}.

JeT
  • 3,020
  • What's the issue here? Windows , as opposed to Linux & Co. does use backslashes in its paths, doesn't it? – Ingmar Jun 17 '22 at 07:33
  • @Ingmar right, I should edit my question. I need to reuse the \currfileabsdir to \input{\currfileabsdir-AnotherFile}. – JeT Jun 17 '22 at 07:36
  • 1
    Have you actually tried it? I am using Tex Live, which produces forward slashes in the first place (even on Windows), but \input{\currfileabsdir/../test.tex} worked fine. I seem to remember that MikTeX can use Unix style paths with slashes and doesn't require backslashes. – Ingmar Jun 17 '22 at 07:54
  • 2
    Otherwise there's always the option of using \str_replace:nnN or something like that. – user202729 Jun 17 '22 at 08:02
  • @Ingmar I tried it indeed. I get an error with backslash but none if I change manually the path with /. – JeT Jun 17 '22 at 08:09
  • 1
    How weird. The "default" one (backslash on Windows) doesn't work but / works? (even after taking the catcode into account here.) I don't have Windows though. Should look deeper...) – user202729 Jun 17 '22 at 08:12
  • @user202729 If I input the path (as displayed on my post image), I get indeed an error. As you can notice, it's \currfile/ for a reason I ignore, the last separator is a slash, the previous one is a backslash. – JeT Jun 17 '22 at 08:16
  • 1
    Looks like LaTeX does always use forward slash though. (collaboration - Paths and Linux/Windows slash conventions - TeX - LaTeX Stack Exchange) If the recorder file use backslash you have to stick with a str_replace, I guess. – user202729 Jun 17 '22 at 08:37
  • 1
    Alternatively there are some solutions in include - How to make the main file recognize relative paths used in the imported files? - TeX - LaTeX Stack Exchange (and possibly linked questions, I didn't read through them all) but they're not entirely satisfactory, I think. – user202729 Jun 17 '22 at 08:38
  • Section "Canonicalize separators" of https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats says: "All forward slashes (/) are converted into the standard Windows separator, the back slash ( \\ ). If they are present, a series of slashes that follow the first two slashes are collapsed into a single slash.", so a mixture of slashes and backslashes should be possible in many situations with recent Windows platforms. – Ulrich Diez Jun 17 '22 at 09:18
  • 1
    @Ingmar \input{\currfileabsdir/../test.tex} Seems \currfileabsdir already delivers a trailing (forward) slash, thus it should probably be \input{\currfileabsdir../test.tex}. – Ulrich Diez Jun 17 '22 at 09:32
  • 2
    Section "4 Absolute paths" of the manual of the package currfile says that the compiler-option -recorder is needed in order to have \currfileabsdir available via \jobname.fls and that with MiKTeX \jobname.fls always stems from the previous latex-run so that with MiKTeX during the first latex-run where \jobname.fls from a previous latex-run does not yet exist expansion of \currfileabsdir in any case yields emptiness. Could that be a reason for error-messages/problems? – Ulrich Diez Jun 17 '22 at 09:45
  • @UlrichDiez I use indeed the -recorder option – JeT Jun 17 '22 at 09:51
  • @JeT \input{\currfileabsdir-AnotherFile}: According to section "4 Absolute paths" of the manual of the package currfile, with MiKTeX during the first latex-run the expansion of \currfileabsdir is empty because info for \currfileabsdir is retrieved from a file \jobname.fls which under MiKTeX is not available for reading during the first latex-run. (With subsequent latex-runs the file stemming from previous latex-runs is available for reading.) So under MiKTeX during the 1st latex-run this is like \input{-AnotherFile}. Probably this circumstance is a source for problems. – Ulrich Diez Jun 17 '22 at 10:09
  • @UlrichDiez you have a cristal ball ? :) indeed, result is like \input{-AnotherFile}. – JeT Jun 17 '22 at 10:16
  • 1
    @Jet No. I just saw it in section 4 of the manual of the currfile package. :-) – Ulrich Diez Jun 17 '22 at 10:18
  • Okay, problem solved or so it seems. Remember to print debug in the same LaTeX run as the error, I guess. – user202729 Jun 17 '22 at 13:10

2 Answers2

2

Is this what you want?

\documentclass{article}
\begin{document}
\ExplSyntaxOn
\cs_set:Npn \path_set_format:n #1
{
  \str_set:Nn \l_tmpa_str{#1} % #1: path  
  old:~\str_use:N \l_tmpa_str\par 
  \regex_replace_all:nnN{\\}{/} \l_tmpa_str
  new:~\str_use:N \l_tmpa_str
}
\path_set_format:n{C:\User\username\Desktop\latex}
\ExplSyntaxOff
\end{document}

enter image description here

ljguo
  • 1,213
  • 1
  • 4
  • 12
  • Thanks for the update ! In the case of my inital question, i'll need to apply your code to \currfileabspath that is not expanded apparently. Would not it make sense to turn it into a newcommand ? lost in translation in latex3 :/ – JeT Jun 17 '22 at 08:59
  • 2
    Seems you have an additional space token behind each directory-name that is preceded by a backslash. The reason might be that \str_set internally uses \detokenize (whatever the expl3-name of \detokenize is) which appends spaces when detokenizing control word tokens while \User and \username and \Desktop and \latex are tokenized as control word tokens. Maybe this doesn't matter with the expansion of \currfileabsdir as - according to the manual of the package currfile - with the expansion of \currfileabsdir category of backslashes is 12(other). – Ulrich Diez Jun 17 '22 at 09:15
  • The input is most likely not these detokenized tokens though. – user202729 Jun 17 '22 at 13:08
2

If you wish to change the definition of a macro like \currfileabsdir so that explicit backslash-characters of category 12(other) are replaced by (forward) slash-characters of category 12(other), you can try something like this:

\documentclass{article}
\usepackage[abspath]{currfile}

\ExplSyntaxOn \cs_set:Npn \ReplaceBackslashesWithForwardSlashesInMacro #1 { \exp_args:Nno \use:n { \str_set:Nn \l_tmpa_str} {#1} \regex_replace_all:nnN{\}{/} \l_tmpa_str \exp_args:NnV \use:n {\cs_gset:Npn #1 } \l_tmpa_str } \ExplSyntaxOff

\begin{document}

Before patching \verb|\currfileabsdir|:

\texttt{\currfileabsdir}

\ReplaceBackslashesWithForwardSlashesInMacro{\currfileabsdir}

After patching \verb|\currfileabsdir|:

\texttt{\currfileabsdir}

\bigskip\hrule\bigskip

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Let's define some other macro whose expansion contains backslashes: \begingroup \catcode\/=0 \catcode\=12 /gdef/SomeMacroWithBackslashes{\home\knoppix\Desktop\Zu Sichern\LaTeX Code} /endgroup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Before patching \verb|\SomeMacroWithBackslashes|:

\texttt{\SomeMacroWithBackslashes}

\ReplaceBackslashesWithForwardSlashesInMacro{\SomeMacroWithBackslashes}

After patching \verb|\SomeMacroWithBackslashes|:

\texttt{\SomeMacroWithBackslashes}

\end{document}

enter image description here

You say you use MiKTeX on Windows - thus I doubt that the mixture of slashes and backslashes is the only source of your problems:

  1. Section "Canonicalize separators" of the Microsoft .NET article "File path formats on Windows systems", url: https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats, says:

    "All forward slashes (/) are converted into the standard Windows separator, the back slash (\). If they are present, a series of slashes that follow the first two slashes are collapsed into a single slash."

    So a mixture of slashes and backslashes should be possible in many situations with recent Windows platforms on the side of routines belonging to Windows' Advanced Programmer Interfaces.

    But I don't know how LaTeX's macros/routines for parsing/splitting directory paths and file names handle backslashes... (In the past I used to delve into such details, but over time so many things were changed and nowadays I am sort of tired of keeping myself up to date. When I really need to know the current state of the art, then I research which of the many documentations actually gives information and try to look things up - here is a list with a few links: Kpathsea manual, source2e.pdf, source3.pdf, interface3.pdf, TeXBook/source, tex.web/Computers & Typesetting Volume B, TeX: The Program , TDS, e-TeX-manual, XeTeX reference guide, XeTeX companion, LuaTeX reference manual, pdfTeX user manual, ISO 32000 (PDF), Web2C manual, xparse-manual, MiKTeX manual, The TeX Live Guide .)

    I wrote "Many situations" because with some Windows platforms there are situations where a mixture of slashes and backslashes doesn't work. E.g., I experienced problems on the command prompt under old legacy platforms like MS-DOS/Windows 3.1, Windows 95 and Windows 98. E.g., Chris Hoffman mentions in the section "How does it Matter?" of the article "Why Windows Uses Backslashes and Everything Else Uses Forward Slashes", url: https://www.howtogeek.com/181774/why-windows-uses-backslashes-and-everything-else-uses-forward-slashes/, which was updated in July 31, 2018, that paths with slashes instead of backslashes don't work out within the "Open" dialogue. That article comes along with a nice screenshot of how with this dialogue the error-message "The file name is invalid" is displayed on a Windows 7 machine.

  2. Section "4 Absolute paths" of the manual of the package currfile says:

    The information which ends up in the definiton of the macro \currfileabsdir is retrieved from a file \jobname.fls.
    If a file \jobname.fls is not available for reading during the LaTeX-run, the expansion of \currfileabsdir yields emptiness.
    In order to have the file \jobname.fls created, the TeX-engine needs to be invoked with the compiler-option -recorder.

    With MiKTeX, however, there is another peculiarity: With MiKTeX in the current LaTeX-run information is retrieved from the file \jobname.fls created during the previous LaTeX-run before having that destroyed and created anew.

    This implies: During the first LaTeX-run there is no file \jobname.fls coming from a previous LaTeX-run available for reading. Thus during the first LaTeX-run in MiKTeX expanding \currfileabsdir yields emptiness, thus in MiKTeX during the first LaTeX-run \input{\currfileabsdir-AnotherFile} is like \input{-AnotherFile}. Probably this circumstance is a source for problems.

So rather than replacing backslashes by (forward) slashes, you might need a routine for finding out if the current latex-run is the first latex-run and in this case providing defaults for the definitions of \currfileabsdir. This might be done, e.g., via writing directives for defining a macro to .aux-file and checking whether the macro in question is defined: During the first LaTeX-run there is no .aux-file yet, thus directives for defining macros coming from the .aux-file cannot be carried out. In subsequent LaTeX-runs directives are carried out and macros are defined.

Alternatively checking whether the expansion of \currfileabsdir yields emptiness and, if this is the case, overriding the empty definition of \currfileabsdir etc with some defaults might be a viable option, too.

Yet another approach could be checking right at the start, even before \documentclass, via \IfFileExists if \jobname.fls already exists and is available for reading, and setting a flag accordingly. In the preamble, if the flag is set accordingly, have the empty definition of \currfileabsdir etc overridden with some defaults.

Ulrich Diez
  • 28,770
  • In particular you could use str_set:No / tl_gset:NV (the latter is \edef\unexpanded, avoid ## etc.) and don't brace input to V-type – user202729 Jun 17 '22 at 14:09