# How can I achieve dictionary headers for two page spreads in LaTeX

I would like to produce a document where I can display the first and last items of each two page spread in the headers of both the left and right pages. I know I can use \markboth{}{} to collect the usual form of marks that feed \leftmark and \rightmark. But that is limited to the text of one page at a time.

There doesn't appear to be a natural way to use the forward reference mechanism to do this, but there must be a trick, right?

-

The fancyhdr manual (Section 10 — Dictionary style headers, p.11) introduces exactly such a page style.

-
That is close to what I want, but for a single page at a time not a two-page spread. I've started there, but I want to know the first and last entries of the right-hand page to include some part of them in the header or footer of the left-hand page, and vice-versa. –  RBerteig Feb 4 '11 at 11:21
In case any one is interested in the page style described by Thorsten, the fancyhdr manual suggests the use of fix2col.sty with marks in two-column tables, but the package is a little hard to find. CTan currently has distributions for two installations at ctan.org/pkg/fix2col . I found more general information, including the actual package manual, at ftp.math.purdue.edu/mirrors/ctan.org/macros/latex ./contrib/fix2col/ . –  brannerchinese Apr 25 '11 at 21:20

An approach that seems to be working for me is to switch to LuaTeX, specifically the LuaLaTeX package, both from the current MiKTeX distribution for Windows.

This has allowed me to write a Lua module that I load with \directlua{require"dictfun"} in my document's preamble. When the dictfun module loads, it tries to initialize a table of the headers for every page from a file named after the \jobname, found in the global tex.jobname. I used \makeevenhead and \makeoddhead to hook into the page header and call a Lua function from dictfun to update the index of header info and construct the text that belongs on this page's header. The text of the header is placed from the Lua side with a call to tex.print().

Finally, after the main body is finished, I make one more call into the Lua module to write out the current content of the index table.

This solution requires that the text be processed by lualatex at least twice with the pagination stable, but that isn't an unreasonable requirement.

I'm sure it could be done in pure TeX, but building data structures is something that native Lua does very well.

Update: Since I've been asked, here are the "interesting" bits. I have not attempted to package this in any rational way, these fragments have simply been lifted out of my book project with some light editing.

First, here are fragments out of book.text, which holds most of the prologue code and which includes all of the book's content by reference. The Makefile builds the final PDF file by compiling this file....

% Start with memoir and tweak.
\documentclass[10pt]{memoir}

% ...
% Stuff related to fonts, sizes, page dimensions and similar cruft left out
% as not interesting here
% ...

% Allow for more than two column layouts. My dictionary ended up being only
% two column, but other page designs were tried, and there may be a reason
% why I kept the multicol package anyway but I've forgotten and didn't
% document that detail.
\usepackage{multicol}

% Make a new environment for the dictionary body. This makes it easier to
% constrain the dictionary page headers to just the definitions pages and
% keep them out of the front matter and appendices.
\copypagestyle{dict}{plain}

% Load our Lua code to handle a database of page marker information. It will
% read its state from a file named after the TeX job, with ".headmarks" appended.
\directlua{require"dictfun"}

% Define even and odd page headers and footers that invoke the Lua module
% to both record information about the words on the pages as well as construct
% the TeX source string that actually becomes the content of the page header
% or footer. For my editorial sanity, the headers include the page numbers, but
% located next to the binding not the page's outer edge.
\makeevenfoot{dict}{\footnotesize \directlua{dictfun.footmarks(\thepage)}}{}{}
\makeoddfoot{dict}{}{}{\footnotesize \directlua{dictfun.footmarks(\thepage)}}

\pagestyle{dict}

% More setup cruft was here...

% Hijack some section commands to collect information. In particular, each word
% entry begins with a paragraphmark command naming the word. We redefine chaptermark
% and sectionmark to do nothing just in case. The markboth directive sets up the
% information that will be passed to Lua in the page header via leftmark and
% rightmark.
\renewcommand{\chaptermark}[1]{}
\renewcommand{\sectionmark}[1]{}
\renewcommand{\paragraphmark}[1]{\markboth{#1}{#1}}

% Actually set the page dimensions to match a specific binding at Lulu.

%%%% PAGE DIMENSIONS
%% Set up the paper for lulu trade paperback
\setstocksize{9in}{6in}
\settrimmedsize{\stockheight}{\stockwidth}{*}
\settrims{0pt}{0pt}
\setulmarginsandblock{0.75in}{.5in}{*}
\setlrmarginsandblock{.65in}{.5in}{*}
\checkandfixthelayout

% Memoir's title page details... changed from my project, obviously
\title{Sample Dictionary}
\author{Various}
%\date{}

\begin{document}
\frontmatter

% We'll emit a title page so the PDF page block has a dust cover.
% Front.tex has fairly obvious content, including a call to maketitle to get
% that part out of the way, and also including some statistics generated
% by the project's build process.
\input{front}

% Here's the actual dictionary content. Each word's entry is a memoir
% paragraph that includes the plain text entry name in all caps, as well as
% the whole definition in multiple TeX paragraphs. Naturally, the content
% is extracted from other sources as part of the build process which actually
% writes the file "block.tex" before LuaLaTeX is called on to compile the
% book.

% Now move to the next recto page and include our actual body text
% block in a suitable column count environment.
\cleardoublepage
\mainmatter
\begin{multicols}{2}
\footnotesize
\input{block}
\normalsize
\end{multicols}

\backmatter

% One final call to our Lua module gives it a chance to update its page
% database. This is the same data flow used by the native TeX forward
% reference system, and does require multiple passes to get all references
% placed so that even page headers can know what will be on the following
% odd page.
\directlua{dictfun.writemarks()}
\end{document}


The LaTeX code did all the plumbing, but the Lua code actually stores and retrieves the data needed by each page header and footer. Here is an abridged version of dictfun.lua which is placed in the same folder as book.tex:

-- module to load from luatex
module(...,package.seeall)

-- Storage for the database of what words begin and end each page

-- Called from the page header with the page number, left word (first on page)
-- and right word (last on page). Update the page database, and format a string
-- containing the first and last words over each two page spread to return.
if not pg then return end
pg = tonumber(pg)
-- anything after a semicolon in each term
headtab[pg]={left:gsub(";.*$",""),right:gsub(";.*$","")}
local lpage, rpage
if pg % 2 == 0 then
-- left page
else
-- right page
end
tex.print(lpage[1].."---"..rpage[2])
end

-- Called from the page footer with the page number. I've demonstrated that
-- it can tell left from right. Other applications are left as an exercise.
function footmarks(pg)
if not pg then return end
pg = tonumber(pg)
local lpage, rpage
if pg % 2 == 0 then
-- left page
tex.print("left")
else
tex.print("right")
end
end

-- Called when the module loads to attempt to open and read the table from
-- a file related to the project name.
if not f then headtab = {} return end
end

-- Called to write the page database back out to a file.
function writemarks()
if not f then return end
f:write"return {\n"
f:write(string.format("  {%q,%q},\n", t[1], t[2]))
end
f:write"}\n"
end

-- Finally, load the page database.

So is dictfun available anywhere? –  cfr Feb 6 '14 at 4:44