2

I try to make life easier by setting key to list with the package enumitem. But, the options before and after seem to be in conflict when used more than once.

Here is some code that show four examples:

  • the first uses only the key cols,
  • the second only the key dots,
  • the third, which is the one which does not work as expected, uses first the key cols and then the key dots,
  • and the last use also the two keys but in the other order and work nice.

I am wondering why the third does not work but the last works fine.

Maybe there is a conflict with the use of before and after twice...

\documentclass[twocolumn]{article}
\RequirePackage[a4paper, top=0.5cm, bottom=1.6cm, left=0.7cm , right=0.7cm]{geometry}
\parindent0cm
\usepackage{multido}
\usepackage{enumitem}
\usepackage{multicol}

\newcommand{\auxpts}[0]{\makebox[\linewidth]{\dotfill} \bigbreak}
% Pointilles
\newcommand{\Pointilles}[1]{%
    \vspace*{-\medskipamount}
    \multido{\i=1+1}{#1}{%
        \auxpts{}
    }
}

\SetEnumitemKey{cols}{before*=\begin{multicols}{#1},
        after*=\end{multicols}} % col for columns

\newif\iffirstItem\firstItemfalse% We need a toggle to track whether the item is first in the list or not

\SetEnumitemKey{dots}{before*={% This saves the standard definition of \item and then redefines at the end
        \let\olditem\item% save the standard definition of \item in a macro, \olditem
        \firstItemtrue% set the toggle for first item in the list to true
        \def\item{\iffirstItem\olditem\firstItemfalse\else \newline \Pointilles{#1} \mbox{}\olditem\fi}% new, temporary defition of \item
    },
    after*={%
        \ \newline \Pointilles{#1}\mbox{}% fill for final item in list
        \let\item\olditem% restore standard definition of \item
    }%
}
%==========================================
\begin{document}

\Pointilles{2}
\hrule
\begin{enumerate}[cols=4]
    \item first
    \item second
    \item third
    \item fourth
\end{enumerate}
\hrule
\begin{enumerate}[dots=2]
    \item first
    \item second
    \item third
    \item fourth
\end{enumerate}
\hrule
\begin{enumerate}[cols=2, dots=2]
    \item first
    \item second
    \item third
    \item fourth
\end{enumerate}
\hrule
\begin{enumerate}[dots=2, cols=2]
    \item first
    \item second
    \item third
    \item fourth
\end{enumerate}
\hrule
\end{document}
  • Usually keys are set in the order that they're given. So, if you have two keys acting on the same mechanism (both cols and dots affect before* and after*), the last one will be the one that overrides the former ones. – Werner May 24 '15 at 6:57
2

When you say before*=<something> and then before*=<something else>, the second declaration overrides the first.

You can set up a different key-value system for this purpose.

\documentclass[twocolumn]{article}
\usepackage[a4paper, top=0.5cm, bottom=1.6cm, left=0.7cm , right=0.7cm]{geometry}
\parindent0cm
\usepackage{multido}
\usepackage{enumitem}
\usepackage{multicol}

\newcommand{\auxpts}[0]{\makebox[\linewidth]{\dotfill} \bigbreak}
% Pointilles
\newcommand{\Pointilles}[1]{%
    \vspace*{-\medskipamount}
    \multido{\i=1+1}{#1}{%
        \auxpts{}
    }
}

\newlist{innanswers}{enumerate}{1}
\setlist[innanswers]{
  label=\arabic*.,
  before=\maybemulticols\maybedots,
  after=\maybefinaldots\maybeendmulticols
}
\newenvironment{answers}[1][]
 {\setkeys{m45}{#1}\innanswers}
 {\endinnanswers}

\let\maybemulticols=\relax
\let\maybeendmulticols=\relax
\let\maybedots=\relax
\let\maybefinaldots=\relax
\def\doitemdots#1{%
  \let\olditem\item% save the standard definition of \item in a macro, \olditem
  \firstItemtrue% set the toggle for first item in the list to true
  \def\item{%
    \iffirstItem
      \olditem\firstItemfalse
    \else
      \newline\Pointilles{#1}\mbox{}\olditem
   \fi
  }% new, temporary defition of \item
}
\def\dofinaldots#1{%
  \ \newline \Pointilles{#1}\mbox{}% fill for final item in list
}

\makeatletter
\define@key{m45}{cols}{%
  \def\maybemulticols{\begin{multicols}{#1}}%
  \def\maybeendmulticols{\end{multicols}}%
}
\newif\iffirstItem\firstItemfalse

\define@key{m45}{dots}{%
  \def\maybedots{\doitemdots{#1}}
  \def\maybefinaldots{\dofinaldots{#1}}
}
\makeatother
%==========================================
\begin{document}

\Pointilles{2}
\hrule
\begin{answers}[cols=4]
    \item first
    \item second
    \item third
    \item fourth
\end{answers}
\hrule
\begin{answers}[dots=2]
    \item first
    \item second
    \item third
    \item fourth
\end{answers}
\hrule
\begin{answers}[cols=2, dots=2]
    \item first
    \item second
    \item third
    \item fourth
\end{answers}
\hrule
\begin{answers}[dots=2, cols=2]
    \item first
    \item second
    \item third
    \item fourth
\end{answers}
\hrule
\end{document}

enter image description here

  • Thanks this works fine ! I added a new question to the post. I redefy \Pointilles to have a vertical skip parameter between the dots, but the question is, how to give this parameter a value in the list like a new key ? – math45 May 24 '15 at 13:31
  • @math45 Don't edit questions so as to invalidate existing answers. Ask a new one, please, using the proposed code. – egreg May 24 '15 at 13:41
  • Done, sorry, I'm not used to. – math45 May 24 '15 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.