How to set a letter to the margin of the page and position it vertically according to alphabetical order?

I would like to place a letter (that indicates which letter in the dictionary is shown) on the outer side of the book, set it for example in a darker box and position that letter vertically. Users of the dictionary can later easily access a searched headword by using the letter division on the side.

Minimum example:

\documentclass[twocolumn]{book}
\usepackage[top=1.5cm, bottom=1.5cm, left=2cm, right=2cm]{geometry}
\usepackage{fancyhdr}
\usepackage[utf8x, utf8]{inputenc}
\usepackage[T1]{fontenc}
\newcommand\entry[3][]{\hangpara{2em}{1}{\fontfamily{phv} selectfont{\textbf{{#2}}}}\
#3\ifx\relax#1\relax\markboth{#2}{#2}\else\markboth{#1}{#1}\fi
\par}\nopagebreak[4]
\newcommand*{\dictchar}[1]{\centerline{\LARGE\textbf{#1}}\par}
\pagestyle{fancy}
\fancypagestyle{basicstyle}{%
\fancyhf{}
\renewcommand{\footrulewidth}{0pt}
\fancypagestyle{dictstyle}{%
\fancyhf{}
\begin{document}
\pagestyle{dictstyle}
\dictchar{a}
\clearpage
\dictchar{b}
\end{document}


How can I place thumb indexes from \dictchar values now to the right odd and left even margin?

-
Which vertical position would you like to have? top, middle or the bottom? Is it one sided or two sided document? Some picture of what you have in mind will be useful here with some MWE. – Harish Kumar May 23 '12 at 9:55
May be this answer Chapter Title in rotated vertical box at the margin will be useful? – Harish Kumar May 23 '12 at 10:00
The documentation of fancyhdr shows how to do this sort of thing. The package should be part of your distribution. See also Indexing an interval of words on top of every page for an example of head words in a dictionary. – Alan Munn May 23 '12 at 10:53
I am familiar with indexing an interval of words. I have read the documentation of fancyhdy. Chapter 21 Thumb-indexes seems to talk about this, but there is no example. @Harish Kumar the Chapter Title in rotated vertical box at the margin is what I want to acheive but I would like to use some text instead of chapter headings. Thank you in advance. @ – chejnik May 23 '12 at 11:17
Figure 5 on p. 21 of the fancyhdr docs gives the thumb index code. Can you adapt that to your purpose? – Alan Munn May 23 '12 at 11:22

I guess what you want are chapter thumbs or a thumb index. Here’s a nearly automatic solution using TikZ:

\documentclass{book}

% load TikZ to draw the boxes
\usepackage{tikz}
\usetikzlibrary{calc}

% use scrpage2 or whatever you want to add
% the boxes to the header to make them appear
% on every page
\usepackage{scrpage2}

% new counter to hold the current number of the
% letter to determine the vertical position
\newcounter{letternum}
% newcounter to set the number of thumbs fitting vertical
% and setting the height of a boxes
\newcounter{letterdiv}
\setcounter{letterdiv}{4}
% some margin settings
\newlength{\thumbtopmargin}
\setlength{\thumbtopmargin}{2cm}
\newlength{\thumbbottommargin}
\setlength{\thumbbottommargin}{2cm}
% calculate the box height by dividing the page height
\newlength{\thumbheight}
\pgfmathsetlength{\thumbheight}{%
(\paperheight-\thumbtopmargin-\thumbbottommargin)%
/%
\value{letterdiv}
}
% box width
\newlength{\thumbwidth}
\setlength{\thumbwidth}{1cm}
% style the boxes
\tikzset{
thumb/.style={
fill=black!50!red,
text=white,
minimum height=\thumbheight,
text width=\thumbwidth,
outer sep=0pt,
font=\sffamily\bfseries\Huge,
inner xsep=1.5em,
}
}
% create two new commands to make the thumbs
% that makes it easy to use them im different header elements,
% like in the plain and normal page style etc.
\newcommand{\evenpageletterthumb}[1]{%
\begin{tikzpicture}[remember picture, overlay]
\node [thumb,align=left,anchor=north west,] at ($% (current page.north west)-% (0,{\thumbtopmargin+(\value{letternum}-1)*\thumbheight})%$) {#1};
\end{tikzpicture}
}
\newcommand{\oddpageletterthumb}[1]{%
\begin{tikzpicture}[remember picture, overlay]
\node [thumb,align=right,anchor=north east,] at ($% (current page.north east)-% (0,{\thumbtopmargin+(\value{letternum}-1)*\thumbheight})%$) {#1};
\end{tikzpicture}
}
% create a new command to set a new lettergroup
\newcommand{\lettergroup}[1]{%
% but I recommend to start a new page
\clearpage
% set a title (optional)
{\Huge\bfseries\sffamily #1}\par\bigskip
% check if we reached the last vertical position and reset it
\ifnum\value{letternum}=\value{letterdiv}\relax
\setcounter{letternum}{0}%
\fi
% check if we reached the last vertical position and reset it
\ifnum\value{letternum}=\value{letterdiv}\relax
\setcounter{letternum}{0}%
\fi
\stepcounter{letternum}%
% use one head or foot element to put in the box
% it doesn't matter which you use since the box
% is positioned on the page absolutely
}

% for some blindtext
\usepackage{lipsum}

\begin{document}

% usage: \lettergroup{<letter>}
% e.g.
\lettergroup{A}
\lipsum[1]

\lettergroup{B}
\lipsum[1]

\lettergroup{C}
\lipsum[1]

\lettergroup{D}
\lipsum[1]

\lettergroup{E}
\lipsum[1]

\lettergroup{F}
\lipsum[1]

\lettergroup{G}
\lipsum[1]
\end{document}


Update

I made an update so it is now possible to set how many letter thumbs should fit in the margin before the next letter group starts from the to again. Thats better for a high number of group where the box height will be very small otherwise. I renamed lettersum by letterdiv so the name matches the function.

The counter letterdiv is used to set the number of boxes fitting in the page height. I set it to 4 in my example to show how it works. As you can see the fifth letter E is printed at the first position form to again.

-
Thank you for the answer. Can you make me hint how to combine it with my code using fancyhdr package? – chejnik May 25 '12 at 19:29
@chejnik: For fancyhdr substitute \lehead with \fancyhead[LE] and \lohead with \fancyhead[LO]. But actually you could use \fancyhead[RE] and \fancyhead[RO] as well or a mix from them, as long you have one for the even pages and one for the odd. – Speravir May 25 '12 at 20:01
Should I place \newcommand{\lettergroup}[1]{..} definition directly to \fancypagestyle{dictstyle}{} definition? – chejnik May 25 '12 at 20:33
@chejnik: Sorry I don’t ever used fanyhdr so I can’t help you about this. It seems to me that Speravir gave the answer about how to use my code with fancyhdr instead of scrpage, but I can’t tell I the \lettergroup definition should be part of \fancypagestyle – Tobi May 25 '12 at 22:47
@chejnik: Tobi reminded me of something: Of course replace \pagestyle{scrheadings} with \pagestyle{fancy}. – Speravir May 25 '12 at 22:56

Here's a version of your document using the background package. It's similar in spirit to Tobi's solution, but hides more of the details.

\documentclass[twocolumn,a4paper]{book}
% set up a counter for the letters and format it
\newcounter{letter}
\renewcommand{\theletter}{\Alph{letter}}
\usepackage{tikz} % the background package loads this, but we add it here  to be explicit
\usepackage[top]{background}
\usepackage{calc,ifthen}
\usepackage{lipsum} % for dummy text
\SetBgContents{} % set the background content to nothing
% Now set up the letters for the thumbs on odd and even pages
% we make this a command \beginthumbs so that we can turn it on
% at the right time in the document.
\makeatletter
\newcommand{\beginthumbs}{%
\ifthenelse{\isodd{\thepage}}%
{\SetBgHshift{68} % Horizontal shift of the thumb
% The next command sets the thumb itself.  It can be any tikz command
% Note that we use tikz commands to change the text colour not the
% background command \SetBgColor since the text is inside a tikz \node
\SetBgContents{\tikz{\node[fill,red,minimum size=1.4em,inner sep=0,text=black]{\theletter};}}
\SetBgScale{4}
\SetBgVshift{-6*\value{letter}}}% Vertical shift will move down
% Now do the same for the even pages, changing the Hshift sign to -
{\SetBgHshift{-68}
\SetBgContents{\tikz{\node[fill,red,minimum size=1.4 em,inner sep=0,text=black]{\theletter};}}
\SetBgScale{4}
\SetBgVshift{-6*\value{letter}}}%
\bg@material}}
\makeatother
% end of thumbs code
\usepackage[top=1.5cm, bottom=1.5cm, left=2cm, right=2cm]{geometry}
\usepackage{fancyhdr}
\usepackage{hanging}
\usepackage[utf8x, utf8]{inputenc}
\usepackage[T1]{fontenc}
\newcommand\entry[3][]{\hangpara{2em}{1}{\fontfamily{phv}\selectfont{\textbf{{#2}}}}\
#3\ifx\relax#1\relax\markboth{#2}{#2}\else\markboth{#1}{#1}\fi
\par}\nopagebreak[4]

% Instead of specifying the letter directly, we just increment the counter
% this could be wrapped into sectioning code with titlesec to be cleaner
\newcommand*{\dictchar}{\stepcounter{letter}\centerline{\LARGE\textbf{\theletter}}\par}

\pagestyle{fancy}
\fancypagestyle{basicstyle}{%
\fancyhf{}
\renewcommand{\footrulewidth}{0pt}
\fancypagestyle{dictstyle}{%
\fancyhf{}
\begin{document}
% now see that the whole thing works
\chapter{A chapter}
\lipsum
\clearpage
\pagestyle{dictstyle}
% now we issue the command to start the thumbs
\beginthumbs
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar
\clearpage
\dictchar

\end{document}


-
Thank you very much for the answer. I prefer the first example as I can define how many letters are set. – chejnik May 25 '12 at 19:31

Here’s the variation of Tobi’s approach with fancyhdr instead of scrpage2, as requested by the OP (too long for a comment). I used the pagestyles of the OP’s example.

Note, that I had to define two \fancypagestyles inside of a \newcommand (lettergroup). Instead of the pagestyle chapterstart I could have redefine the plain pagestyle, but I wanted to avoid possible unwanted side effects.

If one wants to use makeindex or xindy, one has to (re)create a style file with \lettergroupfor the headings.

\documentclass{book}

% load TikZ to draw the boxes
\usepackage{tikz}
\usetikzlibrary{calc}

% use fancyhdr or whatever you want to add
% the boxes to the header to make them appear
% on every page
\usepackage{fancyhdr}
\fancypagestyle{basicstyle}{%
\renewcommand{\footrulewidth}{0pt}
\fancyhf{}
}

% new counter to hold the current number of the
% letter to determine the vertical position
\newcounter{letternum}\fontfamily{phv}\selectfont
% newcounter to set the number of thumbs fitting vertical
% and setting the height of a boxes
\newcounter{letterdiv}
\setcounter{letterdiv}{4}
% some margin settings
\newlength{\thumbtopmargin}
\setlength{\thumbtopmargin}{2cm}
\newlength{\thumbbottommargin}
\setlength{\thumbbottommargin}{2cm}
% calculate the box height by dividing the page height
\newlength{\thumbheight}
\pgfmathsetlength{\thumbheight}{%
(\paperheight-\thumbtopmargin-\thumbbottommargin)%
/%
\value{letterdiv}
}
% box width
\newlength{\thumbwidth}
\setlength{\thumbwidth}{1cm}
% style the boxes
\tikzset{
thumb/.style={
fill=black!50!red,
text=white,
minimum height=\thumbheight,
text width=\thumbwidth,
outer sep=0pt,
font=\sffamily\bfseries\Huge,
inner xsep=1.5em,
}
}
% create two new commands to make the thumbs
% that makes it easy to use them im different header elements,
% like in the plain and normal page style etc.
\newcommand{\evenpageletterthumb}[1]{%
\begin{tikzpicture}[remember picture, overlay]
\node [thumb,align=left,anchor=north west,] at ($% (current page.north west)-% (0,{\thumbtopmargin+(\value{letternum}-1)*\thumbheight})%$) {#1};
\end{tikzpicture}
}
\newcommand{\oddpageletterthumb}[1]{%
\begin{tikzpicture}[remember picture, overlay]
\node [thumb,align=right,anchor=north east,] at ($% (current page.north east)-% (0,{\thumbtopmargin+(\value{letternum}-1)*\thumbheight})%$) {#1};
\end{tikzpicture}
}
% create a new command to set a new lettergroup
\newcommand{\lettergroup}[1]{%
\fancypagestyle{dictstyle}{%
\renewcommand{\footrulewidth}{0pt}
\fancyhf{}
\fancyfoot[LE]{\evenpageletterthumb{#1}}
\fancyfoot[RO]{\oddpageletterthumb{#1}}
}
\fancypagestyle{chapterstart}{%
\renewcommand{\footrulewidth}{0pt}
\fancyhf{}
\chead{\oddpageletterthumb{#1}}% chapters start only on odd pages
\cfoot{\thepage}
}
\chapter*{#1}
\thispagestyle{chapterstart}
\pagestyle{dictstyle}
% check if we reached the last vertical position and reset it
\ifnum\value{letternum}=\value{letterdiv}\relax
\setcounter{letternum}{0}%
\fi
% check if we reached the last vertical position and reset it
\ifnum\value{letternum}=\value{letterdiv}\relax
\setcounter{letternum}{0}%
\fi
\stepcounter{letternum}%
% use one head or foot element to put in the box
% it doesn't matter which you use since the box
% is positioned on the page absolutely
}

% for some blindtext
\usepackage{kantlipsum,lipsum}

\begin{document}
\pagestyle{basicstyle}
\chapter*{Pseudo-Kantian blindtext}
\kant[1-5]

% usage: \lettergroup{<letter>}
% e.g.
\lettergroup{A}
\lipsum[1-15]

\lettergroup{B}
\lipsum[16-30]

\lettergroup{C}
\lipsum[31-45]

\lettergroup{D}
\lipsum[46-60]
\end{document}

-

This answer is summary of all answers, first of all Toby's answer and Speravir's modification using fancyhdr. This solution keeps the first headword and the last headword in the dictionary page in the header while sets a so called thumb-index with a current letter vertically in the margin of the page; position of thumb-indexes depends on the number of the letters.

\documentclass[twocolumn]{book}
\usepackage[top=1.5cm, bottom=1.5cm, left=2cm, right=2cm]{geometry}
\usepackage{fancyhdr}
\usepackage[icelandic, czech, english]{babel}
\usepackage[utf8x, utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hanging}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand\entry[3][]{\hangpara{2em}{1}{\fontfamily{phv}\selectfont{\textbf{{#2}}}}\
#3\ifx\relax#1\relax\markboth{#2}{#2}\else\markboth{#1}{#1}\fi
\par}\nopagebreak[4]
\newcommand*{\dictchar}[1]{\centerline{\LARGE\textbf{#1}}\par}
% use fancyhdr or whatever you want to add
% the boxes to the header to make them appear
% on every page
\pagestyle{fancy}
% new counter to hold the current number of the
% letter to determine the vertical position
\newcounter{letternum}
% newcounter for the sum of all letters to get
% the right height of a box
\newcounter{lettersum}
\setcounter{lettersum}{26}
% some margin settings
\newlength{\thumbtopmargin}
\setlength{\thumbtopmargin}{1cm}
\newlength{\thumbbottommargin}
\setlength{\thumbbottommargin}{3cm}
% calculate the box height by dividing the page height
\newlength{\thumbheight}
\pgfmathsetlength{\thumbheight}{%
(\paperheight-\thumbtopmargin-\thumbbottommargin)%
/%
\value{lettersum}
}
% box width
\newlength{\thumbwidth}
\setlength{\thumbwidth}{1.5cm}
% style the boxes
\tikzset{
thumb/.style={
fill=black!50!red,
text=white,
minimum height=\thumbheight,
text width=\thumbwidth,
outer sep=0pt,
font=\sffamily\bfseries,
}
}
\newcommand{\oddthumb}[1]{%
\begin{tikzpicture}[remember picture, overlay]
\node [thumb,text centered,anchor=north east,] at ($% (current page.north east)-% (0,\thumbtopmargin+\value{letternum}*\thumbheight)%$) {#1};
\end{tikzpicture}
}
\newcommand{\eventhumb}[1]{%
\begin{tikzpicture}[remember picture, overlay]
\node [thumb,text centered,anchor=north west,] at ($% (current page.north west)-% (0,\thumbtopmargin+\value{letternum}*\thumbheight)%$) {#1};
\end{tikzpicture}
}
% create a new command to set a new lettergroup
\newcommand{\lettergroup}[1]{%
\fancypagestyle{chapterstart}{%
\fancyhf{}
\chead{\oddthumb{#1}}% chapters start only on odd pages
\cfoot{\thepage}
}
% step the counter of the letters
\stepcounter{letternum}%
}
\fancypagestyle{basicstyle}{%
\fancyhf{}
\renewcommand{\footrulewidth}{0pt}
\fancypagestyle{dictstyle}{%
\fancyhf{}
\setlength{\columnsep}{20pt}
\setlength{\columnseprule}{0.1pt}

\begin{document}
\pagestyle{dictstyle}
\lettergroup{A}
\dictchar{A}
\clearpage
\lettergroup{B}
\dictchar{B}

Please note that I made an update to my answer. I replaced \lettersum by \letterdiv – Tobi May 28 '12 at 9:42