1

This is my first attempt at a keyval macro. I have a more complicated macro that boils down to the MWE given below. The idea is to typeset a paragraph in multiple columns where the number of columns is an optional named parameter. When I state the number of columns then it works, but I would like a default of one column when no option is stated.

\documentclass{article}

\usepackage{keyval}
\usepackage{lipsum}
\usepackage{multicol}

\makeatletter

\def\printparagraph{\@ifnextchar[\@printparagraph{\@printparagraph[]}}
\def\@printparagraph[#1]{{\setkeys{pp}{#1}}}
\define@key{pp}{columns}{\begin{multicols}{#1}\lipsum[1]\end{multicols}}

\makeatother

\begin{document}

\printparagraph % this doesn't work, doesn't print anything!
\printparagraph[columns=2] % this works
\printparagraph[columns=3] % this works

\end{document}
1
  • just delete \@printparagraph[] so you do nothing in the default case. (or actually what you have is equivalent). it works (and has the default one column setting but you have no text) in that case. note you can't do \begin{multicols{1} so you need to not start multicols at all in that case and you only have \lipsum in the multicols Oct 25, 2017 at 19:27

2 Answers 2

1

You just need to print your dummy text in the default case:

\documentclass{article}

\usepackage{keyval}
\usepackage{lipsum}
\usepackage{multicol}

\makeatletter

\def\printparagraph{\@ifnextchar[\@printparagraph{\lipsum}}
\def\@printparagraph[#1]{{\setkeys{pp}{#1}}}
\define@key{pp}{columns}{\begin{multicols}{#1}\lipsum[1]\end{multicols}}

\makeatother

\begin{document}

\printparagraph % 
\printparagraph[columns=2] % this works
\printparagraph[columns=3] % this works

\end{document}
2
  • Many thanks! Let's say that \begin{multicols{1} worked, where would I then put the default 1?
    – Geoff
    Oct 25, 2017 at 19:39
  • @Geoff \def\printparagraph{\@ifnextchar[\@printparagraph{\@printparagraph[1]} or more simply \newcommand\printparagraph[1][1]{{\setkeys{pp}{#1}} Oct 25, 2017 at 19:44
2

\begin{multicols{1} doesn't work, but beside this: I wouldn't put the multicols in the key definition but use it only to store the value. Then it is easy to set a default (I would also use l3keys instead of keyval, but that's another question):

\documentclass{article}

\usepackage{keyval}
\usepackage{lipsum}
\usepackage{multicol}

\makeatletter
\newcount\my@columns@cnt
\def\printparagraph{\@ifnextchar[\@printparagraph{\@printparagraph[]}}

\def\@printparagraph[#1]{{%
 \setkeys{pp}{columns,#1}%
 \ifnum\my@columns@cnt=1 
  \expandafter\@firstoftwo
 \else 
  \expandafter\@secondoftwo
 \fi
 {\lipsum[1]}
 {\begin{multicols}{\the\my@columns@cnt}\lipsum[1]\end{multicols}}}}

\define@key{pp}{columns}[1]{\my@columns@cnt=#1\relax}

\makeatother

\begin{document}

\printparagraph % this doesn't work, doesn't print anything!
\printparagraph[columns=2] % this works
\printparagraph[columns=3] % this works

\end{document}
2
  • Thanks for the answer. I see the sense of using the key to only store the counter, but am I correct to say, that the extra complication is due to the fact that \begin{mutlicols}{1} doesn't work?
    – Geoff
    Oct 25, 2017 at 19:56
  • Yes, multicol insists to have at least two columns, so you need the \ifnum-test for the value 1. But even without this complication I wouldn't put a complete multicols environment in a key definition. At the end it is much easier to first collect the key values and then do something -- and it doesn't explode if someone uses a key twice. Oct 25, 2017 at 20:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .