3

Background

Would like to use values from macros that reference other macros (n-levels deep) and apply their values to the \path command.

Problem

(Scenario A) The following works:

\usepackage{url}

\newcommand*{\filename}[1]{\expandafter\path\expandafter{#1}}
\newcommand*{\filephpdemo}{index.php}

\path{c:\programs\Apache\htdocs\}\filename{\filephpdemo}

Result:

c:\programs\Apache\htdocs\index.php

(Scenario B) This fails:

\newcommand*{\dirname}[1]{\expandafter\path\expandafter{#1}}

\newcommand*{\dirhomeapachehttp}{c:\programs\Apache\}
\newcommand*{\dirhomeapachehttpdocs}{\dirhomeapachehttp\docs\}

\dirname{\dirhomeapachehttpdocs}\filename{\filephpdemo}

Actual result is an error:

 Missing }.

(Scenario C) This fails:

\newcommand*{\dirhomeapachehttp}{c:\programs\Apache\}
\newcommand*{\dirhomeapachehttpdocs}{c:\programs\Apache\hdtocs}

Actual result:

c:\programs \Apache \htdocs index.php

Question

How can the \path command be used to expand and use the value of \dirhomeapachehttpdocs from Scenario B?

Related

Dave Jarvis
  • 11,809

2 Answers2

5

The problem here is that \ means something to TeX. When you write

\newcommand*\dirhomeapachehttp{c:\programs\Apache}

(note I omitted the trailing slash), you're telling TeX that \dirhomeapachehttp is a macro that expands to 4 tokens: the two character tokens c and : and two control sequence tokens \programs and \Apache. This is not what you want.

One possibility is to make a new command that lets you define a macro that expands to the directory. I wrote such a command (see below), but it occurred to me that the url package already has such a command:

\urldef\dirhomeapachehttp\path{c:\programs\Apache\}

Now your Scenario B becomes

\dirhomeapachehttp\filename{\filephpdemo}

Just in case you were curious, here's what I came up with for a similar macro to the \urldef

{
\catcode`\^0
\catcode`\\12
^gdef^dirsep{\}
}
\newcommand*\defpath[2]{%
        \edef#1{\detokenize{#2}\dirsep}%
}

You use it like this.

\defpath\dirhomeapachehttp{c:\programs\Apache}

This you can use with your \dirname macro.

Edit:
This question is starting to a feel a little bit like a moving target. Note that as per your edit, what you want is for \ to sometimes mean one thing (sometimes you want macro expansion) and sometimes you want it to be a directory separator. I think probably the right thing to do here is to use \urldef to define the various path components and then, if you really need to stuff them together into a single macro, use \newcommand where the replacement text is made up of the various components.

Something like the following.

\urldef\dirhomeapachehttp\path{c:\programs\Apache\}
\urldef\dirdocs\path{docs\}
\newcommand*\dirhomeapachehttpdocs{\dirhomeapachehttp\dirdocs}
\dirhomeapachehttpdocs\path{index.php}
TH.
  • 62,639
  • Thank you. I have updated Scenario B, but I think what you have given me is sufficient for me to make it work. Part of the problem was that I have dozens of directories and I was looking to use the \path macro once. I suppose it doesn't much matter: the important part is that the directory names are written only once. – Dave Jarvis Dec 15 '10 at 14:46
  • @Dave: See the Edit for comments. – TH. Dec 15 '10 at 14:57
  • Thank you for the updated comments: they helped enormously. – Dave Jarvis Dec 18 '10 at 04:11
2

I am not sure if your question was educational i.e, learning about \expandafter or related to a real issue you are working on. I have assumed the latter and provide below a different approach in solving the issue. I normally try to avoid expandafter, if possible and try to simplify the code.

I have defined a \basepath macro, which would normally need to be set once. You can then use the command \fullpath to typeset a full path URI by only providing a filename.

\documentclass[11pt]{article}
\usepackage{url}
\begin{document}

\gdef\basepath{\path{c:\programs\Apache\hdtocs}}
\def\afilename#1{\path{\ #1}}

%% examples
%
\basepath\afilename{index.php}

\basepath\afilename{category.php}

%% Defining a fullpath
%
\def\fullpath#1{\basepath\afilename{#1}}

%% Example fullpath
\fullpath{another.php}
\end{document}
yannisl
  • 117,160