我正在尝试使用自制脚本将 markdown 转换为 latex。我遇到的问题之一是超链接。
在 markdown 中,有多种方式可以放置链接(外部超链接),如下所示:
我最喜欢的搜索引擎是鸭鸭走.
或作为快速链接:https://www.markdownguide.org。
上面的两个选项我转换成 latex 时没有遇到任何问题(除了 hyperref 和 url 之间的包冲突,但我会解决这个问题)。
我最喜欢的搜索引擎是 \href{https://duckduckgo.com}{Duck Duck Go}。
或者作为快速链接:\url{https://www.markdownguide.org}。
问题始于 markdown 的引用链接,如下所示:
地上的一个洞里住着一个霍比特人。这个洞不是肮脏、潮湿、满是虫子尾巴、散发着黏液气味的洞,也不是干燥、光秃、满是沙子、里面没有东西可以坐或吃的洞:这是一个 [霍比特人洞][1],这意味着舒适。
标签 [1] 随后在页面/文档中被称为:
[1]: https://en.wikipedia.org/wiki/Hobbit#Lifestyle
[1]: https://en.wikipedia.org/wiki/Hobbit#Lifestyle "Hobbit lifestyles"
[1]: https://en.wikipedia.org/wiki/Hobbit#Lifestyle 'Hobbit lifestyles'
[1]: https://en.wikipedia.org/wiki/Hobbit#Lifestyle (Hobbit lifestyles)
[1]: <https://en.wikipedia.org/wiki/Hobbit#Lifestyle> "Hobbit lifestyles"
[1]: <https://en.wikipedia.org/wiki/Hobbit#Lifestyle> 'Hobbit lifestyles'
[1]: <https://en.wikipedia.org/wiki/Hobbit#Lifestyle> (Hobbit lifestyles)
这将导致引用不显示并且 [hobbit-hole] 成为超链接。
在 latex 或 hyperref 包中是否有类似的引用链接逻辑?
答案1
问题在于 URL 应该被逐字读取。
如果你有兴趣我可以提供一个界面
\urllabel{⟨referencing-label⟩}⟨verbatim-argument denoting url⟩
和
\urllink{⟨link text⟩}{⟨referencing-label⟩}
其中\urllabel
读⟨表示 url 的逐字参数⟩在 verbatim-catcode-régime 下,并将其复制到 .aux 文件,以便可以在文档的任何地方引用它\urlref
。在引用时\urllink
传递⟨表示 url 的逐字参数⟩到\href
。
该机制基于 kernel-macro \@newl@bel
,但带有一些用于在 verbatim-catcode-régime 下复制/读取参数的包装器。这样,您会收到有关多次定义标签和标签被更改的警告。(\@setref
无法使用,但需要以类似方式实现,因为 hyperref 已重新定义。)
(如果 xparser 提供了在读取 av/+v 参数时获取逐字分隔符的方法,则可以通过 xparser 轻松实现这一点。)
注意事项:
在第一次 LaTeX 运行中,虽然不存在 .aux 文件,但交叉引用标签/动词标签未定义,因此您无法获得超链接。
您至少需要进行两次编译,直到所有内容匹配为止。
类似于
\verb
其他期望其参数在非标准 catcode 制度中被标记的宏,\urllabel
不能在其他宏的参数或定义文本中使用。接口使用 .aux 文件。因此,如果 TeX 发行版中的某些字符以 ^^ 符号写入 .aux 文件(例如,由于 character-translation/tcx-files),则可能会引发问题。
\makeatletter
%%======================Code for \UDcollectverbarg=============================
%% \UDcollectverbarg{<non-optional 1>}{<non-optional 2>}|<verbatim arg>|
%%
%% reads <verbatim arg> under verbatim-catcode-regime and delivers:
%%
%% <non-optional 1>{<non-optional 2>{<verbatim arg>}}
%%-----------------------------------------------------------------------------
%% \UDcollectverbarg*{<non-optional 1>}{<non-optional 2>}|<verbatim arg>|
%%
%% reads <verbatim arg> under verbatim-catcode-regime and delivers:
%%
%% <non-optional 1>{<non-optional 2>{|<verbatim arg>|}}
%%-----------------------------------------------------------------------------
%% Instead of using verbatim-delimiter | or the like the <verbatim arg> can
%% be nested in braces.
%%
%% You cannot use percent or spaces or horizontal tab as verbatim-delimiter.
%%
%% You can use <non-optional 1> for nesting calls to \UDcollectverbarg.
%%
%% The unstarred variant removes the verbatim-delimiters/braces that surround
%% <verbatim arg>.
%% The starred variant keeps the verbatim-delimiters/braces that surround
%% <verbatim arg>.
%% Reason: When you feed things to \scantokens you don't need the verbatim-
%% delimiters.
%% When you use things for writing to temporary files and reading back
%% verbatimized, you may need them.
%%=============================================================================
\@ifdefinable\UDcollectverbarg{%
\DeclareRobustCommand\UDcollectverbarg{%
\@ifstar{\UD@collectverbarg{\@secondoftwo}}{\UD@collectverbarg{\@firstoftwo}}%
}%
}%
\newcommand\UD@collectverbarg[3]{%
% #1 - indicator whether to remove/keep the verb-delimiter (\@firstoftwo/\@secondoftwo)
% #2 - non-optional 1
% #3 - non-optional 2
\begingroup
\let\do\@makeother % <- this and the next line switch to
\dospecials % verbatim-category-code-régime.
\catcode`\{=1 % <- give opening curly brace the usual catcode so a
% curly-brace-balanced argument can be gathered in
% case of the first thing of the verbatimized-argument
% being a curly opening brace.
\catcode`\ =10 % <- give space and horizontal tab the usual catcode so \UD@@collectverbarg
\catcode`\^^I=10 % cannot catch a space or a horizontal tab as its 4th undelimited argument.
% (Its 4th undelimited argument denotes the verbatim-
% syntax-delimiter in case of not gathering a
% curly-brace-nested argument.)
\catcode`\%=14 % <- make percent comment.
\kernel@ifnextchar\bgroup
{% seems a curly-brace-nested argument is to be picked:
\catcode`\}=2 % <- give closing curly brace the usual catcode also.
\UD@@collectverbarg{#1}{\@firstoftwo}{#2}{#3}{}%
}{% seems an argument with verbatim-syntax-delimiter is to be picked:
\do\{% <- give opening curly brace the verbatim-catcode again.
\UD@@collectverbarg{#1}{\@secondoftwo}{#2}{#3}%
}%
}%
\newcommand\UD@@collectverbarg[5]{%
% #1 - indicator whether to remove/keep the verb-delimiter (\@firstoftwo/\@secondoftwo)
% #2 - indicator whether braces or verb-delimiter (\@firstoftwo/\@secondoftwo)
% #3 - non-optional 1
% #4 - non-optional 2
% #5 - verb-delimiter or emptiness
\do\ % <- Now that \UD@@collectverbarg has the delimiter or
\do\^^I% emptiness in its 4th arg, give space and horizontal tab
% the verbatim-catcode again.
\do\^^M% <- Give the carriage-return-character the verbatim-catcode.
\do\%% <- Give the percent-character the verbatim-catcode.
\long\def\@tempb##1#5{%
#1{\def\@tempb{##1}}{#2{\def\@tempb{{##1}}}{\def\@tempb{#5##1#5}}}%
\@onelevel@sanitize\@tempb % <- Turn characters into their "12/other"-pendants.
% This may be important with things like the
% inputenc-package which may make characters
% active/which give them catcode 13(active).
\expandafter\UD@@@collectverbarg\expandafter{\@tempb}{#3}{#4}% <- this "spits out the result.
}%
\@tempb
}%
\newcommand\UD@@@collectverbarg[3]{\endgroup#2{#3{#1}}}%
%%================= End of code for \UDcollectverbarg =========================
%%
\DeclareRobustCommand\urllabel[1]{%
\@bsphack\UDcollectverbarg*{\@firstofone}{\UD@writeverblabel{#1}}%
}%
\newcommand\UD@writeverblabel[2]{%
\begingroup
\newlinechar=\endlinechar
\immediate\write\@auxout{\string\newverblabel{#1}#2\@percentchar}%
\endgroup
\@esphack
}%
\newcommand\newverblabel[1]{%
\UDcollectverbarg{\@firstofone}{\UD@defineverblabel{#1}}%
}%
\newcommand\UD@defineverblabel[2]{\@newl@bel{vrblbl}{#1}{#2}}%
\DeclareRobustCommand\urlref[2]{%
\expandafter\ifx\csname vrblbl@#2\endcsname\relax
\protect\G@refundefinedtrue
\@latex@warning {Reference `#2' on page \thepage\space undefined}%
#1%
\else
\expandafter\expandafter\expandafter\href
\expandafter\expandafter\expandafter{\csname vrblbl@#2\expandafter\endcsname}{#1}%
\fi
}%
\makeatother
\documentclass{article}
\usepackage{hyperref}
\begin{document}
Some text.
\urlref{CTAN}{2} is an important resource for users of \TeX.
\urlref{TeX LaTeX StackExchange is a question-answer-platform.}{TeXLaTeXStackExchange}
Some more text.
%-------------------------------------------------------------------
\urllabel{TeXLaTeXStackExchange}|https://tex.stackexchange.com/|
\urllabel{2}|https://ctan.org/|
\end{document}