[Tex/LaTex] How to reverse the positions of two (unequal width) columns so that the wider one is always against the inner margin

double-sidedmulticolparcolumnstwo-column

I'm new to LaTeX and I'm trying to use it to write a spotlessly-typesetted draft of my novel (from the rough, typewritten hard draft) for MFA program applications, and eventually to send to publishers. I realize that with respect to the latter, many strongly prefer MS Word, but Word simply can't do the things I need done.

So. Here's my current problem (plus a couple other questions about related issues). Sorry in advance for the long post–please bear with me!

Half of my chapters (the odd-numbered ones) use a layout in which any given page has two columns of varying length, as well as outer margin notes. I need the wider of the two columns to always be flush with the inner margin such that, for any double-page spread, the wider columns will be next to each other on opposite pages, with the narrower columns on opposite sides of the central pair of wider columns. Basically, the text for the wider columns is its own separate thing, and the text for the narrower columns is commentary. (This of course means they need to remain separated from each other while having their respective texts flow continuously across page breaks–which won't be a problem, given that they're columns and not boxes, right?).

The \parcolumns package seems like a good choice as far as the differing width issue, but I can't seem to find any information about how to use it to form this layout that I need. (In other words, it seems that, from what I've been able to find, the first column in \parcolumns will always be on the same side). Would it be possible to write some set of conditionals directly into the code of parcolumns itself so that the package would do this automatically? Or could one just put all that in the preamble of the document?

(Amidst a lot of research while not writing this, I noticed on p. 16 of the article/guide for the \multicol environment, they coded \moveright\multicol@leftmargin as the first in a series of operations to go about switching the order of the columns for R->L languages. Could this maybe play a role?)

[REMOVED as irrelevant; see UPDATE]

Finally: a vital caveat I should mention here is that I need to be able to put some sort of smaller text boxes within the narrower of the two columns that are, say, 0.6\linewidth of the narrower column, are flush with the inner margin of the column, then have the body of the column's text wrap around them. Also, because I've developed my own alternate format for basic prose writing which uses non-indented text blocks of varying widths to distinguish between the text of the narration (full line width) versus that of dialogue (REMOVED due to improvement; see UPDATE) I need to be able to use these commands in the wide column in question here…which, as I've learned from lots of reading, just wouldn't work using longtables. Thus, these chapters absolutely must be assembled using actual columns.

UPDATE:

Upon further reading (both of posts on this site, as well as careful inspection of the Implementation section of the user guide for \parcolumns), I've discovered the \ifoddpage package. So, to add a bit more specificity here, might it work to make the following modifications to parcolumns.sty?

a) Add \RequirePackage{ifoddpage} to the preamble.

b) Between lines 95 and 96, set \checkoddpage \@ifoddpage{(lines 96-173, with the "<" in \loop\ifnum\count@<\pc@columncount% of lines 96, 111, 125, 144, and 164 changed to "=")}{(original lines 96-173)}, or some equivalent conditional.

I'm sure there must be some much more sophisticated, less code-clunky way of doing this, but I'm not sure how…Also, should there be any other section of the code set under the conditional? Is \ifoddpage even capable of handling conditionals of this size? And is there something important I'm missing about a command like \checkoddpage, like I would have to write some extra code for the package to be able to even detect page numbers?

I've gotten everything else more or less figured out, from the minipage/wrapfigure boxes in my first columns to the margin notes, to a better set of commands that will allow text to flow continuously across pages for my alternate prose format more generally (using the adjustwidth environment from \changepage, instead of using \parbox…I'm almost there. I just need these columns to flip. Any non-\parcolumns alternatives to suggest?

UPDATE #2

Per Stephan Lehmke's request/suggestion, here is the code and images of the PDF produced.

\documentclass[11pt,letterpage,twosides]{bookest}
%
\geometry{textheight=9in,vmarginratio=1:1,outermargin=1.5in,innermargin=.5in,%
marginparwidth=1.25in,marginparsep=.2in}
\usepackage{parcolumns}
\usepackage{marginnote}
\usepackage{wrapfig}
\usepackage{lipsum}
% 
% % % % % [Many lines of new commands have been omitted, as they are not relevant here.]
%
%%%%% For use in \parcolumns environment
\newcommand{\warfo}{\begin{wrapfigure}{o}[.15in]{1.5in} \begin{minipage}[t]{1.4in} %
\noindent \Large}
\newcommand{\warfi}{\begin{wrapfigure}{i}[.15in]{1.5in} \begin{minipage}[t]{1.4in} %
\noindent \Large}
\newcommand{\wraf}{\end{minipage} \vspace{-.265in} \end{wrapfigure}}
\newcommand{\stm}{\marginnote}
%
\begin{document}
%
\chapter{Sample Experimental Chapter Layout}
%
\begin{parcolumns}[sloppy=true,sloppyspaces=true,nofirstindent=true,colwidths={1=2.8in, %
2=3.5in}]{2}
%
\colchunk[1]{\small \indent \lipsum[14] \warfi{Sample  wrapped text box, using a minipage %
inside a wrapfig environment.} \wraf \lipsum[15] \warfo{Another sample wrapped text box, % 
placed along the inner side of the \\ column.} \wraf \lipsum[16]  \lipsum[17]}
%
\colchunk[2]{\Large \indent \stm{\normalsize \textbf{Sample margin note, always to be on % 
the outer margin. \\ ---------- \\ Aside from the placement of the margin note, the layout %
 of this odd page is incorrect. The order of the two columns should be switched, so that % 
 the larger/wider column is placed along the inner margin, and the smaller/thinner column % 
 is placed along the outer margin.}} \lipsum[10] \lipsum[11] \lipsum[12] \lipsum[13] %
 \stm{\textbf{\normalsize The layout of this even page is correct, with the larger column % 
 on the inner margin and the smaller column on the outer one, with the wrapped text box on %
 the inner edge of the smaller column. \\ ---------- \\ However, can I suppress this extra%
 line between paragraphs in the inner column?}} \lipsum[14]}
%
\end{parcolumns}
%
\end{document}

Here are the pages produced. Everything is explained in the margin notes.
enter image description here
enter image description here

Note the blank line between larger, inner paragraphs on p.2–How can I get rid of that breaking when entering a \marginnote?

Best Answer

EDIT (July 25, 2012)

There is a small bug concerning the column separating space in the version below. I fixed that and wrapped up the whole parcolumns patch in a tiny package named parcolsx, so that you can do something like:

\documentclass{book}
\usepackage{geometry}
\usepackage{parcolumns}
\usepackage{parcolsx}
\usepackage{lipsum}
\begin{document}
\chapter{Chapter heading}
\begin{parcolumns}[%
  sloppy        = true,
  sloppyspaces  = true,
  nofirstindent = true,
  colwidths     = {1=0.43\textwidth, 2=0.53\textwidth}
]{2}
\colchunk[1]{\small\indent%
  \lipsum[14] 
  \lipsum[15]
  \lipsum[16]
  \lipsum[17]
}
\colchunk[2]{\Large\indent%
  \lipsum[10]
  \lipsum[11]
  \lipsum[12]
  \lipsum[13]
}
\end{parcolumns}
\end{document}

Note the additional key/value pair alternate = true in the arguments of the parcolumns environment. This way the alternating columns can be activated at will.

The package parcolsx to be saved in a file named parcolsx.sty:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{parcolsx}

\RequirePackage{changepage}
\strictpagecheck

% add the additional boolean key `alternate' 
% to the `parcolumns' environment
\newif\ifpc@alternate
\define@key{parcolumns}{alternate}[true]{%
\pc@boolkey{pc@alternate}{#1}%
}

% slightly modify the `\pc@placeboxes' macro to distinguish between odd
% and even pages, if the option `alternate=true' was passed to the
% `parcolumns' environment
\def\pc@placeboxes{%
  \global\let\@tempa\relax%
  \hb@xt@\linewidth{%
    \vfuzz30ex %
    \vbadness\@M%
    \splittopskip\z@skip%
    % odd is the default
    \ifpc@alternate \checkoddpage \else \oddpagetrue \fi%
    \ifoddpage
      % count up from 1 to N_col
      \count@\z@%
      \loop\ifnum\count@<\pc@columncount%
        \advance\count@\@ne%
        \pcx@placeboxes@body%
        \ifnum\count@<\pc@columncount%
          \strut\hfill\ifpc@rulebetween\vrule\hfill\fi%
        \fi%
      \repeat%
    \else
      % count down from N_col to 1
      \count@\pc@columncount%
      \loop\ifnum\count@>\z@%
        \pcx@placeboxes@body%
        \advance\count@\m@ne%
        \ifnum\count@>\z@%
          \strut\hfill\ifpc@rulebetween\vrule\hfill\fi%
        \fi%
      \repeat%
    \fi
  }%
  \@tempa%
}

% the fraction of `\pc@placeboxes' that does not depend on the page
% parity
\def\pcx@placeboxes@body{%
  \expandafter\ifvoid\csname pc@column@\number\count@\endcsname%
    \hskip\csname pc@column@width@\number\count@\endcsname%
  \else%
    \expandafter\setbox\expandafter\@tempboxa%
      \expandafter\vsplit\csname pc@column@\number\count@\endcsname%
        to \dp\strutbox%
    \expandafter\@tempdimb\csname pc@column@width@\number\count@\endcsname%
    \hbox to \@tempdimb {\vbox{\unvbox\@tempboxa}\hfill}%
  \fi%
  \expandafter\ifvoid\csname pc@column@\number\count@\endcsname%
  \else%
    \global\let\@tempa\pc@placeboxes%
  \fi%
}

On a side note: that patch also fixes the incompatibility of the parcolumns with the wrapfigure package. I will comment on this in the other thread: Wrapfigure-Minipage Woes


Original answer (including column separator bug)

You ask for many different things and your sample document contains a lot of stuff that might not be helpful here. However, I might have found a solution for your column switching problem.

Please see this more minimalistic example:

\documentclass{book}
\usepackage{geometry}
\usepackage{parcolumns}

\usepackage{changepage}
\strictpagecheck

\usepackage{lipsum}

\makeatletter

\def\pc@placeboxes{%
  \global\let\@tempa\relax%
  \hb@xt@\linewidth{%
    \vfuzz30ex %
    \vbadness\@M%
    \splittopskip\z@skip%
    \checkoddpage\ifoddpage
      \count@\z@%
      \loop\ifnum\count@<\pc@columncount%
        \advance\count@\@ne%
        \my@placeboxes@body%
      \repeat%
    \else
      \count@\pc@columncount%
      \loop\ifnum\count@>\z@%
        \my@placeboxes@body%
        \advance\count@\m@ne%
      \repeat%
    \fi
  }%
  \@tempa%
}

\def\my@placeboxes@body{%
  \expandafter\ifvoid\csname pc@column@\number\count@\endcsname%
    \hskip\csname pc@column@width@\number\count@\endcsname%
  \else%
    \expandafter\setbox\expandafter\@tempboxa%
      \expandafter\vsplit\csname pc@column@\number\count@\endcsname%
        to \dp\strutbox%
    \vbox{\unvbox\@tempboxa}%
  \fi%
  \expandafter\ifvoid\csname pc@column@\number\count@\endcsname%
  \else%
    \global\let\@tempa\pc@placeboxes%
  \fi%
  \ifnum\count@>\z@%
    \strut%
    \hfill%
    \ifpc@rulebetween%
      \vrule%
      \hfill%
    \fi%
  \fi%
}

\makeatother

\begin{document}

\chapter{Chapter heading}

\begin{parcolumns}[%
  sloppy        = true,
  sloppyspaces  = true,
  nofirstindent = true,
  colwidths     = {1=0.43\textwidth, 2=0.53\textwidth}
]{2}

\colchunk[1]{\small\indent%
  \lipsum[14] 
  \lipsum[15]
  \lipsum[16]
  \lipsum[17]
}

\colchunk[2]{\Large\indent%
  \lipsum[10]
  \lipsum[11]
  \lipsum[12]
  \lipsum[13]
}

\end{parcolumns}

\end{document}

I slightly modified the macro \pc@placeboxes from the parcolumns package, so that it distinguishes between odd and even pages. The actual check is done using macros from the changepage package, which is why it is loaded in the preamble. You will have to compile at least twice, since this relies on page lables.

The resulting output is, I think, what you desire, i.e. the columns interchange at every page break:

enter image description here enter image description here

I have not bothered about the margin notes and you might experience side effects. If that is the case you should better open a new question and tackle one problem at a time.

EDIT (July 22, 2012)

The parcolumns package works in two steps: first, the contents of each column is typeset in a box. This is done by the \colchunk command. Second, for every line on the output page one line from each column box is extracted and placed on the page. That is done by the \pc@placeboxes macro.

So, assuming N columns, the original \pc@placeboxes in principle does the following: For colums i=1 up to i=N the first line of the i-th column box is cut and pasted on the page. If i<N a column separating space is inserted.

I simply hooked into this macro and inverted the order on every second page: the modified \pc@placeboxes does exactly the same as the original one for odd pages. However, for even pages it loops from i=N down to i=1 when cutting and pasting the lines from the column boxes.

The problem with the wrapfig stuff very likely stems from this two-step approach. Having not looked into the wrapfig package I can just guess that it uses \parshape to modify the shape of the typeset paragraph. This will influence what is typeset into the column boxes. Apparently, things go wrong when the lines of the column boxes are distributed on the page. I can not, unfortunately, offer a solution for this issue at the moment (actually I hoped that some of the TeX gurus here would have a suggestion for you).

Related Question