TikZ:在基线下绘制并保持线之间的正常间距

TikZ:在基线下绘制并保持线之间的正常间距

问题

我想实现一个类似 lilypond 的歌词绑定命令。现在我几乎可以正常工作了,但缺点是 tikz 图片会影响行间距,这会增加太多额外空间,从而使整体文本看起来不太好。

平均能量损失

\documentclass[a4paper]{article}
\usepackage{lipsum}
\usepackage{calc}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand{\tie}[1]{%
    {\hspace*{-0.5ex}\tikz[baseline=(a.base)]{
        \node[inner sep=2pt,outer sep=0pt] (a) {#1};
        \node[below=-1ex of a,outer sep=0pt] (b) {\resizebox{\widthof{#1} * \real{0.85}}{1ex}{\rotatebox{90}{$\Bigl($}}};
    }}%
}%

\begin{document}
First, to show the normal line spacing: \lipsum[1]
When \tie{this is} called, additional space is added between the lines, but I want to keep the original white space,
even if that means, that the tie touches the letters in the next line. In the next line \tie{it's called} \tie{two times}.
\lipsum[1]
\end{document}

示例图像

在下图中,我们可以清楚地看到,在放置 tikz 代码的两行中,行与行之间的空白看起来很糟糕。我也希望这里的行与行之间有相同的空白。即使这意味着绘图会触及或覆盖下一行。

tikz:在基线下绘制

请注意,我不能使用该问题的解决方案addvspace,因为后来我使用列表中的代码,但其中addvspace不起作用。

答案1

和每个节点一样,b节点也会对 TikZpicture 的边界框做出贡献。这样一来,整个图片就太深了,无法适应法线。

随着选项overlay您可以指示 TikZ 不要考虑节点(或您在其上使用的任何节点)对边界框的贡献。这与宏非常相似\llap,基本上。\lrap\smash

我添加了\Tie另一种仅使用 TikZ 定义此命令的方法,没有positioning也没有calc包,因为 TikZ 附带 PGFmath。(我们也可以只测量#1其中的节点并将其用于缩放,但这需要比更多的工作width("#1")。)

在这里,我将所有内部和外部 sep 设置为零,以便节点能够紧密贴合文本。节点作为(标签完成,我们可以在其中直接引用父节点(此处south:指定父节点的南锚点)。

在文档的末尾,我将两个选项叠加在一起以显示差异。

代码

\documentclass[a4paper]{article}
\usepackage{lipsum,calc}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand{\Tie}[1]{% no calc package and no positioning library
  \tikz[inner sep=+0pt, outer sep=+0pt,baseline=+0pt]
    \node[anchor=base, label={[%
        overlay, anchor=east, yshift=+-.1ex,
        rotate=90, xscale=.8,
        yscale={.85*width("#1")/(height("{$\Bigl($}")+depth("{$\Bigl($}"))}
      ] south:$\Bigl($}]{#1};%
}%
\newcommand{\tie}[1]{%
    {\hspace*{-0.5ex}\tikz[baseline=(a.base)]{
        \node[inner sep=2pt,outer sep=0pt] (a) {#1};
        \node[overlay,below=-1ex of a,outer sep=0pt] (b) {\resizebox{\widthof{#1} * \real{0.85}}{1ex}{\rotatebox{90}{$\Bigl($}}};
    }}%
}%

\begin{document}
First, to show the normal line spacing: \lipsum[1]
When \tie{this is} called, additional space is added between the lines, but I want to keep the original white space,
even if that means, that the tie touches the letters in the next line. In the next line \tie{it's called} \tie{two times}.
\lipsum[1]

First, to show the normal line spacing: \lipsum[1]
When \Tie{this is} called, additional space is added between the lines, but I want to keep the original white space,
even if that means, that the tie touches the letters in the next line. In the next line \tie{it's called} \Tie{two times}.
\lipsum[1]

{\pgfsetfillopacity{.5}%
       \color{blue}x\tie{two times}x%
  \llap{\color{red}x\Tie{two times}x}
\end{document}

答案2

感谢奎伯比尔贝尔,我overlay在之前的代码中添加了选项来修复主要问题,还发现below=someDimension of nodeName.base可以在 TikZ 中使用它来定义完美的 y 坐标。然后,包含深字母的单词(如p和)g在基线高度处也有平分。

\documentclass[a4paper]{article}
\usepackage{lipsum}
\usepackage{calc}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand{\tie}[1]{\mbox{\hspace*{-0.5ex}\tikz[baseline=(a.base)]{%
    \node[inner sep=2pt,outer sep=0pt] (a) {#1};%
    \node[below=-0.5ex of a.base,outer sep=0pt,overlay] (b) {\resizebox{\widthof{#1} * \real{0.9}}{0.5ex}{\rotatebox{90}{$\Bigl($}}};%
}\hspace*{-0.5ex}}}

\begin{document}
First, to show the normal line spacing: \lipsum[1]
When \tie{this is} called, \tie{additional space} is added between the lines, but I want to keep the original white space,
even if that means, that the tie touches the letters in the next line. In the next line \tie{it's called} \tie{two times}.
\lipsum[1]
\end{document}

在此处输入图片描述

相关内容