如何自动将多个文本文档包含到一个 LaTeX 文档中?

如何自动将多个文本文档包含到一个 LaTeX 文档中?

我有几个.txt.dat文件,其名称的形式为:dn-ddmmyyyy.txt。例如:

d0-01021989.txt
d1-21021989.txt
d2-15021994.txt
d3-12121996.txt
d4-14032014.txt
d5-22022035.txt
...many more...

\include包含所有文件而无需手动逐个使用的最佳方法是什么?

有没有办法为每个文档创建一个标题(如章节标题),如“文档 N”,并提取文件名中的数字(即日期)并将其放入标题中?

有没有办法仅使用 TeX 来实现这一点?

答案1

我不知道是否有仅限 TeX 的解决方案(但我可以想象这lualatex很方便),但我通常会这样做:

1)使用类似的命令dir /b *.tex > allFiles.txt?获取所有 TeX 文件的文件。(/b除了文件名之外,隐藏所有内容)

2)打开 Excel,粘贴内容allFiles.txt并使用字符串连接来构建包含命令。

对于一次性来说,这是最有效的解决方案。如果我需要定期更新 TeX 文件,我会编写一个简短的 Python/Bash/Batch 文件。

编辑:

lualatex我在其中一个答案中找到了通过 Lua 调用包含的一些合适的代码这里并能够对其进行一些调整。它\write18也使用,因此必须与一起使用--shell-escape。我非常确定仅使用 Lua 的解决方案是可能的,但这显然超出了我的 Lua 知识范围。

%!TEX TS-program = LuaLaTeX

\documentclass[12pt,ngerman]{scrartcl}
\usepackage{luacode}

\begin{document}
Some text before the Lua call.

\begin{luacode}
function scandir(directory)
    local i, t, popen = 0, {}, io.popen
    for filename in popen('dir "'.. directory .. '" /b d*.tex'):lines() do
        i = i + 1
        t[i] = filename
       tex.print('\\input{includes/' .. filename .. '} from ' .. filename ..'\\clearpage')  
    end
    return t
end
scandir("C:/Users/Uwe/LuaLula/includes/")
\end{luacode}

\end{document}

答案2

此解决方案仅适用于 Microsoft Windows 用户。对于 Linux、MAC、Unix 用户,您必须调整批处理相关部分。对此造成的不便深表歉意,感谢您的合作。

下面这段代码其实也是几十年前准备好的此处(点击). 使用 进行编译pdflatex -shell-escape filename. 确保

  • 要包含的输入文件放在子目录中Sub-Dir
  • 路径中不允许有空格(以简化代码)。

通用最小工作示例

% filename.tex

\documentclass[preview,border=12pt,12pt,varwidth]{standalone}

\usepackage{filecontents}
\begin{filecontents*}{batch.txt}
rem batch.bat
echo off

rem %1 path (relative to the main input file) to the files to be iterated 
rem %2 output file name
rem remaining args represent the extension of file to be iterated

set curdir=%CD%
cd "%~1"
shift

rem output must be enclosed with "" to allow spaces in the path
set output="%curdir%\%~1.list"

if exist %output% del %output%
copy nul %output%
shift

:loop
if "%~1"=="" goto :eof
dir /b *.%~1 >> %output%
shift
goto :loop
\end{filecontents*}


\begin{filecontents*}{oh-my-ghost.tex}
No body no body but you!
\[
E\not = mc^2
\]
\end{filecontents*}

\begin{filecontents*}{hahaha.tex}
PSTricks is fun!
\[
pV = nRT
\]
\end{filecontents*}


\immediate\write18{%
    del batch.bat && 
    rename batch.txt batch.bat && 
    move oh-my-ghost.tex Sub-Dir/oh-my-ghost.tex && 
    move hahaha.tex Sub-Dir/hahaha.tex
}


\newread\reader
\newcount\TotalFiles    


\makeatletter
\newcommand\IterateInputFiles[2][tex]{%
% #1: directory path with a trailing /
% #2: a list of file extensions: tex 
\immediate\write18{batch "#2" \jobname\space #1}
\openin\reader=\jobname.list\relax
\loop
    \read\reader to \filename
    \unless\ifeof\reader
    \filename@parse{\filename}
    \section{\filename@base}% change to \chapter if you want 
    \include{"#2\filename@base"}
    \advance\TotalFiles1\relax
\repeat
\closein\reader
}
\makeatother



\begin{document}
\IterateInputFiles{Sub-Dir/}

\section{Summary}
There is(are) \the\TotalFiles\ file(s) in total.
\end{document}

输出

下面的输出证明我没有说谎。

在此处输入图片描述


多平台版本

% filename.tex

\documentclass[preview,border=12pt,12pt,varwidth]{standalone}

\newif\ifDOS
%\DOStrue
\DOSfalse

\usepackage{filecontents}
\ifDOS
\begin{filecontents*}{batch.txt}
rem batch.bat
echo off

rem %1 path (relative to the main input file) to the files to be iterated
rem %2 output file name
rem remaining args represent the extension of file to be iterated

set curdir=%CD%
cd "%~1"
shift

rem output must be enclosed with "" to allow spaces in the path
set output="%curdir%\%~1.list"

if exist %output% del %output%
copy nul %output%
shift

:loop
if "%~1"=="" goto :eof
dir /b *.%~1 >> %output%
shift
goto :loop
\end{filecontents*}
\else
\begin{filecontents*}{batch.txt}
#!/bin/bash
# bash batch.sh Sub-Dir output tex

# $1 path (relative to the main input file) to the files to be iterated
# $2 output file name
# remaining args represent the extension of file to be iterated

output="$2.list"

if [ -e "$output" ]; then
    rm "$output"
fi

for ext in ${@:3}; do
    ls "$1"/*."$ext" >> "$output"
done
# $ (to squelch bad syntax highlighting in my editor)
\end{filecontents*}
\fi

\begin{filecontents*}{oh-my-ghost.tex}
No body no body but you!
\[
E\not = mc^2
\]
\end{filecontents*}

\begin{filecontents*}{hahaha.tex}
PSTricks is fun!
\[
pV = nRT
\]
\end{filecontents*}


\ifDOS
\immediate\write18{%
  del batch.bat &&
  rename batch.txt batch.bat &&
  move oh-my-ghost.tex Sub-Dir/oh-my-ghost.tex &&
  move hahaha.tex Sub-Dir/hahaha.tex
}
\else
\immediate\write18{%
  mv batch.txt batch.sh &&
  mkdir -p Sub-Dir &&
  mv oh-my-ghost.tex hahaha.tex Sub-Dir/
}
\fi


\newread\reader
\newcount\TotalFiles

\makeatletter
\newcommand\IterateInputFiles[2][tex]{%
% #1: directory path with a trailing /
% #2: a list of file extensions: tex
\ifDOS
\immediate\write18{batch "#2" \jobname\space #1}
\else
\immediate\write18{bash batch.sh "#2" \jobname\space #1}
\fi
\openin\reader=\jobname.list\relax
\let\filename\relax
\loop
  \read\reader to \filename
  \typeout{<<< here again}
  \unless\ifeof\reader
  \filename@parse{\filename}
  \section{\filename@base}% change to \chapter if you want
  \include{"#2\filename@base"}
  \advance\TotalFiles1\relax
\repeat
\closein\reader
}
\makeatother

\begin{document}
\IterateInputFiles{Sub-Dir/}

\section{Summary}
There is(are) \the\TotalFiles\ file(s) in total.
\end{document}

相关内容