问题沃纳的方法

问题沃纳的方法

我正在编写自己的信件类,我想知道如何处理多个附件。目前,我为自己制作了一个宏,接受一个应该在序言中设置的参数。内容(如果有)由我的信件环境自动打印。

如果有多个附件,我想调用两次宏,这通常会覆盖第一个声明(参见我的 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}

抱歉,无法将其放在一个文件中,但如果我将其更改documentclassarticle并将类的内容粘贴到我的序言中,测试就会突然\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的目的是计算添加的附件数量。这样就可以决定是否打印AttachmentAttachments(或其他)。

答案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}

在此处输入图片描述

相关内容