在文本中的字母/单词周围绘制具有共同高度的连通框

在文本中的字母/单词周围绘制具有共同高度的连通框

(有几个相关问题,例如

我想要实现以下目标:

  • 将文本中的一些单词括在方框中,
  • 所有这些单词都是垂直对齐的,因为它们实际上只是文本,
  • 并且这些框应该具有相同的高度,足以容纳这些单词的所有字母,包括、、g等等;f'
  • 此外,各个框之间应该有一个固定的空间,并且之间要有一条线。

首先,我最接近期望的解决方案是这样的,

在此处输入图片描述

使用以下代码获取:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calligraphy, positioning, calc}

\tikzset{mystyle/.style={
            rectangle,
            draw,
            inner xsep=2pt,
            inner ysep=2pt,
            %minimum height=height("aaagtaa`a'") + 5pt
        }}

\begin{document}

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
\tikz[node distance=1mm, anchor=text, baseline=(A.base)]{
  \node[mystyle] (A) {a};
  \node[mystyle] (B) [base right=of A.base east] {aa};
  \node[mystyle] (C) [base right=of B.base east] {a};
  \node[mystyle] (D) [base right=of C.base east] {g};
  \node[mystyle] (E) [base right=of D.base east] {t};
  \node[mystyle] (F) [base right=of E.base east] {\phantom{a}};
  \node[mystyle, text=white, fill=black] (G) [base right=of F.base east] {a};
  \node[mystyle, text=white, fill=black] (H) [base right=of G.base east] {`a'};
  \draw[mystyle] ($(A.base east) + (0,.5ex)$) -- ($(B.base west) + (0,.5ex)$);
  \draw[mystyle] ($(B.base east) + (0,.5ex)$) -- ($(C.base west) + (0,.5ex)$);
  \draw[mystyle] ($(C.base east) + (0,.5ex)$) -- ($(D.base west) + (0,.5ex)$);
  \draw[mystyle] ($(D.base east) + (0,.5ex)$) -- ($(E.base west) + (0,.5ex)$);
  \draw[mystyle] ($(E.base east) + (0,.5ex)$) -- ($(F.base west) + (0,.5ex)$);
  \draw[mystyle] ($(F.base east) + (0,.5ex)$) -- ($(G.base west) + (0,.5ex)$);
  \draw[mystyle] ($(G.base east) + (0,.5ex)$) -- ($(H.base west) + (0,.5ex)$);
  \draw[red, very thin] (A.base west) -- (H.base east);
  \draw[red, very thin] (A.west |- D.south) -- (D.south -| H.east);
  \draw[red, very thin] (A.west |- H.north) -- (H.north east);
}
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
\end{document}

从注释行可以看出,我知道如何计算所有盒子的最大高度,就好像它们是孤立的一样,但显然这不是我想要的高度

然而,在写这个问题的时候,我想到了一个非常丑陋的技巧,就是\vphantom{aaagtaa在每个节点中都放一个'}`:

\tikz[node distance=1mm, anchor=text, baseline=(A.base)]{
  \node[mystyle] (A) {a\vphantom{aaagtaa`a'}};
  \node[mystyle] (B) [base right=of A.base east] {aa\vphantom{aaagtaa`a'}};
  \node[mystyle] (C) [base right=of B.base east] {a\vphantom{aaagtaa`a'}};
  \node[mystyle] (D) [base right=of C.base east] {g\vphantom{aaagtaa`a'}};
  \node[mystyle] (E) [base right=of D.base east] {t\vphantom{aaagtaa`a'}};
  \node[mystyle] (F) [base right=of E.base east] {\phantom{a}\vphantom{aaagtaa`a'}};
  \node[mystyle, text=white, fill=black] (G) [base right=of F.base east] {a\vphantom{aaagtaa`a'}};
  \node[mystyle, text=white, fill=black] (H) [base right=of G.base east] {`a'\vphantom{aaagtaa`a'}};
  \draw[mystyle] ($(A.base east) + (0,.5ex)$) -- ($(B.base west) + (0,.5ex)$);
  \draw[mystyle] ($(B.base east) + (0,.5ex)$) -- ($(C.base west) + (0,.5ex)$);
  \draw[mystyle] ($(C.base east) + (0,.5ex)$) -- ($(D.base west) + (0,.5ex)$);
  \draw[mystyle] ($(D.base east) + (0,.5ex)$) -- ($(E.base west) + (0,.5ex)$);
  \draw[mystyle] ($(E.base east) + (0,.5ex)$) -- ($(F.base west) + (0,.5ex)$);
  \draw[mystyle] ($(F.base east) + (0,.5ex)$) -- ($(G.base west) + (0,.5ex)$);
  \draw[mystyle] ($(G.base east) + (0,.5ex)$) -- ($(H.base west) + (0,.5ex)$);
  \draw[red, very thin] (A.base west) -- (H.base east);
  \draw[red, very thin] (A.west |- D.south) -- (D.south -| H.east);
  \draw[red, very thin] (A.west |- H.north) -- (H.north east);
}

它确实有效 在此处输入图片描述

但我挑战你称其为一个干净的解决方案。

答案1

您可以预处理所有条目(PGFMath 函数depthheight帮助)并进行text height适当设置text depth

使用mid westmid east锚点有助于连接高度处的节点.5ex(而不是节点的垂直中心)。

我使用xparse'ss和不推荐的参数说明符来解析开头u的可选项条目列表,这将启用*风格。

由于检测之间的文字空间并非易事,,因此我~在这里选择的宏(通常是不可破坏的空间)为\vphantom{a},文字空间没有高度/深度。

代码

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\usepackage{xparse}
\NewDocumentCommand\tikzrowofnodescheck{s u\STOP}{%
  \IfBooleanT{#1}{\tikzset{tikzrowofnode style'}}%
  \tikzset{node contents={#2}}}
\tikzset{
  tikzrowofnode style/.style={
    rectangle, draw, inner xsep=2pt, inner ysep=2pt},
  tikzrowofnode style'/.style={fill, text=white},
  tikzrowofnode determine height and depth/.style={%
    /utils/exec=\def\tikzrowofnodesheight{0pt}%
                \def\tikzrowofnodesdepth{0pt},%
    /utils/temp/.code=%
      \pgfmathsetlengthmacro\tikzrowofnodesheight{max(\tikzrowofnodesheight,height("##1")}%
      \pgfmathsetlengthmacro\tikzrowofnodesdepth{max(\tikzrowofnodesdepth,depth("##1")},
    /utils/temp/.list={#1},
    tikzrowofnode style/.append style/.expanded={text height=\tikzrowofnodesheight, text depth=\tikzrowofnodesdepth}
  }
}
\newcommand*\tikzrowofnodes[1]{%
 \tikz[
   node distance=1mm,
   baseline=(chain-begin.base),
   start chain=chain going base right,
   every join/.append style={to path={(\tikztostart.mid east) -- (\tikztotarget.mid west)}},
   every on chain/.append style={tikzrowofnode style,join},
   check row of node/.code={\tikzrowofnodescheck##1\STOP},
   tikzrowofnode determine height and depth={#1},
]
   \def~{\phantom{a}}% dirty
   \foreach \t in {#1}
     \node[on chain=chain,check row of node/.expand once=\t];%
}
\begin{document}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
\tikzrowofnodes{a, aa, a, g, t, ~, *a, *`a'}
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
\end{document}

输出

在此处输入图片描述

相关内容