如果位于 \ExplSyntaxOn/Off 中,则将虚假的“.pdf”添加到 \href 的第一个参数中

如果位于 \ExplSyntaxOn/Off 中,则将虚假的“.pdf”添加到 \href 的第一个参数中

以下 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 包含,那%您就完了,当然,除非您逃脱它。

在此处输入图片描述

相关内容