% \CheckSum{220} % % \iffalse meta-comment % % Copyright (C) 2005 by Stephan Hennig % ------------------------------------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.2 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.2 or later is part of all distributions of LaTeX % version 1999/12/01 or later. % % \fi % % \iffalse %<*dtx> \ProvidesFile{mcaption.dtx} % %\ProvidesPackage{mcaption} %<*dtx|package> [2009/03/13 v3.0 Put captions into the outer document margin (SH)] % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] % %<*driver> \documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{mcaption.dtx} \PrintChanges \PrintIndex \end{document} % % %<*example> \listfiles \documentclass{book} \usepackage{wrapfig} \usepackage[top]{mcaption} \usepackage[ font={footnotesize,it}, labelfont=bf, justification=raggedright] {caption}[2005/06/28] \usepackage[english]{babel} \usepackage{blindtext} \begin{document} \setlength{\margincapsep}{3\columnsep} \author{Stephan Hennig} \title{mcaption test file} \maketitle \listoffigures \listoftables \chapter{Demonstration of the mcaption package} \section{This is one-column mode} \blindtext[1] \begin{wrapfigure}{o}{5cm} \begin{margincap} \rule{5cm}{2cm} \caption{A wrapfigure caption in the outer margin.} \label{fig:wrapOneCol} \end{margincap} \end{wrapfigure} \blindtext[1] \begin{table} \begin{margincap} \centering \begin{tabular}{@{}lr@{}} foo & 7\\ bar & 21 \\ baz & 23 \\ \end{tabular} \caption{A table caption in the outer margin.} \label{tab:shorttab} \end{margincap} \end{table} \twocolumn \section{This is two-column mode} \blindtext[1] \begin{wrapfigure}{o}{2cm} \begin{margincap} \rule{2cm}{1cm} \caption[A hanging wrapfigure caption.]{Another wrapfigure caption in the outer margin. Note, we are in the outer column. And we're hanging!} \label{fig:wrapTwoCol} \end{margincap} \end{wrapfigure} \blindtext[5] \begin{figure*} \begin{margincap} \centering \rule{10cm}{2cm} \caption{A figure caption in the outer margin.} \label{fig:figure*} \end{margincap} \end{figure*} Let's reference all figures and tables: \newcommand*{\pref}[1]{\ref{#1} & \pageref{#1}} \begin{tabular}{ll} float & page\\\hline figure~\pref{fig:wrapOneCol}\\ table~\pref{tab:shorttab}\\ figure~\pref{fig:wrapTwoCol}\\ figure~\pref{fig:figure*}\\ \end{tabular} \end{document} % % \fi % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \GetFileInfo{mcaption.dtx} % % % \title{The \textsf{mcaption} package\thanks{This document corresponds % to \textsf{mcaption}~\fileversion, dated \filedate.}} % \author{Stephan Hennig\\ \texttt{stephanhennig@arcor.de}} % % \maketitle % % \begin{abstract} % This package provides a |margincap| environment for putting captions % into the outer document margin with either a top or bottom % alignment. % \end{abstract} % % % \section{Package options}\label{sec:options} % % The \textsf{mcaption} package provides the following options: % % \smallskip % \begin{tabular}{lll} % option & brief description & page\\\hline % |bottom| & vertical caption alignment & \pageref{sec:alignv}\\ % |top| & vertical caption alignment & \pageref{sec:alignv}\\ % |v2.2| & compatibility option & \pageref{sec:usage}\\ % \end{tabular} % % % \section{Usage}\label{sec:usage} % % The |margincap|\DescribeEnv{margincap}\ environment places its % contents into a box whose width matches the current line witdh and % attaches a caption (with an optional label) next to the box in the % outer margin. Caption text and the label are taken from |\caption| % and |\label| commands within the environment. A typical use-case is % to put the |margincap| environment into a float, such as a |figure| or % |tabular| environment: % % \begin{verbatim} %\begin{figure} % \begin{margincap} % \centering % \includegraphics{picture} % \caption[short caption text]{long caption text} % \label{fig:pic} % \end{margincap} %\end{figure} % \end{verbatim} % % The |margincap| environment also works with the % |wrapfigure|\DescribeEnv{wrapfigure}\ environment provided by the % |wrapfig| package. Note, wrapped figures or tables have to appear in % the outer margin, \emph{i.\,e.}, parameters `o' or `O' have to be % applied to the |wrapfigure| environment. This even works in % two-column mode. See file |example.tex| for an example. % % Up to \textsf{mcaption}~v2.2\marginpar{\raggedleft\fbox{v2.2}} the % |margincap| environment had a different syntax. Macros |\caption| and % |\label| haven't been recognized inside the environment. Instead, % short and long caption texts had to be given as optional and mandatory % arguments to the |margincap| environment. To apply a label to a % |margincap| environment, the |\label| command had to passed as part of % the long caption text. The \textsf{mcaption} package provides a % compatibility option |v2.2|\marginpar{\raggedleft |v2.2|} that enables % the old behaviour. This option is disabled by default. % % % \section{Caption Format} % % \subsection{Vertical alignment}\label{sec:alignv} % Vertical alignment of margin captions can be controlled by package % options |top|\marginpar{\raggedleft |top|} or % |bottom|\marginpar{\raggedleft |bottom|}. % % Option |top| aligns the top-most line of the caption to the top of the % |margincap| environment's contents (an image, tabular, \emph{etc.}) % Similarly, option |bottom| aligns the bottom-most line of the caption % to the bottom of the |margincap| environment's contents. In case a % caption has a larger height or depth than a figure, it will hang or % grow beneath the running text. Option |bottom| is the default. % % Up to \textsf{mcaption}~v2.2\marginpar{\raggedleft\fbox{v2.2}}, the % vertical alignment of captions required some user-interaction. For % tabulars, the baseline alignment had to match that of the caption. % For that reason a macro % |\margincapalign|\DescribeMacro{\margincapalign}\ had been provided % that had to be passed as an alignment specifier to all tabular % declarations. Newer versions of \textsf{mcaption} don't need this % alignment specifier. For backwards compatibility macro % |\margincapalign| is still provided, but it's use is deprecated. % Legacy documents, that use |\margincapalign| in tabular declarations, % should still compile as soon as \textsf{mcaption} is loaded with % package option |v2.2| (see section~\ref{sec:usage}). % % \subsection{Horizontal alignment} % Horizontal spacing between a |margincap| environment's contents and % the caption can be adjusted by the length % |\margincapsep|\DescribeMacro{\margincapsep}{}. This has to be done % after |\begin{document}| or via |\AtBeginDocument| in the preamble. % Since changing |\margincapsep| will affect all further |margincap| % environments, the author suggests one document wide setting to get a % consistent look throughout the document. Default value is % |\marginparsep|. % % \subsection{Further tweaks} % To get visually pleasing results you should provide wide enough outer % margins. To further smoothen line breaking consider using a smaller % caption font and setting captions ragged. The author suggests using % the \textsf{caption} package to format captions. \emph{E.\,g.}, % issuing the following line in the document preamble % % \begin{verbatim} %\usepackage[font=footnotesize,justification=raggedright]{caption} % \end{verbatim} % will typeset all further captions at a smaller font size and flush % left. The |RaggedRight| option might be useful here, too, to allow % for hyphenation inside ragged text. % % % \section{Known Problems}\label{sec:problems} % % \begin{enumerate} % % \item Captions may appear in the wrong margin, sometimes. Running % \LaTeX\ twice should solve that problem. \emph{Background:} For % robustness, \textsf{mcaption} relies on the \textsf{changepage} % package with option |strict| to detect left- and right-hand pages. % This requires two \LaTeX-passes. The behaviour can be changed with % macro |\easypagecheck| (see package |changepage|). % % \item Captions are positioned slightly too high. This is because % |margincap| doesn't reliably know the contents' exact bottom-most % base line. Additional artificial zero height lines are used to % align environment contents and caption text. For that reason, the % true depth of both are not taken into account. \emph{Todo:} Provide % means for vertical fine-tuning of captions. % % \item When using the |wrapfig| package the auto sizing feature of the % |wrapfigure| environment won't work when putting a |margincap| % environment in. You'll have to specify the width of a |wrapfigure| % manually. % \end{enumerate} % % % \section{Bugs} % % If you find bugs, feel free to contact me at % \texttt{stephanhennig@arcor.de}. % % % \DoNotIndex{\begin,\end,\def,\RequirePackage,\else,\fi,\equal,\relax} % % % \StopEventually{\PrintChanges} % % % \changes{v2.0}{2005/09/20}{Prepared .dtx package.} % % % \iffalse %<*package> % \fi % \section{Implementation} % % \changes{v3.0}{2009/03/07}{Complete revision of vertical alignment % mechanism.} % % Make sure the |changepage| package is loaded. % \changes{v3.0}{2009/03/12}{Replace package \textsf{chngpage} by % newer \textsf{changepage}.} % \begin{macrocode} \RequirePackage[strict]{changepage} % \end{macrocode} % % \begin{macro}{\mcaption@alignv} % This macro is used by options |bottom| and |top|. % \begin{macrocode} \newcommand*{\mcaption@alignv}{} % \end{macrocode} % \end{macro} % % Declare options |bottom| and |top| to determine vertical alignment of % a caption. Default package option is |bottom|. % \changes{v2.2}{2005/09/29}{New package options `bottom' and `top'.} % \begin{macrocode} \DeclareOption{top}{\renewcommand*{\mcaption@alignv}{t}} \DeclareOption{bottom}{\renewcommand*{\mcaption@alignv}{b}} \ExecuteOptions{bottom} % \end{macrocode} % % Declare compatibility option |v2.2|, that restores the behaviour of % \textsf{mcaption}~v2.2 for the |margincap| environment. % \changes{v3.0}{2009/03/10}{New package option `v2.2'.} % \begin{macrocode} \DeclareOption{v2.2}{% \AtEndOfPackage{% % \end{macrocode} % % Activate |margincap| with optional and mandatory caption argument. % \begin{macrocode} \let\margincap\mcaption@mcIIdotII% \let\endmargincap\endmcaption@mcIIdotII% % \end{macrocode} % % \begin{macro}{\margincapalign} % Macro |\margincapalign| is deprecated (cf. macro % |\mcaption@alignv|). It is only provided for backwards % compatibility. % \changes{v3.0}{2009/03/08}{Deprecated.} % \begin{macrocode} \newcommand*{\margincapalign}{\mcaption@alignv} % \end{macrocode} % \end{macro} % % \begin{macrocode} }% }% % \end{macrocode} % % Process the options. % \begin{macrocode} \ProcessOptions\relax % \end{macrocode} % % \begin{macro}{\margincapsep} % Length |\margincapsep| determines the horizontal distance between % contents and caption and can be adjusted by the user. This length % has to be set only after |\begin{document}| and equals % |\marginparsep| by default. % \begin{macrocode} \newlength{\margincapsep} \AtBeginDocument{% \setlength{\margincapsep}{\marginparsep}% } % \end{macrocode} % \end{macro} % % Declare macros for storing long and short caption text and a flag. % \begin{macrocode} \newcommand*{\mcaption@CaptionLong}{} \newcommand*{\mcaption@CaptionShort}{} \newcommand*{\mcaption@CaptionFlag}{} % \end{macrocode} % % Declare macros for storing a label and a flag. % \begin{macrocode} \newcommand*{\mcaption@Label}{} \newcommand*{\mcaption@LabelFlag}{} % \end{macrocode} % % Declare boxes to store the contents and caption of a |margincap| % environment. % \begin{macrocode} \newsavebox{\mcaption@ObjectBox} \newsavebox{\mcaption@CaptionBox} % \end{macrocode} % % % \begin{environment}{mcaption@mcIIdotII} % Declare a template for the traditional |margincap| environment as of % \textsf{mcaption}~v2.2, that takes an optional and a mandatory % caption text argument, \emph{cf.} environment |mcaption@mcIIIdot|. % \changes{v2.1}{2005/09/29}{Now works with standard classes.} % \begin{macrocode} \newenvironment{mcaption@mcIIdotII}[2][\mcaption@DefaultOpt]{% % \end{macrocode} % % Call |\caption| with or without optional argument. Trick taken from % UK-\TeX-FAQ, question 286: `Optional arguments like |\section|'. % \begin{macrocode} \def\mcaption@DefaultOpt{#2}% % \end{macrocode} % % Store optional and mandatory caption arguments for later processing. % Flag a caption without label. % \changes{v3.0}{2009/03/10}{Delay caption handling.} % \begin{macrocode} \def\mcaption@CaptionShort{#1}% \def\mcaption@CaptionLong{#2}% \gdef\mcaption@CaptionFlag{t}% \gdef\mcaption@LabelFlag{f}% % \end{macrocode} % % Collect environment contents in a box |\mcaption@ObjectBox| of width % |\linewidth|. % \begin{macrocode} \begin{lrbox}{\mcaption@ObjectBox}% \begin{minipage}{\linewidth}% }{% \end{minipage}% \end{lrbox}% % \end{macrocode} % % Call the working macros. % \begin{macrocode} \mcaption@align@boxes% \mcaption@output@boxes% % \end{macrocode} % % We're done. % \begin{macrocode} }% % \end{macrocode} % \end{environment} % % % \begin{environment}{mcaption@mcIIIdot} % Declare a template for the new |margincap| environment as of % \textsf{mcaption}~v3.0, that accepts |\caption| and |\label| % arguments inside the environment, \emph{cf.} environment % |mcaption@mcIIdotII|. % \changes{v3.0}{2009/03/10}{Recognize \texttt{\textbackslash caption} % and \texttt{\textbackslash label} commands.} % \begin{macrocode} \newenvironment{mcaption@mcIIIdot}{% % \end{macrocode} % % Replace |\caption| and |\label| commands by custom variants and unset % flags. % \begin{macrocode} \let\mcaption@origcaption\caption% \let\caption\mcaption@caption% \gdef\mcaption@CaptionFlag{f}% \let\mcaption@origlabel\label% \let\label\mcaption@label% \gdef\mcaption@LabelFlag{f}% % \end{macrocode} % % Collect environment contents in a box |\mcaption@ObjectBox| of width % |\linewidth|. % \begin{macrocode} \begin{lrbox}{\mcaption@ObjectBox}% \begin{minipage}{\linewidth}% }{% \end{minipage}% \end{lrbox}% % \end{macrocode} % % Restore original |\caption| and |\label| definitions. % \begin{macrocode} \let\caption\mcaption@origcaption% \let\label\mcaption@origlabel% % \end{macrocode} % % Call the working macros. % \begin{macrocode} \mcaption@align@boxes% \mcaption@output@boxes% % \end{macrocode} % % We're done. % \begin{macrocode} }% % \end{macrocode} % \end{environment} % % % \begin{environment}{margincap} % Provide the |margincap| environment. % \begin{macrocode} \newenvironment{margincap}{}{}% % \end{macrocode} % % Activate the new behaviour for the |margincap| environment. % \begin{macrocode} \let\margincap\mcaption@mcIIIdot% \let\endmargincap\endmcaption@mcIIIdot% % \end{macrocode} % \end{environment} % % % Define auxillary macros and environments. % % These macros are used for saving the original |\caption| and |\label| % definitions. % \begin{macrocode} \newcommand*{\mcaption@origcaption}{} \newcommand*{\mcaption@origlabel}{} % \end{macrocode} % % Declare an auxillary macro for storing the \emph{unexpanded} optional % |\caption| argument. % \begin{macrocode} \newcommand*{\mcaption@DefaultOpt}{} % \end{macrocode} % % \begin{macro}{\mcaption@caption} % This |\caption| replacement macro just stores its arguments in % |\mcaption@CaptionShort| and |\mcaption@CaptionLong| for later % reference and sets a flag. % \begin{macrocode} \newcommand*{\mcaption@caption}[2][\mcaption@DefaultOpt]{% \gdef\mcaption@DefaultOpt{#2}% \gdef\mcaption@CaptionShort{#1}% \gdef\mcaption@CaptionLong{#2}% \gdef\mcaption@CaptionFlag{t}% \ignorespaces }% % \end{macrocode} % \end{macro} % % \begin{macro}{\mcaption@label} % This |\label| replacement macro just stores its arguments in % |\mcaption@Label| for later reference and sets a flag. % \begin{macrocode} \newcommand*{\mcaption@label}[1]{% \gdef\mcaption@Label{#1}% \gdef\mcaption@LabelFlag{t}% \ignorespaces }% % \end{macrocode} % \end{macro} % % \begin{macro}{\mcaption@align@boxes} % This macro prepares and aligns contents and caption boxes. % \begin{macrocode} \newcommand*{\mcaption@align@boxes}{% % \end{macrocode} % % If the user issued a |\caption| command, put the caption text into box % |\mcaption@CaptionBox|. Else prepare an empty box. % \changes{v3.0}{2009/03/07}{Use temporary \LaTeX\ length.} % \begin{macrocode} \begin{lrbox}{\mcaption@CaptionBox}% \setlength{\@tempdima}{\marginparwidth}% \addtolength{\@tempdima}{\marginparsep}% \addtolength{\@tempdima}{-\margincapsep}% \begin{minipage}{\@tempdima}% \if\mcaption@CaptionFlag t% \setlength{\abovecaptionskip}{0pt}% \setlength{\belowcaptionskip}{0pt}% \caption[\mcaption@CaptionShort]{\strut\mcaption@CaptionLong\strut}% \fi% \if\mcaption@LabelFlag t% \label{\mcaption@Label}% \fi% \end{minipage}% \end{lrbox}% % \end{macrocode} % % Wrap contents into zero height top and bottom lines to get the desired % reference point. Then use |\vtop| or |\vbox| for aligning boxes. % \begin{macrocode} \sbox{\mcaption@ObjectBox}{% \if\mcaption@alignv t\vtop \else\vbox \fi {% \vskip0pt% \hbox{\usebox{\mcaption@ObjectBox}}% \vskip0pt% }% }% \sbox{\mcaption@CaptionBox}{% \if\mcaption@alignv t\vtop \else\vbox \fi {% \vskip0pt% \hbox{\usebox{\mcaption@CaptionBox}}% \vskip0pt% }% }% }% % \end{macrocode} % \end{macro} % % % \begin{macro}{\mcaption@output@oddpage} % This macro first outputs the contents and then the caption box. % \begin{macrocode} \newcommand*{\mcaption@output@oddpage}{% \makebox[\linewidth][l]{% \usebox{\mcaption@ObjectBox}% \hspace*{\margincapsep}% \smash{\usebox{\mcaption@CaptionBox}}% }% }% % \end{macrocode} % \end{macro} % % \begin{macro}{\mcaption@output@evenpage} % This macro first outputs the caption and then the contents box. % \begin{macrocode} \newcommand*{\mcaption@output@evenpage}{% \makebox[\linewidth][r]{% \smash{\usebox{\mcaption@CaptionBox}}% \hspace*{\margincapsep}% \usebox{\mcaption@ObjectBox}% }% }% % \end{macrocode} % \end{macro} % % \begin{macro}{\mcaption@output@boxes} % This macro outputs contents and caption boxes in the correct order. % \begin{macrocode} \newcommand*{\mcaption@output@boxes}{% % \end{macrocode} % % In two-sided documents check for odd and even pages. In one-sided % documents treat every page as an odd page. % \changes{v2.2}{2005/09/29}{Fixed: In one-sided documents captions were % put into the wrong margin.} % \changes{v3.0}{2009/03/12}{Fixed: In one-sided documents % \textsf{chngpage/changepage}'s even/odd page detection was subtly % broken by \textsf{mcaption}.} % \begin{macrocode} \if@twoside% \checkoddpage% \ifoddpage% \mcaption@output@oddpage% \else% \mcaption@output@evenpage% \fi% \else% \mcaption@output@oddpage% \fi% }% % \end{macrocode} % \end{macro} % % \iffalse % % \fi % \Finale