![将两个宏结果相加](https://linux22.com/image/395195/%E5%B0%86%E4%B8%A4%E4%B8%AA%E5%AE%8F%E7%BB%93%E6%9E%9C%E7%9B%B8%E5%8A%A0.png)
我的 overleaf 文档中有一个用于字数统计的宏,它目前位于文档的每个 .tex 部分中,但我希望能够将它们的结果相加(即所有部分的字数统计)。我尝试了几种方法,但都不起作用,该怎么做?我真的不想把所有部分都放在主文档中
我的宏如下
\newcommand{\quickwordcount}[1]{%
\immediate\write18{texcount -1 -sum -merge #1.tex > #1-words.sum }%
\input{#1-words.sum}words%
}
答案1
您可以定义一个\inputcount
命令,这样您就不需要更改部分文件中的代码。
最后的\totalcount
命令将根据计算出的字数打印文档摘要。
\documentclass{article}
\usepackage[a4paper,margin=2cm]{geometry} % to fit just one page
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\inputcount}{m}
{
\file_input:n { #1 }
\aimee_count:n { #1 }
}
\NewDocumentCommand{\totalcount}{}
{
\aimee_count_total:
}
\tl_new:N \g_aimee_count_tl
\seq_new:N \g_aimee_count_file_seq
\seq_new:N \g_aimee_count_words_seq
\cs_new_protected:Nn \aimee_count:n
{
\seq_gput_right:Nx \g_aimee_count_file_seq { \tl_to_str:n { #1 } }
\sys_shell_get:nnN { texcount~-1~-sum~-merge~#1.tex } {} \l__aimee_count_temp_tl
\seq_gput_right:NV \g_aimee_count_words_seq \l__aimee_count_temp_tl
% print the count at the end
\par\bigskip
Section~\tl_to_str:n { #1 }~has~\l__aimee_count_temp_tl\ words
}
\cs_new_protected:Nn \aimee_count_total:
{
\tl_gclear:N \g_aimee_count_tl
\int_step_inline:nn { \seq_count:N \g_aimee_count_file_seq }
{
\tl_gput_right:Nx \g_aimee_count_tl
{
\seq_item:Nn \g_aimee_count_file_seq { ##1 }
&
\seq_item:Nn \g_aimee_count_words_seq { ##1 }
\exp_not:N \\
}
}
\begin{tabular}{@{}lr@{}}
Section & \multicolumn{1}{c@{}}{\#} \\
\hline
\g_aimee_count_tl
\hline
& \int_eval:n { 0+\seq_use:Nn \g_aimee_count_words_seq { + } } \\
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\inputcount{first}
\inputcount{second}
\inputcount{third}
\section*{Total count}
\totalcount
\end{document}
部分文件first.tex
,second.tex
和third.tex
仅包含文本;在我的示例中,first.tex
是
\section{First}
As any dedicated reader can clearly see, the Ideal of
practical reason is a representation of, as far as I know, the things
in themselves; as I have shown elsewhere, the phenomena should only be
used as a canon for our understanding. The paralogisms of practical
reason are what first give rise to the architectonic of practical
reason. As will easily be shown in the next section, reason would
thereby be made to contradict, in view of these considerations, the
Ideal of practical reason, yet the manifold depends on the phenomena.
Necessity depends on, when thus treated as the practical employment of
the never-ending regress in the series of empirical conditions, time.
Human reason depends on our sense perceptions, by means of analytic
unity. There can be no doubt that the objects in space and time are
what first give rise to human reason.
输出
决赛桌
警告
抱歉,它无法在 Overleaf 上运行。问题是 Overleaf 仍在运行过时的 TeX Live 2016 版本,也许他们会在不确定的“不久的将来”切换到同样过时的 TL 2018。
答案2
欢迎来到 TeX.SE!
我的解决方案假设您的 LaTeX 代码将创建一个文件(我们称之为word_count.txt
),每行包含一个数字:给定文件的字数.tex
。我的代码忽略了 中的空行word_count.txt
,因此您可以执行以下操作:
\immediate\write18{echo > word_count.txt}
\immediate\write18{texcount -1 -sum -merge file1.tex >> word_count.txt}
\immediate\write18{texcount -1 -sum -merge file2.tex >> word_count.txt}
...
\immediate\write18{texcount -1 -sum -merge lastfile.tex >> word_count.txt}
第一个命令的目的是允许所有.tex
文件以相同的方式处理,以便>>
将每个文件的字数统计作为新行附加word_count.txt
。否则,如果您可以对第一个文件进行特殊处理,那么这也是可以的(请注意,第一行有>
而不是>>
,以便在写入第一个每个文件的字数统计之前清空文件):
\immediate\write18{texcount -1 -sum -merge file1.tex > word_count.txt}
\immediate\write18{texcount -1 -sum -merge file2.tex >> word_count.txt}
...
\immediate\write18{texcount -1 -sum -merge lastfile.tex >> word_count.txt}
当然,如果您愿意,每个这样的命令都可以放在自己的文件中。如果使用 POSIX shell 运行命令(例如在 Linux 上),\immediate\write18{: > word_count.txt}
可以使用 代替\immediate\write18{echo > word_count.txt}
(:
应该比 快一皮秒echo
左右 :-)。
现在您已将所有这些命令放入.tex
文件中,请编译您的文档。这必须\immediate\write18 ...
对所有.tex
文件执行,无论这些命令都位于“主文件”中还是分散在各个.tex
文件中;并且这些命令中的第一个必须为空word_count.txt
,如上所示。您应该获得word_count.txt
如下所示的文件:
100
252
12
15
>>
(如果您选择对每个文件使用 的方法.tex
,并在所有文件之前使用echo
或:
命令(清空word_count.txt
),则会有一个初始空白行;我的代码已经设计为可以应对这种情况,没问题。它甚至可以处理仅有空白的word_count.txt
文件。)
因此,现在我们有一个正确的word_count.txt
文件,其中每行(可能还有空白行)都有一个每个文件的字数,您可以使用以下命令:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\msg_new:nnn { mycountwords } { file-not-found }
{ File~'#1'~not~found. }
\ior_new:N \g_my_stream_ior
% #1: file name containing one word count per line (blank lines are ignored;
% if the file is empty, this counts as 0 words).
\cs_new_protected:Npn \my_count_words:n #1
{
\ior_open:NnF \g_my_stream_ior {#1}
{ \msg_error:nnn { mycountwords } { file-not-found } {#1} }
\tl_clear:N \l_tmpa_tl
\ior_str_map_inline:Nn \g_my_stream_ior
{
\tl_if_blank:nF {##1} % ignore blank lines
{
\tl_if_empty:NF \l_tmpa_tl % prepend a + unless it's the first count
{ \tl_put_right:Nn \l_tmpa_tl { ~+~ } }
\tl_put_right:Nn \l_tmpa_tl {##1}
}
}
\ior_close:N \g_my_stream_ior
% Handle the case where the file contained nothing but whitespace
\tl_if_blank:VT \l_tmpa_tl
{ \tl_set:Nn \l_tmpa_tl { 0 } }
% Print the word count calculation as an inline mathematical formula
$ \l_tmpa_tl = \int_eval:n { \l_tmpa_tl } $
}
\NewDocumentCommand \mycountwords { m }
{
\my_count_words:n {#1}
}
\ExplSyntaxOff
\begin{document}
Number of words: \mycountwords{word_count.txt}.
\end{document}