透過巨集傳遞轉義特殊字元以用作 URL

透過巨集傳遞轉義特殊字元以用作 URL

從之前的一個問題開始轉義特殊字元以用作 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}

相關內容