Перепишите \url{https://example.com/path} в \href{https://example.com/path}{path} из макроса

Перепишите \url{https://example.com/path} в \href{https://example.com/path}{path} из макроса

Этот документ вырезан из файла .bbl, созданного с помощью BibTeX:

\documentclass{article}
\usepackage{url}
\usepackage{hyperref}
\newcommand{\showDOI}[1]{\textsc{doi:}#1}
\begin{document}
\urldef\tempurl\url{https://doi.org/10.1016/j.comnet.2004.08.013}
\showDOI{\tempurl}
\end{document}

Выглядит это так:

введите описание изображения здесь

Я хочу получить вывод, как если бы документ был прочитан

\documentclass{article}
\usepackage{url}
\usepackage{hyperref}
\newcommand{\showDOI}[1]{\textsc{doi:}#1}
\begin{document}
\showDOI{\href{https://doi.org/10.1016/j.comnet.2004.08.013}%
              {\UrlFont 10.1016/j.comnet.2004.08.013}
\end{document}

то есть

введите описание изображения здесь

при этом гиперссылка PDF по-прежнему указывает на полный URL-адрес.

Но поскольку я не хочу возиться с файлом .bst, и поскольку мне нужно поведение, \verbподобное поведению \urlapplied before \showDOIis expanded (некоторые DOI в моей библиографии содержат подчеркивания и/или знаки процента), я хочу добиться этого, изменивтолькоопределение \showDOI, а не способ его использования.

Возможно ли это? Если да, то как?

решение1

Простой текст URL, созданный с помощью, \urldefможно изменить, определив \UrlLeftи \UrlRight. Адаптировано изurlруководство по упаковке, используя xstringдля обработки строк:

\documentclass{article}
\usepackage{url}
\usepackage{hyperref}
\usepackage{xstring}
\setlength{\parskip}{1em}   % for presentation only

\newcommand{\showDOI}[1]{%
\let\oldleft\UrlLeft%
\let\oldright\UrlRight%
\def\UrlLeft##1\UrlRight{\StrGobbleLeft{##1}{16}}%
\textsc{doi:} #1%
\let\UrlLeft\oldleft%
\let\UrlRight\oldright%
}

\begin{document}
\url{http://www.regular-url.com/}

\urldef\tempurl\url{https://doi.org/10.1016/j.comnet.2004.08.013}
\showDOI{\tempurl}

\url{http://www.other-url.com/}
\end{document}

Это работает, потому что hyperrefсначала создает ссылку с исходным аргументом, а затем форматирует ссылку с помощью urlпакета, который, в свою очередь, использует предоставленное определение. Обратите внимание, что определения необходимо сохранять и восстанавливать вокруг отображения DOI, чтобы избежать усечения обычных URL.

Результат (целевая ссылка отображается в виде подсказки):

введите описание изображения здесь

решение2

\documentclass{article}
\usepackage{hyperref}
\makeatletter
\def\showDOI#1{\expandafter\showDOI@i#1\@nil}
\def\showDOI@i#1//#2/#3\@nil{\textsc{DOI:} \href{#1//#2/#3}{\UrlFont#3}}
\makeatother
\begin{document}
\def\tempurl{https://doi.org/10.1016/j.comnet.2004.08.013}
\showDOI{\tempurl}%

\showDOI{https://doi.org/10.1016/j.comnet.2004.08.013}
\end{document}

введите описание изображения здесь

решение3

Давайте удалим все, что стоит перед ним doi.org/(даже если у вас httpвместо будет https, макрос будет работать так же).

\documentclass{article}
\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn
\NewDocumentCommand{\showDOI}{m}
 {
  \textsc{doi:}
  %\nobreakspace % if you want a space, uncomment this
  \zwol_showdoi:n { #1 }
 }

\tl_new:N \l__zwol_showdoi_tl
\tl_new:N \l__zwol_showdoi_full_tl

\cs_new_protected:Nn \zwol_showdoi:n
 {
  \tl_if_single:nTF { #1 }
   { % single token
    \cs_if_exist:cTF { \cs_to_str:N #1 ~ }
     {% we assume it is \urldef
      \__zwol_showdoi_urldef:c { \cs_to_str:N #1 ~ }
     }
     {
      \tl_set:Nx \l__zwol_showdoi_tl { #1 }
     }
   }
   {
    \tl_set:Nn \l__zwol_showdoi_tl { #1 }
   }
  \tl_set_eq:NN \l__zwol_showdoi_full_tl \l__zwol_showdoi_tl
  \regex_replace_once:nnN { \A .*doi\.org/ } { } \l__zwol_showdoi_tl
  \href{\l__zwol_showdoi_full_tl}{\UrlFont\l__zwol_showdoi_tl}
 }

\cs_new_protected:Nn \__zwol_showdoi_urldef:N
 {
  \tl_set_eq:NN \l__zwol_showdoi_tl #1
  \regex_replace_once:nnN { \c{url} \cB. (.*) \cE. } { \1 } \l__zwol_showdoi_tl
 }
\cs_generate_variant:Nn \__zwol_showdoi_urldef:N { c }
\ExplSyntaxOff

\begin{document}

\urldef\tempurl\url{https://doi.org/10.1016/j.comnet.2004.08.013}

\showDOI{\tempurl}

\showDOI{https://doi.org/10.1016/j.comnet.2004.08.013}

\end{document}

введите описание изображения здесь

Вам может потребоваться обновить дистрибутив TeX, поскольку регулярные выражения вошли в ядро ​​expl3 совсем недавно. Если вы не можете обновить, добавьте \usepackage{l3regex}.

Связанный контент