使用嵌套宏定义扩展目录名称

使用嵌套宏定义扩展目录名称

背景

想要使用引用其他宏(n 级深度)的宏的值并将其值应用于命令\path

问题

(场景 A)以下工作有效:

\usepackage{url}

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

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

结果:

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

(场景 B)失败:

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

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

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

实际结果是错误:

 Missing }.

(场景 C)失败:

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

实际结果:

c:\programs \Apache \htdocs index.php

问题

如何\path使用命令来扩展和使用\dirhomeapachehttpdocs场景 B 的值?

有关的

答案1

这里的问题是,这\对 TeX 来说意味着什么。当你写

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

(注意我省略了尾部斜杠),你告诉 TeX 这\dirhomeapachehttp是一个扩展为 4 个标记的宏:两个字符标记c:以及两个控制序列标记\programs\Apache。这不是你想要的。

一种可能性是创建一个新命令,让您定义一个扩展到目录的宏。我写了这样一个命令(见下文),但我突然想到该url包已经有这样一个命令:

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

现在你的场景 B 变成了

\dirhomeapachehttp\filename{\filephpdemo}

如果你好奇的话,以下是我为类似宏想出的\urldef

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

你照樣使用。

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

您可以将其与\dirname宏一起使用。

编辑:
这个问题开始感觉有点像一个移动的目标。请注意,根据您的编辑,您想要的是\有时表示一件事(有时您想要宏扩展),有时您希望它是目录分隔符。我认为这里正确的做法可能是使用\urldef来定义各种路径组件,然后,如果您真的需要将它们塞进一个宏中,请使用\newcommand替换文本由各种组件组成的地方。

类似下面的内容。

\urldef\dirhomeapachehttp\path{c:\programs\Apache\}
\urldef\dirdocs\path{docs\}
\newcommand*\dirhomeapachehttpdocs{\dirhomeapachehttp\dirdocs}
\dirhomeapachehttpdocs\path{index.php}

答案2

我不确定你的问题是否具有教育意义,即了解\expandafter或与你正在处理的实际问题相关。我假设是后者,并在下面提供了一种解决问题的不同方法。我通常会尽量避免expandafter,如果可能的话,并尝试简化代码。

我定义了一个\basepath宏,通常只需设置一次。然后,您可以使用该命令\fullpath仅通过提供文件名来排版完整路径 URI。

\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}

相关内容