我需要保留一个文件列表(最多约 500 个)以及路径。
鉴于每个文件名和路径最多可包含 100 个字符,我是否应该使用 将其保存在以逗号分隔的列表中\g@addto@macro
,还是应该使用 datatool 包或其他什么?
我主要担心的是可能遇到的任何限制。
如果有关系的话,我正在考虑的列表处理就是简单地通过pgf
's\foreach
来遍历每个文件
- 统计文件的类型。
- 也许可以根据文件属性/内容创建单独的子列表。
- 生成包含文件链接的 PDF。
参考
答案1
通常,将列表设置为可执行比使用逗号分隔列表(需要解析)更有效,传统上 LaTeX 使用\@elt
这种方式,但任何宏都可以,其基本思想是
\def\foo{aaa,bbb,ccc,ddd}
\foreach \tmp in \foo ...{\mymacro{\tmp}}
你做
\def\foo{\mymacro{aaa}\mymacro{bbb}\mymacro{ccc}\mymacro{ddd}}
所以它需要更多的存储空间,但要执行它,你只需这样做
\foo
并获得不同的处理,你在本地\mymacro
定义
\count@=0
\def\mymacro#1{\advance\count@ 1 }
\foo
将留下项目数量的计数\count@
答案2
(大卫的打字速度显然比我快!但是,他要打字的东西较少。)
这是一种可能的使用方法datatool
:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{datatool}
\usepackage{hyperref}
\DTLnewdb{files}
\newcommand*{\extlist}{}
\makeatletter
\newcommand*{\getfileext}[2]{%
% Get the file extension
\def\thisfile{#2}%
\filename@parse\thisfile
\let#1\filename@ext
}
\newcommand*{\addfile}[1]{%
\getfileext{\thisfileext}{#1}%
% Has a count register been defined?
\ifcsundef{\thisfileext @count}%
{%
\expandafter\global
\expandafter\newcount\csname \thisfileext @count\endcsname
\listeadd{\extlist}{\thisfileext}%
}%
{}%
\expandafter\global
\expandafter\advance\csname \thisfileext @count\endcsname by 1\relax
\DTLnewrow{files}%
\dtlgetrow{files}{\DTLrowcount{files}}%
\dtlappendentrytocurrentrow{File}{#1}%
\dtlappendentrytocurrentrow{Ext}{\thisfileext}%
\@onelevel@sanitize\thisfile
\dtlappendentrytocurrentrow{Link}{\noexpand\url{\thisfile}}%
\dtlrecombine
}
\makeatother
\addfile{/home/me/documents/paper1/paper1.tex}
\addfile{/home/me/documents/paper1/images/img1.png}
\addfile{/home/me/documents/paper1/images/img2.jpg}
\addfile{/home/me/documents/paper1/images/img2.png}
\addfile{/home/me/documents/paper2/paper2.tex}
\addfile{/home/me/documents/paper2/images/img1.png}
\addfile{/home/me/documents/paper2/images/img2.jpg}
\addfile{/home/me/documents/paper2/images/img2.png}
\begin{document}
File types:
\renewcommand{\do}[1]{Extension: #1.
Count: \number\csname#1@count\endcsname\par}
\dolistloop{\extlist}
\DTLforeach*{files}{\File=File,\Ext=Ext,\Link=Link}{%
File: \File\par
Ext: \Ext\par
Link: \Link\par
}
\end{document}
得出的结果为:
笔记:
\@onelevel@sanitize
我使用for use in清理了路径名\url
,但这可能不是必需的,除非您的文件名中包含奇怪的字符,但这也可能导致数据库出现问题,因此可能有点小题大做。- 如果要在数据库中添加一行,使用 方法
\dtlgetrow
比使用 更快\DTLnewdbentry
。(由于您有 500 个条目,您可能更喜欢更快的不太整洁的选项,而不是更慢的更整洁的选项。)
答案3
我制作了一个文件列表/usr/local/texlive/2013/texmf-dist/tex/latex/base
,其中第一行看起来像
/usr/local/texlive/2013/texmf-dist/tex/latex/base/alltt.sty
/usr/local/texlive/2013/texmf-dist/tex/latex/base/ansinew.def
/usr/local/texlive/2013/texmf-dist/tex/latex/base/applemac.def
/usr/local/texlive/2013/texmf-dist/tex/latex/base/article.cls
/usr/local/texlive/2013/texmf-dist/tex/latex/base/article.sty
/usr/local/texlive/2013/texmf-dist/tex/latex/base/ascii.def
/usr/local/texlive/2013/texmf-dist/tex/latex/base/bezier.sty
我将列表保存在文件中filelist.txt
。然后我准备了这个文档:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\MakeFileList}{mm}
{%1 = list name, #2 = file name
\grill_make_file_list:nn { #1 } { #2 }
}
\NewDocumentCommand{\CountItemsInList}{ O{} m }
{
\grill_count_items_in_list:nn { #1 } { #2 }
}
\ior_new:N \l_grill_file_list_stream
\seq_new:N \l__grill_file_list_temp_seq
\cs_new_protected:Npn \grill_make_file_list:nn #1 #2
{
\seq_new:c { g_grill_file_list_#1_seq }
\ior_open:Nn \l_grill_file_list_stream { #2 }
\ior_map_inline:Nn \l_grill_file_list_stream
{
\seq_gput_right:cn { g_grill_file_list_#1_seq } { ##1 }
}
}
\cs_new_protected:Npn \grill_count_items_in_list:nn #1 #2
{
\seq_clear:N \l__grill_file_list_temp_seq
\seq_map_inline:cn { g_grill_file_list_#2_seq }
{
\tl_if_in:nnT { ##1 } { #1 }
{
\seq_put_right:Nn \l__grill_file_list_temp_seq { ##1 }
}
}
\seq_count:N \l__grill_file_list_temp_seq
}
\ExplSyntaxOff
\begin{document}
\MakeFileList{LaTeX}{filelist.txt}
There are \CountItemsInList{LaTeX} files in total.
There are \CountItemsInList[.tex]{LaTeX} \texttt{.tex} files.
There are \CountItemsInList[.def]{LaTeX} \texttt{.def} files.
There are \CountItemsInList[.ltx]{LaTeX} \texttt{.ltx} files.
There are \CountItemsInList[.sty]{LaTeX} \texttt{.sty} files.
\end{document}
当然,还有其他方法可以构建列表。可以使用正则表达式对文件类型进行更精细的控制。用于计数项目的相同方法可用于根据文件扩展名构建新列表或创建链接。
结果如下。
为了证明结果的正确性,下面是一组 shell 命令:
> ls /usr/local/texlive/2013/texmf-dist/tex/latex/base/ | wc -l
149
> ls /usr/local/texlive/2013/texmf-dist/tex/latex/base/*.tex | wc -l
12
> ls /usr/local/texlive/2013/texmf-dist/tex/latex/base/*.def | wc -l
32
> ls /usr/local/texlive/2013/texmf-dist/tex/latex/base/*.ltx | wc -l
6
> ls /usr/local/texlive/2013/texmf-dist/tex/latex/base/*.sty | wc -l
30