以下 MWE 表明,如果(且仅当,AFAICS)后者在/内使用.pdf
,则会在第一个参数中给出的 URL 中添加一个虚假的“ ” (它还表明该命令没有问题)。\href
\ExplSyntaxOn
\ExplSyntaxOff
\url
您知道发生了什么事吗?如何摆脱这个麻烦?
\documentclass{article}
\usepackage{expl3}
\usepackage{hyperref}
%
\begin{document}
\section{href}
\subsection{Inside ``ExplSyntax'' (NOT okay)}
\ExplSyntaxOn
\href{http://www.ctan.org/pkg/foo}{foo}
~$\rightarrow$~\url{http://www.ctan.org/pkg/foo.pdf}
\ExplSyntaxOff
\subsection{Outside ``ExplSyntax'' (okay)}
\href{http://www.ctan.org/pkg/foo}{foo}
~$\rightarrow$~\url{http://www.ctan.org/pkg/foo}
\section{url}
\subsection{Inside ``ExplSyntax'' (okay)}
\ExplSyntaxOn
\url{http://www.ctan.org/pkg/foo}
\ExplSyntaxOff
\subsection{Outside ``ExplSyntax'' (okay)}
\url{http://www.ctan.org/pkg/foo}
\end{document}
编辑:egreg 提供的 hack 回答了我关于 MWE 的问题,但在涉及包的实际用例中没有回答,如以下 M(n)WE 所示:
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{mynicepackage.sty}
\RequirePackage{xparse}
\RequirePackage{hyperref}
\ProvidesExplPackage{mynicepackage}{2016/04/18} {0.1}{mynicepackage}
\ExplSyntaxOn
\cs_new_protected:Nn \__npkg_package:nnn
{
\texorpdfstring{%
\IfBooleanTF {#1}
{%
\textsf{#3}
}{
\tl_if_empty:nTF {#2}
{%
\href{http://www.ctan.org/pkg/#3}{\textsf{#3}}%
}{%
\href{#2}{\textsf{#3}}%
}%
}
}{
\textsf{#3}%
}
}%
\NewDocumentCommand{\package}{ s O{} m } {
\__npkg_package:nnn {#1}{#2}{#3}
}
\ExplSyntaxOff
% Below is the hack provided by egreg:
\begingroup
\makeatletter
\endlinechar=-1 %
\catcode`\^^A=14 %
\catcode`\^^M\active
\catcode`\%\active
\catcode`\#\active
\catcode`\_\active
\catcode`\$\active
\catcode`\&\active
\gdef\hyper@normalise{^^A
\begingroup
\@makeother{:}^^A THIS WAS MISSING
\catcode`\^^M\active
\def^^M{ }^^A
\catcode`\%\active
\let%\@percentchar
\let\%\@percentchar
\catcode`\#\active
\def#{\hyper@hash}^^A
\def\#{\hyper@hash}^^A
\@makeother\&^^A
\edef&{\string&}^^A
\edef\&{\string&}^^A
\edef\textunderscore{\string_}^^A
\let\_\textunderscore
\catcode`\_\active
\let_\textunderscore
\let~\hyper@tilde
\let\~\hyper@tilde
\let\textasciitilde\hyper@tilde
\let\\\@backslashchar
\edef${\string$}^^A
\Hy@safe@activestrue
\hyper@n@rmalise
}^^A
\endgroup
\end{filecontents}
\usepackage{mynicepackage}
\begin{document}
\package{foo} $\rightarrow$ \url{http://www.ctan.org/pkg/foo.pdf}
\end{document}
答案1
由于@egreg 已经解释了问题是什么——这里有一个解决这个问题的建议:
\documentclass{article}
\usepackage{expl3,xparse,hyperref}
\ExplSyntaxOn
% this saves the url with all characters catcode other:
\str_const:Nn \c__npkg_standard_url_str { http://www.ctan.org/pkg/ }
% separate formatting:
\cs_new_protected:Npn \__npkg_package_format:n #1
{ \textsf {#1} }
% the main macro
% #1: boolean (true => no hyperlink)
% #2: optional url
% #3: package name
\cs_new_protected:Npn \__npkg_package:nnn #1#2#3
{
\texorpdfstring
{
\bool_if:nTF {#1}
{ \__npkg_package_format:n {#3} }
{
\tl_if_blank:nTF {#2}
{
\href
{ \c__npkg_standard_url_str #3 }
{ \__npkg_package_format:n {#3} }
}
{ \href {#2} { \__npkg_package_format:n {#3} } }
}
}
{#3}
}
% the user macro:
\NewDocumentCommand {\package} {sO{}m}
{ \__npkg_package:nnn {#1} {#2} {#3} }
\ExplSyntaxOff
\begin{document}
\section{\package{acro}}
\package[http://www.ctan.org/tex-archive/graphics/pgf]{pgf}
\package*{tabularx}
\end{document}
答案2
该\hyper@normalise
函数应用时\href
并未考虑:
可能存在不同的类别代码。
\documentclass{article}
\usepackage{expl3}
\usepackage{hyperref}
\begingroup
\makeatletter
\endlinechar=-1 %
\catcode`\^^A=14 %
\catcode`\^^M\active
\catcode`\%\active
\catcode`\#\active
\catcode`\_\active
\catcode`\$\active
\catcode`\&\active
\gdef\hyper@normalise{^^A
\begingroup
\@makeother{:}^^A THIS WAS MISSING
\catcode`\^^M\active
\def^^M{ }^^A
\catcode`\%\active
\let%\@percentchar
\let\%\@percentchar
\catcode`\#\active
\def#{\hyper@hash}^^A
\def\#{\hyper@hash}^^A
\@makeother\&^^A
\edef&{\string&}^^A
\edef\&{\string&}^^A
\edef\textunderscore{\string_}^^A
\let\_\textunderscore
\catcode`\_\active
\let_\textunderscore
\let~\hyper@tilde
\let\~\hyper@tilde
\let\textasciitilde\hyper@tilde
\let\\\@backslashchar
\edef${\string$}^^A
\Hy@safe@activestrue
\hyper@n@rmalise
}^^A
\endgroup
\begin{document}
\section{href}
\subsection{Inside ``ExplSyntax'' (NOT okay)}
\ExplSyntaxOn
\href{http://www.ctan.org/pkg/foo}{foo}
~$\rightarrow$~\url{http://www.ctan.org/pkg/foo.pdf}
\ExplSyntaxOff
\subsection{Outside ``ExplSyntax'' (okay)}
\href{http://www.ctan.org/pkg/foo}{foo}
~$\rightarrow$~\url{http://www.ctan.org/pkg/foo}
\section{url}
\subsection{Inside ``ExplSyntax'' (okay)}
\ExplSyntaxOn
\url{http://www.ctan.org/pkg/foo}
\ExplSyntaxOff
\subsection{Outside ``ExplSyntax'' (okay)}
\url{http://www.ctan.org/pkg/foo}
\end{document}
您可以检查链接是否符合预期。
你在我的回答后添加的例子是非常与原始问题中的不同。您正在调用\href
另一个命令的参数,因此参数\href
已经被标记化,并且不受的影响\hyper@normalise
。
您可以使用\tl_rescan:nn
来强制重读该参数。
\RequirePackage{filecontents}
\begin{filecontents*}{mynicepackage.sty}
\RequirePackage{xparse}
\RequirePackage{hyperref}
\ProvidesExplPackage{mynicepackage}{2016/04/18} {0.1}{mynicepackage}
\NewDocumentCommand{\package}{ s o m }
{
\IfBooleanTF { #1 }
{
\textsf{#3}
}
{
\IfNoValueTF { #2 }
{
\__npkg_package:nn { http://www.ctan.org/pkg/#3 } { #3 }
}
{
\__npkg_package:nn { #2 } { #3 }
}
}
}
\cs_new_protected:Nn \__npkg_package:nn
{
\texorpdfstring { \tl_rescan:nn { } { \href{#1}{\textsf{#2}} } } { #2 }
}
\end{filecontents*}
\documentclass{article}
\usepackage{mynicepackage}
\begin{document}
\package{foo} $\rightarrow$ \url{http://www.ctan.org/pkg/foo.pdf}
\end{document}
注意命令的不同定义\package
,按照指南操作。
如果 URL 包含,那%
您就完了,当然,除非您逃脱它。