I am trying to achieve the effect in the image below where text is highlighted with a coloured underline and linked to margin notes with partial borders that are also coloured. I have done some research and seen people achieve an effect close to what I am after with soul (although it does seem a bit ancient and unsupported) or alternatively todonotes. I have no idea how one might achieve this aesthetic here and would really appreciate some pointers.
Highlight text with colored underline link to margin notes
marginnotetodonotes
Related Solutions
EDIT: I've updated the solution below to use the wrapfig environment, which simplified at least some parts of the code. This solved all the spacing issues I had before. I also changed the definition of the command to only require that it is put before each paragraph, and added functionality for putting long notes on new lines. The only issues remaining is that the solution still does not work well with page breaks, and also that it is quite cumbersome to but the same command before each paragraph, even if it is less cumbersome than the syntax of my previous solution.
I've now made a new solution (with the help of David Carlise) which I think is a bit closer to what you intended than my last attempt. It still has some problems though:
- Some unwanted spaces sometimes appear between paragraphs
- Notes are never put on separate lines
- No sidebreaks are allowed inside paragraphs
The result now look as in the image below:
And the source code.. :)
\documentclass[10pt]{article}
% Packages
\usepackage[newcommands]{ragged2e}
\usepackage{newfile}
\usepackage{color}
\usepackage{xparse}
\usepackage{graphics}
\usepackage[dvipsnames]{xcolor}
\usepackage{hyperref}
\usepackage{wrapfig}
\usepackage{ifthen}
% Settings
\colorlet{Pbardefault}{yellow!70} % Default color for the colored bar left to the notes
\colorlet{Plightdefault}{yellow!10}% Default color for background of the note
\def\Pmin{0.5} % ~minimal amount main text
\def\Pmax{0.95} % ~maximal amount main text / \Psf
\def\Psf{1.14} %
\newcounter{localsidenotecounter}
\newlength{\currentparskip}
\setlength{\currentparskip}{\parskip}
% The formatting of the note
\newdimen\Pparsep
\Pparsep=0.2em
\newdimen\Pcolorwidth
\Pcolorwidth=2mm
% The paragraph command
\makeatletter
\def\sidenotepi#1\par%
{
%
\immediate\openout\tempfile=sidenotes.tex %
%
\twopara%
{
#1 \immediate\closeout\tempfile
}
{\input{sidenotes.tex}}
}
\makeatother
% A command for finding the optimal text widths
\makeatletter
\long\def\twopara#1#2{%
\newdimen\columnsep
\columnsep=\dimexpr \Pparsep + \Pcolorwidth
\def\@elt##1{\global\value{##1}\the\value{##1}\relax}%
\edef\TY@ckpt{\cl@@ckpt}%
\@tempdima\dimexpr\textwidth-\columnsep\relax
{\hbadness\@M\raggedright\hsize.5\@tempdima \@tempdima\hsize
\setbox\z@\vbox{{#1\endgraf}}%
\setbox\tw@\vbox{{#2\endgraf}}%
\Gscale@div\tmp{\ht\z@}{\dimexpr\ht\z@+\ht\tw@\relax}%
\global\let\xtmp\tmp}%
\dimen@ \xtmp\@tempdima
\ifdim\dimen@<\Pmin\@tempdima \dimen@\Pmin\@tempdima\fi
\ifdim\dimen@>\Pmax\@tempdima \dimen@\Pmax\@tempdima\fi
\dimen@ii\dimexpr\@tempdima-\dimen@\relax
\TY@ckpt
\ifdim\dimen@ii<20pt
#1
\else
\ifdim \Psf\dimen@ii>\dimexpr\textwidth-\Pmin\textwidth
#1
\let\Pnotebox\Pnotebox@
\dimen@ii = \dimexpr \textwidth-4mm
\setlength{\intextsep}{2pt}%
\begin{figure}[h]
#2
\end{figure}
\else
\let\Pnotebox\Pnotebox@
\dimen@ii\dimexpr\Psf\dimen@ii
\setlength{\intextsep}{0pt}%
\begin{wrapfigure}{o}[-4mm]{\dimen@ii}
#2
\end{wrapfigure}
#1
\fi
\fi
\let\Pnotebox\Pnotebox@@
}
\makeatother
% The unformatted note text
\makeatletter
\long\def\Pnotebox@@#1#2#3{ %barcolor, backcolor, text
#3}
\makeatother
\makeatletter
\long\def\Pnotebox#1#2#3{ %barcolor, backcolor, text
#3}
\makeatother
% The formatting of the notes
\makeatletter
\newdimen\Pnoteheight
\long\def\Pnotebox@#1#2#3{ %barcolor, backcolor, text
\settoheight{\Pnoteheight}{\parbox{\dimen@ii}{#3}}%
\begin{minipage}{\dimexpr\dimen@ii+\Pcolorwidth}
\textcolor{#1}{\rule[\dimexpr-\Pnoteheight+1mm]{\Pcolorwidth}{\dimexpr 2\Pnoteheight}}%
\colorbox{#2}{\parbox{\dimen@ii}{#3}}
\end{minipage}%
}
\makeatother
% Commands for making the sidenote
\newwrite\tempfile
\makeatletter
\DeclareDocumentCommand \sidenote {m O{Pbardefault} O{Plightdefault}} {%
\stepcounter{localsidenotecounter}%
\hyperlink{sidenote\arabic{localsidenotecounter}}{${}^\textrm{\footnotesize\arabic{localsidenotecounter}}$}%
\immediate\write\tempfile%
{%
\noexpand\Pnotebox{#2}{#3}{%
\noexpand\footnotesize \noexpand{\noexpand\hypertarget{sidenote\arabic{localsidenotecounter}}{${}^{\arabic{localsidenotecounter}}$} \unexpanded{#1 }}%
}}}
\makeatother
\begin{document}
\sidenotepi
But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue\sidenote{Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure} pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure
\sidenotepi
But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure.
\sidenotepi
But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue\sidenote{Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure} pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure.\sidenote{Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure.}[blue][blue!5]
\end{document}
Here I use the stackengine
package to develop the macros \markabove
and \markbelow
that uses text lapping to achieve an edit, without affecting the layout of the original document, if you are careful with your %
signs. It works in footnotes, too, as shown.
EDITED to allow a TODO like functionality, when your comments are too long to stick directly into the text.
\documentclass{article}
\textheight=6in
\usepackage{xcolor}
\usepackage{stackengine}
\setstackgap{L}{.5\baselineskip}
\newcommand\markabove[2]{{\sffamily\color{red}\hsmash{$\uparrow$}%
\smash{\toplap{#1}{\scriptsize\bfseries#2}}}}
\newcommand\markbelow[2]{{\sffamily\color{red}\hsmash{$\downarrow$}%
\smash{\bottomlap{#1}{\scriptsize\bfseries#2}}}}
\usepackage{ifthen}
\newcounter{todoindex}
\setcounter{todoindex}{0}
\newcommand\TODO[1]{%
\addtocounter{todoindex}{1}%
\expandafter\def\csname todo\roman{todoindex}\endcsname{#1}%
\markabove{c}{\Alph{todoindex}}%
}
\newcounter{index}
\newcommand\showTODOs{%
\vspace{5ex}%
\rule{10ex}{.5ex}\textcolor{red}{TO-DO LIST}\rule{10ex}{.5ex}\\%
\setcounter{index}{0}%
\whiledo{\value{index} < \value{todoindex}}{%
\addtocounter{index}{1}%
\markabove{c}{\Alph{index}} \csname todo\roman{index}\endcsname\\%
}%
}
\begin{document}
When writing documents\footnote{Note, this is a copy of the OP's
\markbelow{c}{That is the name for the questioner}%
text}, I like to 'mark up'
\markabove{c}{Do you mean like this?}%
draft/partial text (e.g., short summaries
\TODO{I am using the TODO macro for longer notes that do not fit into a single
line, or are otherwise inconvenient to make short}%
of what will go in a section) so that I can clearly see what needs to be adjusted. I know that things like the todonotes package exist (see this question, for example), but I want something
\markbelow{r}{, anything actually,}%
that can span arbitrary parts of the document (e.g., multiple paragraphs or even sections with whatever text is in there).
I have been using the color package's \verb|\color| 'switch'
\TODO{I presume you actually meant that you are using the \textsf{xcolor}
package, since it improves upon the functionality of the former package.}%
to do this (with an alternate \verb|\textcolor| based command for short inline bits of text), with commands like this:
\begin{verbatim}
\usepackage[usenames,dvips]{color}
\newcommand{\todo}[1]{\textcolor{Purple}{#1}}
\newcommand{\startToDo}{\color{Purple}}
\newcommand{\stopToDo}{\color{Black}}
\end{verbatim}
However, this has problems in various situations (such as footnotes, URLs, tables), some dependent on the particular other packages used. (See this question and this one.)
\markabove{r}{I'm sorry, but the links didn't show}%
Does anyone have any ideas on a robust alternative I could use? I would prefer not to use marginal lines (as used to indicate changes) so that it is clear exactly which bits of text, figures, etc. are included. Differently-coloured
\markbelow{l}{and lapped, I think}%
text was the obvious choice for me.
There's a chance that my outstanding question will get an answer that 'fixes' my explicit \verb|\color| usage (though I imagine with lots of very arcane low-level TeX) but obviously a pre-existing package or simple LaTeX that achieves the same or similar effect would be better.
\showTODOs
\end{document}
Best Answer
Welcome to StackExchange! And thanks for the interesting question which just happens to dovetail nicely with a project of mine.
The example that you show was likely created with the help of Adobe's InDesign or Illustrator, or similar software, which I used and supported for years. The advantage that TeX has (or, rather, one of them) is that some of the more tedious tasks in creating a document such as this can be -- to a certain extent -- automated. Even so, there is generally at least some tweaking of the final result to get something that approximates reasonably closely to an ideal. The following code allows for a relatively large number of tweaks. I was at a loss to see how, in TeX, both to underline and highlight text at the same time. Fortunately, Steven Segletes came brilliantly to the rescue as you can see for yourself: Is it possible to highlight and underline at the same time? (also serves as an excellent and practical object lesson in the extraordinary usefulness of being a part of this community).
The code, though prolix, is fairly straightforward and reasonably well commented. The example code uses a large number of the tweaks, and will repay close inspection.
Two important things: First, this code requires to be run twice. If you run the code and it looks simply awful, then just run it again and all should be well. Second, in the course of writing my code, I found a small problem for which Steven speedily supplied a fix, with more on the way; my code contains the original fix.
I did take one liberty. In the original, the side notes (both left and right) have colored rules on their left. I suggest that the rules would be more attractive on the side of the side notes (awful turn of phrase) that face the main text -- right side rule for side notes on the left (text also right-justified), and left side rule for notes on the right)-- and from which all the arrows can start.
It is entirely likely that this may not be my last word on this subject... As is often the case with TeX, there are many, many ways of solving a problem. This is just one such...
Update
To my original query about underlining and highlighting (Is it possible to highlight and underline at the same time?) Javier Bezos suggested that I take a look at
soulpos.sty
which I did. I've incorporated its use (easy-peasy) into my code (there are no changes in the interface):Update 2
I was a little unhappy with requiring Gentle User to fiddle with
geometry.sty
in order to create a document. I herewith change that with the addition of an environment,mkcalloutdoc
. It takes two arguments: the width and the (supposed) height of the main text -- both can be changed at will. There is also an option,mainframe
that will draw a box around the main text. There are no changes to the\myhl
command.Note: The side notes are placed using the TikZ
overlay
option. You will notice that the side notes extend beyond the left and right margins (shown with theshowframe
option togeometry.sty
) with no complaint from TeX: theoverlay
option makes the side notes essentially invisible to TeX's space calculations. You can adjust thenotewidth
option to themkcalloutdoc
environment or the width (first argument tomkcalloutdoc
) if you need to fit the document between margins.