22

What am trying to achieve is the following:

enter image description here

Of course, if this can be done so that there is a switch between even and odd pages. Currently I am only interested in the not appearing on the LHS margin. I currently do not have a MWE but I am throwing out the question. Probably you can start from here:

\documentclass[letterpaper]{article}
\usepackage[dvipsnames]{xcolor}
\usepackage{marginnote}
\usepackage{etoolbox}
\usepackage{calc}

\makeatletter
\patchcmd{\@mn@margintest}{\@tempswafalse}{\@tempswatrue}{}{}
\patchcmd{\@mn@margintest}{\@tempswafalse}{\@tempswatrue}{}{}
\reversemarginpar
\makeatother

\setlength{\marginparwidth}{2in}

\oddsidemargin 2in

\def\fbx#1{\vbox{\hbox{\hbox{#1}\setbox0\lastbox\copy0\kern\fboxsep\vrule width\fboxrule depth\dimexpr \fboxsep+\dp0\relax}%
            \hrule height\fboxrule}} 

\newcommand\caution[1]{%
\renewcommand*{\raggedleftmarginnote}{}
\relax\leavevmode\marginnote{%
        {\sffamily\bfseries\textcolor{BrickRed}{Caution!}}\\[1pt]%
        \fbx{\parbox[t]{\dimexpr\linewidth-3\marginparsep\relax}{#1}}%
    }
}
\begin{document}
test \caution{some random text for testing caution frame}. some random text some random text some random text some random text some random text.
\end{document}

enter image description here

2
  • And how it the position of the lateral arrow head determined? Jun 20, 2013 at 15:29
  • @GonzaloMedina The arrow should be pointing 0.5\height of the text in which the caution is placed. Or any aesthetic suggestions could work as well. I would suppose that the options of the marginnote would allow a vertical shift of the caution note. But this would be used just in extreme case where such a vertical shift is necessary. I know margin notes cannot break pages so that is out of the question.
    – azetina
    Jun 20, 2013 at 15:36

3 Answers 3

21

Here's one possibility using the mdframed package and \marginnote from the marginnote package:

\documentclass{article}
\usepackage[lmargin=5cm,textwidth=15cm,marginparwidth=4cm]{geometry}
\usepackage[dvipsnames]{xcolor}
\usepackage{ragged2e}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{marginnote}
\usetikzlibrary{calc}
\usepackage{lipsum}

\reversemarginpar

\newsavebox\mybox
\newlength\BoxHt

\newcommand\caution[2][-2.2\baselineskip]{%
\begin{lrbox}{\mybox}
\parbox{\marginparwidth}{#2}
\end{lrbox}%
\settoheight\BoxHt{\usebox\mybox}%
\raisebox{\BoxHt}[0pt][0pt]{\marginnote{%
  \begin{mdframed}[
    userdefinedwidth=\marginparwidth,
    innerleftmargin=3pt,
    innerrightmargin=3pt,
    linecolor=BrickRed,
    frametitle=\colorbox{white}{\space Caution\space},
    frametitlefont=\color{BrickRed}\sffamily,
    innertopmargin=10pt,
    frametitleaboveskip=-\ht\strutbox,
    frametitlebelowskip=-\ht\strutbox,
    frametitlealignment=\raggedright,
    singleextra={\fill[BrickRed] let \p1=(P), \p2=(O)  in 
    ( $ (P|-0,0.5*\y2+0.5*\y1) + (0,-4pt) $ ) -- +(4pt,4pt) -- +(0,8pt) -- cycle;}
]\RaggedRight\small#2\end{mdframed}}[#1]}}

\begin{document}

\lipsum*[3-4]\caution{\lipsum[2]}\lipsum[3-5]

Some test text\caution{Some text goes here just to illustrate the command}

\end{document}

enter image description here

A zoomed image:

enter image description here

The optional argument for \caution allows you to control the vertical shifting if necessary.

And here's another simpler option (which I personally like more) using tikz (and tikzpagenodes):

\documentclass{article}
\usepackage[lmargin=5cm,textwidth=15cm,marginparwidth=4cm]{geometry}
\usepackage[dvipsnames]{xcolor}
\usepackage{ragged2e}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usepackage{lipsum}

\newcounter{mycaution}

\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]\node[inner xsep=0pt,outer sep=0pt] (#1) {};}
\newcommand\caution[1]{%
\stepcounter{mycaution}%
\tikzmark{\themycaution}%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=BrickRed,anchor=east,xshift=-\marginparsep]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.west|-\themycaution) 
  {\parbox{\marginparwidth}{\vskip10pt\RaggedRight\small#1}};
\node[fill=white,font=\color{BrickRed}\sffamily,anchor=west,xshift=7pt]
  at (mybox\themycaution.north west) {\ Caution!\ };
\fill[BrickRed]
  ([yshift=3pt]mybox\themycaution.east) --
  ([xshift=3pt]mybox\themycaution.east) --
  ([yshift=-3pt]mybox\themycaution.east) -- cycle;
\end{tikzpicture}%
}

\begin{document}

\lipsum*[3-4]\caution{\lipsum[2]}\lipsum[3-5]

Some test text\caution{Some text goes here just to illustrate the command}

\end{document}

enter image description here

And a zoomed image:

enter image description here

An improved version; now there's an optional argument allowing you to change the position of the box and of the pointer; possible values are b, t, and c, to place the pointer at the bottom, at the top, and at the center, respectively, of the box:

\documentclass{article}
\usepackage[lmargin=5cm,textwidth=15cm,marginparwidth=4cm]{geometry}
\usepackage[dvipsnames]{xcolor}
\usepackage{ragged2e}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usepackage{lipsum}

\newcounter{mycaution}
\newcommand\pointeranchor{}
\newcommand\boxanchor{}
\newlength\boxvshift
\newlength\uppertrianglecorner

\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]\node[inner xsep=0pt,outer sep=0pt] (#1) {};}

\newcommand\caution[2][c]{%
\stepcounter{mycaution}%
\tikzmark{\themycaution}%
\if#1b\relax
\renewcommand\pointeranchor{mybox\themycaution.south east}%
\renewcommand\boxanchor{south east}%
\setlength\boxvshift{-10pt}%
\setlength\uppertrianglecorner{13pt}%
\else
\if#1t\relax
\renewcommand\pointeranchor{mybox\themycaution.north east}%
\renewcommand\boxanchor{north east}%
\setlength\boxvshift{10pt}%
\setlength\uppertrianglecorner{-7pt}%
\else
\if#1c\relax
\renewcommand\pointeranchor{mybox\themycaution.east}%
\renewcommand\boxanchor{east}%
\setlength\boxvshift{0pt}%
\setlength\uppertrianglecorner{3pt}%
\fi\fi\fi%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=BrickRed,anchor=\boxanchor,xshift=-\marginparsep,yshift=\boxvshift]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.west|-\themycaution) 
  {\parbox{\marginparwidth}{\vskip10pt\RaggedRight\small#2}};
\node[fill=white,font=\color{BrickRed}\sffamily,anchor=west,xshift=7pt]
  at (mybox\themycaution.north west) {\ Caution!\ };
\fill[BrickRed]
  ([yshift=\uppertrianglecorner]\pointeranchor) --
  ([yshift=\uppertrianglecorner-3pt,xshift=3pt]\pointeranchor) --
  ([yshift=\uppertrianglecorner-6pt]\pointeranchor) -- cycle;
\end{tikzpicture}%
}

\newcommand\Test{Nulla malesuada porttitor diam. Donec felis erat, congue non, volutpat at, tincidunt tristique, libero. Vivamus viverra fermentum felis. Donec nonummy pellentesque ante. Phasellus adipiscing
semper elit.}

\begin{document}

\lipsum*[4]\caution[t]{\Test}\lipsum[3]\par\bigskip

\lipsum*[4]\caution{\Test}\lipsum[3]\par\bigskip

\lipsum*[4]\caution[b]{\Test}\lipsum[3]

\end{document}

enter image description here

The t option is useful if the box will appear in the first lines of the text area; b can be used in case the box will appear near the bottom of the text area.

A little variation required in a comment; now \caution has three optional arguments and a mandatory one:

\caution[<pos>][<color>][<title>]{<text>}

where ias an in the code immediately before, and can be b, t, or c (default=c); <color> controls the color used for the frame and title (default=BrickRed); <title> changes the title used for the frame (defualt=Caption!); <text> is the content of the note.

\documentclass{article}
\usepackage[lmargin=5cm,textwidth=15cm,marginparwidth=4cm]{geometry}
\usepackage[dvipsnames]{xcolor}
\usepackage{ragged2e}
\usepackage{xparse}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usepackage{lipsum}

\newcounter{mycaution}
\newcommand\pointeranchor{}
\newcommand\boxanchor{}
\newlength\boxvshift
\newlength\uppertrianglecorner

\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]\node[inner xsep=0pt,outer sep=0pt] (#1) {};}

\NewDocumentCommand{\caution}{O{c}O{BrickRed}O{Caution!}m}{%
\stepcounter{mycaution}%
\tikzmark{\themycaution}%
\if#1b\relax
\renewcommand\pointeranchor{mybox\themycaution.south east}%
\renewcommand\boxanchor{south east}%
\setlength\boxvshift{-10pt}%
\setlength\uppertrianglecorner{13pt}%
\else
\if#1t\relax
\renewcommand\pointeranchor{mybox\themycaution.north east}%
\renewcommand\boxanchor{north east}%
\setlength\boxvshift{10pt}%
\setlength\uppertrianglecorner{-7pt}%
\else
\if#1c\relax
\renewcommand\pointeranchor{mybox\themycaution.east}%
\renewcommand\boxanchor{east}%
\setlength\boxvshift{0pt}%
\setlength\uppertrianglecorner{3pt}%
\fi\fi\fi%
\begin{tikzpicture}[remember picture,overlay]
\node[draw=#2,anchor=\boxanchor,xshift=-\marginparsep,yshift=\boxvshift]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.west|-\themycaution) 
  {\parbox{\marginparwidth}{\vskip10pt\RaggedRight\small#4}};
\node[fill=white,font=\color{#2}\sffamily,anchor=west,xshift=7pt]
  at (mybox\themycaution.north west) {\ #3\ };
\fill[#2]
  ([yshift=\uppertrianglecorner]\pointeranchor) --
  ([yshift=\uppertrianglecorner-3pt,xshift=3pt]\pointeranchor) --
  ([yshift=\uppertrianglecorner-6pt]\pointeranchor) -- cycle;
\end{tikzpicture}%
}

\newcommand\Test{Nulla malesuada porttitor diam. Donec felis erat, congue non, volutpat at, tincidunt tristique, libero. Vivamus viverra fermentum felis. Donec nonummy pellentesque ante. Phasellus adipiscing
semper elit.}

\begin{document}

\lipsum*[4]\caution[t]{\Test}\lipsum[3]\par\bigskip

\lipsum*[4]\caution[c][cyan!80!black]{\Test}\lipsum[3]\par\bigskip

\lipsum*[4]\caution[b][orange][Defcon 5!]{\Test}\lipsum[3]

\end{document}

enter image description here

7
  • I like how you did the triangle shaped marker. Interesting approach!
    – azetina
    Jun 20, 2013 at 19:52
  • @azetina new update. Thanks to an optional argument, you can now control the position of the box and of the pointer. Jun 20, 2013 at 20:22
  • @GonzaloMedina: Great answer ;-) Jun 20, 2013 at 20:23
  • @GonzaloMedina Very nice. Quick question, is it easy to take your above solution and use keyval/options (not sure what the precise term is) to change the marginnote name and colour ie instead of solely defining \mycaution with "Caution" and red outline have it as \mycaution[orange!green]{Be mildly wary!} or \mycaution[red!50]{Defcon 5!} or\mycaution[green]{All's well} or whatever \mycaution[colour]{Text} may be.
    – Leeser
    Jun 21, 2013 at 10:11
  • 1
    @GonzaloMedina: Great answer!!! Is there a way to have a colored background? For example yellow, just to make it look like a post it note?
    – Thanos
    Nov 14, 2013 at 17:43
5

I tried to improve Gonzalo Medina's code to be able to use two-sided documents.

The four aguments (the first three are optional and the last one is mandatory) are the same than in Gonzalo Medina's code.

I have tried to do my best so that the pointer is facing the text wich was juste before \caution (this is the reason why my MWE is so long, I had to get rid of the \lipsum and paste the whole text to put a \caution in the middle). In this way, chosing b, t or c for the first argument not only determines the place of the pointer inside the box, but also the placement of the box with respect to the text around the \caution command.

Furthermore, I recommand using \caution inside \marginnote to avoid splitting the paragraph around \caution.

I tried this code with book and tufte-book classes and it seems to work quite fine. However, the use of ifoddpage needs two or three compilations with pdfLaTeX

\documentclass[twoside,10pt]{book}
\usepackage[dvipsnames]{xcolor}
\usepackage{ragged2e}
\usepackage{xparse}
\usepackage[framemethod=tikz]{mdframed}
\usepackage{tikzpagenodes}
\usepackage{lipsum}
\usepackage{ifoddpage}
\usepackage[fulladjust]{marginnote}

\newcounter{mycaution}
\newlength\trianglexshift
\newlength\boxhshift
\newlength\boxvshift
\newlength\noteheight
\newlength\uppertrianglecorner
\newcommand\side{}
\newcommand\boxanchor{}
\newcommand\otherside{}
\newcommand\pointeranchor{}

\newcommand\tikzmark[1]{%
  \tikz[remember picture,overlay]\node[inner xsep=0pt,outer sep=0pt] (#1) {};}

\NewDocumentCommand{\caution}{O{c}O{BrickRed}O{Caution!}m}{%
%
\checkoddpage
\ifoddpageoroneside
\setlength\trianglexshift{-3pt}
\setlength\boxhshift{\marginparsep}
\renewcommand{\side}{west}
\renewcommand{\otherside}{east}
\else
\setlength\trianglexshift{3pt}
\setlength\boxhshift{-\marginparsep}
\renewcommand{\side}{east}%
\renewcommand{\otherside}{west}
\fi

\settoheight{\noteheight}{\parbox{\marginparwidth}{\RaggedRight\small#4}}
\stepcounter{mycaution}%
\tikzmark{\themycaution}%

\if#1b\relax
\renewcommand\pointeranchor{mybox\themycaution.south \side}%
\renewcommand\boxanchor{south \side}%
\setlength\boxvshift{\noteheight}%
\addtolength\boxvshift{0.7\baselineskip}
\setlength\uppertrianglecorner{13pt}%
\else
\if#1t\relax
\renewcommand\pointeranchor{mybox\themycaution.north \side}%
\renewcommand\boxanchor{north \side}%
\setlength\boxvshift{-\noteheight}%
\addtolength\boxvshift{1.3\baselineskip}
\setlength\uppertrianglecorner{-7pt}%
\else
\if#1c\relax
\renewcommand\pointeranchor{mybox\themycaution.\side}%
\renewcommand\boxanchor{\side}%
\setlength\boxvshift{\baselineskip}%
\setlength\uppertrianglecorner{3pt}%
\fi\fi\fi%

\begin{tikzpicture}[remember picture,overlay]
\node[draw=#2,anchor=\side,xshift=\boxhshift,yshift=\boxvshift]   
  (mybox\themycaution)
  at ([yshift=3pt]current page text area.\otherside|-\themycaution) 
  {\parbox{\marginparwidth}{\vskip10pt\RaggedRight\small#4}};
\node[fill=white,font=\color{#2}\sffamily,anchor=west,xshift=7pt]
  at (mybox\themycaution.north west) {\ #3\ };
\fill[#2]
  ([yshift=\uppertrianglecorner]\pointeranchor) --
  ([yshift=\uppertrianglecorner-3pt,xshift=\trianglexshift]\pointeranchor) --
  ([yshift=\uppertrianglecorner-6pt]\pointeranchor) -- cycle;
\end{tikzpicture}}


\newcommand\Test{Nulla malesuada porttitor diam. Donec felis erat, congue non, volutpat at, tincidunt tristique, libero. Vivamus viverra fermentum felis. Donec nonummy pellentesque ante. Phasellus adipiscing
semper elit.}

\begin{document}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.
Donec vehicula augue eu neque\marginnote{\caution[t][cyan!80!black]{\Test}}. Pellentesque habitant morbi tristique senectus
et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra
metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus
eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Cur-
abitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue
eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim
rutrum.

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.
Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus
et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra
metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus
eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada\marginnote{\caution{\Test}} eu, pulvinar at, mollis ac, nulla. Cur-
abitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue
eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim
rutrum.
Quisque ullamcorper placerat ipsum. Cras nibh. Morbi vel justo vitae lacus
tincidunt ultrices.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In
hac habitasse platea dictumst. Integer tempus convallis augue. Etiam facilisis.
Nunc elementum fermentum wisi. Aenean placerat. Ut imperdiet, enim sed
gravida sollicitudin, felis odio placerat quam, ac pulvinar elit purus eget enim.
Nunc vitae tortor. Proin tempus nibh sit amet nisl. Vivamus quis tortor vitae
risus porta vehicula.

\lipsum[3]\par\bigskip
\newpage
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit,
vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida
mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna.
Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus
et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra
metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus
eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium
quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu, pulvinar at, mollis ac, nulla. Cur-
abitur auctor semper nulla\marginnote{\caution[b][ForestGreen][Nice !]{\Test}}. Donec varius orci eget risus. Duis nibh mi, congue
eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim
rutrum.
Quisque ullamcorper placerat ipsum. Cras nibh. Morbi vel justo vitae lacus
tincidunt ultrices.  Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In
hac habitasse platea dictumst. Integer tempus convallis augue. Etiam facilisis.
Nunc elementum fermentum wisi. Aenean placerat. Ut imperdiet, enim sed
gravida sollicitudin, felis odio placerat quam, ac pulvinar elit purus eget enim.
Nunc vitae tortor. Proin tempus nibh sit amet nisl. Vivamus quis tortor vitae
risus porta vehicula.

\end{document}

An odd page

An odd page An even page

An even page

4

REVISED TO INCLUDE BOTH MARGINS! The first mandatory argument is a l or a r denoting in which margin the note is to be placed. The second argument is the note. REVISED to allow an optional argument that specifies the upward shift of the box relative to the unchanging arrow pointer.

In my example shown below, I shift the left box up 2ex relative to the default position. In the right box, I leave it at its default position.

EDITED to upgrade the syntax by replacing the deprecated \topinset macro with its \stackinset equivalent.

\documentclass{article}
\usepackage{xcolor}
\usepackage{stackengine}
\usepackage{lipsum}
\usepackage{MNsymbol}
\usepackage{graphicx}

\newcommand*\caution[3][0pt]{%
  \if l#2\reversemarginpar\def\pointer{\filledmedtriangleright}%
    \def\stackalignment{r}\fi%
  \if r#2\normalmarginpar\def\pointer{\filledmedtriangleleft}%
    \def\stackalignment{l}\fi%
  \marginpar{%
    \stackinset{\stackalignment}{-2ex}{t}{3ex+#1}{%
      \scalebox{1.5}{\textcolor{yellow}{$\pointer$}}}{%
      \belowbaseline[-1.5\baselineskip-#1]{%
        \stackengine%
          {-5pt}%
          {\fcolorbox{yellow}{white}{\parbox{1.8cm}%
            {\vspace{3pt}\raggedright#3}}}%
          {~\colorbox{white}{\sffamily Caution}}%
          {O}%
          {l}%
          {F}%
          {F}%
          {S}%
        }%
      }% 
  }%
}

\begin{document}
\lipsum[1-2]
this is a\caution[2ex]{l}{some text for the caution box} test

\lipsum[3]
This is another test\caution{r}{another caution box test testing the
right side}

\lipsum[4]

\end{document}

enter image description here

and here's the close up:

enter image description here

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .