Sorry for the long title (and even longer question), but this is a rather complex subject and requires a bit of elaboration.
Goal: I want to define a pair of latex macros which I can write in the source code to delimit a region of text as "to appear in the next page, landscaped, after this one is full". Those macros cannot be a new kind of environment (but can be based in one)
Motivation
I have a document written in markdown, which pandoc
translates to LaTeX. Each markdown table is converted to a longtable
. All happens automatically, and works ok.
However, some of the tables are too wide for the page width (the automatically generated longtables
do not have p
-type columns and I don't have control over this). So I wanted to put those tables sideways. Now the problems begun. I'll tell you the (failed) attempts so far.
1st attempt. Use pdflscape
I can edit the latex template used by pandoc, and add packages and my own commands to the preamble. So I added \usepackage{pdflscape}
. Moreover, if latex macros appear in the markdown source, pandoc passes them unchanged to the generated latex file, so I tried writting the following in my markdown document:
\begin{landscape}
... markdown code for the long table
...
\end{landscape}
The generated latex compiled without problem, but the result was not what I expected. Not only the \begin/\end
macros passed unchanged, but also all the internal markdown code between them. I.e: the markdown table was not translated into a proprer latex table, but instead passed "verbatim".
After reading pandoc documentation, I discovered that this is expected behaviour. When pandoc detects a pair \begin{something}
/\end{something}
assumes that the content of that latex environment is also latex, and thus this approach did not work.
2nd attempt. Faked landscape
environment
Since the problem was that pandoc had hardcoded the special syntax \begin{}/\end{}
, I tried to avoid that syntax.
I defined the following macros in the preamble of the latex template:
\usepackage{pdflscape}
\def\startlandscape{\begin{landscape}}
\def\stoplandscape{\end{landscape}}
And wrote the following in the markdown source:
\startlandscape
... markdown code for the long table
...
\stoplandscape
This worked! These macros were passed "as is" to the latex document, which compiled without problem. The wide tables are now typeset in landscape.
The problem is that longtable
is not a floating environment, and thus at the point where that long table appears, the current page is aborted (filled with white), and the table put into the next page, in landscape. So I have big gaps in the text.
Trying to be smarter I did my:
3rd attempt. Postpone the output of the longtable via afterpage
afterpage
package provides command \afterpage{}
which holds the text it receives as arguments and outputs it only after the current page is full. This will fill current page with more text before typesetting the table in the next page.
The problem now is: how to pass the complete landscape
environment to \afterpage
?
The naïve approach:
\newenvironment{postponelandscape}{%
\afterpage{\begin{landscape}
}{%
\end{landscape}}
}
is obviously wrong because I have unbalanced braces in both arguments of \newenvironment
.
4th attempt. Using environ
package
This package is able to create environments which "capture" the contents and store it in a macro called \BODY
, which can be passed later as argument to any other command (\afterpage
in my case). So I added the following lines to my preamble:
\usepackage{pdflscape}
\usepackage{afterpage}
\usepackage{environ}
\NewEnviron{postponelandscape}{%
\afterpage{\begin{landscape}\BODY\end{landscape}}
}
This defines the new environment postponelandscape
. I tested this environment in a pure latex source code, as for example:
Text before the table
\begin{postponelandscape}
\begin{longtable}{...}
...
\end{longtable}
\end{postponelandscape}
More text after the table
and worked beautifully. The whole long table appears in the next page, in landscape, and the current page is filled with "More text after the table", instead of blank space.
So, it only remains to "fake" this environment into a pair of \start/\stop
commands, as I did before, to trick pandoc. I added this to the preamble:
\def\startlandscape{\begin{postponelandscape}}
\def\stoplandscape{\end{postponelandscape}}
So I tried:
\startlandscape
\begin{longtable}{...}
...
\end{longtable}
\stoplandscape
But this fails with error:
! LaTeX Error: \begin{postponelandscape} on input line XX ended by \end{document}.
So, (finally!) my questions:
Why did that happen? Why the
\start/\stop
trick worked forlandscape
env (2nd attempt) but not forpostponedlandscape
env (4th attempt)?Any idea about how could I solve my problem? Any other way is welcome.
Let me restate the goal: I want to define a pair of latex macros which I can write in the source code to delimit a region of text as "to appear in the next page, landscaped, after this one is full".