背景
想要使用引用其他宏(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}