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.
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}
As announced in my comment above here comes a MWE which uses the option calcmargin=
of the caption
package to setup a right margin which hopefully fits your specification:
\documentclass{article}
\usepackage{calc}
\usepackage[figurename=Fig.]{caption}
\DeclareCaptionStyle{figstyle}
[format=plain,margin=0pt,justification=centering]
{format=hang,calcmargin={0pt,\widthof{\captionfont\captionlabelfont\figurename~\thefigure: }},
font=small,labelfont=bf}
\captionsetup[figure]{style=figstyle}
\begin{document}
\begin{figure}
\hrulefill
\caption{Blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah\ldots}
\hrulefill
\end{figure}
\begin{figure}
\hrulefill
\caption{Blah blah blah blah blah blah blah blah blah blah blah\ldots}
\hrulefill
\end{figure}
\end{document}
The syntax of the calcmargin=
option is the same as margin=
but its value will not be set immediately but calculated for every individual caption instead. (Unfortunately calcmargin=
isn't documented yet.)
For example, the same is possible for tables with the same format:
\DeclareCaptionStyle{tabstyle}
[format=plain,margin=0pt,justification=centering]
{format=hang,calcmargin={0pt,\widthof{\captionfont\captionlabelfont\tablename~\thetable: }},
font=small,labelfont=bf}
\captionsetup[table]{style=tabstyle}
and for subfigures in the format of (a)
, (b)
, etc. using the subcaption
package
\DeclareCaptionStyle{subfigstyle}
[format=plain,margin=0pt,justification=centering]
{format=hang,calcmargin={0pt,\widthof{\captionfont\captionlabelfont(\thesubfigure) }},
font=small,labelfont=bf}
\captionsetup[subfigure]{style=subfigstyle}
Update: My first example code was crap, hopefully this one is better.
Update 2 (by riddleculous): added the same for tables and subcaptions
Best Answer
welcome here. Before getting to your problem, first a gentle and well-meaning reminder (actually two):
OK, with that out of the way, here are solutions to your problems.
Problem 1 -- a) Badly behaved margin figures captions and b) caption fontsize smaller
I couldn't reproduce your misbehaved margin figures captions, probably because I automatically used the caption and graphicx packages whereas you might not have done so. Nevertheless, without seeing the code you used, I'm at a loss to explain why your work turned out the way it did.
Setting the caption fontsize smaller (and many, many useful things besides) can be achieved with the
\captionsetup
command from the caption package.Here's an example of the output my code produces (code included below):
Problem 2 -- Subfig caption in wrapfig environment constrained to typeblock
Because you wanted subfigures to protrude into the margins, you created
0.3\textwidth
-widewrapfigure
environments and then proceeded to place0.5\textwidth
-wide figures into them. This gives the effect you want with your figures -- they spill nicely into the margins -- but, unfortunately, LaTeX wraps the overall figure caption to the page typeblock, giving you the most visually unappealing caption "clipping" effect that you see.The solution's simple enough, if not entirely obvious. Use the optional 'overhang' argument with each invocation of
wrapfigure
. (I set the margin protrusion to[3cm]
in the code below). Note also that to avoid overfull hboxes, I set thewrapfigure
environment width a little larger than the contained object width:0.46\textwidth
to0.45\textwidth
, respectively, below.)Tidying up your code, I recommend:
\vspace
(negative) heights specified in terms of\baselineskip
rather than absolute pointsize dimensions when it comes to aligning objects with lines of text (this is just habit in this case, absolute dimensions will be fine),wrapfigure
to use an exact number of lines (in our case[33]
) to force it to more exactly meet your needs, andwrapfigure
distance explicitly, e.g., with something like\setlength\columnsep{\marginparsep}
.Here's the output from the code below:
Solution code