Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

As a follow up to Adding TikZ code to TOC, I have a TikZ code added to each index entry. That code may contain these specific letters: A, N, C, P and Q. See the following example:

\documentclass{article}

\usepackage[titles]{tocloft}
\usepackage{tikz}

\newcommand*\info[1]{%
  \begin{tikzpicture}
    \node[draw,inner sep=1pt, minimum height=0.32cm, minimum width=0.9cm] {\tt\scriptsize #1};
  \end{tikzpicture}}

\newcommand{\listfoo}{List of foo}
\newlistof[section]{foo}{idf}{\listfoo}

\begin{document}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCP}\ Hello world.}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCPQ}\ Hello bar.}

\listoffoo

\end{document}

List of foo 1

As you can see, (pardon my possible misuse of the terms) both text objects are centralized, but the latter - because of the letter Q - does not look that aesthetic to me.

Since I know all the possible letters I may use, and as the only problematic letter is the Q, I wrote this fix using the xstring package and Martin Scharrer's suggestion:

\documentclass{article}

\usepackage[titles]{tocloft}
\usepackage{tikz}
\usepackage{xstring}

\newcommand*\info[1]{%
  \begin{tikzpicture}
    \IfSubStr{#1}{Q}{%
    \node[draw,inner sep=1pt, minimum height=0.32cm, minimum width=0.9cm] {\raisebox{\dimexpr-.5\height+.5\depth-.8ex\relax}{\tt\scriptsize #1}};}{%
    \node[draw,inner sep=1pt, minimum height=0.32cm, minimum width=0.9cm] {\tt\scriptsize #1};}
  \end{tikzpicture}}

\newcommand{\listfoo}{List of foo}
\newlistof[section]{foo}{idf}{\listfoo}

\begin{document}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCP}\ Hello world.}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCPQ}\ Hello bar.}

\listoffoo

\end{document}

List of foo 2

That pretty much solves my issue.

I'd like to know if there are better ideas of how to solve this particular alignment issue, dynamically or not.

share|improve this question

3 Answers 3

up vote 2 down vote accepted

Using \raisebox is actually the right direction. However, in this case I would use its second optional argument to set the depth of the text to zero: \raisebox{0pt}[\height][0pt]{...}. This ignores everything below the baseline, while the text is actually not raised and the height stays like it is.

\documentclass{article}

\usepackage[titles]{tocloft}
\usepackage{tikz}
\usepackage{xstring}

\newcommand*\info[1]{%
  \begin{tikzpicture}
      \node[draw,inner sep=1pt, minimum height=0.32cm, minimum width=0.9cm] {\tt\scriptsize\raisebox{0pt}[\height][0pt]{#1}};
  \end{tikzpicture}}

\newcommand{\listfoo}{List of foo}
\newlistof[section]{foo}{idf}{\listfoo}

\begin{document}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCP}\ Hello world.}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCPQ}\ Hello bar.}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCPQgyj}\ Hello bar.}

\listoffoo

\end{document}

Result

You could also use the baseline={(<the node name>.base)} option to place the picture baseline to the text baseline. Then the framed text and not its frame is based at the same line as the other text. Finally, you can also move the baseline a little to adjust how the frame lies relative to the normal text: baseline={([yshift=<length>]<the node name>.base)}

\documentclass{article}

\usepackage[titles]{tocloft}
\usepackage{tikz}
\usepackage{xstring}

\newcommand*\info[1]{%
  \begin{tikzpicture}[baseline={(TEXT.base)}]
      \node[draw,inner sep=1pt, minimum height=0.32cm, minimum width=0.9cm] (TEXT) {\tt\scriptsize\raisebox{0pt}[\height][0pt]{#1}};
  \end{tikzpicture}}

\newcommand{\listfoo}{List of foo}
\newlistof[section]{foo}{idf}{\listfoo}

\begin{document}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCP}\ Hello world.}

\refstepcounter{foo}
\addcontentsline{idf}{foo}{\protect \info{ANCPQ}\ Hello bar.}

\listoffoo

\end{document}

Result

share|improve this answer
    
It's a bit funny how it looks in the end better and worse at the same time. I think these boxes require font with all caps not (or only barely) crossing the baseline. Then box (after raising) will be able to fit within [baseline,cap height] and its bottom should lie on the baseline. This way weird look should be mostly dismissed. @Paulo: Maybe consider using TEX Gyre Cursor? –  przemoc Jun 25 '11 at 23:39
    
Cool! I'll probably stick with the first one, since \raisebox sounds more semantic to me than the baseline option. Thanks a lot, Martin! –  Paulo Cereda Jun 26 '11 at 10:42
    
@przemoc: Hm I didn't know that font, thanks for mentioning it! Unfortunately, for this particular case, this font will be out of style with the rest of the document. =) –  Paulo Cereda Jun 26 '11 at 10:45

Another option would be to explicitly set text height and text depth:

\node[draw,inner sep=1pt, minimum height=0.32cm, minimum width=0.9cm,text height=0.6em,text depth=0.1em] {\ttfamily\scriptsize #1};
share|improve this answer
    
Cool, I didn't know of these parameters! I tried text centered, but since it didn't work, I gave up on trying anything else through TikZ. It's also a great solution, Gonzalo! Thanks! –  Paulo Cereda Jun 26 '11 at 10:36

Say

{\smash[b]{\tt\scriptsize #1}}

instead of only {\tt\scriptsize #1} in the original definition. Requires amsmath.

share|improve this answer
    
Hm it's an interesting idea, egreg! Unfortunately, I can't use amsmath for this particular code, but I'll definitely save it for later. =) –  Paulo Cereda Jun 26 '11 at 10:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.