来自之前的一个问题转义特殊字符以用作 URL,用来\string
转义第二个示例中的特殊 URL 字符效果很好:
\DefineMyFormatLinkParameters{%
*[Main Search Site]{Google}{http://www.google.com},
{people.brunel.ac.uk}{http://people.brunel.ac.uk/\string~mastmmg/ssguide/set\string_work.html\string#4\string_32},
{Yahoo}{http://www.yahoo.com}
}
\DefineMyFormatLinkParameters
定义参数列表\MyFormatLinkParameters
:
\newcommand*{\DefineMyFormatLinkParameters}[1]{%
\edef\MyFormatLinkParameters{#1}%
}%
但是如果我改用
\newcommand*{\DefineMyFormatLinkParametersNew}[2][TypeB]{%
%\edef\MyFormatLinkParametersNew{#2}% Don't assign it here directly,
% but pass it along
\IfStrEqCase{#1}{%
{TypeA}{\DefineMyFormatLinkParametersTypeA{#2}}%
{TypeB}{\DefineMyFormatLinkParametersTypeB{#2}}%
}[\typeout{*** ERROR: Unknown link type: #1}]%
}%
将参数列表传递给另一个宏,\DefineMyFormatLinkParametersTypeA
或者\DefineMyFormatLinkParametersTypeB
,在处理特殊字符时出现问题。对于不使用特殊 TeX 字符的情况,一切正常,如下面的 MWE 所示:
笔记
- 在 MWE 中,问题案例在调用中被注释掉
\DefineMyFormatLinkParametersNew
。取消注释该people.brunel.ac.uk
行即可重现该问题。
代码:
\documentclass{article}
\usepackage{url}
\usepackage{pgffor}
\usepackage{xparse}
\usepackage{xstring}
\usepackage[colorlinks=true]{hyperref}
\NewDocumentCommand{\FormatLinks}{%
s% #1 =* not used yet
O{}% #2 = optional title
m% #3 = Mandatory title
m% #4 = URL Link
}{%
\par
\hspace*{1.0cm}\href{#4}{#3\IfValueT{#2}{~(#2)}}%
}%
\newcommand*{\MyFormatLinkParameters}{}% Initialize
\newcommand*{\DefineMyFormatLinkParameters}[1]{%
\edef\MyFormatLinkParameters{#1}%
}%
%% \DefineMyFormatLinkParametersNew (compared to \DefineMyFormatLinkParameters) has
%% one extra level of macro processing based on the optional #1 parameter
\newcommand*{\Title}{}%
\newcommand*{\DefineMyFormatLinkParametersTypeA}[1]{%
\edef\MyFormatLinkParametersNew{#1}%
\def\Title{Type A Links}%
}%
\newcommand*{\DefineMyFormatLinkParametersTypeB}[1]{%
\edef\MyFormatLinkParametersNew{#1}%
\def\Title{Type B Links}%
}%
\newcommand*{\DefineMyFormatLinkParametersNew}[2][TypeB]{%
%\edef\MyFormatLinkParametersNew{#2}% Don't assign it here directly,
% but pass it along
\IfStrEqCase{#1}{%
{TypeA}{\DefineMyFormatLinkParametersTypeA{#2}}%
{TypeB}{\DefineMyFormatLinkParametersTypeB{#2}}%
}[\typeout{*** ERROR: Unknown link type: #1}]%
}%
\begin{document}
% ------------------------------- First version: works fine.
\DefineMyFormatLinkParameters{%
*[Main Search Site]{Google}{http://www.google.com},
{people.brunel.ac.uk}{http://people.brunel.ac.uk/\string~mastmmg/ssguide/set\string_work.html\string#4\string_32},
{Yahoo}{http://www.yahoo.com}
}
\foreach \x in \MyFormatLinkParameters {%
\typeout{DEBUG: "\x"}
\expandafter\FormatLinks\x
}%
%------------------------------- Second version: Not working if uncomment
% people.burnel.ac.uk. Only difference
% is that it has one extra level of macro
% processing which causes some problem!
\DefineMyFormatLinkParametersNew[TypeB]{%
*[Main Search Site]{Google}{http://www.google.com},
%{people.brunel.ac.uk}{http://people.brunel.ac.uk/\string~mastmmg/ssguide/set\string_work.html\string#4\string_32},
{Yahoo}{http://www.yahoo.com}
}
\bigskip\Title:%
\foreach \x in \MyFormatLinkParametersNew {%
\typeout{DEBUG: "\x"}
\expandafter\FormatLinks\x
}
\end{document}
答案1
如果已经加载了 l3 和 pgf,我不确定我是否会使用 xstring,但无论如何:
\documentclass{article}
\usepackage{url}
\usepackage{pgffor}
\usepackage{xparse}
\usepackage{xstring}
\usepackage[colorlinks=true]{hyperref}
\NewDocumentCommand{\FormatLinks}{%
s% #1 =* not used yet
O{}% #2 = optional title
m% #3 = Mandatory title
m% #4 = URL Link
}{%
\par
\hspace*{1.0cm}\href{#4}{#3\IfValueT{#2}{~(#2)}}%
}%
\newcommand*{\MyFormatLinkParameters}{}% Initialize
\newcommand*{\DefineMyFormatLinkParameters}[1]{%
\edef\MyFormatLinkParameters{#1}%
}%
%% \DefineMyFormatLinkParametersNew (compared to \DefineMyFormatLinkParameters) has
%% one extra level of macro processing based on the optional #1 parameter
\newcommand*{\Title}{}%
\newcommand*{\DefineMyFormatLinkParametersTypeA}[1]{%
\edef\MyFormatLinkParametersNew{#1}%
\def\Title{Type A Links}%
}%
\newcommand*{\DefineMyFormatLinkParametersTypeB}[1]{%
\edef\MyFormatLinkParametersNew{#1}%
\def\Title{Type B Links}%
}%
\newcommand*{\DefineMyFormatLinkParametersNew}[2][TypeB]{%
%\edef\MyFormatLinkParametersNew{#2}% Don't assign it here directly,
% but pass it along
\edef\tempz{\unexpanded{#2}}%
\IfStrEqCase{#1}{%
{TypeA}{\DefineMyFormatLinkParametersTypeA{\tempz}}%
{TypeB}{\DefineMyFormatLinkParametersTypeB{\tempz}}%
}[\typeout{*** ERROR: Unknown link type: #1}]%
}%
\begin{document}
% ------------------------------- First version: works fine.
\DefineMyFormatLinkParameters{%
*[Main Search Site]{Google}{http://www.google.com},
{people.brunel.ac.uk}{http://people.brunel.ac.uk/\string~mastmmg/ssguide/set\string_work.html\string#4\string_32},
{Yahoo}{http://www.yahoo.com}
}
\foreach \x in \MyFormatLinkParameters {%
\typeout{DEBUG: "\x"}
\expandafter\FormatLinks\x
}%
%------------------------------- Second version: Not working if uncomment
% people.burnel.ac.uk. Only difference
% is that it has one extra level of macro
% processing which causes some problem!
\DefineMyFormatLinkParametersNew[TypeB]{%
*[Main Search Site]{Google}{http://www.google.com},
{people.brunel.ac.uk}{http://people.brunel.ac.uk/\string~mastmmg/ssguide/set\string_work.html\string#4\string_32},
{Yahoo}{http://www.yahoo.com}
}
\bigskip\Title:%
\foreach \x in \MyFormatLinkParametersNew {%
\typeout{DEBUG: "\x"}
\expandafter\FormatLinks\x
}
\end{document}