9

It's a bit of a long story as to why I need to do this, but please bear with me. I have a fairly complicated custom class which expects documents to begin with a command:

\coverandabstract{Abstract text goes here}

What this does is lay out a (one column) cover page, basically a custom maketitle, then switches to two column layout with different page dimensions on page two, beginning with an abstract that spans both columns.

Now, I want to be able to draft the document in Markdown and convert to this class (and other formats) via Pandoc. The most cross-format way of representing the abstract is as a blockquote, which gets converted to a quote environment.

\begin{quote}
Abstract text goes here
\end{quote}

So what I need to do is find a way of converting the first, and only the first, quote environment into the \coverandabstract command.

Now one way of doing this would be to use the environ package:

\usepackage{environ}
\let\oldquote=\quote
\let\endoldquote=\endquote
\makeatletter
\renewenvironment{quote}%
  {\Collect@Body\coverandabstract}%
  {\let\quote=\oldquote
   \let\endquote=\endoldquote}
\makeatother

The problem is that the class is based on memoir, and changing the page layout means using \checkandfixthelayout. This doesn't work properly if called within an environment, probably as a result of the grouping. This means the above technique ruins the layout for the remainder of the document.

So is there a way of passing the contents of an environment to a command without having it wrapped in a TeX group?

1
  • 1
    Welcome to TeX.SX! You may have a look on our starter guide.
    – mafp
    Commented May 24, 2013 at 21:42

3 Answers 3

4

If you stick with environ you can lift the code out of the group with \aftergroup

enter image description here

\documentclass{article}

\def\coverandabstract#1{\twocolumn[#1]}

\usepackage{environ}
\let\oldquote=\quote
\let\endoldquote=\endquote
\let\quote\relax
\let\endquote\relax

\NewEnviron{quote}%
  {\global\let\tmp\BODY\aftergroup\docoverandabstract}



\def\docoverandabstract{%
  \let\quote=\oldquote
  \let\endquote=\endoldquote
  \coverandabstract{\tmp}}

\begin{document}


\begin{quote}
Abstract text Abstract text Abstract text 
Abstract text Abstract text Abstract text 
Abstract text Abstract text Abstract text 
\end{quote}

\texttt{\meaning\quote}

a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a


\end{document}
5

I'd say

\let\oldquote\quote
\let\oldendquote\endquote
%% the following to please environ
\let\quote\relax
\let\endquote\relax

\NewEnviron{quote}{%
  \xdef\dolatercoverandabstract{%
    \noexpand\coverandabstract{\unexpanded\expandafter{\BODY}}%
    \unexpanded{\let\quote\oldquote\let\endquote\oldendquote}%
  }\aftergroup\dolatercoverandabstract}

Without \unexpanded, the definition of the new quote environment should be

\NewEnviron{quote}{%
  \expandafter\gdef\expandafter\dolater\expandafter{%
    \expandafter\coverandabstract\expandafter{\BODY}%
    \let\quote\oldquote\let\endquote\oldendquote
  }\aftergroup\dolater}
1

After a lot of head scratching and failed experiments, I finally came up with a hack that does the trick.

\let\oldquote=\quote
\let\endoldquote=\endquote
\makeatletter
\def\quote#1\end{%
  \end{quote}%
  \coverandabstract{#1}%
  \let\quote=\oldquote
  \let\endquote=\endoldquote
  \@gobble}
\makeatother

The first two lines save the normal definition of the quote environment.

What the (re)definition does is nullify the effect of \begin{quote}, then extract everything between \begin{quote} and the next \end (it means not using another environment inside this one, but that's fine.) It then immediately closes the quote environment, leaving us back at the top level. I can then put the collected content in the \coverandabstract command (which now operates as intended) and revert the quote environment back to its original definition.

This just leaves a stray {quote} token for TeX to parse (from \end{quote}), so I remove it with \@gobble (hence the \makeatletter and \makeatother).

You must log in to answer this question.

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