1

In my memoir-based document, I need to occasionally insert some content (text quote or pseudocode) and I want to be able to add a caption. Because the content must appear exactly where I want it, I cannot use a floating environment. The caption needs to appear in the margin.

I tried to define a new environment, which does part of what I want, but the formatting is not good enough. Here's what I've done:

\documentclass[a4paper]{memoir}
\setstocksize{29.7cm}{21.0cm} % A4 stock
\settrimmedsize{27.94cm}{21.0cm}{*} % 27.94cm = 11in
\setlength{\trimtop}{0.0cm}
\setlength{\trimedge}{\stockwidth}
\addtolength{\trimedge}{-\paperwidth}
\settypeblocksize{23.94cm}{12.3cm}{*}
\setlrmargins{1.13cm}{*}{*}
\setulmargins{2.0cm}{*}{*}
\setmarginnotes{\onelineskip}{6.15cm}{\onelineskip}
\sidecapmargin{outer}
\setsidecaps{\onelineskip}{6.15cm}
\usepackage{lipsum}
\newlength{\mymargin}
\setlength{\mymargin}{\paperwidth}
\addtolength{\mymargin}{-\textwidth}
\addtolength{\mymargin}{-2\spinemargin}
\checkandfixthelayout

%%% caption for new environment, typeset as margin comment
\makeatletter
\newcommand{\mycaption}[1]{%
 \strictpagecheck\marginpar{\setlength{\parindent}{1.0em}\small
  \@afterindentfalse\@afterheading {\textbf{My caption \thechapter.\themynewcount:}} #1}%
}
\makeatother

%%% new environment
\newcounter{mynewcount}[chapter]
\newenvironment{mynewenv}[1]{%
  \stepcounter{mynewcount}%
  \vspace{\abovedisplayskip}%
  \mycaption{#1}%
  \begin{minipage}[t]{\textwidth}%
  }{\end{minipage}\vspace{\belowdisplayskip}}

\begin{document}
\chapter{Introduction}
\lipsum[1]
\begin{mynewenv}{Caption text}
\lipsum[2]
\end{mynewenv}
\lipsum[3]

\end{document}

This gives me the following:

enter image description here

So at the moment, there are three problems:

  1. The contents of the new environment are typeset indented, which I can't get rid of even if I add a \noindent in the environment definition.
  2. As a consequence, the contents of the environment are too wide and spill into the margin.
  3. I want the top of the caption to be aligned with the top of the contents of the environment.

In addition, there are a couple of things that would be 'nice to have':

  1. The ability to specify whether the caption should be aligned with the top or the bottom of the contents.
  2. The ability to specify a symmetric indentation on both sides of the contents.

PS. I do not have any experience writing environments worth speaking of, so any feedback is appreciated.

  • Have you tried tcolorbox environment? I take it should be doable with a sidebyside tcolorbox! – Hafid Boukhoulda Dec 27 '18 at 18:20
  • What exactly is meant by: symmetric indentation on both sides of the contents? – Hafid Boukhoulda Dec 27 '18 at 20:46
  • What I meant by "symmetric indentation" is that the content's left margin could be indented with respect to the left margin of the document itself and that the right margin would be indented by the same amount with respect to the right margin of the document. – user1362373 Dec 28 '18 at 10:07
3

Add a negative vertical space \vspace{-\abovedisplayskip} and \noindent before the minipage environment:

\documentclass[a4paper]{memoir}
\setstocksize{29.7cm}{21.0cm} % A4 stock
\settrimmedsize{27.94cm}{21.0cm}{*} % 27.94cm = 11in
\setlength{\trimtop}{0.0cm}
\setlength{\trimedge}{\stockwidth}
\addtolength{\trimedge}{-\paperwidth}
\settypeblocksize{23.94cm}{12.3cm}{*}
\setlrmargins{1.13cm}{*}{*}
\setulmargins{2.0cm}{*}{*}
\setmarginnotes{\onelineskip}{6.15cm}{\onelineskip}
\sidecapmargin{outer}
\setsidecaps{\onelineskip}{6.15cm}
\usepackage{lipsum}
\newlength{\mymargin}
\setlength{\mymargin}{\paperwidth}
\addtolength{\mymargin}{-\textwidth}
\addtolength{\mymargin}{-2\spinemargin}
\checkandfixthelayout

%%% caption for new environment, typeset as margin comment
\makeatletter
\newcommand{\mycaption}[1]{%
 \strictpagecheck\marginpar{\setlength{\parindent}{1.0em}\small
  \@afterindentfalse\@afterheading {\textbf{My caption \thechapter.\themynewcount:}} #1}%
}
\makeatother

%%% new environment
\newcounter{mynewcount}[chapter]
\newenvironment{mynewenv}[1]{%
  \stepcounter{mynewcount}%
  \vspace{\abovedisplayskip}%
  \mycaption{#1}%
  \vspace{-\abovedisplayskip} <------------------
  \noindent\begin{minipage}[t]{\textwidth}% <------------------
  }{\end{minipage}\vspace{\belowdisplayskip}}

\begin{document}
\chapter{Introduction}
\lipsum[1]
\begin{mynewenv}{Caption text}
\lipsum[2]
\end{mynewenv}
\lipsum[3]

\end{document}

enter image description here

Another solution using tcolorbox Here is an attempt using tcolorbox package in conjunction with the caption and newfloat packages. This could certainly be enhanced much more.

\documentclass[a4paper]{memoir}
\usepackage{lipsum}
\usepackage{tcolorbox,caption,newfloat}
\DeclareFloatingEnvironment[name= My caption]{myfloat}
\captionsetup[myfloat]{labelfont=bf}

\newtcolorbox{mytcolorbox}[1][sidebyside align=top seam]{
                          frame empty,
                          segmentation empty,
                          %colback=white,
                          sidebyside,
                          sidebyside gap=\marginparsep,
                          size=minimal,
                          grow to right by = \marginparsep + \marginparwidth,
                          toggle enlargement,
                          check odd page,
                          if odd page or oneside={
                          lefthand width=\linewidth,
                          halign lower=flush center,
                          before lower=\captionof{myfloat}
                          }{
                          righthand width=\linewidth,
                          halign upper=flush center,
                          before upper=\captionof{myfloat}
                          },
                          #1}


\begin{document}
\chapter{Introduction}
\lipsum[1]
\begin{mytcolorbox}
\lipsum[2]
\tcblower
Caption text
\end{mytcolorbox}
\begin{mytcolorbox}[sidebyside align=bottom seam]
\lipsum[3]
\tcblower
Another caption text
\end{mytcolorbox}
\clearpage
\lipsum[1]
\begin{mytcolorbox}
Caption text
\tcblower
\lipsum[2]
\end{mytcolorbox}
\begin{mytcolorbox}[sidebyside align=bottom seam]
Another caption text
\tcblower
\lipsum[3]
\end{mytcolorbox}

\end{document}

enter image description here

enter image description here

  • Thanks, this does what I need. I will take a look at the tcolorbox package. However, I'm also curious whether it would be possible to do in a "leaner" way, i.e., without using an external package. What I mean is what did I not do or do wrong in my first attempt? – user1362373 Dec 28 '18 at 10:09
  • @user1362373 I have updated my answer with a solution that doesn't need an external package! – Hafid Boukhoulda Dec 28 '18 at 12:35
  • Thanks, that does what I need. The additional negative \vspace made the difference. – user1362373 Dec 28 '18 at 13:15

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.