自动生成文档中 \url 用法列表

自动生成文档中 \url 用法列表

我正在写一篇论文,我大量使用了通过\url\url在 内的超链接\footnote。现在我想添加一个列表(有点像简化的参考书目,其中每个链接只出现一次),其中包含文档中的所有超链接。有没有办法自动为我生成这个列表?

答案1

  1. 下面的示例使用hyperref(问题中提到了“超链接”)并挂钩\hyper@linkurl来获取 URL。

  2. 捕获的 URL 被写入索引文件\jobname-url.idx

    \urlentry{<hex coded URL>}{<page number>}
    

    URL 采用十六进制编码,以避免特殊字符的困扰。

  3. filecontents帮助创建\jobname-url.mst的样式文件makeindex。Makeindex 自动查找与输入文件同名但扩展.mst名为样式文件的文件。然后只需.idx将文件作为 的参数给出即可makeindex

  4. Makeindex 生成文件\jobname-url.ind

    \begin{theurls}
    \urlitem{<hex coded URL>}{<page list>}
    ...
    \end{theurls}
    
  5. 环境theurls并被\urlitem适当地定义来打印 URL 列表。\listurlname包含该部分的标题。

评论

  • Makeindex 负责排序并删除重复项。
  • 挂钩\hyper@linkurl的优点是 URL 被规范化(例如,%\%相同,%catcode 为 12/other)。
  • 十六进制编码的优点是,特殊字符(例如百分比、哈希值)或对 makeindex 有特殊含义的字符(at 符号,...)不需要特殊处理。

示例文件:

\RequirePackage{filecontents}
\begin{filecontents*}{\jobname-url.mst}
% Input style specifiers
keyword "\\urlentry"
% Output style specifiers
preamble "\\begin{theurls}"
postamble "\\end{theurls}\n"
group_skip ""
headings_flag 0  
item_0 "\n\\urlitem{"
delim_0 "}{"
delim_t "}"
line_max 500
\end{filecontents*}

\documentclass{article}   
\usepackage[colorlinks]{hyperref}
\usepackage{pdfescape}

\makeatletter
\newwrite\file@url
\openout\file@url=\jobname-url.idx\relax

\newcommand*{\write@url}[1]{%
  \begingroup
    \EdefEscapeHex\@tmp{#1}%
    \protected@write\file@url{}{%
      \protect\urlentry{\@tmp}{\thepage}%
    }%
  \endgroup
}
\let\saved@hyper@linkurl\hyper@linkurl
\renewcommand*{\hyper@linkurl}[2]{%
  \write@url{#2}%
  \saved@hyper@linkurl{#1}{#2}%
}
\newcommand*{\listurlname}{List of URLs}
\newcommand*{\printurls}{%
  \InputIfFileExists{\jobname-url.ind}{}{}%
}
\newenvironment{theurls}{%
  \section*{\listurlname}%
  \@mkboth{\listurlname}{\listurlname}%
  \let\write@url\@gobble  
  \ttfamily
  \raggedright
}{%
  \par
}
\newcommand*{\urlitem}[2]{%
  \hangindent=1em
  \hangafter=1   
  \begingroup    
    \EdefUnescapeHex\@tmp{#1}%
    \expandafter\url\expandafter{\@tmp}%
  \endgroup
  \par
}
\makeatother

\usepackage[T1]{fontenc}
\usepackage[variablett]{lmodern}

\begin{document}
This this file answers the
\href{http://tex.stackexchange.com/q/121977/16967}{question}
on \href{http://tex.stackexchange.com/}{\TeX.SE}.

Further examples for URLs:
\url{http://www.dante.de/}\\
\url{http://www.ctan.org/}\\
\url{mailto:[email protected]/}\\
\url{ftp://ftp.dante.de/pub/tex/}\\
\url{http://www.example.com/\%7efoo/index.html}\\
\url{http://www.example.com/%7efoo/index.html} 

\printurls
\end{document}

以下命令生成结果(linux/bash):

$ pdflatex test

生成test-url.msttest-url.idx

$ makeindex test-url

生成test-url.ind

$ pdflatex test

结果

更新页码

页码的格式化方法有很多种。以下示例使用点将 URL 与行末出现的页码分开(类似于包的索引doc)。根据要求p.,如果后面只有一个页码,则页码以 为前缀,pp.否则为前缀。这是在包的帮助下xstring通过测试页码列表是否包含逗号分隔符或范围说明符中的连字符来实现的。

\RequirePackage{filecontents}
\begin{filecontents*}{\jobname-url.mst}
% Input style specifiers
keyword "\\urlentry"
% Output style specifiers
preamble "\\begin{theurls}"
postamble "\n\\end{theurls}\n"
group_skip ""
headings_flag 0  
item_0 "\n\\urlitem{"
delim_0 "}{"
delim_t "}"
line_max 500
\end{filecontents*}

\documentclass{article}   
\usepackage[colorlinks]{hyperref}
\usepackage{pdfescape}
\usepackage{xstring}

\makeatletter
\newwrite\file@url
\openout\file@url=\jobname-url.idx\relax

\newcommand*{\write@url}[1]{%
  \begingroup
    \EdefEscapeHex\@tmp{#1}%
    \protected@write\file@url{}{%
      \protect\urlentry{\@tmp}{\thepage}%
    }%
  \endgroup
}
\let\saved@hyper@linkurl\hyper@linkurl
\renewcommand*{\hyper@linkurl}[2]{%
  \write@url{#2}%
  \saved@hyper@linkurl{#1}{#2}%
}
\newcommand*{\listurlname}{List of URLs}
\newcommand*{\printurls}{%
  \InputIfFileExists{\jobname-url.ind}{}{}%
}
\newenvironment{theurls}{%
  \section*{\listurlname}%
  \@mkboth{\listurlname}{\listurlname}%
  \let\write@url\@gobble  
  \ttfamily
  \raggedright
  \setlength{\parfillskip}{0pt}%
}{%
  \par
}
\newcommand*{\urlitem}[2]{%
  \hangindent=1em
  \hangafter=1   
  \begingroup    
    \EdefUnescapeHex\@tmp{#1}%
    \expandafter\url\expandafter{\@tmp}%
  \endgroup
  \urlindex@pfill
  \IfSubStr{#2}{,}{pp}{%
    \IfSubStr{#2}{-}{pp}{p}%
  }.\@\space\ignorespaces
  #2%
  \par
}
\newcommand*{\urlindex@pfill}{% from \pfill of package `doc'
  \unskip~\urlindex@dotfill
  \penalty500\strut\nobreak
  \urlindex@dotfil~\ignorespaces
}
\newcommand*{\urlindex@dotfill}{% from \dotfill of package `doc'
  \leaders\hbox to.6em{\hss .\hss}\hskip\z@ plus  1fill\relax
}
\newcommand*{\urlindex@dotfil}{% from \dotfil of package `doc'
  \leaders\hbox to.6em{\hss .\hss}\hfil
}
\makeatother

\usepackage[T1]{fontenc}
\usepackage[variablett]{lmodern}

\begin{document}
This this file answers the
\href{http://tex.stackexchange.com/q/121977/16967}{question}
on \href{http://tex.stackexchange.com/}{\TeX.SE}.

Further examples for URLs:
\url{http://www.dante.de/}\\
\url{http://www.ctan.org/}\\
\url{mailto:[email protected]/}\\
\url{ftp://ftp.dante.de/pub/tex/}\\
\url{http://www.example.com/\%7efoo/index.html}\\
\url{http://www.example.com/%7efoo/index.html} 

% further pages to generate more page numbers for testing the url index
\newpage
\url{http://www.ctan.org}
\newpage
\url{http://www.ctan.org}
\url{http://tex.stackexchange.com/}

\newpage
\printurls

\end{document}

带页码的结果

答案2

警告 注意:以下代码仅适用于简单 URL,即不包含特殊字符的 URL,例如%。有关完整解决方案,请参阅 Heiko 的回答。


正如 Nicola 在评论中提到的,重新定义\url可能是一个有趣的想法,但 URL 中的某些字符可能会导致问题。遗憾的是我的 TeX-fu 还不足以解决这个问题,但这是一个初步的开始:

\documentclass{article}
\usepackage{url}
\usepackage{imakeidx}

\let\originalurl\url

\makeindex[name=urls, title={Links found in this document}, columns=1]

\renewcommand{\url}[1]{\originalurl{#1}\index[urls]{\protect\originalurl{#1}}
}

\begin{document}

Hello, make sure to visit \url{http://www.google.com} and,
of course, our own place \url{http://tex.stackexchange.com}.

By the way, \url{http://tex.stackexchange.com} is awesome!

\printindex[urls]

\end{document}

然后生成列表:

链接

希望能帮助到你。:)

相关内容