为了自动生成报告,我使用了包\ForEach
的循环forarray
。这真是太棒了,因为它节省了我很多时间。
但是,有一个问题:当我迭代的项目包含下划线时,我会收到很多错误(即使 LaTeX 完成编译并创建了 PDF)。
这是一个最小(非)工作示例:
\documentclass[a4paper]{article}
\usepackage{forarray}
\begin{document}
\ForEach
{,}
{
\section{\thislevelitem}
This section covers the topic of \thislevelitem.
} {test_one, test_two, test_three}
\end{document}
如果我将下划线替换为破折号,一切就都正常了。
有没有办法在循环中处理这些下划线\ForEach
?
编辑得更具体:虽然使用test_\one
等在上述最小示例中有效,但对于我的目的来说却无效,因为我通常使用\thislevelitem
来访问图形(包括路径中的下划线)。如果可以在生成图形路径之前用 替换,\_
那么_
这\thislevelitem
将是一个解决方案。
答案1
在文件名中,您可以使用\string
它将特殊输入字符转换_
为普通字符。
请注意,pdf 输出文件中的 LaTeX 计算机现代罗马字体不会为下划线输入字符提供下划线,而是提供变音符号点。
为了在输出中获取下划线输入字符的下划线字符,您需要切换到例如计算机现代打字机(cmr):
\documentclass[a4paper]{article}
\usepackage{forarray}
\begin{document}
\ForEach{,}%
{%
\section{\texttt{\thislevelitem}}%
This section covers the topic of \texttt{\thislevelitem}.%
}%
{%
test\string_one, test\string_two, test\string_three%
}%
\end{document}
顺便说一句:使用\input
(La)TeX 会在收集文件名时不断扩展标记。因此,您可以实现一个\if..
-switch 和一个宏,该宏可以根据内容是打印在文本中还是在系统中用作文件名的一部分来提供\textunderscore
或提供\string_
:
\documentclass[a4paper]{article}
\begin{filecontents*}{test_one.tex}
This is test\textunderscore one
\end{filecontents*}
\begin{filecontents*}{test_two.tex}
This is test\textunderscore two
\end{filecontents*}
\begin{filecontents*}{test_three.tex}
This is test\textunderscore three
\end{filecontents*}
\usepackage{forarray}
\newif\iffilename
\global\filenamefalse
\makeatletter
\newcommand\myunderscore{%
\iffilename
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi{\string_}{\textunderscore}%
}%
\makeatother
\begin{document}
\ForEach{,}%
{%
\section{\thislevelitem}%
This section covers the topic of \thislevelitem.%
{% open up a local scope.
\filenametrue
\\This is the file-name with underscores: \texttt{\thislevelitem}%
\filenamefalse
\\This is the content of the file \textbf{\thislevelitem.tex}:
\filenametrue
\input{\thislevelitem.tex}%
}% close the local scope.
}%
{%
% Be aware that \ForEach does remove leading spaces but does not remove
% trailing spaces from comma-separated items and therefore the last item
% must be trailed by a comment-char neutralizing the space which comes
% into being due to \endlinechar:
test\myunderscore one, test\myunderscore two, test\myunderscore three%<-This comment must be!!!
}%
\end{document}
更通用的是,您可以实现一个宏,它根据其当前定义选择参数:
\documentclass[a4paper]{article}
\begin{filecontents*}{test_one.tex}
This is test\textunderscore one
\end{filecontents*}
\begin{filecontents*}{test_two.tex}
This is test\textunderscore two
\end{filecontents*}
\begin{filecontents*}{test_three.tex}
This is test\textunderscore three
\end{filecontents*}
\usepackage{forarray}
\newcommand\SelectMyThingie[3]{#3}%
\newcommand\printdigits{\renewcommand\SelectMyThingie[3]{##3}}%
\newcommand\printtextphrases{\renewcommand\SelectMyThingie[3]{##2}}%
\newcommand\createfilenames{\renewcommand\SelectMyThingie[3]{##1}}%
\begin{document}
\ForEach{,}%
{%
{% open up a local scope:
\printdigits
\section{\thislevelitem}%
This section covers the topic of \thislevelitem.\\
\printtextphrases
This is the content of the file \textbf{\thislevelitem.tex}:
\createfilenames
\input{\thislevelitem.tex}%
}% close the local scope.
}%
{%
% Be aware that \ForEach does remove leading spaces but does not remove
% trailing spaces from comma-separated items and therefore the last item
% must be trailed by a comment-char neutralizing the space which comes
% into being due to \endlinechar:
test\SelectMyThingie{\string_one}{\textunderscore one}{~1},
test\SelectMyThingie{\string_two}{\textunderscore two}{~2},
test\SelectMyThingie{\string_three}{\textunderscore three}{~3}%<-this comment must be!
}%
\end{document}