Skip to content

Instantly share code, notes, and snippets.

@basilfx
Last active August 29, 2015 14:06
Show Gist options
  • Save basilfx/5d21ee238c254563e19d to your computer and use it in GitHub Desktop.
Save basilfx/5d21ee238c254563e19d to your computer and use it in GitHub Desktop.
Captions in the margin of a two-sided book, including wide (margin) images.
%!TEX root=test.tex
%%
%% This is file `mycaption.sty',
%% generated with the docstrip utility + positioning modifications.
%%
%% The original source files were:
%%
%% mcaption.dtx (with options: `package')
%%
%% This is a generated file.
%%
%% Copyright (C) 2005 by Stephan Hennig <[email protected]>
%%
%% 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.
%%
%http://tex.stackexchange.com/questions/16328/test-if-text-fits-on-one-line
\ProvidesPackage{mycaption}
[2009/03/13 v3.0 Put captions into the outer document margin (SH)]
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\RequirePackage[strict]{changepage}
\RequirePackage{etoolbox}
\newcommand*{\mcaption@alignv}{}
\DeclareOption{top}{\renewcommand*{\mcaption@alignv}{t}}
\DeclareOption{bottom}{\renewcommand*{\mcaption@alignv}{b}}
\ExecuteOptions{bottom}
\DeclareOption{v2.2}{%
\AtEndOfPackage{%
\let\margincap\mcaption@mcIIdotII%
\let\endmargincap\endmcaption@mcIIdotII%
\newcommand*{\margincapalign}{\mcaption@alignv}
}%
}%
\ProcessOptions\relax
\newlength{\margincapsep}
\newlength{\margincapwidth}
\AtBeginDocument{%
\setlength{\margincapsep}{\marginparsep}%
\setlength{\margincapwidth}{\marginparsep}%
\addtolength{\margincapwidth}{\marginparwidth}%
}
\newcommand*{\mcaption@CaptionLong}{}
\newcommand*{\mcaption@CaptionShort}{}
\newcommand*{\mcaption@CaptionFlag}{}
\newcommand*{\mcaption@Label}{}
\newcommand*{\mcaption@LabelFlag}{}
\newsavebox{\mcaption@ObjectBox}
\newsavebox{\mcaption@CaptionBox}
\newenvironment{mcaption@mcIIdotII}[2][\mcaption@DefaultOpt]{%
\def\mcaption@DefaultOpt{#2}%
\def\mcaption@CaptionShort{#1}%
\def\mcaption@CaptionLong{#2}%
\gdef\mcaption@CaptionFlag{t}%
\gdef\mcaption@CaptionOpt{n}%
\gdef\mcaption@LabelFlag{f}%
\begin{lrbox}{\mcaption@ObjectBox}%
\begin{minipage}{\linewidth}%
}{%
\end{minipage}%
\end{lrbox}%
\mcaption@align@boxes%
\mcaption@output@boxes%
}%
\newenvironment{mcaption@mcIIIdot}[1][n]{%
\newcommand\ifopt{\expandafter\ifstrequal\expandafter}%
\ifopt{#1}{wt}{%
\gdef\mcaption@CaptionWide{t}%
\gdef\mcaption@CaptionAlign{b}}{}%
\ifopt{#1}{wb}{%
\gdef\mcaption@CaptionWide{t}%
\gdef\mcaption@CaptionAlign{t}}{}%
\ifopt{#1}{w}{%
\gdef\mcaption@CaptionWide{t}%
\if\mcaption@alignv{t}%
\gdef\mcaption@CaptionAlign{b}%
\else%
\gdef\mcaption@CaptionAlign{t}%
\fi}{}%
\ifopt{#1}{b}{%
\gdef\mcaption@CaptionWide{f}%
\gdef\mcaption@CaptionAlign{b}}{}%
\ifopt{#1}{t}{%
\gdef\mcaption@CaptionWide{f}%
\gdef\mcaption@CaptionAlign{t}}{}%
\ifopt{#1}{n}{%
\gdef\mcaption@CaptionWide{f}%
\gdef\mcaption@CaptionAlign{\mcaption@alignv}}{}%
\let\mcaption@origcaption\caption%
\let\caption\mcaption@caption%
\gdef\mcaption@CaptionFlag{f}%
\let\mcaption@origlabel\label%
\let\label\mcaption@label%
\gdef\mcaption@LabelFlag{f}%
\begin{lrbox}{\mcaption@ObjectBox}%
\begin{minipage}{\linewidth}%
}{%
\end{minipage}%
\end{lrbox}%
\let\caption\mcaption@origcaption%
\let\label\mcaption@origlabel%
\mcaption@align@boxes%
\mcaption@output@boxes%
}%
\newenvironment{margincap}{}{}%
\let\margincap\mcaption@mcIIIdot%
\let\endmargincap\endmcaption@mcIIIdot%
\newcommand*{\mcaption@origcaption}{}
\newcommand*{\mcaption@origlabel}{}
\newcommand*{\mcaption@DefaultOpt}{}
\newcommand*{\mcaption@caption}[2][\mcaption@DefaultOpt]{%
\gdef\mcaption@DefaultOpt{#2}%
\gdef\mcaption@CaptionShort{#1}%
\gdef\mcaption@CaptionLong{#2}%
\gdef\mcaption@CaptionFlag{t}%
\ignorespaces
}%
\newcommand*{\mcaption@label}[1]{%
\gdef\mcaption@Label{#1}%
\gdef\mcaption@LabelFlag{t}%
\ignorespaces
}%
\newcommand*{\mcaption@align@boxes}{%
\begin{lrbox}{\mcaption@CaptionBox}%
\setlength{\@tempdima}{\marginparwidth}%
\addtolength{\@tempdima}{\marginparsep}%
\addtolength{\@tempdima}{-\margincapsep}%
\setlength{\@tempdimb}{\totalheightof{\usebox{\mcaption@ObjectBox}}}%
\begin{minipage}{\@tempdima}%
\if\mcaption@CaptionWide t%
\if\mcaption@CaptionAlign t%
\vspace{\marginparsep}\vspace{\@tempdimb}%
\fi%
\fi%
\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%
\if\mcaption@CaptionWide t%
\if\mcaption@CaptionAlign b%
\vspace{\marginparsep}\vspace{\@tempdimb}%
\fi%
\fi%
\end{minipage}%
\end{lrbox}%
\sbox{\mcaption@ObjectBox}{%
\if\mcaption@CaptionAlign t\vtop
\else\vbox
\fi
{%
\vskip0pt%
\hbox{\usebox{\mcaption@ObjectBox}}%
\vskip0pt%
}%
}%
\sbox{\mcaption@CaptionBox}{%
\if\mcaption@CaptionAlign t\vtop
\else\vbox
\fi
{%
\vskip0pt%
\hbox{\usebox{\mcaption@CaptionBox}}%
\vskip0pt%
}%
}%
}%
\newcommand*{\mcaption@output@oddpage}{%
\makebox[\linewidth][l]{%
\usebox{\mcaption@ObjectBox}%
\hspace*{\margincapsep}%
\if\mcaption@CaptionWide t%
\hspace*{-\margincapwidth}%
\fi%
\smash{\usebox{\mcaption@CaptionBox}}%
}%
}%
\newcommand*{\mcaption@output@evenpage}{%
\makebox[\linewidth][r]{%
\smash{\usebox{\mcaption@CaptionBox}}%
\if\mcaption@CaptionWide t%
\hspace*{-\margincapwidth}%
\fi%
\hspace*{\margincapsep}%
\usebox{\mcaption@ObjectBox}%
}%
}%
\newcommand*{\mcaption@output@boxes}{%
\if@twoside%
\checkoddpage%
\ifoddpage%
\mcaption@output@oddpage%
\else%
\mcaption@output@evenpage%
\fi%
\else%
\mcaption@output@oddpage%
\fi%
}%
\endinput
%%
%% End of file `mycaption.sty'.
\documentclass[a4paper,twoside]{book}
\usepackage{showframe}
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{float}
\usepackage[demo]{graphicx}
\usepackage{etoolbox}
\usepackage{mycaption}
\usepackage{marginnote}
\usepackage{caption}
\usepackage{changepage}
\usepackage{calc}
\captionsetup{
labelfont={bf},
font=small}
\newlength{\normalwidth}
\setlength{\normalwidth}{\textwidth}
\newlength{\fullwidth}
\setlength{\fullwidth}{\textwidth}
\addtolength{\fullwidth}{\marginparsep}
\addtolength{\fullwidth}{\marginparwidth}
\newlength{\marginwidth}
\setlength{\marginwidth}{0pt}
\addtolength{\marginwidth}{-\marginparwidth}
\addtolength{\marginwidth}{-\marginparsep}
\newenvironment{widepage}{
\begin{adjustwidth*}{}{\marginwidth}%
\setlength{\textwidth}{\fullwidth}%
\setlength{\linewidth}{\fullwidth}%
\setlength{\columnwidth}{\fullwidth}%
}{\end{adjustwidth*}}
\renewenvironment{figure*}[1][htbp]{
\begin{figure}[#1]%
\begin{widepage}%
}{\end{widepage}\end{figure}}
\begin{document}
\lipsum[1]
\begin{figure*}[H]
\begin{margincap}[wb]
\includegraphics[width=\textwidth,height=200pt]{broken_loop}
\caption{Wide bottom. Some caption that is a bit longer than you might expect to see here, but that is OK. Some caption that is a bit longer than you might expect to see here, but that is OK. Some caption that is a bit longer than you might expect to see here, but that is OK.}
\end{margincap}
\end{figure*}
\lipsum[2]
\begin{figure}[H]
\begin{margincap}[b]
\includegraphics[width=\textwidth]{broken_loop}
\caption{Bottom. Some caption that is a bit longer than you might expect to see here, but that is OK.}
\end{margincap}
\end{figure}
\newpage
\lipsum[3]
\begin{figure*}[H]
\begin{margincap}[wt]
\includegraphics[width=\textwidth]{broken_loop}
\caption{Wide top. Some caption that is a bit longer than you might expect to see here, but that is OK. Some caption that is a bit longer than you might expect to see here, but that is OK.}
\end{margincap}
\end{figure*}
\lipsum[4]
\begin{figure}[H]
\begin{margincap}[t]
\includegraphics[width=\textwidth]{broken_loop}
\caption{Top. Some caption that is a bit longer than you might expect to see here, but that is OK. Some caption that is a bit longer than you might expect to see here, but that is OK.}
\end{margincap}
\end{figure}
\newpage
\lipsum[5]
\begin{figure*}[H]
\begin{margincap}[w]
\includegraphics[width=\textwidth]{broken_loop}
\caption{Wide (default align). Some caption that is a bit longer than you might expect to see here, but that is OK. Some caption that is a bit longer than you might expect to see here, but that is OK.}
\end{margincap}
\end{figure*}
\lipsum[6]
\begin{figure}[H]
\begin{margincap}
\includegraphics[width=\textwidth]{broken_loop}
\caption{Default align. Some caption that is a bit longer than you might expect to see here, but that is OK. Some caption that is a bit longer than you might expect to see here, but that is OK.}
\end{margincap}
\end{figure}
\lipsum[7]
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment