我有一堆单独的 .tex 文件,希望能够单击其中一个 PDF 文件中的链接并打开相应的 PDF 文件。这些文件很小,因此实际上不需要对它们进行索引,只需打开它们即可。
要打开的文件名(在大多数情况下)可以从描述性链接文本中确定——下面的算法。在某些情况下,文件名无法轻易确定,因此我希望能够手动指定它。因此,我定义:
\NewDocumentCommand{\CrossReference}{O{\NoValue} m}
在哪里
#1 = optional file name (determined from #2 if not provided)
#2 = link text
我遇到过这种情况,我手动指定了下面 MWE 中的文件名。但是,由于文件名很容易确定,所以我想不必提供它。这就是它\ConvertToFileNameWithPath
应该发挥作用的地方。
文件命名算法:
如果未指定文件名,则通过以下方式从给定的链接文本中获取:
- 将所有字符改为小写。
- 用破折号替换所有空白。
- 添加
.pdf
扩展
笔记:
为了使下面的 MWE 起作用(即测试链接是否可点击),该文件
equation-of-circle.pdf
必须存在于当前目录中。最终,宏
\ConvertToFileNameWithPath
将在特定目录列表中搜索此文件名——下一步将解决这个问题。所以这将是上述算法中的第 4 步。我确实看过包裹
xr
不确定它是否适合这种情况,主要是因为笔记2(可能有多个同名的文件)。
参考/失败的尝试:
我尝试改编 Joseph Wright 的回答\MakeUppercase 是否有纯粹可扩展的变体?,但没有成功。在同一个问题上,它还提到
\tl_expandable_lowercase:n
现在可用,所以这肯定会有所帮助。但我不明白expl3
,我不能再进一步了。我这样做是基于 Bruno Le Floch 对我的问题的回答:输出不应显示的文本。虽然我在这方面没有取得很大进展,但也许这可以帮助其他人解决这个问题。
我也尝试使用一系列的
\StrSubstitute{\Temp}{A}{A}[\Temp]
来\StrSubstitute{\Temp}{B}{b}[\Temp]
进行转换,但是这会遇到扩展问题,而使用\tl_expandable_lowercase:n
应该更容易。
代码:
当上方和下方的文本\hrule
相同时,这应该可以工作:当然假设您equation-of-circle.pdf
在当前目录中,并且可以通过第 1 行和第 3 行打开它。目前我只能通过第 1 行打开它,其中我手动指定了文件名:
\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}
\usepackage{hyperref}
%\ExplSyntaxOn -- am guessing that this will be needed...
\DeclareExpandableDocumentCommand{\ConvertToFileNameWithPath}{o m}{%
% This will eventually also locate a file in a given path
\IfNoValueTF{#1}{% file name not specified so need to figure it out
% ????????? What goes here ???????
./#2.pdf% Need to convert #2 to a file name. ????????
}{% We were given, the file name -- Even I can handle this case
./#1.pdf%
}%
}
%\ExplSyntaxOff
\NewDocumentCommand{\CrossReference}{O{\NoValue} m}{%
% #1 = optional file name (determined from #2 if not provided)
% #2 = link text
\edef\PdfFileName{\ConvertToFileNameWithPath[#1]{#2}}%
\IfFileExists{\PdfFileName}{%
\href{run:\PdfFileName}{#2}%
}{%
\fcolorbox{red}{yellow}{#2}%
\footnote{Unable to locate \PdfFileName}%
}%
}%
\begin{document}
Manual References: \CrossReference[equation-of-circle]{Equation of Circle}%
Manual References: \CrossReference[non-existant-file]{Non Existant File}%
\medskip\hrule\medskip
Automatic References: \CrossReference{Equation of Circle}%
Automatic References: \CrossReference{Non Existant File}%
\end{document}
答案1
\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}
\usepackage{hyperref}
\ExplSyntaxOn
\NewDocumentCommand{\CrossReference}{ o m }
{
\IfNoValueTF{#1}
{ \grill_convert_name:n { #2 } }
{ \tl_set:Nn \l_grill_file_name_tl { #1 } }
\grill_set_link:n { #2 }
}
\tl_new:N \l_grill_file_name_tl
\cs_new:Npn \grill_convert_name:n #1
{
\tl_to_lowercase:n { \tl_set:Nn \l_grill_file_name_tl { #1 } }
\tl_replace_all:Nnn \l_grill_file_name_tl { ~ } { - }
}
\cs_new:Npn \grill_set_link:n #1
{
\file_if_exist:nTF { \l_grill_file_name_tl .pdf }
{
\group_begin:
\cs_set:Npx\grill_temp:
{
\group_end:
\exp_not:N \href{run\token_to_str:N : \l_grill_file_name_tl .pdf}{ #1 }
}
\grill_temp:
}
{
\fcolorbox{red}{yellow}{#1}
\footnote{Unable~to~locate~\l_grill_file_name_tl}
}
}
\ExplSyntaxOff
\begin{document}
\CrossReference{Abc Def}
\CrossReference[abc-def]{abc def}
\end{document}
用连字符替换空格并转换为小写很容易。
答案2
我无法想象为什么你需要在这里使用小写字母扩展(这样链接就无法使用了),那么为什么不直接
\def\foo#1#2{{%
\lccode`\ `\-%
\lowercase{#1{#2.pdf}}}}
\foo{\write20}{AB cd / eFG}
\bye
生成结果:
tex lc
This is TeX, Version 3.1415926 (Web2C 2010)
(./lc.tex [1
ab-cd-/-efg.pdf
] )
在 LaTeX 中使用它并稍微调整以匹配你的 MWE:
\documentclass{article}
\textheight10\baselineskip
\usepackage{hyperref,color}
\def\xCrossReference#1#2{%
\IfFileExists{#1}{%
\href{#1}{#2}}{%
\fcolorbox{red}{yellow}{#2}%
\footnote{Unable to locate #1}}}
\newcommand\CrossReference[2][\relax]{%
\ifx\relax#1%
\bgroup\lccode`\ `\-\lowercase{\egroup
\xCrossReference{#2.pdf}}{#2}%
\else
\xCrossReference{#1.pdf}{#2}%
\fi}
\begin{document}
Manual References: \CrossReference[equation-of-circle]{Equation of Circle}%
Manual References: \CrossReference[non-existant-file]{Non Existant File}%
\medskip\hrule\medskip
Automatic References: \CrossReference{Equation of Circle}%
Automatic References: \CrossReference{Non Existant File}%
\end{document}
\end{document}