2

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:

  1. Why did that happen? Why the \start/\stop trick worked for landscape env (2nd attempt) but not for postponedlandscape env (4th attempt)?

  2. 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".

1

Use

\afterpage{\clearpage\input{mytable}}

where mytable does

\begin{landscape}
\begin{longtable}
...
\end{longtable}
\end[landscape}

That will (most likely) do the right thing in latex, and presumably can be made to do the equivalent of simply

\input{mytable}

in any pandoc conversion to other formats.

  • Thank you for answering. Unfortunately, your answer assume that the ... part is latex code which I obtained somehow (or that I wrote it). Instead, what I have is markdown syntax for a table, and the longtable env is generated by pandoc. +1 anyway because this answer can be helpful in other context – JLDiaz Oct 8 '15 at 16:14
  • @JLDiaz don't really know much about pandoc but if you let markdown generate the longtable into a file mylt.tex can't you get it to inject \afterpage{\clearpage\begin{lscape}\input{mylt}\end{lscape}} into the generated master latex document? – David Carlisle Oct 8 '15 at 19:56
  • Yes, I could do that. But then separate markdown files are required for the markdown tables, and a more complex toolchain to get the final document (separately "compile" to latex those files, and the main one, to finally latex-compile the main one). If all were in a single file, a simple command would do it all: pandoc mydoc.markdown -o result.pdf (which uses latex behind the scenes and then removes the .tex and all auxiliar files). I'll keep trying to find a solution which does not require separate pandoc runs. – JLDiaz Oct 9 '15 at 7:59

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.