我正在编写自己的信件类,我想知道如何处理多个附件。目前,我为自己制作了一个宏,接受一个应该在序言中设置的参数。内容(如果有)由我的信件环境自动打印。
如果有多个附件,我想调用两次宏,这通常会覆盖第一个声明(参见我的 MWE)。但是,当 LaTeX 从上到下读取代码时,它首先看到我的第一个声明并对其进行处理。如果我可以把这个值存储在大批这样就安全了。如果出现第二个声明,我可以将其内容附加到第一个声明中。然后使用 for 循环可以打印列表中的所有附件。这在其他编程语言(如 PHP 或 Python)中非常容易,所以我认为 LaTeX 也能处理这个问题。
平均能量损失
班级
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{customLetterClass}[2017/10/20 Custom Letter Class]
\LoadClass{article}
% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%
\usepackage[english]{babel}
\usepackage{%
parskip,%
tabularx,%
environ,%
etoolbox%
}
% %%%%%%%%%%%%%%%%%
% Declare Variables
% %%%%%%%%%%%%%%%%%
% Attachment
\def\attachment#1{\gdef\@attachment{#1}}
\def\@attachment{}
% %%%%%%%%%%%%%%%%%%
% Define environment
% %%%%%%%%%%%%%%%%%%
\NewEnviron{letter}%
{%
% Letter text
{\BODY}%
%
% Attachment (if set)
\ifdefempty{\@attachment}%
{}%
{
\\[5\baselineskip]
\begin{tabularx}{\textwidth}{@{}lX@{}}
Attachment: & \@attachment
\end{tabularx}
}%
}%
主要的
% %%%%%%%%%%%%%%
% Document Setup
% %%%%%%%%%%%%%%
\documentclass{customLetterClass}
% %%%%%%%%%%%%%%%%%%%
% Set Variable Values
% %%%%%%%%%%%%%%%%%%%
% Attachment
\attachment{Foo}
\attachment{Bar}
\begin{document}
\begin{letter}
Hallo
\end{letter}
\end{document}
抱歉,无法将其放在一个文件中,但如果我将其更改documentclass
为article
并将类的内容粘贴到我的序言中,测试就会突然\ifdefempty
无法正常工作。我没有发现问题,所以在这里我发布了两个文件。
问题沃纳的方法
如果我将 Werner 假设的代码包含到环境中letter
,我会收到一条奇怪的错误消息。如果我使用他提供的 MWE,则不会发生这种情况。我多次检查了代码,但找不到问题所在。这就是我向这个 MWE 提供产生错误的代码的原因,这样每个人都知道我们在哪里。也许我们也可以解决最后一点。:-)
班级
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{customLetterClass}[2017/10/20 Custom Letter Class]
\LoadClass{article}
% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%
\RequirePackage[english]{babel}
\RequirePackage{%
parskip,%
tabularx,%
environ,%
etoolbox%
}
% %%%%%%%%%%%%%%%%%
% Declare Variables
% %%%%%%%%%%%%%%%%%
% Attachment
\newcounter{attachment}
\newcommand{\attachmentpar}{%
\renewcommand{\attachmentpar}{\par}%
}
\newcommand{\attachment}[1]{%
\stepcounter{attachment}%
\listadd{\attachments}{#1}%
}
% %%%%%%%%%%%%%%%%%%
% Define environment
% %%%%%%%%%%%%%%%%%%
\NewEnviron{letter}%
{%
% Letter text
{\BODY}%
%
% Attachment (if set)
\ifnum\value{attachment}>0 % No \attachment
\\[5\baselineskip]
\begin{tabularx}{\linewidth}{ @{} l X @{} }
\ifnum\value{attachment}=1 % Only one \attachment
Attachment
\else % Multiple \attachments
Attachments
\fi &
\renewcommand{\do}[1]{\attachmentpar #1}% How each item should be processed
\dolistloop{\attachments}% Process list of \attachments
\end{tabularx}
\fi
}%
主要的
与上相同
错误
\c@attachment=\count89
! \env@letter@process 定义中的参数数量非法。
答案1
由于你正在使用etoolbox
,您可以使用其列表处理功能。使用 存储项目\listadd{<list csname>}{<item>}
并使用 处理它们\dolistloop{<list csname>}
。
customLetterClass.cls
:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{customLetterClass}[2017/10/20 Custom Letter Class]
\LoadClass{article}
% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%
\RequirePackage[english]{babel}
\RequirePackage{%
parskip,%
tabularx,%
environ,%
etoolbox%
}
% %%%%%%%%%%%%%%%%%
% Declare Variables
% %%%%%%%%%%%%%%%%%
% Attachment
\newcounter{attachment}
\newcommand{\attachmentpar}{%
\renewcommand{\attachmentpar}{\par}%
}
\newcommand{\attachment}[1]{%
\stepcounter{attachment}%
\listadd{\attachments}{#1}%
}
% %%%%%%%%%%%%%%%%%%
% Define environment
% %%%%%%%%%%%%%%%%%%
\NewEnviron{letter}%
{%
% Letter text
{\BODY}%
%
% Attachment (if set)
\ifnum\value{attachment}>0 % No \attachment
\\[5\baselineskip]
\begin{tabularx}{\linewidth}{ @{} l X @{} }
\ifnum\value{attachment}=1 % Only one \attachment
Attachment
\else % Multiple \attachments
Attachments
\fi &
\renewcommand{\do}[1]{\attachmentpar ##1}% How each item should be processed
\dolistloop{\attachments}% Process list of \attachments
\end{tabularx}
\fi
}%
main.tex
:
% %%%%%%%%%%%%%%
% Document Setup
% %%%%%%%%%%%%%%
\documentclass{customLetterClass}
% %%%%%%%%%%%%%%%%%%%
% Set Variable Values
% %%%%%%%%%%%%%%%%%%%
% Attachment
\attachment{Foo}
\attachment{Bar}
\begin{document}
\begin{letter}
Hallo
\end{letter}
\end{document}
编写宏\attachment
的目的是计算添加的附件数量。这样就可以决定是否打印Attachment
或Attachments
(或其他)。
答案2
应\def\attachment
先检查是否\@attachment
为空,然后将其定义为\@attachment
,否则先使用\xdef
语句进行扩展\@attachment
,然后将新的附件粘贴到扩展的变量上并再次分配给\@attachment
。
主文件:
% %%%%%%%%%%%%%%
% Document Setup
% %%%%%%%%%%%%%%
\documentclass{customLetterClass}
% %%%%%%%%%%%%%%%%%%%
% Set Variable Values
% %%%%%%%%%%%%%%%%%%%
% Attachment
\attachment{Foo}
\attachment{Bar}
\begin{document}
\begin{letter}
Hallo
\end{letter}
\end{document}
类文件:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{customLetterClass}[2017/10/20 Custom Letter Class]
\LoadClass{article}
% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%
\RequirePackage[english]{babel}
\RequirePackage{%
parskip,%
tabularx,%
environ,%
etoolbox%
}
% %%%%%%%%%%%%%%%%%
% Declare Variables
% %%%%%%%%%%%%%%%%%
% Attachment
\def\attachment#1{\ifdefempty{\@attachment}{\gdef\@attachment{#1}}{\xdef\@attachment{\@attachment\par#1}}}
\def\@attachment{}
% %%%%%%%%%%%%%%%%%%
% Define environment
% %%%%%%%%%%%%%%%%%%
\NewEnviron{letter}%
{%
% Letter text
{\BODY}%
%
% Attachment (if set)
\ifdefempty{\@attachment}%
{}%
{
\\[5\baselineskip]
\begin{tabularx}{\textwidth}{@{}lX@{}}
Attachment: & \@attachment
\end{tabularx}
}%
}%
**带有检查的第二个版本课程Attachments/Attachment
:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{customLetterClass}[2017/10/20 Custom Letter Class]
\LoadClass{article}
% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%
\RequirePackage[english]{babel}
\RequirePackage{%
parskip,%
tabularx,%
environ,%
etoolbox%
}
% %%%%%%%%%%%%%%%%%
% Declare Variables
% %%%%%%%%%%%%%%%%%
% Attachment
\def\attachment#1{\ifdefempty{\@attachment}{\gdef\@attachment{#1}}{\xappto\@attachment{\@attachment,#1}}}
\def\@attachment{}
% %%%%%%%%%%%%%%%%%%
% Define environment
% %%%%%%%%%%%%%%%%%%
\newcounter{attachcntr}
\NewEnviron{letter}%
{%
% \def\@@attachment{}
\setcounter{attachcntr}{0}
% Letter text
{\BODY}%
%
% Attachment (if set)
\ifdefempty{\@attachment}%
{}%
{
\\[5\baselineskip]
\def\localattachmentname{%
\gdef\@@attachment{}
\@for\@splitter@:=\@attachment\do{%
\stepcounter{attachcntr}%
\xappto\@@attachment{\@@attachment\par\@splitter@}
}
\ifnum1<\c@attachcntr%
\def\realattachmentname{Attachments}% Use appropriate \GetTranslation here
\else
\def\realattachmentname{Attachment}% Use appropriate \GetTranslation here
\fi
}
\localattachmentname%
\begin{tabularx}{\textwidth}{@{}lX@{}}
\realattachmentname: & \@@attachment
\end{tabularx}
}%
}%
答案3
这里有一个实现expl3
;您可以对其他变量执行类似的操作,\tl_gset:Nn
对于非“增量”的变量使用。
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{customLetterClass}[2017/10/20 Custom Letter Class]
\LoadClass{article}
% %%%%%%%%%%%%%%%%
% Require Packages
% %%%%%%%%%%%%%%%%
\RequirePackage[english]{babel}
\RequirePackage{
parskip,
tabularx,
environ,
xparse,
}
\ExplSyntaxOn
% allocate the variables
\tl_new:N \g_clc_address_tl
\seq_new:N \g_clc_attachment_seq
% user commands
\NewDocumentCommand{\address}{m}
{
\tl_gset:Nn \g_clc_address_tl { #1 }
}
\NewDocumentCommand{\attachment}{m}
{
\seq_gput_right:Nn \g_clc_attachment_seq { #1 }
}
% user environment
\NewEnviron{letter}
{
% address box (if set)
\tl_if_empty:NF \g_clc_address_tl
{
\hspace*{\fill}
\begin{tabular}{@{}l@{}}
\tl_use:N \g_clc_address_tl
\end{tabular}
\vspace{3\baselineskip}
}
% letter text
\BODY
%
% attachment (if set)
\seq_if_empty:NF \g_clc_attachment_seq
{
\par\nopagebreak\vspace{5\baselineskip}
\begin{tabularx}{\textwidth}{@{}lX@{}}
Attachment: &
\seq_use:Nn \g_clc_attachment_seq { \\ Attachment: & }
\end{tabularx}
}
}
\ExplSyntaxOff
这是一封示例信件。
\documentclass{customLetterClass}
% %%%%%%%%%%%%%%%%%%%
% Set Variable Values
% %%%%%%%%%%%%%%%%%%%
% Address
\address{
egreg \\
\TeX.Stackexchange \\
Web
}
% Attachment
\attachment{Foo}
\attachment{Bar}
\begin{document}
\begin{letter}
Hallo
\end{letter}
\end{document}