5

tl;dr: Like footnotes, but on the side (easy part). These notes must be on the same page as their reference points, so the "main text" needs to break whenever the notes break.

I'm trying to produce something like this:

sample scan

I've been using memoir. Here's an idea I had. My understanding is that \footnote creates a float that tries to place itself at the bottom of the nearest page. Would it be possible to place the "footnote anchor" elsewhere? For example, with some interesting page geometry, something like this:

handwritten idea

The difficult part is in the question title: ensuring that page breaks respect the column-column alignment.

Here is a MWE.

\documentclass{memoir}

% geometry stuff here

\begin{document}
Blind Text

Lorem ipsum dolor sit amet. \columnnote{This is the first ``footnote.''}

The quick brown fox jumped over the lazy dog. \columnnote{This is the second ``footnote.''}
\end{document}
Simon Kuang
  • 1,861
  • Possible relevant: http://tex.stackexchange.com/q/69517/34721 – Simon Kuang Aug 04 '15 at 21:04
  • 1
    I'm also thinking about paracol, but that still leaves the page breaks to be dealt with. – Simon Kuang Aug 04 '15 at 21:59
  • BTW, do you want these numbers to reset every page? – John Kormylo Aug 05 '15 at 17:38
  • @JohnKormylo, no. They are reset by chapter. – Simon Kuang Aug 05 '15 at 17:56
  • @JohnKormylo, the only thing that's left is the "alignment" and the special breaking. – Simon Kuang Aug 05 '15 at 17:57
  • At the moment, memoir's sidebar has the vertical alignment right, but it doesn't create page breaks that keep the \sidebar command's context and the actual sidebar on the same page. – Simon Kuang Aug 05 '15 at 18:30
  • When you run out of room on the right column, you are already too far in the left column. But if you number the paragraphs (see http://tex.stackexchange.com/questions/10513/automatically-assign-a-number-to-every-paragraph) and write the last good paragraph number to the aux file, then the next run you can force a page break after that many paragraphs on that page. Or possibly force a page break before shipping the current paragraph off. – John Kormylo Aug 05 '15 at 21:01
  • @JohnKormylo, do you mean hooking the shipout to mark the last good paragraph so that it breaks at the next compilation? I've actually done something similar, except using source lines. – Simon Kuang Aug 05 '15 at 21:03
  • I'm not sure what is most important for the document --- the main text or the notes. From your example the notes seem to have the priority. – Peter Wilson Aug 06 '15 at 19:16
  • @PeterWilson, if you mean that I will tolerate awkward page breaks in the main text to respect the positioning of unbreakable individual notes, then yes. – Simon Kuang Aug 06 '15 at 19:21
  • My earlier comment seems to have been delivered before I had finished. I had added that a combination of memoir's code for \sidefootnote and \sidebar might do the trick except for the page breaking requirement which I think is possible but devily hard. – Peter Wilson Aug 06 '15 at 19:30
  • @PeterWilson: I've been working with \sidebar. So far I think the most viable solution will be to require a double compilation in which the first compilation hooks shipouts to determine ideal break points (viz. with a per-sidebar incrementing counter)---definitely not impossible ... – Simon Kuang Aug 06 '15 at 20:32
  • @PeterWilson et al.: the hard part (which makes this task much harder than this) is that we have to know not only on which page the note command was called but on which page it ends up typeset. – Simon Kuang Aug 06 '15 at 22:33
  • This might be useful to you: http://tex.stackexchange.com/questions/244853/reflowing-marginpars-typeset-using-pdfsavepos/245215#245215 – 1010011010 Aug 07 '15 at 13:09
  • 2
    Your handwriting is worthy of a font! Not because it is perfect, but because it is distinctive. – Steven B. Segletes Aug 07 '15 at 13:34
  • @StevenB.Segletes: thank you! It's more or less perfect (mostly less) when I try to make it better, but this is my note-taking script ... it gets the words through. I at least pretend to follow some kind of Spencerian Business Script. – Simon Kuang Aug 07 '15 at 15:54

1 Answers1

5

This will write notes from top to bottom using the entire right column. Page breaking is done using the aux file and \everypar.

Needless to say, this approach will conflict with any package which uses \everypar (within the paracol environment).

\documentclass{memoir}
\usepackage{xcolor}
\usepackage{paracol}
\usepackage{lipsum}

\newcommand{\darkmark}[1]% #1 = text to write white on black background
{\rlap{\rule[-.2\baselineskip]{\bibindent}{\baselineskip}}%
 \makebox[\bibindent]{\color{white}#1}}

% global registers

\newcounter{abortparagraph}% incremet for every aborted paragraph
\newcounter{columnnote}[chapter]
\globalcounter{columnnote}% synchronized across columns
\newlength{\columnheight}% space used for column notes
\newlength{\columnroom}% available space for column notes
\newif\ifparagraphaborted% ignore extra everypar after abort
\newcommand{\leftcolumnpage}{}% reserve global names
\newcommand{\rightcolumnpage}{}% for page synchronization

% move current paragraph to next page

\newcommand{\newabortparagraph}[1]% #1 = \theparagraph, #2 = \thepage
{\stepcounter{abortparagraph}%
 \global\expandafter\def\csname abortparagraph\arabic{abortparagraph}\endcsname{#1}}

\makeatletter
\newcommand{\abortparagraph}% \everypar
{\ifparagraphaborted% ignore extra everypar after abort
  \global\paragraphabortedfalse
\else
  \global\edef\leftcolumnpage{\arabic{page}}%
  \stepcounter{paragraph}%
  \bgroup% in case \tempa and \tempb previously used
    \@ifundefined{abortparagraph\arabic{abortparagraph}}{}%
    {\edef\tempa{\csname abortparagraph\arabic{abortparagraph}\endcsname}%
     \edef\tempb{\theparagraph}%
     \ifx\tempa\tempb% compare strings
       \strut\newpage
       \stepcounter{abortparagraph}%
       \global\paragraphabortedtrue
     \fi}%
  \egroup
\fi}

% synchronize pages

\newcommand{\columnnotepage}[2]% #1 = label, #2 = \thepage
{\global\expandafter\def\csname columnnotepage#1\endcsname{#2}}

% redefine paracol environment start

\let\oldparacol=\paracol

\renewcommand{\paracol}[1]{\oldparacol{#1}%
  \everypar{\abortparagraph}%
  \setlength{\columnheight}{0pt}%
  \setlength{\columnroom}{\@colroom}%
  \global\edef\leftcolumnpage{\arabic{page}}%
  \global\edef\rightcolumnpage{\arabic{page}}%
}

% write notes in right column

\newcommand{\columnnote}[1]% #1 = text for second column
{\refstepcounter{columnnote}%
 \darkmark{\thecolumnnote}%
 \@ifundefined{columnnotepage\thechapter.\thecolumnnote}{}%
   {\def\leftcolumnpage{\csname columnnotepage\thechapter.\thecolumnnote\endcsname}}%
 \ifnum\rightcolumnpage<\leftcolumnpage\relax% synchronize pages
   \global\columnroom=\textheight
   \global\columnheight=0pt
   \switchcolumn[1]%
     \loop\ifnum\c@page<\leftcolumnpage \strut\newpage\repeat
     \global\edef\rightcolumnpage{\arabic{page}}%
   \switchcolumn[0]%
 \fi
 \bgroup% compute size of note
   \setbox0=\hbox{\begin{minipage}{\dimexpr \columnwidth-\bibindent}#1\end{minipage}}%
   \global\advance\columnheight by \dimexpr \baselineskip + \ht0 + \dp0\relax
 \egroup
 \ifdim\columnheight>\columnroom\relax% time to break page
   \immediate\write\@auxout{\string\newabortparagraph {\theparagraph}}%
   \switchcolumn[1]%
     \strut\newpage%
     \global\edef\rightcolumnpage{\arabic{page}}
   \switchcolumn[0]%
   \global\columnroom=\textheight
   \bgroup% re-compute size of note
     \setbox0=\hbox{\begin{minipage}{\dimexpr \columnwidth-\bibindent}#1\end{minipage}}%
     \global\columnheight=\dimexpr \baselineskip + \ht0 + \dp0\relax
   \egroup
 \else
   \immediate\write\@auxout{\string\columnnotepage {\thechapter.\thecolumnnote}{\thepage}}%
 \fi
 \switchcolumn[1]%
   \noindent\hspace{\bibindent}%
   \begin{minipage}{\dimexpr \columnwidth-\bibindent}%
     \mbox{\llap{\darkmark{\thecolumnnote}}%
       \color{lightgray}\rule[-0.2\baselineskip]{\textwidth}{\baselineskip}}%
     \linebreak#1\end{minipage}%
   \linebreak\vspace{\marginparpush}%
 \switchcolumn[0]%
 \global\advance\columnheight by \marginparpush%
}
\makeatother

\begin{document}
\setcounter{abortparagraph}{1}% reuse counter after aux file read
\chapter{One}
\begin{paracol}{2}
Blind text.

Lorem ipsum dolor sit amet. \columnnote{This is the first ``footnote.''}

The quick brown fox jumped over the lazy dog. \columnnote{This is the second ``footnote.''}

Too big for the page.  \columnnote{\rule{1pt}{.9\textheight}}

Next paragraph.
\end{paracol}
\end{document}

test page 1

It should be noted that \switchcolumn doesn't synchronize the pages either. That had to be done separately. Note that \thepage is not reliable when paragraphs are split over two pages, so are saved to the aux file instead. Also, one must be careful to NOT synchronize the aborted paragraphs as they NEED to fail the test every time.

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • I already have the number layout done with TikZ. The real hard part is still the vertical alignment, since marginpar is a long way off from the intended alignment.

    MWE coming.

    – Simon Kuang Aug 05 '15 at 15:52
  • Have you looked at the sidenote package, together with marginfix ? Appart from the shape of numbers (which you can probably redefine), I think it looks like what you are searching for. – mvienney Aug 05 '15 at 16:45
  • @mvienney memoir's sidebar looks hopeful. – Simon Kuang Aug 05 '15 at 18:24
  • By the way, OP stands for Original Post, I think. – Simon Kuang Aug 05 '15 at 20:39
  • 1
    I just replaced the entire answer, so old comments are now out of context. – John Kormylo Aug 05 '15 at 22:31
  • @SimonKuang You mention the alignment issues with \marginpar. Forgetting the appearance for the moment, is the ability to adjust vertical alignment as in my answer at http://tex.stackexchange.com/questions/120224/create-a-framed-environment-for-a-margin-note/120266#120266 at all helpful in adapting \marginpar to your needs, do you think? – Steven B. Segletes Aug 07 '15 at 13:39
  • @StevenB.Segletes: I'm not sure what you mean. Do you refer to using stackengine's functionality to shift the box up and down? By vertical alignment, I meant gluing the first note box of each page to the vertical placement of the text block. My former comment has been obsolete ever since JohnKormylo edited his answer. – Simon Kuang Aug 07 '15 at 16:54
  • I make some more improvements. Specifically, if you start paracol in the middle of a page (like after \chapter) the notes are now even with the left column, not the top of the text area. BTW, use \flushpage instead of \newpage. – John Kormylo Aug 08 '15 at 17:17
  • This version does not use everypage at all. – John Kormylo Aug 10 '15 at 12:46
  • Thank you! One more thing though: if you replace the contents of paracol with \newcommand{\longtext}{\lipsum[1] Hello. \columnnote{This columnnote is really long: \lipsum[3-4] end}\lipsum[2]} \longtext\par\longtext (retaining the \everypar etc.), the second \longtext breaks in the wrong place, and the reference is not on the same page as the note. – Simon Kuang Aug 26 '15 at 21:57
  • I think it is fixed now. I was switching columns when I didn't need to. – John Kormylo Aug 27 '15 at 03:36