根据文本基线而不是对象本身将文本置于 TikZ 的中心

根据文本基线而不是对象本身将文本置于 TikZ 的中心

作为后续行动将 TikZ 代码添加到目录,我在每个索引条目中添加了一个 TikZ 代码。该代码可能包含以下特定字母:、、A和。请参阅以下示例:NCPQ

\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}

foo 1 列表

正如你所看到的,(请原谅我可能误用了这些术语)对象是集中的,但后者——因为这封信Q——看起来并不对我来说是美学。

因为我知道我可能使用的所有字母,而且唯一有问题的字母是Q,所以我使用包编写了这个修复程序xstring,并且Martin Scharrer 的建议

\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}

foo 2 列表

这基本解决了我的问题。

我想知道是否有更好的想法来解决这个特定的对齐问题,无论是动态的还是非动态的。

答案1

使用\raisebox实际上是正确的方向。但是,在这种情况下,我将使用其第二个可选参数将文本的深度设置为零:\raisebox{0pt}[\height][0pt]{...}。这会忽略基线以下的所有内容,而文本实际上并未凸起,高度保持不变。

\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}

结果

您还可以使用baseline={(<the node name>.base)}选项将图片基线置于文本基线。然后,带框的文本(而不是其框架)与其他文本位于同一行。最后,您还可以稍微移动基线以调整框架相对于普通文本的位置: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}

结果

答案2

另一种选择是明确设置text heighttext 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};

答案3

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

而不是只{\tt\scriptsize #1}在原始定义中。需要数学

相关内容