34

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?

chejnik
  • 1,441
  • 2
  • 23
  • 42

4 Answers4

40

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.

Tobi
  • 56,353
  • 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
  • 1
    @chejnik: Tobi reminded me of something: Of course replace \pagestyle{scrheadings} with \pagestyle{fancy}. – Speravir May 25 '12 at 22:56
  • Thank you Speravir. Of course not, I have finally managed to create thumb indexes while keeping the original fancypagestyle that was defined in the minimum example. Thank you all for patience. Now I try to add the colors to boxes; that issue was described earlier, hope I managed too :). – chejnik May 26 '12 at 06:53
  • @Speravir: Good idea. – Tobi May 28 '12 at 10:10
  • That is great, I used it in my Thesis but I realized that a standard printer is not able to print the letterthumb just in the border of the printer (or at least I don't know how). Does anybody have an idea of how this can be done? – Felipe Aguirre Oct 03 '12 at 17:36
  • @FelipeAguirre: There are some printers that support borderless printing, if your’s doesn’t you may shift the labels inside the printable area by changing the coordinate (0,{\thumbtopmargin+(\value{letternum}-1)*\thumbheight})% to (±X,…) in the definition of \even/oddpageletterthumb. – Tobi Oct 03 '12 at 19:07
  • Interesting! I just checked and the printer in my lab supports borderless printing. Do you have a source to read or some pointers to initiate myself on this? I use Ubuntu 12.04 btw. – Felipe Aguirre Oct 03 '12 at 20:36
  • @FelipeAguirre: Sorry, but I don’t understand your question? O:-) – Tobi Oct 03 '12 at 22:01
  • Well, I don't know how to tell the printer to use the borderless feature. – Felipe Aguirre Oct 04 '12 at 21:25
  • @FelipeAguirre: That depens on your driver. On my Mac I choose the paper format, which is “DIN A4 (borderless)” in this case. – Tobi Oct 05 '12 at 07:00
14

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}{%
    \AddEverypageHook{%
    \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{\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}
% 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
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}
\clearpage
\dictchar
\entry[headwords]{headwords}{translations}

\end{document}

output of code

Alan Munn
  • 218,180
  • 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
3

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{\headrulewidth}{0.4pt}
  \renewcommand{\footrulewidth}{0pt}
  \fancyhf{}
  \fancyhead[LE,RO]{\fontfamily{phv}\selectfont\textbf{\rightmark}}
  \fancyhead[LO,RE]{\textbf{\thepage}}
}

% 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]{%
     % 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]{%
  \fancypagestyle{dictstyle}{%
    \renewcommand{\headrulewidth}{0.4pt}
    \renewcommand{\footrulewidth}{0pt}
    \fancyhf{}
    \fancyhead[LO]{\fontfamily{phv}\selectfont{\textbf{\scshape Letter #1}}}
    \fancyhead[C]{\thepage}
    \fancyhead[RE]{\fontfamily{phv}\selectfont{\textbf{\scshape Letter #1}}}
    \fancyfoot[LE]{\evenpageletterthumb{#1}}
    \fancyfoot[RO]{\oddpageletterthumb{#1}}
  }
  \fancypagestyle{chapterstart}{%
    \renewcommand{\headrulewidth}{0pt}
    \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}
% your text
\lipsum[1-15]

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

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

\lettergroup{D}
\lipsum[46-60]
\end{document}
Speravir
  • 19,491
2

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]{%
    % see pgfmanual.pdf for more information about this part
    \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]{%
    % see pgfmanual.pdf for more information about this part
    \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{}
\renewcommand{\headrulewidth}{0pt}
\chead{\oddthumb{#1}}% chapters start only on odd pages
\cfoot{\thepage}
}
\fancyhead[LO]{\fontfamily{phv}\selectfont{\textbf{\rightmark}}\oddthumb{#1}}%
\fancyhead[RE]{\fontfamily{phv}\selectfont{\textbf{\leftmark}}\eventhumb{#1}}%
% step the counter of the letters
\stepcounter{letternum}%
}
\fancypagestyle{basicstyle}{%
\fancyhf{}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0pt}
\fancyhead[LE,RO]{\textbf{\chaptitle}}
\fancyhead[LO,RE]{\textbf{\thepage}}}
\fancypagestyle{dictstyle}{%
\renewcommand{\headrulewidth}{0.4pt}
\fancyhf{}
\fancyhead[LE,LO]{{\fontfamily{phv}\selectfont{\textbf{\rightmark}}}}
\fancyhead[CO,CE]{\thepage}
\fancyhead[RE,RO]{{\fontfamily{phv}\selectfont{\textbf{\leftmark}}}}}
\setlength{\columnsep}{20pt}
\setlength{\columnseprule}{0.1pt}

\begin{document}
\pagestyle{dictstyle}
\lettergroup{A}
\dictchar{A}
\entry[headwords]{headwords}{translations}
\entry[headwords2]{headwords2}{translations2}
\clearpage
\lettergroup{B}
\dictchar{B}
\entry[headwords]{headwords}{translations}
\entry[headwords2]{headwords2}{translations2}
\clearpage
\lettergroup{C}
\dictchar{C}
\entry[headwords]{headwords}{translations}
\entry[headwords2]{headwords2}{translations2}
\clearpage
\end{document}
chejnik
  • 1,441
  • 2
  • 23
  • 42
  • 1
    Please note that I made an update to my answer. I replaced \lettersum by \letterdiv – Tobi May 28 '12 at 09:42