3

Starting from this solution to my older post: Distance Variable in front or back pages, how can I set the width and height of a tcolorbox in a way that depends on whether the box is put on an odd page or on an even page?

I propose to start from the following code, which is based on the code from the answer in the above link:

\documentclass{article}
\usepackage{datatool}
\usepackage{filecontents}
\usepackage[strict]{changepage}
\usepackage{tcolorbox}
\begin{filecontents*}{test1.csv}
Acol, Bcol,Ccol
Ax,Bx,1
Ay,By,3
A1,B22,1
A2,B44,2
A3,B11,3
\end{filecontents*}

\DTLloaddb{mydata1}{test1.csv}

\newlength{\xlengthForOddPages}
\newlength{\xlengthForEvenPages}
\newlength{\ylengthForOddPages}
\newlength{\ylengthForEvenPages}

\setlength{\xlengthForOddPages}{2cm}
\setlength{\xlengthForEvenPages}{10cm}
\setlength{\ylengthForOddPages}{1.5cm}
\setlength{\ylengthForEvenPages}{5cm}

\newcommand*{\xpageDependent}{%
  \ifoddpage
    \expandafter
    \xlengthForOddPages
  \else
    \expandafter
    \xlengthForEvenPages
  \fi
}

\newcommand*{\ypageDependent}{%
  \ifoddpage
    \expandafter
    \ylengthForOddPages
  \else
    \expandafter
    \ylengthForEvenPages
  \fi
}

\begin{document}

\DTLforeach*{mydata1}{\A=Acol,\B=Bcol,\C=Ccol}%
{%
  \begin{tcolorbox}[width=\xpageDependent,height=\ypageDependent,title={Title}]
  %\begin{tcolorbox}[width=\checkoddpage{\xpageDependent},height=\checkoddpage{\ypageDependent},title={title}]
    \C
  \end{tcolorbox}
  \newpage
}%

\end{document}

Thanks

4

I propose two solutions.

Using tcolorbox's if odd page option

tcolorbox has special options to run different code depending on whether the box is on an odd page or on an even page. Here, we use if odd page to set the width and height options in a page-dependent way. In case you have breakable boxes, read section Even and Odd Pages of the tcolorbox manual (you might be interested in using if odd page*, depending on what you want for split parts).

\documentclass{article}
\usepackage{datatool}
\usepackage{filecontents}
\usepackage{tcolorbox}

\begin{filecontents*}{test1.csv}
Acol, Bcol,Ccol
Ax,Bx,1
Ay,By,3
A1,B22,1
A2,B44,2
A3,B11,3
\end{filecontents*}

\DTLloaddb{mydata1}{test1.csv}

\newlength{\xlengthForOddPages}
\newlength{\xlengthForEvenPages}
\newlength{\ylengthForOddPages}
\newlength{\ylengthForEvenPages}

\setlength{\xlengthForOddPages}{2cm}
\setlength{\xlengthForEvenPages}{10cm}
\setlength{\ylengthForOddPages}{1.5cm}
\setlength{\ylengthForEvenPages}{5cm}

\begin{document}

\DTLforeach*{mydata1}{\A=Acol,\B=Bcol,\C=Ccol}%
{%
\begin{tcolorbox}[
  if odd page={width=\xlengthForOddPages,
               height=\ylengthForOddPages}%
              {width=\xlengthForEvenPages,
               height=\ylengthForEvenPages},
  title={Title}]
  \C
\end{tcolorbox}
\newpage
}

\end{document}

Using tcolorbox's phantom option and \ifoddpage

We can still use the machinery from that answer with tcolorbox, but we need to ensure that \checkoddpage is called:

  • before the corresponding uses of \xpageDependent or \ypageDependent, and

  • in a place where we can be sure that the \checkoddpage call will be on the same page as the tcolorbox.

This can be done using tcolorbox's phantom option, it is clearly designed for this kind of use:1

Labels are ensured to reference the correct page number.

(see Counters, Labels, and References in the tcolorbox manual)

One difficulty with this option is that the user-provided code is run inside a TeX group, however the assignment done by \checkoddpage that sets the conditional is local (I mean, the assignment that says whether \ifoddpage is made \let-equal to \iftrue or to \iffalse). Therefore, if we use this technique, we need to globally propagate the \ifoddpage “flag” that \checkoddpage sets locally. This can be done as follows:

\newcommand*{\mycheckoddpage}{%
  \checkoddpage
  \global\let\ifmyoddpage=\ifoddpage
}

This way, the globally-set flag \ifmyoddpage will be visible outside the group started by the phantom option. Then we just need to test this flag inside the definitions of \xpageDependent and \ypageDependent.

\documentclass{article}
\usepackage{datatool}
\usepackage[strict]{changepage}
\usepackage{filecontents}
\usepackage{tcolorbox}

\begin{filecontents*}{test1.csv}
Acol, Bcol,Ccol
Ax,Bx,1
Ay,By,3
A1,B22,1
A2,B44,2
A3,B11,3
\end{filecontents*}

\DTLloaddb{mydata1}{test1.csv}

\newlength{\xlengthForOddPages}
\newlength{\xlengthForEvenPages}
\newlength{\ylengthForOddPages}
\newlength{\ylengthForEvenPages}

\setlength{\xlengthForOddPages}{2cm}
\setlength{\xlengthForEvenPages}{10cm}
\setlength{\ylengthForOddPages}{1.5cm}
\setlength{\ylengthForEvenPages}{5cm}

\newif\ifmyoddpage              % always set globally, contrary to \ifoddpage

\newcommand*{\xpageDependent}{%
  \ifmyoddpage
    \expandafter
    \xlengthForOddPages
  \else
    \expandafter
    \xlengthForEvenPages
  \fi
}

\newcommand*{\ypageDependent}{%
  \ifmyoddpage
    \expandafter
    \ylengthForOddPages
  \else
    \expandafter
    \ylengthForEvenPages
  \fi
}

\newcommand*{\mycheckoddpage}{%
  \checkoddpage
  \global\let\ifmyoddpage=\ifoddpage
}

\begin{document}

\DTLforeach*{mydata1}{\A=Acol,\B=Bcol,\C=Ccol}%
{%
\begin{tcolorbox}[phantom={\mycheckoddpage},
                  width=\xpageDependent,height=\ypageDependent,
                  title={Title}]
  \C
\end{tcolorbox}
\newpage
}

\end{document}

Note: one could also define \mycheckoddpage as follows, with the same result:

\newcommand*{\mycheckoddpage}{%
  \checkoddpage
  \ifoddpage
    \global\myoddpagetrue       % global assignment
  \else
    \global\myoddpagefalse      % global assignment
  \fi
}

Screenshots

Both examples given above produce the same output. Arranging this output with Gimp to have all boxes on the same image (to avoid showing you five almost-blank pages here), one gets:

All boxes on the same image


Footnote

  1. \checkoddpage works by setting a new label wherever it is used, and testing whether the page number for this label is odd or even.

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.