我使用\input
几个spreadtab
来自这个答案在我的文档中直到我收到此错误:
TeX capacity exceeded, sorry [text input levels=15].
我在网上看到,我可以通过将这个参数从 更改为 来解决这个max_in_open = 15
问题max_in_open = 30
。
问题是我不知道在哪里可以找到进行更改的数据。我在 Mac 上使用 TeXStudio。
我正在寻找可以使我的文档正常工作的设置。
\documentclass{article}
\usepackage[a4paper,left=2.5cm,right=2.5cm,bottom=2.8cm,top=2.8cm]{geometry}
\usepackage{longtable,tabu}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{datetime}
\usepackage{siunitx}
\usepackage{multirow}
\usepackage[sc]{mathpazo}
\usepackage{datatool}
\usepackage{spreadtab,booktabs,xpatch}
\usepackage[]{numprint}
\usepackage[]{eurosym}
\usepackage{fp}
\usepackage{booktabs}
\usepackage{tabularx,siunitx}
\usepackage{numprint}
}%=========================
\makeatletter
\def\spreadtab@ii{\IfSubStr\ST@tab{\noexpand\input}{\expandafter\spreadtab@iii\ST@tab\@nil}\relax}
\def\spreadtab@iii#1\input#2#3\@nil{%
\long\def\spreadtab@iv##1\spreadtab@iv{\endgroup\def\ST@tab{#1##1#3}\spreadtab@ii}%
\begingroup
\everyeof{\spreadtab@iv\noexpand}%
\expandafter\spreadtab@iv\@@input#2
}
\xpretocmd\spreadtab@i\spreadtab@ii{}{}
\makeatother
\subsection*{B}
\begin{spreadtab}{{tabular}{@{\hskip1pt}r@{\hskip7pt}p{2.7cm}crrr}}
\toprule
&@ Ku& @ Re & @ Ne & @ Me & @ Br \\
\midrule
\input{Bu1.txt}
\input{Bu2.txt}
\input{Bu3.txt}
\input{Bu4.txt}
\input{Bu5.txt}
\input{Bu6.txt}
\input{Bu7.txt}
\input{Bu8.txt}
\input{Bu9.txt}
\input{Bu10.txt}
\input{Bu11.txt}
\input{Bu12.txt}
\input{Bu13.txt}
\input{Bu14.txt}
\input{Bu15.txt}
\midrule
&@ To & @\thefo &(sum(d2:[0,-1]))tag(BN) & sum(e2:[0,-1])tag(BM)& sum(f2:[0,-1])tag(BB)\\
\bottomrule
\end{spreadtab}
样本内容Bu1.txt
:
@\thefoo&@BU1& @513& 270.00& 551.30& 3231.30\\
其余的*.txt
看上去也类似。
答案1
正如 David 在评论中指出的那样,代码\everyeof{\spreadtab@iv\noexpand} \expandafter\spreadtab@iv\@@input#2
导致每个代码在完成之前\input
都启动另一个代码\input
,就 TeX 而言,这有效地嵌套了输入。
我真的不知道spreadtab
,所以我没有一个好的解决方案。相反,这是一个非常非常非常非常非常非常非常,非常,非常使文档正常工作的糟糕方法。新spreadtabwithinput
环境将用 的内容替换\input{<file>}
其主体中的每个命令<file>
,然后将所有内容传回spreadtab
。您可以\input
在其中放置任意多个命令。
继续需要您自担风险。
% \newwrite\wrt
% \def\x#1;{\immediate\openout\wrt"Bu#1.txt"
% \immediate\write\wrt{@\noexpand\thefoo
% &@BU#1& @513& 270.00& 551.30& 3231.30\noexpand\\}%
% \immediate\closeout\wrt
% \ifnum#1<15 \expandafter\x\number\numexpr#1+1\expandafter;\fi}\x1;
\documentclass{article}
\usepackage{spreadtab,booktabs}
% HACK % HACK % HACK % HACK % HACK % HACK % HACK % HACK % HACK % HACK %
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__ihpro_spreadtab_hack_tl
\tl_new:N \l__ihpro_tmpa_tl
\NewDocumentEnvironment { spreadtabwithinput } { +b }
{
\tl_clear:N \l__ihpro_spreadtab_hack_tl
\__ihpro_spreadtab_loop:w \prg_do_nothing: #1
\input \q_recursion_tail \q_recursion_stop
\exp_last_unbraced:Nno
\begin{spreadtab}
\l__ihpro_spreadtab_hack_tl
\end{spreadtab}
} { }
\cs_new_protected:Npn \__ihpro_spreadtab_loop:w #1 \input #2
{
\tl_put_right:No \l__ihpro_spreadtab_hack_tl {#1}
\quark_if_recursion_tail_stop:n {#2}
\file_get:nnNF {#2} { } \l__ihpro_tmpa_tl
{
\msg_error:nnn { ihpro } { file-not-found } {#2}
\tl_clear:N \l__ihpro_tmpa_tl
}
\exp_last_unbraced:NNo
\__ihpro_spreadtab_loop:w \prg_do_nothing: \l__ihpro_tmpa_tl
}
\msg_new:nnn { ihpro } { file-not-found } { File~'#1'~not~found. }
\ExplSyntaxOff
% HACK % HACK % HACK % HACK % HACK % HACK % HACK % HACK % HACK % HACK %
\newcounter{foo}
\begin{document}
\subsection*{B}
\begin{spreadtabwithinput}{{tabular}{@{\hskip1pt}r@{\hskip7pt}p{2.7cm}crrr}}
\toprule
&@ Ku& @ Re & @ Ne & @ Me & @ Br \\
\midrule
\input{Bu1.txt}
\input{Bu2.txt}
\input{Bu3.txt}
\input{Bu4.txt}
\input{Bu5.txt}
\input{Bu6.txt}
\input{Bu7.txt}
\input{Bu8.txt}
\input{Bu9.txt}
\input{Bu10.txt}
\input{Bu11.txt}
\input{Bu12.txt}
\input{Bu13.txt}
\input{Bu14.txt}
\input{Bu15.txt}
\midrule
&@ To & @\thefoo &(sum(d2:[0,-1]))tag(BN) & sum(e2:[0,-1])tag(BM)& sum(f2:[0,-1])tag(BB)\\
\bottomrule
\end{spreadtabwithinput}
\end{document}
答案2
Heiko Oberdiek 即兴创作的包装捕获文件我想到的是。
您可以使用此包的宏从文件内容中定义宏。
我可以提供例行
\CatchFilesForScantokens{⟨comma-separated file list⟩}{⟨preamble code⟩}{⟨postamble code⟩}
它读取并收集⟨前导码⟩以及每个文件的内容⟨逗号分隔的文件列表⟩和⟨邮寄代码⟩在 verbatim-catcode-regime 中,然后将收集/积累的东西传递到,以便\scantokens
在逐字材料被重新标记时正常的 catcode-régime 生效。
您可以使用此例程作为
\CatchFilesForScantokens{⟨comma-separated file list⟩}%
{⟨stuff for initiating spreadtab-environment}%
{⟨stuff for ending the spreadtab-environment⟩}
(每个文件内部都有⟨逗号分隔的文件列表⟩该例程使用\CatchFileDef
包的宏捕获文件用于从该文件的内容中(重新)定义临时宏 A,以 verbatim-catcode/category-12-régime 进行标记,然后将该临时宏 A 的扩展附加到另一个临时宏 B 的定义中。⟨前导码⟩和⟨邮寄代码⟩也转到另一个临时宏 B。因此,所有内容都累积在另一个临时宏 B 中,其扩展可以\scantokens
在正常的 catcode 制度下传递到该临时宏 B 进行重新标记。
我很懒,所以我使用 expl3 的函数\clist_map_inline:nn
来解析⟨逗号分隔的文件列表⟩)。
以下是示例:
% Create 15 MyBu<X>.txt-files
% ==========================
\begin{filecontents*}{MyBu1.txt}
[0,-1]+1&@BU1& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu2.txt}
[0,-1]+1&@BU2& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu3.txt}
[0,-1]+1&@BU3& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu4.txt}
[0,-1]+1&@BU4& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu5.txt}
[0,-1]+1&@BU5& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu6.txt}
[0,-1]+1&@BU6& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu7.txt}
[0,-1]+1&@BU7& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu8.txt}
[0,-1]+1&@BU8& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu9.txt}
[0,-1]+1&@BU9& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu10.txt}
[0,-1]+1&@BU10& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu11.txt}
[0,-1]+1&@BU11& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu12.txt}
[0,-1]+1&@BU12& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu13.txt}
[0,-1]+1&@BU13& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu14.txt}
[0,-1]+1&@BU14& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
\begin{filecontents*}{MyBu15.txt}
[0,-1]+1&@BU15& @513& 270.00& 551.30& 3231.30\\
\end{filecontents*}
% ==========================================================================================
% Define macro
%
% \CatchFilesForScantokens{<comma-separated file list>}{<preamble code>}{<postamble code>}
%
% to read and collect <preamble-code> and each file of <comma-separated file list> and
% <postamble code> in verbatim-catcode-regime and to pass collected things to \scantokens:
% ==========================================================================================
\RequirePackage{catchfile}
\newcommand\MyScratchmacroA{}%
\newcommand\MyScratchmacroB{}%
% Within a local scope temporarily change the catcode-régime:
\begingroup
%
\makeatletter
\ExplSyntaxOn
%
% We won't need \makeatother / \ExplSyntaxOff as -- like the other changes to the
% catcode-régime -- the effects of \makeatletter and \ExplSyntaxOn will be gone
% when the local scope is closed by \@firstofone.
%
% Use the SOH(=Start Of Heading)-character, code-point-number 1 in ASCII, accessible
% as ^^A in TeX's ^^-notation, for commenting:
\catcode`\^^A=14 %
% Make the CR(=Carriage-Return)-character, code-point-number 13 in ASCII, accessible
% as ^^M in TeX's ^^-notation, an ordinary character --- every line must end by something
% that is taken for a comment-character by TeX as long as this setting is in effect :
\catcode`\^^M=12\relax%
% Make % an ordinary character:
\catcode`\%=12\relax^^A
^^A
\@firstofone{^^A
^^A the first thing \@firstofone shall do is close the local scope where the
^^A catcode-régime is changed:
\endgroup^^A
^^A=============================================================================
^^A PARAPHERNALIA:
^^A \UD@firstoftwo, \UD@secondoftwo, \UD@stopromannumeral, \UD@CheckWhetherNull,
^^A=============================================================================
\newcommand\UD@firstoftwo[2]{#1}^^A
\newcommand\UD@secondoftwo[2]{#2}^^A
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}^^A
^^A-----------------------------------------------------------------------------
^^A Check whether argument is empty:
^^A.............................................................................
^^A \UD@CheckWhetherNull{<Argument which is to be checked>}%
^^A {<Tokens to be delivered in case that argument
^^A which is to be checked is empty>}%
^^A {<Tokens to be delivered in case that argument
^^A which is to be checked is not empty>}%
^^A
^^A The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
^^A <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{^^A
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter^^A
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter^^A
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter^^A
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{^^A
\expandafter\UD@stopromannumeral\UD@firstoftwo}^^A
}^^A
^^A-----------------------------------------------------------------------------
^^A Check whether_verbatimized_ argument has a trailing explicit
^^A <carriage-return>-character-token of catcode 12(other):
^^A-----------------------------------------------------------------------------
^^A \UD@CheckWhetherTrailingCarriageReturn{<Argument which is to be checked>}%
^^A {<Tokens to be delivered in case
^^A <argument which is to be checked>'s
^^A last token is an explicit <carriage-
^^A return>-character-token of
^^A catcode 12(other)>}%
^^A {<Tokens to be delivered in case
^^A <argument which is to be checked>'s
^^A last token is not an explicit
^^A <carriage-return>-character-token of
^^A catcode 12(other)>}%
\newcommand\UD@CheckWhetherTrailingCarriageReturn[1]{^^A
\UD@@CheckWhetherTrailingCarriageReturn#1\UD@SelDom^^M\UD@SelDom\UD@@SelDom^^A
}^^A
\@ifdefinable\UD@@CheckWhetherTrailingCarriageReturn{^^A
\long\def\UD@@CheckWhetherTrailingCarriageReturn#1^^M\UD@SelDom#2\UD@@SelDom{^^A
\UD@CheckWhetherNull{#2}{\UD@secondoftwo}{\UD@firstoftwo}^^A
}^^A
}^^A
^^A=============================================================================
\NewDocumentCommand\CatchFilesForScantokens{m}{^^A
\begingroup^^A
\let\do\@makeother^^A
\do\^^I^^A
\CatchFilesForScantokensInner{#1}^^A
}^^A
\newcommand\verbatimregime{^^A
\let\do\@makeother^^A
\dospecials^^A
\do\^^I^^A
\do\^^M^^A
\endlinechar=`\^^M\relax^^A
\newlinechar=\endlinechar^^A
}^^A
\NewDocumentCommand\CatchFilesForScantokensInner{m+v+v}{^^A
\endgroup^^A
\begingroup^^A
\edef\MyScratchmacroB{^^A
\expandafter\UD@CheckWhetherTrailingCarriageReturn\expandafter{\detokenize{#2}}^^A
{\unexpanded\expandafter{\detokenize{#2}}}^^A
{\unexpanded\expandafter{\detokenize{#2^^M}}}^^A
}^^A
\clist_map_inline:nn{#1}{^^A
^^A\message{##1^^J}^^A
\CatchFileDef{\MyScratchmacroA}{##1}{\verbatimregime}^^A
\edef\MyScratchmacroB{^^A
\unexpanded\expandafter\expandafter\expandafter{\expandafter\MyScratchmacroB\detokenize\expandafter{\MyScratchmacroA}}^^A
}^^A
}^^A
\edef\MyScratchmacroB{^^A
\unexpanded\expandafter\expandafter\expandafter{\expandafter\MyScratchmacroB\detokenize{#3}%}^^A
}^^A
\newlinechar=\endlinechar^^A
^^A=======================================================================
^^A If you want to see on connsole what \scantokens gets as spreadtab,
^^A then enable the next but one line by removing the leading ^^A
^^A=======================================================================
^^A\show\MyScratchmacroB^^A
\scantokens\expandafter{\expandafter\endgroup\MyScratchmacroB}^^A
}^^A
}%
% Create document:
% =================
\documentclass{article}
\usepackage[a4paper,left=2.5cm,right=2.5cm,bottom=2.8cm,top=2.8cm]{geometry}
\usepackage{longtable,tabu}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{datetime}
\usepackage{siunitx}
\usepackage{multirow}
\usepackage[sc]{mathpazo}
\usepackage{datatool}
\usepackage{spreadtab,booktabs,xpatch}
\usepackage[]{numprint}
\usepackage[]{eurosym}
\usepackage{fp}
\usepackage{booktabs}
\usepackage{tabularx,siunitx}
\usepackage{numprint}
\begin{document}
\CatchFilesForScantokens{%
MyBu1.txt,
MyBu2.txt,
MyBu3.txt,
MyBu4.txt,
MyBu5.txt,
MyBu6.txt,
MyBu7.txt,
MyBu8.txt,
MyBu9.txt,
MyBu10.txt,
MyBu11.txt,
MyBu12.txt,
MyBu13.txt,
MyBu14.txt,
MyBu15.txt
}%
{%
\begin{spreadtab}{{tabular}{@{\hskip1pt }r@{\hskip7pt }p{2.7cm }crrr}}
\toprule
&@ Ku& @ Re & @ Ne & @ Me & @ Br \\ % <- This is row 1.
\midrule
\SThiderow 0&&&&&\\ % <- This is row 2 and it is invisible and used for initial values.
}%
{%
\midrule
&@To & [-2,-1] &(sum(d3:[0,-1]))tag(BN) & sum(e3:[0,-1])tag(BM)& sum(f3:[0,-1])tag(BB)\\
\bottomrule
\end{spreadtab}
}%
\end{document}
!!! 这种方法基于逐字分类代码机制读取/标记文件。因此,\input
在⟨逗号分隔的文件列表⟩将不会执行。即,\input
无法嵌套。您所能做的就是提供文件列表。!!!
!!! 它也依赖于读取和标记⟨前导码⟩和⟨邮寄代码⟩在逐字分类代码制度中。这反过来意味着\CatchFilesForScantokens
- 不能隐藏在任何宏的定义中,并且
- 不能在宏参数中使用,即
- 必须以这样的方式使用,确保在临时引入的类别代码制度的变化
\CatchFilesForScantokens
生效时,通过从 .tex 输入文件中读取和标记内容来获取参数。
!!!
答案3
在许多 TeX 发行版中,存在一个名为 texmf.cnf 的文件。它通常位于texmf/web2c
并包含上述参数。通常不建议乱用这种配置文件。但是,如果您的 TeX 支持此选项,则可以在命令行中使用开关进行设置--cnf-line='max_in_open=30'
,例如:
lualatex --cnf-line='max_in_open=30' some-file.tex
许多编辑器支持针对项目或单个 TeX 文件的特殊命令行。例如,GNU Emacs 支持添加名为的文件局部变量,TeX-command-extra-options: "--cnf-line='max_in_open=30'"
这样 TeX 文件的结尾可能如下所示:
% mode: latex
% TeX-master: t
% TeX-command-extra-options: "--cnf-line='max_in_open=30'"
% End: