
Из более раннего вопроса оЭкранирование специальных символов для использования в качестве 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
Не уверен, что стоит использовать xstring, если у вас уже загружены l3 и pgf, но все равно:
\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}