11

I have been typesetting a two-columned book where I sometimes need to put a mark in the margin to say, that particular line might need special attention. (The book is actually a psalter - for chanting.)

Because it isn't possible to use \marginpar in the multicol environment, I use \marginnote from the package marginnote instead. The problem is, that all the margin notes appear in the outer margin of the page. I need each to appear next to the column, where it occurs - some in the inner margin, some in the outer margin - to match the problematic lines closely.

Is there any way to achieve this? I searched the internet thoroughly and haven't found anything relevant...

\documentclass{article}

\usepackage{multicol}
\usepackage{marginnote}

\begin{document}
\begin{multicols}{2}

Some text, a very long one.

And somewhere in the middle of it I need a (very small) margin note, like this:

Text text text\marginnote{\textbf{!}} and more text...

\end{multicols}
\end{document}
Gonzalo Medina
  • 505,128
igneus
  • 265

2 Answers2

7

One can use \pdfsavepos to detect if the mark is on the left or right column. This is best done using Heiko Oberdiek's zref package.

Since we can get the actual x-position of the mark (in sp units) we can use it to detect if we are in the left or right columns.

A somewhat simplistic implementation is shown in the minimal below.

\documentclass{article}
\usepackage{multicol,zref-savepos}
\def\putmarginpar#1#2{%
  \zsavepos{#1}%
  \ifnum20432158>\number\zposx{#1}%
     \hbox to 0pt{\hskip\dimexpr-\zposx{#1}sp +0.5cm \relax#2}%
  \else
      \hbox to 0pt{\hskip4cm #2}%
  \fi%
}
\parskip0pt
\begin{document}
\begin{multicols}{2}

Testing \footnotemark\putmarginpar{a:1}{First} of something that is very long and if  it need be can be set somewhere\footnotemark \putmarginpar{a:2}{Second}, where it can be subsequently found or lost\footnotemark \putmarginpar{a:3}{Third.}

\zsavepos{dd}\zposx{dd}
\end{multicols}

\end{document}

You might need to run the example more than once for the position to settle. This works both for pdfLaTeX as XeLaTeX.

enter image description here

The MWE is dependent on the actual geometry used, but one can automate the calculations. Also the boxes have been kept simple for clarity. Substituting:

\hbox to 0pt{\hskip4.2cm {\vtop to 0pt{\parindent0pt\hsize 2cm#2}}}

will enable paragraphs to be inserted.

yannisl
  • 117,160
  • Thanks. This nearly solves my issue. The only problem that remains is, that my document is composed of many files (using \input) and some of the files are included several times. – igneus Apr 01 '12 at 08:57
  • In this setup, only in the last occurence of a particular included file the margin notes are placed correctly. – igneus Apr 01 '12 at 09:01
  • @JakubPavlík This works by saving the position in the auxiliary file, so obviously if you include the same file twice, only the last one will be known as previous ones will be overwritten. – yannisl Apr 01 '12 at 09:11
  • @JakubPavlík This shouldn't happen if you use \input; doing \include{file} twice is wrong. – egreg Apr 01 '12 at 09:50
  • @egreg But it happens. I only use \input, no \include. – igneus Apr 01 '12 at 12:21
  • 1
    @JakubPavlík Oh, yes, of course! The labels are the same! You could make the labels dependent on a counter that's incremented when the file is loaded. – egreg Apr 01 '12 at 12:24
  • @egreg It sounds good. Unfortunatelly I'm not able to write the code myself, because I'm just on the beginning of learning how to program TeX. – igneus Apr 01 '12 at 12:35
  • @egreg It seems I have found how to do it (i.e. compose labels from a constant string and a value of a counter). – igneus Apr 01 '12 at 13:12
  • @JakubPavlík That's what I was thinking to. Good job! – egreg Apr 01 '12 at 13:14
  • @JakubPavlík Could you post that code to compose labels, please (or maybe the whole example with that?)? I've spent a few minutes trying to do that and I haven't had any luck. – pushcx Nov 14 '12 at 07:33
  • @pushcx I'm sorry, I missed your comment back then. Having the \putmarginpar command defined as in the answer above, I wrap it in another command, which accepts only content to be printed and takes care of generating a new unique label by joining a fixed prefix and a counter incremented every time: ```\newcounter{myCounterName} \setcounter{myCounterName}{1}

    \newcommand{\makeMarginMark}[#1]{% \stepcounter{myCounterName}% \putmarginpar{labelPrefix:\arabic{myCounterName}}{#1} }```

    – igneus Jan 04 '22 at 13:44
3

Getting the margin notes on the correct side automatically is problematic at the best of times, and multicol balancing makes that harder. Similarly the features of shifting marginal notes to avoid them clashing. If you give up those features and choose manually which column to use, and fix any clashes by manually moving one of the notes, things are easier and you can easily add things to the column in a way that doesn't upset multicol too much:

enter image description here

\documentclass{article}

\usepackage{multicol}
\makeatletter

\def\xmarginnote{%
  \xymarginnote{\hskip -\marginparsep \hskip -\marginparwidth}}

\def\ymarginnote{%
  \xymarginnote{\hskip\columnwidth \hskip\marginparsep}}

\long\def\xymarginnote#1#2{%
\vadjust{#1%
\smash{\vtop{{%
        \hsize\marginparwidth
        \@parboxrestore
        \@marginparreset
#2}}}}}

\begin{document}
\begin{multicols}{2}

Some text, a very long one.

And somewhere\xmarginnote{\textbf{!1}}  in the middle of it
I need a (very small) margin note, like this:

Text text text\ymarginnote{\textbf{!2}} and more text...

\end{multicols}
\end{document}
David Carlisle
  • 757,742
  • This would solve my issue if I had just one book to typeset. But I have more of them and all of them share many common pieces (psalms) included using \input . And in each of the books the pieces appear in different order and in different columns. So maybe I'll just have to find some other way to say "this line is special" than the margin-notes. – igneus Mar 31 '12 at 18:29
  • well in that case it's too hard to do in half a dozen lines of TeX, perhaps someone has a package already, but I don't know of one. Probably if I had to do this I'd use etex marks with a class of mark for this kind of note, then in theory by inspecting the first and last mark on each column you'd be able to see if left or right margin was needed and correct on a second latex run. – David Carlisle Mar 31 '12 at 18:36
  • @DavidCarlisle Please see my answer using two LaTeX runs which is similar to your suggestion but using zref. – yannisl Apr 01 '12 at 06:01