1

I would like to create a macro that creates a table with two columns. One thing should go into the inner column and another thing into the outer column, regardless of whether inner means left or right, so:

\newcommand{\testmacro}{
% On odd pages:
\begin{tabular}{lr}Inner text & Outer text\end{tabular}

% On even pages: \begin{tabular}{lr}Outer text & Inner text\end{tabular} }

Is there a way to achieve this?

Iziminza
  • 195

2 Answers2

3

Unfortunately the @lziminza's suggestion can fail:

\documentclass[twoside]{article}
\usepackage{ifoddpage}

\newcommand{\testmacro}{% \checkoddpage \ifoddpage \begin{tabular}{lr}Inner text & Outer text\end{tabular} \else \begin{tabular}{lr}Outer text & Inner text\end{tabular} \fi }

\usepackage{blindtext}

\begin{document}

\blindtext[2]

\vskip 4\baselineskip

\blindtext[2]

\testmacro

\blindtext

\testmacro

\end{document}

results in:

wrong decision

on second page after two or more LaTeX runs.

To avoid this issue, you should at least prohibit page breaks between the \checkoddpage and \ifoddpage. I recommend to also explicitly allow page breaks before the \checkoddpage:

\documentclass[twoside]{article}
\usepackage{ifoddpage}

\newcommand{\testmacro}{% % \par % could also be a good idea \pagebreak[1] \checkoddpage\nobreak \ifoddpage \begin{tabular}{lr}Inner text & Outer text\end{tabular} \else \begin{tabular}{lr}Outer text & Inner text\end{tabular} \fi }

\usepackage{blindtext}

\begin{document}

\blindtext[2]

\vskip 4\baselineskip

\blindtext[2]

\testmacro

\blindtext

\testmacro

\end{document}

results in:

correct decision

on second page.

Another suggestion would be to set a test label inside the tabular and do the test outside:

\documentclass[twoside]{article}
\usepackage{refcount}

\newcounter{testpage} \newcommand{\testmacro}{% \ifodd \getpagerefnumber{testpage:\thetestpage} \begin{tabular}{lr}\label{testpage:\thetestpage}\stepcounter{testpage}Inner text & Outer text\end{tabular} \else \begin{tabular}{lr}\label{testpage:\thetestpage}\stepcounter{testpage}Outer text & Inner text\end{tabular} \fi }

\usepackage{blindtext}

\begin{document}

\blindtext[2]

\testmacro

\vskip 3\baselineskip

\blindtext[2]

\testmacro

\blindtext

\testmacro

\end{document}

also works:

enter image description here

cabohah
  • 11,455
0

Use \usepackage{ifoddpage} package.

\newcommand{\testmacro}{
\checkoddpage
\ifoddpage
    \begin{tabular}{lr}Inner text & Outer text\end{tabular}
\else
    \begin{tabular}{lr}Outer text & Inner text\end{tabular}
\fi
}
Iziminza
  • 195
  • 1
    TL,DR: you'll need to compile at least twice. Page numbers in TeX are a bit tricky, since TeX doesn't know where the page break goes until after it's typed the content. \pageref and ifoddpage get around this by placing a reference, writing the page of the reference to the aux file, and then reading the aux file to figure out the page that was used. But using the aux means that you have to compile again after the table has been placed on its eventual page. – Teepeemm Nov 14 '23 at 16:34
  • 2
    Be careful: This can fail because the test is done before the table is typeset. So if the table results in a page break, the test would be wrong. – cabohah Nov 14 '23 at 17:09