如何每次创建相同的文本结构?

如何每次创建相同的文本结构?

我的文档包含具有相同结构的“文本块”。它们总是有一个标题(总是一个日期)、一个审查部分和去做部分。代码如下:

\documentclass[11pt]{article}

\usepackage{enumerate}

\newenvironment{review}
    {\textbf{Review:} \begin{itemize}}
    {\end{itemize}}
\newenvironment{todo}
    {\textbf{To do:} \begin{itemize}}
    {\end{itemize}}

\begin{document}

\section*{30th November 2013}
\begin{enumerate}[1)]
    \item blabla
\end{enumerate}

\begin{review}
    \item blabla
\end{review}

\begin{todo}
    \item blabla
\end{todo}
\end{document}

我想知道是否有可能省去每次输入此结构的麻烦,并创建一个名为文章为了节省时间并更好地组织我的文档。我该怎么做?

答案1

这里有一个想法:一个由三部分组成的环境,称为Article,其唯一(强制)参数是日期(指定为{<day>}{<month>}{<year>})。

要启动审查部分,只需使用我的\review宏即可。要启动去做部分,只需使用我的\todo宏。重命名这些宏以避免与现有宏发生冲突可能是明智之举;例如,我知道包todonotes定义了一个名为的宏 \todo

为了提高可维护性,您可能还想使用用于排版日期的包,例如 Nicola Talbot 的包datetime,我在示例中使用了它。通过这样做,您无需对日期进行硬编码(如30th November 2013您的示例中所示),并且您可以在任何阶段更改其排版方式。

在此处输入图片描述

\documentclass[11pt]{article}

\usepackage{enumerate}
\usepackage[long,nodayofweek]{datetime}


\newenvironment{Article}[1]
{%
    \newcommand\review
    {%
        \end{enumerate}
        \textbf{Review:}
        \begin{itemize}
    }
    \newcommand\todo
    {%
        \end{itemize}
        \textbf{To do:}
        \begin{itemize}
    }
    \section*{\formatdate#1}
    \begin{enumerate}[1)]   
}{%
    \end{itemize}
}


\begin{document}

\begin{Article}{{30}{11}{2013}}
        \item foo
        \item bar
    \review
        \item foo
        \item bar
    \todo
        \item foo
        \item bar
\end{Article}

\end{document}

答案2

再次,这比您要求的要多一些,但这是一种理想情况,使用密钥可以很好地简化事情(在构建它们的初始开销之后)。

我在此采取四管齐下的方法。

  1. 我定义了我将要使用的键。

  2. 我为用户界面定义了一个宏。在本例中,\myarticle它接受一个键值对参数。然后,该宏调用另一个宏来处理格式。

  3. 我定义了一个内部宏\my@article,它决定要执行什么代码。这有点像中间人,但对于快速重新格式化、更改显示顺序或只是调试来说非常有用。

  4. 对于决赛的每个方面环境我定义了一个宏来处理格式。每个宏都遵循命名约定\jeroen@build@...。有一个宏是为日期,另一个审查,第三个去做。如果您想更改内容的呈现方式,则需要重新定义这些宏。

对于密钥,我说明了三种不同的方法:

  • 使用内部机制.initialpgfkeys存储和调用键值。
  • 使用将.store in键的值存储在用户定义的宏中。
  • .code当调用特定键时,使用来执行一些代码。

我认为.code在当前背景下,这是最有趣的,因为在接下来的 MWE 中,它将允许用户选择不使用审查列表。此外,对于前页我做了类似的事情:键值像其他键一样传递 - 就像它是一个列表一样 - 但是它的最终格式就像一个普通段落。

这是MWE:

\documentclass{article}
%%-------------------------------------------
%% packages you need for this to work        
\usepackage{pgfkeys}
\usepackage{pgffor}
%%-------------------------------------------
%% package OP requested                      
\usepackage{enumitem}           
%%-------------------------------------------
\makeatletter
%%-------------------------------------------
%% These next two macros are not entirely    
%% necessary.  I put them here to illustrate 
%% further possibilities about how `pgfkeys` 
%% can manage keys.                          
\def\jeroen@review@items{}
\def\jeroen@to@do@items{}
\newif\ifjeroen@review@
\newif\ifjeroen@front@matter@
%% define the keys                           
\pgfkeys{/jeroen/article/.cd,
  date/.initial=,
  front matter/.code=\jeroen@front@matter@code{#1},
  review items/.code=\jeroen@review@code{#1},
  to do items/.store in=\jeroen@to@do@items,
}
%% define the macro for user interface       
\newcommand\myarticle[1]{%%
  \bgroup  
  \pgfkeys{/jeroen/article/.cd,#1}%%
  \build@my@article
  \egroup
}
\def\jeroen@front@matter@code#1{%%
  \jeroen@front@matter@true
  \def\jeroen@front@matter@content{#1}}
\def\jeroen@review@code#1{%%
  \jeroen@review@true
  \def\jeroen@review@items{#1}}

%% an internal macro for initially handling  
%% and formatting the content.               
\def\build@my@article{%%
  \jeroen@build@date
  \jeroen@build@front@matter
  \jeroen@build@review
  \jeroen@build@to@do
}
%% macro for formatting the "date"                     
%% If you want to change how the "date" is presented   
%% this is the code you should tweak.                  
\def\jeroen@build@date{%%
  \section*{\pgfkeysvalueof{/jeroen/article/date}}}
%% macro for formatting the "front matter"             
%% If you want to change how the "front matter" is     
%% presented this is the code you should tweak.        
\def\jeroen@build@front@matter{%%
  \ifjeroen@front@matter@
    \foreach \mystuff in \jeroen@front@matter@content
    {\mystuff\space}%%
    \vspace{2ex}\par
  \fi
}
%% macro for working with the list of "review" items   
%% This is the code you should tweak to change how     
%% the "review" is formatted.                          
\def\jeroen@build@review{%%
  \ifjeroen@review@
    \noindent
    \textbf{Review:}
    \begin{enumerate}%%
    \foreach \reviewitem in \jeroen@review@items
    {%%
      \item \reviewitem 
     }%%
    \end{enumerate}
  \fi
}
%% macro for working iwth the list of "to do" items    
%% This is the code you should tweak to change how     
%% the "to do" is formatted.                           
\def\jeroen@build@to@do{%%
  \noindent
  \textbf{To do:}
  \begin{itemize}
  \foreach \todoitem in \jeroen@to@do@items
  {%%
    \item \todoitem
  }%%
  \end{itemize}
}
\makeatother

\begin{document}

\myarticle{
  date={November 29, 2013},
  review items={
    {turkey},
    {stuffing},
    {yams}
    },
  to do items={
    {apples},
    {pears},
    {peaches},
    {ice cream}}
}

\myarticle{
  date={November 30, 2013},
  front matter={
    {The quick brown fox jumped over the lazy dog.},
    {Pack my box with five dozen liquor jugs.}},
  to do items={
    {carrots},
    {celery},
    {parsnips},
    {ice cream!!}}
}

\end{document}

在此处输入图片描述

我应该注意以下几点:

  • 中的括号date={November 30, 2013}是必要的,以防止pgfkeys认为逗号日期是分隔器钥匙。
  • 其他键的格式应为:{ {item 1} , {item 2} , {item 3} , ...}

当然,这需要做大量的前期工作。但最终它会为你最终如何格式化内容提供很大的自由度。

答案3

仅向最佳实践者推荐的解决方案。

创建包

由于您希望在许多项目中重复使用环境和项目,最好的解决方案是将它们全部放在一个包中。将包保存在 LaTeX 可访问的目录中(如果您不知道如何操作,稍后会解释)。

在下面的例子中,我选择了mytodolist.sty作为包的名称。您可以根据需要更改它。

% mytodolist.sty
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{mytodolist}[2013/12/01 v0.01 LaTeX package for my consistent todo list]

\RequirePackage{enumerate}

\newenvironment{review}
    {\textbf{Review:} \begin{itemize}}
    {\end{itemize}}
\newenvironment{todo}
    {\textbf{To do:} \begin{itemize}}
    {\end{itemize}}

\newcommand{\Section}[1][\today]{\section*{#1}}

% items that will be reused many times
\newcommand{\foo}{\item foo}
%\newcommand{\bar}{\item bar} % it cannot be made as \bar is already defined!
\newcommand{\baz}{\item baz}

\endinput

如果有新项目要添加,只需编辑此包。使用\newcommand而不是\def确保现有宏不会被重新定义。

使用包

现在您可以按如下方式使用该包。

% main.tex

\documentclass[preview,border=12pt,12pt,varwidth]{standalone}% change it back to your own document class
\usepackage{mytodolist}

\begin{document}
\Section
\begin{review}
\foo
%\bar
\baz
\end{review}

\begin{todo}
\foo
%\bar
\baz
\end{todo}

\Section[Dec 25, 2013]
\begin{review}
\foo
%\bar
\baz
\end{review}

\begin{todo}
\foo
%\bar
\baz
\end{todo}
\end{document}

在此处输入图片描述

模拟二合一

以下代码片段可用于模拟动态创建包并使用它。您不应该在生产场景中这样做。

\documentclass[preview,border=12pt,12pt,varwidth]{standalone}% change it back to your own document class

\usepackage{filecontents}

\begin{filecontents*}{mytodolist.sty}
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{mytodolist}[2013/12/01 v0.01 LaTeX package for my consistent todo list]

\RequirePackage{enumerate}

\newenvironment{review}
    {\textbf{Review:} \begin{itemize}}
    {\end{itemize}}
\newenvironment{todo}
    {\textbf{To do:} \begin{itemize}}
    {\end{itemize}}

\newcommand{\Section}[1][\today]{\section*{#1}}

% items that will be reused many times
\newcommand{\foo}{\item foo}
%\newcommand{\bar}{\item bar} % it cannot be made as \bar is already defined!
\newcommand{\baz}{\item baz}

\endinput
\end{filecontents*}


\usepackage{mytodolist}

\begin{document}
\Section
\begin{review}
\foo
%\bar
\baz
\end{review}

\begin{todo}
\foo
%\bar
\baz
\end{todo}

\Section[Dec 25, 2013]
\begin{review}
\foo
%\bar
\baz
\end{review}

\begin{todo}
\foo
%\bar
\baz
\end{todo}
\end{document}

相关内容