7

I have a document where paragraphs should be aligned across odd/even (left/right) pages. I use the following code from this answer (courtesy of Nicola Talbot)

\documentclass[12pt]{scrbook}
\usepackage{flowfram}
\usepackage{lipsum}
\usepackage{etoolbox}

% set up frames

\newflowframe{\textwidth}{\textheight}{0pt}{0pt}[main]

\newdynamicframe[odd]{\textwidth}{\textheight}{0pt}{0pt}[details]
\newdynamicframe[even]{\textwidth}{\textheight}{0pt}{0pt}[annote]

% \checkisroom{idl}{text}
\makeatletter
\providecommand{\@gobblethree}[3]{}
\newsavebox\tmpsbox
\newif\ifenoughroom
\newcommand{\checkisroom}[2]{%
  \bgroup
    % get the frame's idn (stored in \ff@id)
    \@dynamicframeid{#1}%
    % temporarily suspend writing to external files
    \let\protected@write\@gobblethree
    % put the frame's contents and the pending text into 
    % the temporary sbox
    \begin{lrbox}{\tmpsbox}%
    \begin{minipage}{\textwidth}%
     \csname @dynamicframe@\romannumeral\ff@id\endcsname
     \par
     #2%
    \end{minipage}
    \end{lrbox}%
    % Does it fit the page?
    \settoheight{\@ff@tmp@y}{\usebox\tmpsbox}%
    \settodepth{\dimen@ii}{\usebox\tmpsbox}%
    \addtolength{\@ff@tmp@y}{\dimen@ii}%
    \ifdim\@ff@tmp@y>\textheight
       \global\enoughroomfalse
    \else
       \global\enoughroomtrue
    \fi
  \egroup
}

% \getcontentsheight{length}{text}
\newcommand{\getcontentsheight}[2]{%
 \bgroup
    \let\protected@write\@gobblethree
    \begin{lrbox}{\tmpsbox}%
      \begin{minipage}{\textwidth}%
       #2%
      \end{minipage}%
    \end{lrbox}%
    \settoheight{\@ff@tmp@y}{\usebox\tmpsbox}%
    \settodepth{\dimen@ii}{\usebox\tmpsbox}%
    \addtolength{\@ff@tmp@y}{\dimen@ii}%
    \global#1=\@ff@tmp@y\relax
 \egroup
}

\newcounter{heading}

% \heading{label}{title}
\newcommand{\heading}[2]{%
  \refstepcounter{heading}%
  \label{#1}%
  \markboth{#2}{#2}%
  \annote
    {%
      \section*{\ref{#1}. #2}%
    }%
    {%
      \section*{\ref{#1}. #2}%
      \addcontentsline{toc}{section}{#2}%
      \par\strut
    }%
  \afterheadingtrue
}

\newif\ifafterheading

\newlength\blockheight

\newcommand{\blocksep}{\par\vspace{2ex}}

% \annote{annotation}{text}
\newcommand{\annote}[2]{%
  \getcontentsheight{\blockheight}{#1}%
  \def\largerblock{#1}%
  \getcontentsheight{\@ff@tmp@y}{#2}%
  \ifdim\blockheight<\@ff@tmp@y
    \blockheight=\@ff@tmp@y\relax
    \def\largerblock{#2}%
  \fi
  \ifafterheading
    \edef\startblock{%
      \noexpand\blocksep
      \noexpand\begin{minipage}[t][\the\blockheight]{\the\textwidth}%
      \noexpand\setlength{\noexpand\parindent}{\the\parindent}%
      \noexpand\par\noexpand\noindent
    }%
    \afterheadingfalse
  \else
    \edef\startblock{%
      \noexpand\begin{minipage}[t][\the\blockheight]{\the\textwidth}%
      \noexpand\setlength{\noexpand\parindent}{\the\parindent}%
      \noexpand\par\noexpand\indent
    }%
  \fi
  \checkisroom{details}{\largerblock}%
  \ifenoughroom
    \@dynamicframeid{annote}%
    \expandafter\appenddynamiccontents\expandafter\ff@id
     \expandafter{%
       \expandafter\blocksep
       \startblock
       #1%
       \end{minipage}}%
    \@dynamicframeid{details}%
    \expandafter\appenddynamiccontents\expandafter\ff@id
     \expandafter{%
       \expandafter\blocksep
        \startblock
         #2%
         \end{minipage}}%
  \else
    % output 2 pages
    \cleartoeven
    \@dynamicframeid{annote}%
    \expandafter\setdynamiccontents\expandafter\ff@id
     \expandafter{\startblock#1\end{minipage}}%
    \@dynamicframeid{details}%
    \expandafter\setdynamiccontents\expandafter\ff@id
     \expandafter{\startblock#2\end{minipage}}%
  \fi
}
\makeatother

\newcommand{\cleartoeven}{%
  \ifthispageodd % KOMA command
  {\newpage}%
  {\mbox{}\newpage\mbox{}\newpage}%
}

\appto\tableofcontents{\cleartoeven}

\AtEndDocument{\cleartoeven}

\title{Sample Document}
\author{A.N. Other}

\begin{document}
\maketitle

\tableofcontents

\heading{sample}{Sample Heading}

\annote
 {Annotation on the left}
 {A longer paragraph on the right matching the annotation on the
  left.

  \lipsum[1]
 }

\heading{sample2}{Another Sample Heading}

\annote
 {\lipsum[2]}
 {\lipsum[3]}

\annote
 {Another annotation.}
 {\lipsum[4]}

\annote
 {\lipsum[5-6]}
 {\lipsum[7]}

\end{document}

I have to problems that I failed to solve:

  1. I like to start each heading at the a new page. I tried the cleartoeven is so many different ways but I failed. How can I achieve this in particular case and/or in other part of document?
  2. Is it possible to have first/second argument of \heading{}{} as the header of left/right pages? As of this moment one argument is shown on both odd/even page header.

For clearance: I'm using this code for a work of translation where original text is on the left and translated version on the right.

  • 1
    I think there are better packages for what you want to do. Have you looked at ctan.org/pkg/eledpar for example? – cfr Mar 12 '14 at 3:36
  • @cfr, I tried and I failed. I installed the package manually (it wasn't included in mactex 2012) but it has all kind of problems including \Pages is an undefined control sequence. – Pouya Mar 12 '14 at 9:04
  • Can you clarify point 2? The arguments of \annote{}{} contain paragraphs, which aren't suitable for headers. – Nicola Talbot Mar 12 '14 at 9:10
  • @NicolaTalbot, My bad! I meant \heading{}{}! I want the argument of heading to be at page header. I will edit the question. – Pouya Mar 12 '14 at 9:17
4

The following MWE makes each \heading{label}{title} clear a double-page spread, which deals with your first problem. The page headers are set using \markboth{title}{title}, which I haven't changed from the original MWE, but now that \heading always starts a new page, the page headers aren't getting confused by having multiple \heading on the same double-page spread, so hopefully this deals with your second problem.

\documentclass[12pt]{scrbook}
\usepackage{flowfram}
\usepackage{lipsum}
\usepackage{etoolbox}

% set up frames

\newflowframe{\textwidth}{\textheight}{0pt}{0pt}[main]

\newdynamicframe[odd]{\textwidth}{\textheight}{0pt}{0pt}[details]
\newdynamicframe[even]{\textwidth}{\textheight}{0pt}{0pt}[annote]

% \checkisroom{idl}{text}
\makeatletter
\providecommand{\@gobblethree}[3]{}
\newsavebox\tmpsbox
\newif\ifenoughroom
\newcommand{\checkisroom}[2]{%
  \bgroup
    % get the frame's idn (stored in \ff@id)
    \@dynamicframeid{#1}%
    % temporarily suspend writing to external files
    \let\protected@write\@gobblethree
    % put the frame's contents and the pending text into 
    % the temporary sbox
    \begin{lrbox}{\tmpsbox}%
    \begin{minipage}{\textwidth}%
     \csname @dynamicframe@\romannumeral\ff@id\endcsname
     \par
     #2%
    \end{minipage}
    \end{lrbox}%
    % Does it fit the page?
    \settoheight{\@ff@tmp@y}{\usebox\tmpsbox}%
    \settodepth{\dimen@ii}{\usebox\tmpsbox}%
    \addtolength{\@ff@tmp@y}{\dimen@ii}%
    \ifdim\@ff@tmp@y>\textheight
       \global\enoughroomfalse
    \else
       \global\enoughroomtrue
    \fi
  \egroup
}

% \getcontentsheight{length}{text}
\newcommand{\getcontentsheight}[2]{%
 \bgroup
    \let\protected@write\@gobblethree
    \begin{lrbox}{\tmpsbox}%
      \begin{minipage}{\textwidth}%
       #2%
      \end{minipage}%
    \end{lrbox}%
    \settoheight{\@ff@tmp@y}{\usebox\tmpsbox}%
    \settodepth{\dimen@ii}{\usebox\tmpsbox}%
    \addtolength{\@ff@tmp@y}{\dimen@ii}%
    \global#1=\@ff@tmp@y\relax
 \egroup
}

\newcounter{heading}

% \heading{label}{title}
\newcommand{\heading}[2]{%
  \cleartoeven
  \setdynamiccontents*{annote}{}%
  \setdynamiccontents*{details}{}%
  \refstepcounter{heading}%
  \label{#1}%
  \markboth{#2}{#2}%
  \annote
    {%
      \section*{\ref{#1}. #2}%
    }%
    {%
      \section*{\ref{#1}. #2}%
      \addcontentsline{toc}{section}{#2}%
      \par\strut
    }%
  \afterheadingtrue
}

\newif\ifafterheading

\newlength\blockheight

\newcommand{\blocksep}{\par\vspace{2ex}}

% \annote{annotation}{text}
\newcommand{\annote}[2]{%
  \getcontentsheight{\blockheight}{#1}%
  \def\largerblock{#1}%
  \getcontentsheight{\@ff@tmp@y}{#2}%
  \ifdim\blockheight<\@ff@tmp@y
    \blockheight=\@ff@tmp@y\relax
    \def\largerblock{#2}%
  \fi
  \ifafterheading
    \edef\startblock{%
      \noexpand\blocksep
      \noexpand\begin{minipage}[t][\the\blockheight]{\the\textwidth}%
      \noexpand\setlength{\noexpand\parindent}{\the\parindent}%
      \noexpand\par\noexpand\noindent
    }%
    \afterheadingfalse
  \else
    \edef\startblock{%
      \noexpand\begin{minipage}[t][\the\blockheight]{\the\textwidth}%
      \noexpand\setlength{\noexpand\parindent}{\the\parindent}%
      \noexpand\par\noexpand\indent
    }%
  \fi
  \checkisroom{details}{\largerblock}%
  \ifenoughroom
    \@dynamicframeid{annote}%
    \expandafter\appenddynamiccontents\expandafter\ff@id
     \expandafter{%
       \expandafter\blocksep
       \startblock
       #1%
       \end{minipage}}%
    \@dynamicframeid{details}%
    \expandafter\appenddynamiccontents\expandafter\ff@id
     \expandafter{%
       \expandafter\blocksep
        \startblock
         #2%
         \end{minipage}}%
  \else
    % output 2 pages
    \cleartoeven
    \@dynamicframeid{annote}%
    \expandafter\setdynamiccontents\expandafter\ff@id
     \expandafter{\startblock#1\end{minipage}}%
    \@dynamicframeid{details}%
    \expandafter\setdynamiccontents\expandafter\ff@id
     \expandafter{\startblock#2\end{minipage}}%
  \fi
}
\makeatother

\newcommand{\cleartoeven}{%
  \ifthispageodd % KOMA command
  {\newpage}%
  {\mbox{}\newpage\mbox{}\newpage}%
}

\AtEndDocument{\cleartoeven}

\title{Sample Document}
\author{A.N. Other}

\begin{document}
\maketitle

\tableofcontents

\heading{sample}{Sample Heading}

\annote
 {Annotation on the left}
 {A longer paragraph on the right matching the annotation on the
  left.

  \lipsum[1]
 }

\heading{sample2}{Another Sample Heading}

\annote
 {\lipsum[2]}
 {\lipsum[3]}

\annote
 {Another annotation.}
 {\lipsum[4]}

\annote
 {\lipsum[5-6]}
 {\lipsum[7]}

\end{document}

First double-page spread (pages 4 and 5):

Image of page 4 and 5

Second double-page spread (pages 6 and 7):

Image of page 6 and 7

| improve this answer | |
  • Thank you very much. Headings create new pages very beautifully. My problem however is with headers (it's not the problem with your code!). I modified your code and convert it to \markboth{#1}{#2} and now I have different headings on odd/even pages when the arguments of heading is ascii. The first argument of heading in my code is russian and this cause a problem. A single page is added to the begining of the document with that russian word there and the the rest of the layout comes out messy. Again, this is not problem of your code, but I thought you might have some ideas. Thanks a lot :) – Pouya Mar 12 '14 at 19:21
  • Never mind! I solved it by modifying the \label command :D. Thank you again for your time and awesome code. – Pouya Mar 12 '14 at 19:28

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.