有一个相关问题,但答案显示了如何使用 URL 文本手动创建链接。这不是我想要的。
我想创建一个命令(称为\urlb
),它将排版带有超链接的 URL,但丢弃链接文本中的协议。这似乎可以使用代码来完成,但我还没有找到可以做到这一点的包。
我是否遗漏了什么?
例子
我想输入:
\urlb{https://mydomain.example.com}
并获取超链接的输出:
因此定义可能看起来像这样:
\newcommand{\urlb}[1]{%
\href{#1}{\stripProto{#1}}%
}
电子邮件地址
我还希望它适用于电子邮件地址。在这种情况下,输入将是,输出将是带有文本的超链接。mailto:[email protected]
[email protected]
答案1
为了正确处理 URL 等,我们需要一个不仅仅能根据模式进行拆分的命令。
- 需要处理下划线和与号等字符,否则会导致错误。
- 如果有一个通用版本能够处理至少一些其他协议(例如等)
file
那就好了。ftp
- 由于 URL 可能很长,并且永远不会构成 TeX 可以使用标准连字符模式断开的单词,因此我们需要启用额外的换行符。
以下代码尝试满足这些标准。
\NewDocumentCommand
的v
参数类型用于确保输入按逐字处理。这将\href{}{}
作为第一个参数传递。- 如果标签(默认情况下,第一个参数传递的值)包含
://
或,则将其拆分,否则,:
或,否则,按原样使用。如果拆分,则使用右侧的所有内容,其余部分将被丢弃。 xurl
已加载并且链接标签\url{}
在传递给之前被包装起来\href{}{}
。
语法是
\urlb[<alternative label text>]{<content for link>}
\urlb{<content for link>}
如果省略可选参数,<content for link>
则用于两个参数。
拆分是使用名为 的参数处理器完成的\HyperSplit
。处理后的参数随后被包装在 中\url{}
,并将结果展开一次,然后作为 的第二个参数传递\href{}{}
。
- 扩展由处理在接收它们之前
\ExpandArgs {no} ...
传递给的参数的处理。只是按原样传递第一个。扩展第二个一次。\href{}{}
\href{}{}
n
o
在以下情况下
\urlb{https://mydomain.example.com}
\urlb{mailto:[email protected]}
结果与使用分隔模式拆分输入相同,如LdBeth 的回答。但是,下面的代码在以下情况下也能正确执行
\urlb{file:///etc/ssl/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem}
\urlb{https://www.startpage.com/sp/search?query=protocol+formats&cat=web&pl=opensearch&language=english}
否则会导致错误,因为它们包含“奇怪”(“活动”?)字符,例如_
和&
。由于xurl
使用了 ,两个链接也会跨行断开,因此它们不会超出行宽。
可选参数还允许覆盖链接的重复使用,以防万一你想要
\urlb[open file]{file:///etc/ssl/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem}
代码:
\documentclass{article}
% ateb: https://tex.stackexchange.com/a/715932/
\usepackage[T1]{fontenc}
\usepackage{hyperref}
\usepackage{xurl}
\NewDocumentCommand \urlb {>{\HyperSplit}O{#2}v}
{%
\ExpandArgs {no}\href{#2}{\url{#1}}%
}
\ExplSyntaxOn
\cs_new_protected:Npn \HyperSplit #1
{
\regex_split:nnNF { :// } { #1 } \l_tmpa_seq
{
\regex_split:nnNF { : } { #1 } \l_tmpa_seq
{
\seq_put_left:NV \l_tmpa_seq \c_empty_tl
}
}
\seq_get_right:NN \l_tmpa_seq \ProcessedArgument
}
\ExplSyntaxOff
\begin{document}
\urlb{https://mydomain.example.com}
\urlb{mailto:[email protected]}
\urlb{file:///etc/ssl/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem}
\urlb{https://www.startpage.com/sp/search?query=protocol+formats&cat=web&pl=opensearch&language=english}
\urlb[mydomain]{https://mydomain.example.com}
\urlb[email me]{mailto:[email protected]}
\urlb[open file]{file:///etc/ssl/certs/TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi_-_Surum_1.pem}
\urlb[search the 'net]{https://www.startpage.com/sp/search?query=protocol+formats&cat=web&pl=opensearch&language=english}
\urlb{www.my_web.org}
\urlb[my web]{www.my_web.org}
\end{document}
抱歉,没有提供视觉辅助。目前,X 上的 Okular 生成的图像非常糟糕,我已放弃发布它们,直到我想出一个合理的方法或修复错误(或者我弄清楚了 Wayland,我猜)。
答案2
使用普通的 TeX 宏可以很容易地实现这一点。它被设计为能够执行简单的模式匹配任务。
\def\stripProto#1://{}
\stripProto https://mydomain.example.com
=> mydomain.example.com
然后你只需定义
\newcommand{\urlb}[1]{%
\href{#1}{\stripProto#1}%
}
相似地,
\def\stripMailTo#1:{}
您想让同一个命令对两种类型的链接起作用吗?没问题 :)
\documentclass{article}
\usepackage{url}
\usepackage{hyperref}
% These are TeX's "strip until a string pattern"
\def\stripProto#1://{}
\def\stripMailTo#1:{}
% Save text up to the first `:` to macro definition \proto
\def\getProto#1:#2\end{\def\proto{#1}}
% save protocol names as "string constants"
% so they can be compared with \ifx
\def\strhttp{https}\def\strmto{mailto}
%
\def\stripstrip#1{%
\getProto #1\end
\ifx\proto\strhttp
\stripProto #1%
\else\ifx\proto\strmto
\stripMailTo #1\fi\fi}
\newcommand{\urlb}[1]{%
\href{#1}{\stripstrip{#1}}%
}
\begin{document}
\urlb{https://mydomain.example.com}
\urlb{mailto:[email protected]}
\end{document}