将 URL 存储在宏中,无需替换 # 和 %

将 URL 存储在宏中,无需替换 # 和 %

#如果 URL 中包含and/或 a,我该如何将其存储在宏中%?下面的 MWE 对前两个有效,但对第三个无效。

在此处输入图片描述

笔记:

  • 一种解决方案是#\string#%替换\%,但想知道是否有更简单的方法。

  • 我意识到这可能会弄乱语法高亮,但\csdef{}此处显示的部分将位于单独的.def文件中,因此\input{}不是问题。

参考:

代码

\documentclass{article}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{tikz}

\csdef{url Title 1}{The Google}
\csdef{url Link 1}{http://www.google.com}

\csdef{url Title 2}{TeX.SE}
\csdef{url Link 2}{http://tex.stackexchange.com}

%\csdef{url Title 3}{Algebra and Trigonometry:~History of Trigonometry}
%\csdef{url Link 3}{https://books.google.com/books?id=4tFFDwAAQBAJ&pg=PT233&dq=history+of+trigonometry&hl=en&newbks=1&newbks_redir=0&sa=X&ved=2ahUKEwjIzcj0-tnqAhXwFjQIHZ6XDLUQ6AEwAnoECAQQAg#v=onepage&q&f=false}

\def\MaxNUmberOfURLs{5}
\newcommand{\DisplayURLs}{%
    \textbf{List of URLs}
    \foreach \xCount in {1,...,\MaxNUmberOfURLs} {%
        \ifcsdef{url Title \xCount}{%
            \par\xCount:
            \href{\csuse{url Link \xCount}}{\csuse{url Title \xCount}}
        }{}%
    }%
}

\begin{document}
\DisplayURLs
\end{document}

答案1

hyperref's\hyper@normalise在这里非常有用。它可用于净化宏的参数并允许它接受特殊字符而无需转义。(我想我第一次\hyper@normalise了解到迈克尔·厄默尔斯回答在脚注中获取那些 %#!^& 符号!

只需使用它来定义一个新的宏,如\newcommand*{\csdefurl}[1]{\hyper@normalise{\csdef{#1}}}。(请注意,要“规范化”的参数是不是明确地作为定义的部分。\newcommand*{\csdefurl}[2]{\hyper@normalise{\csdef{#1}}{#2}}不会起作用,因为随后会使用非规范化的 catcode 设置读取参数。)

\documentclass{article}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{tikz}

\makeatletter
\newcommand*{\csdefurl}[1]{\hyper@normalise{\csdef{#1}}}
\makeatother

\csdef{url Title 1}{The Google}
\csdefurl{url Link 1}{http://www.google.com}

\csdef{url Title 2}{TeX.SE}
\csdefurl{url Link 2}{http://tex.stackexchange.com}

\csdef{url Title 3}{Algebra and Trigonometry:~History of Trigonometry}
\csdefurl{url Link 3}{https://example.com/~test/a%20and%20b.html#anchor}

\def\MaxNUmberOfURLs{5}
\newcommand{\DisplayURLs}{%
    \textbf{List of URLs}
    \foreach \xCount in {1,...,\MaxNUmberOfURLs} {%
        \ifcsdef{url Title \xCount}{%
            \par\xCount:
            \href{\csuse{url Link \xCount}}{\csuse{url Title \xCount}}
        }{}%
    }%
}

\begin{document}
\DisplayURLs
\end{document}

输出的屏幕截图。第三项显示“代数和三角学:三角学的历史”,PDF 查看器悬停时显示的小弹出窗口显示“https://example.com/~test/a%20and%20b.html#anchor”


进一步的测试表明

\makeatletter
\newcommand*{\csdefurl@i}{}
\newrobustcmd*{\csdefurl}[1]{%
  \def\csdefurl@i{\csdef{#1}}%
  \hyper@normalise\csdefurl@i}
\makeatother

可能会更安全。

将此定义与上面的定义进行比较

\documentclass{article}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{tikz}

\makeatletter
\newcommand*{\csdefurl@i}{}
\newrobustcmd*{\csdefurl}[1]{%
  \def\csdefurl@i{\csdef{#1}}%
  \hyper@normalise\csdefurl@i}
\makeatother

\csdef{ürl Title 1}{The Google}
\csdefurl{ürl Link 1}{http://www.google.com}

\csdef{ürl Title 2}{TeX.SE}
\csdefurl{ürl Link 2}{http://tex.stackexchange.com}

\csdef{ürl Title 3}{Algebra and Trigonometry:~History of Trigonometry}
\csdefurl{ürl Link 3}{https://example.com/~test/a%20and%20b.html#anchor}

\def\MaxNUmberOfURLs{5}
\newcommand{\DisplayURLs}{%
    \textbf{List of URLs}
    \foreach \xCount in {1,...,\MaxNUmberOfURLs} {%
        \ifcsdef{ürl Title \xCount}{%
            \par\xCount:
            \href{\csuse{ürl Link \xCount}}{\csuse{ürl Title \xCount}}
        }{}%
    }%
}

\begin{document}
\DisplayURLs
\end{document}

其中,我们使用非 ASCIIürl来代替url

答案2

你问,

“如果 URL中包含#and/或 a ,我该如何将其存储在宏中?”%

\urldef该包的指令允许url您创建这样的宏。例如,

\urldef{\myURL}\url{https://books.google.com/books?id=4tFFDwAAQBAJ&pg=PT233&dq=history+of+trigonometry&hl=en&newbks=1&newbks_redir=0&sa=X&ved=2ahUKEwjIzcj0-tnqAhXwFjQIHZ6XDLUQ6AEwAnoECAQQAg#v=onepage&q&f=false}

注意语法: 。必须\urldef{<macroname>}\url{<URLstring>}遵守\url{<URLstring>}不是用花括号括起来。

\myUrl可用于\footnote指令的参数。

相关内容