[Tex/LaTex] How to set a letter to the margin of the page and position it vertically according to alphabetical order

dictionariesmarginspositioning

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{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0pt}
\fancyhead[LE,RO]{\textbf{\chaptitle}}
\fancyhead[LO,RE]{\textbf{\thepage}}}
\fancypagestyle{dictstyle}{%
\fancyhf{}
\fancyhead[LE,LO]{{\fontfamily{phv}\selectfont{\textbf{\rightmark}}}}
\fancyhead[CO,CE]{\thepage}
\fancyhead[RE,RO]{{\fontfamily{phv}\selectfont{\textbf{\leftmark}}}}}
\begin{document}
\pagestyle{dictstyle}
\dictchar{a}
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar{b}
\entry[headwords]{headwords}{translations}
\end{document}

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

Best Answer

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

thumbs

\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}
\pagestyle{scrheadings}

% 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]{%
     % see pgfmanual.pdf for more information about this part
     \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
    \lohead[\oddpageletterthumb{#1}]{\oddpageletterthumb{#1}}%
    \lehead[\evenpageletterthumb{#1}]{\evenpageletterthumb{#1}}%
}

% for some blindtext
\usepackage{lipsum}

\begin{document}

% usage: \lettergroup{<letter>}
% e.g.
\lettergroup{A}
% your text
\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.

Related Question