3

I am trying to define a new environment for photographic plates in a tufte-book.cls book. The environment should:

  1. Work just as the existing figure / table environments do for non-starred uses, and
  2. Place the caption inside the main body region, below the graphic, for starred (full width) uses.

Each page will have a single image. Portrait images are dealt with by the non-starred environment. Landscape images are dealt with by the starred.

I have (1) working by defining a 'plate' environment with its own counter etc. following Caption placement for new float in tufte-book class. See the MWE below. However, I am stuck on (2).

change caption in tufte class full-page figure comes close - but you lose the short caption / list of figures / hyperef functionality. I think I need to redefine the \@caption command for starred use - following something like How do I change the label separator for marginfigure in Tufte Book/Handout? or How can I have figure labels without captions in tufte-book?

One messy solution could be to use \newgeometry{} on each page a plate* appears and define the marginpar to equal (or almost equal) the page width.

This is needed for landscape floats (starred) with long captions as they disappear off the bottom of the page in the standard tufte-book implementation. This is not a problem with non-starred use as you have the marginpar to use. Full width float and long caption.:

My MWE is:

\documentclass[a4paper,justified,twoside,openright]{tufte-book}

\geometry{landscape,top=1in,bottom=0.75in,textheight=7in,textwidth=6in,marginparsep=0.5in,marginparwidth=3in}

\usepackage{tikz}

%% Plate environment %%%%%%%%%%%%%%% from https://tex.stackexchange.com/questions/113631/caption-placement-for-new-float-in-tufte-book-class
\newcounter{plate}
\newcommand\platename{Plate}
\newcommand\listplatename{List of Plates}
\makeatletter
\newcommand\listofplates{%
  \ifthenelse{\equal{\@tufte@class}{book}}%
    {\chapter*{\listplatename}}%
    {\section*{\listplatename}}%
%  \begin{fullwidth}%
    \@starttoc{lop}%
%  \end{fullwidth}%
}
\renewcommand\theplate
%     {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@plate}
     {\@arabic\c@plate} % alter numbering to be continuous
\def\fps@plate{tbp}
\def\ftype@plate{1}
\def\ext@plate{lop}
\def\fnum@plate{\platename\nobreakspace\theplate}

\newenvironment{plate}[1][htbp]
  {\begin{@tufte@float}[#1]{plate}{}}
  {\end{@tufte@float}}

\newenvironment{plate*}[1][htbp]%
  {\begin{@tufte@float}[#1]{plate}{star}}
  {\end{@tufte@float}}

\newcommand{\@tufte@lop@line}[2]{%
  % #1 is the figure/table number and its caption text
  % #2 is the page number on which the figure/table appears
  \leftskip 0.0em
  \rightskip 0em
  \parfillskip 0em plus 1fil
  \parindent 0.0em
  \@afterindenttrue
  \interlinepenalty\@M
  \leavevmode
  \@tempdima 2.0em
  \advance\leftskip\@tempdima
  \null\nobreak\hskip -\leftskip
  {#1}\nobreak\qquad\nobreak#2%
  \par%
}

\let\l@plate\l@figure

\makeatother

%% End plate environment %%%%%%%%%%%

\begin{document}

\listofplates

\chapter{Plate Environment}

\begin{plate}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption{Non-starred}
\label{plate:1}
\end{plate}

\begin{plate}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption[Non-starred - long caption.]{Non-starred - long caption. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum.}
\label{plate:2}
\end{plate}

\begin{plate*}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption{Starred}
\label{plate:3}
\end{plate*}

\begin{plate*}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption[Starred - long caption.]{Starred - long caption. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum.}
\label{plate:4}
\end{plate*}

\end{document}
3

Here's an approach I've used to get something working. Not the neatest...

I copied the @tufte@float environment definition and the \@tufte@float@fullwidth command definition into my preamble, renaming them as @TC@float and \@TC@float@fullwidth, respectively.

I altered my plate* environment definition to use @TC@float instead of the standard tufte-class figure* environment.

This allows me to alter the width of the caption text box (altering the line \begin{minipage}[\floatalignment]{2\marginparwidth}\hbox{} makes it twice the normal width) and the location by forcing \@TC@float@fullwidth to only use the option I want (commenting out the unwanted options, effectively).

As my \textwidth = 2\marginparwidth, and an option in \@TC@float@fullwidth allows the position to be bottom left, I can have a long caption appear below my figure and in the same space as the body text would normally fill.

Solution with caption bottom left and the width of the body text

MWE:

\documentclass[a4paper,justified,twoside,openright]{tufte-book}
\usepackage{layouts}
\usepackage{showframe}
\geometry{landscape,top=1in,bottom=0.75in,textheight=7in,textwidth=6in,marginparsep=0.5in,marginparwidth=3in}

\usepackage{tikz}

%% Plate environment %%%%%%%%%%%%%%% from http://tex.stackexchange.com/questions/113631/caption-placement-for-new-float-in-tufte-book-class
\newcounter{plate}
\newcommand\platename{Plate}
\newcommand\listplatename{List of Plates}
\makeatletter
\newcommand\listofplates{%
  \ifthenelse{\equal{\@tufte@class}{book}}%
    {\chapter*{\listplatename}}%
    {\section*{\listplatename}}%
%  \begin{fullwidth}%
    \@starttoc{lop}%
%  \end{fullwidth}%
}
\renewcommand\theplate
%     {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@plate}
     {\@arabic\c@plate} % alter numbering to be continuous
\def\fps@plate{tbp}
\def\ftype@plate{1}
\def\ext@plate{lop}
\def\fnum@plate{\platename\nobreakspace\theplate}

\newenvironment{plate}[1][htbp]
  {\begin{@tufte@float}[#1]{plate}{}}
  {\end{@tufte@float}}

% \newenvironment{plate*}[1][htbp]%
%   {\begin{@tufte@float}[#1]{plate}{star}}  % need to define a new @tufte@float environment - copy the existing one and alter all the names then change the position of the caption box. Something like @TC@float
%   {\end{@tufte@float}}

\newenvironment{plate*}[1][htbp]%
  {\begin{@TC@float}[#1]{plate}{star}}  % need to define a new @tufte@float environment - copy the existing one and alter all the names then change the position of the caption box. Something like @TC@float
  {\end{@TC@float}}

\newcommand{\@tufte@lop@line}[2]{%
  % #1 is the figure/table number and its caption text
  % #2 is the page number on which the figure/table appears
  \leftskip 0.0em
  \rightskip 0em
  \parfillskip 0em plus 1fil
  \parindent 0.0em
  \@afterindenttrue
  \interlinepenalty\@M
  \leavevmode
  \@tempdima 2.0em
  \advance\leftskip\@tempdima
  \null\nobreak\hskip -\leftskip
  {#1}\nobreak\qquad\nobreak#2%
  \par%
}

\let\l@plate\l@figure

\newenvironment{@TC@float}[3][htbp]%
  {% begin @tufte@float
    % Should this float be full-width or just text-width?
    \ifthenelse{\equal{#3}{star}}%
      {\gsetboolean{@tufte@float@star}{true}}%
      {\gsetboolean{@tufte@float@star}{false}}%
    % Check page side (recto/verso) and store detected value -- can be overriden in environment contents
    \@tufte@checkoddpage%
    \ifthenelse{\boolean{@tufte@odd@page}}%
      {\gsetboolean{@tufte@float@recto}{true}\@tufte@float@debug{Detected page: [recto/odd]}}%
      {\gsetboolean{@tufte@float@recto}{false}\@tufte@float@debug{Detected page: [verso/even]}}%
    % If the float placement specifier is 'b' and only 'b', then bottom-align the mini-pages, otherwise top-align them.
    \renewcommand{\@tufte@fps}{#1}%
    \@tufte@float@debug{Allowed positions: [#1]}
    \ifthenelse{\equal{#1}{b}\OR\equal{#1}{B}}%
      {\renewcommand{\floatalignment}{b}\@tufte@float@debug{Presumed position: [bottom]}}%
      {\renewcommand{\floatalignment}{t}\@tufte@float@debug{Presumed position: [top]}}%
    % Capture the contents of the \caption and \label commands to use later
    \global\let\@tufte@orig@caption\caption%
    \global\let\@tufte@orig@label\label%
    \renewcommand{\caption}{\optparams{\@tufte@caption}{[][0pt]}}%
    \renewcommand{\label}[1]{\@tufte@label{##1}}%
    % Handle subfigure package compatibility
    \ifthenelse{\boolean{@tufte@packages@subfigure}}{%
      % don't move the label while inside a \subfigure or \subtable command
      \global\let\label\@tufte@orig@label%
    }{}% subfigure package is not loaded
    \@tufte@orig@float{#2}[#1]%
    \ifthenelse{\boolean{@tufte@float@star}}%
      {\setlength{\@tufte@float@contents@width}{\@tufte@fullwidth}}%
      {\setlength{\@tufte@float@contents@width}{\textwidth}}%
    \begin{lrbox}{\@tufte@figure@box}%
      \begin{minipage}[\floatalignment]{\@tufte@float@contents@width}\hbox{}%
  }{% end @tufte@float
      \par\hbox{}\vspace{-\baselineskip}\ifthenelse{\prevdepth>0}{\vspace{-\prevdepth}}{}% align baselines of boxes
      \end{minipage}%
    \end{lrbox}%
    % build the caption box
    \begin{lrbox}{\@tufte@caption@box}%
% EDIT THE WIDTH OF THE CAPTION HERE
      \begin{minipage}[\floatalignment]{2\marginparwidth}\hbox{}% 
        \ifthenelse{\NOT\equal{\@tufte@stored@caption}{}}{\@tufte@orig@caption[\@tufte@stored@shortcaption]{\@tufte@stored@caption}}{}%
        \ifthenelse{\NOT\equal{\@tufte@stored@label}{}}{\@tufte@orig@label{\@tufte@stored@label}}{}%
        \par\vspace{-\prevdepth}%% TODO: DOUBLE-CHECK FOR SAFETY
      \end{minipage}%
    \end{lrbox}%
    % now typeset the stored boxes
    \begin{fullwidth}%
      \begin{minipage}[\floatalignment]{\linewidth}%
        \ifthenelse{\boolean{@tufte@float@star}}%
          {\@TC@float@fullwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}%
          {\@TC@float@textwidth[\@tufte@caption@vertical@offset]{\@tufte@figure@box}{\@tufte@caption@box}}%
      \end{minipage}%
    \end{fullwidth}%
    \@tufte@orig@endfloat% end original LaTeX float environment
    % output debug info
    \ifthenelse{\boolean{@tufte@debug}}{%
      \typeout{^^J^^J----------- Tufte-LaTeX float information ----------}%
      \ifthenelse{\equal{\@tufte@stored@label}{}}%
        {\typeout{Warning: Float unlabeled!}}%
        {\typeout{Float label: [\@tufte@stored@label]}}%
      \typeout{Page number: [\thepage]}%
      \def\MessageBreak{^^J}%
      \typeout{\@tufte@float@debug@info}%
      \ifthenelse{\boolean{@tufte@symmetric}}%
        {\typeout{Symmetric: [true]}}%
        {\typeout{Symmetric: [false]}}%
      \typeout{----------------------------------------------------^^J^^J}%
    }{}%
    % reset commands and temp boxes and captions
    \gdef\@tufte@float@debug@info{}%
    \let\caption\@tufte@orig@caption%
    \let\label\@tufte@orig@label%
    \begin{lrbox}{\@tufte@figure@box}\hbox{}\end{lrbox}%
    \begin{lrbox}{\@tufte@caption@box}\hbox{}\end{lrbox}%
    \gdef\@tufte@stored@shortcaption{}%
    \gdef\@tufte@stored@caption{}%
    \gdef\@tufte@stored@label{}%
    \gsetlength{\@tufte@caption@vertical@offset}{0pt}% reset caption offset
  }

% COMMENT OUT ALL OPTIONS, THEN SELECT THE OPTION YOU WANT AND PLACE AT SHOWN POINT
%
\newcommand{\@TC@float@fullwidth}[3][0pt]{%
  % \ifthenelse{\equal{\floatalignment}{b}}%
  %   {% place caption above figure
  %     \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}%
  %       {\hfill\smash{\raisebox{#1}{\usebox{#3}}}\par\usebox{#2}\@tufte@float@debug{Caption position: [above right]}}% caption on the right
  %       {\smash{\raisebox{#1}{\usebox{#3}}}\hfill\par\usebox{#2}\@tufte@float@debug{Caption position: [above left]}}% caption on the left
  %   }{% place caption below figure
  %     \ifthenelse{\NOT\boolean{@tufte@symmetric}\OR\boolean{@tufte@float@recto}}%
  %       {\usebox{#2}\par\hfill\smash{\raisebox{#1}{\usebox{#3}}}\@tufte@float@debug{Caption position: [below right]}}% caption on the right
  %       {\usebox{#2}\par\smash{\raisebox{#1}{\usebox{#3}}}\hfill\@tufte@float@debug{Caption position: [below left]}}% caption on the left
  %   }%
% CHOSEN OPTION GOES HERE
\usebox{#2}\par\smash{\raisebox{#1}{\usebox{#3}}}\hfill\@tufte@float@debug{Caption position: [below left]}% caption on the left
}

\makeatother

%% End plate environment %%%%%%%%%%%

\begin{document}
\setuplayouts

\listofplates

\chapter{Plate Environment}

\begin{plate}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption{Non-starred}
\label{plate:1}
\end{plate}

\begin{plate}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption[Non-starred - long caption.]{Non-starred - long caption. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum.}
\label{plate:2}
\end{plate}

\begin{plate*}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption{Starred}
\label{plate:3}
\end{plate*}

\begin{plate*}
\tikz{\path[draw=red,fill=blue] (0,0) rectangle (\textwidth-1cm,\textheight-1cm);}
\caption[Starred - long caption.]{Starred - long caption. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum. Lorem ipsum, lorem ipsum,Lorem ipsum, lorem ipsum,Lorem ipsum.}
\label{plate:4}
\end{plate*}

\clearpage

\begin{figure}
  \centering
%\setlayoutscale{0.3}
 \currentpage
\drawparametersfalse
\drawpage
  \caption{Test}
\end{figure}
%\setlayoutscale{0.3}
%\drawpage

\end{document}

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.