13

I'm writing some xsl that takes xml source and outputs a .tex file. The source has an element that is meant to frequently become a multicols environment in the .tex output, and it has a cols attribute to specify how many columns there are.

I'd like the default to be one column if no cols attribute has been specified. But it appears that \begin{multicols}{1} still produces two-column output. I could write the xsl in a casewise way and skip the multicols environment altogether when cols is not specified (or is specified as 1), but for the sake of consistency I'd prefer not to.

Is there any LaTeX way to get the multicols environment to produce one-column output?

3
  • clearly this is possible -- the multicol documentation (texdoc multicol) contains single-column segments, such as the start of section 4. the source for that document would show how it's done. Mar 18, 2015 at 19:14
  • @barbarabeeton I can't find the source but I would assume it achieves single-column by simply not invoking the multicols environment. If I were writing a one-off .tex file, that would be fine. But the xsl element to this question is pushing me to try to make \begin{multicols}{1} work. Mar 18, 2015 at 19:19
  • the source is multicol.dtx and the relevant section begins \begin{multicols}{2}[\section{The Implementation} % We are now switching to two-column output ...] there's also a \subsection within the scope of the optional argument. but definitely not \begin{multicols}{1}. Mar 18, 2015 at 19:55

3 Answers 3

16

This solution is inspired by Werner's, but it supports the optional argument to \begin{multicols} and, more importantly, doesn't collect the whole contents in a single swoop, which is best to avoid, if possible. It also doesn't require changing the environment's name.

\documentclass{article}
\usepackage{multicol,lipsum,xparse}

\let\multicolmulticols\multicols
\let\endmulticolmulticols\endmulticols

\RenewDocumentEnvironment{multicols}{mO{}}
 {%
  \ifnum#1=1
    #2%
  \else % More than 1 column
    \multicolmulticols{#1}[#2]
  \fi
 }
 {%
  \ifnum#1=1
  \else % More than 1 column
    \endmulticolmulticols
  \fi
 }

\begin{document}

\begin{multicols}{2}[\section{Title in single column}]
\lipsum[1-2]
\end{multicols}

\begin{multicols}{1}
\lipsum[1-2]
\end{multicols}

\end{document}

enter image description here

7

You can use an alternative environment which conditions on whether you're managing a single or multiple columns:

enter image description here

\documentclass{article}
\usepackage{multicol,lipsum,environ}

\NewEnviron{auxmulticols}[1]{%
  \ifnum#1<2\relax% Fewer than 2 columns
    %\vspace{-\baselineskip}% Possible vertical correction
    \BODY
  \else% More than 1 column
    \begin{multicols}{#1}
      \BODY
    \end{multicols}%
  \fi
}

\begin{document}

\begin{auxmulticols}{2}
\lipsum[1-2]
\end{auxmulticols}

\begin{auxmulticols}{1}
\lipsum[1-2]
\end{auxmulticols}

\end{document}

multicol expects to capture the end of the environment in order to gauge where the multicols text ends. Wrapping it inside a new environment that captures the entire content in (say) \BODY (as is done using environ) allows you to condition on certain arguments before handling the output.

2
  • The above assumes that you have the capacity to invoke auxmulticols rather than multicols.
    – Werner
    Mar 18, 2015 at 19:26
  • Yes, I can write the xsl to use auxmulticols. Thanks for the answer. Mar 18, 2015 at 19:28
1

Why not just use :

\documentclass{article}
\usepackage{multicol,lipsum,environ}    

\begin{document}

\begin{multicols}{2}

your 2 columns text

\end{multicols}

your 1 column text

\end{document}

enter image description here

1
  • 3
    The question answers your question. It says "I could write the xsl in a casewise way and skip the multicols environment altogether when cols is not specified (or is specified as 1), but for the sake of consistency I'd prefer not to." Mar 10, 2017 at 22:13

You must log in to answer this question.

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