tikz:如何定位具有可变宽度的相邻(节点)框?

tikz:如何定位具有可变宽度的相邻(节点)框?

我想输出文本字符串“Abstract”,但每个字符都应该被其边界框包围。现在我有如下代码。

\documentclass{scrartcl}

\usepackage{tikz}

\pagestyle{empty}

\begin{document}
\begin{tikzpicture}
\foreach \g in {A, b, s, t, r, a, c, t}
  \draw node [anchor=base,
              draw,
              line width=1pt]
             {\fontsize{100pt}{0pt}\selectfont
              \g};
\end{tikzpicture}
\end{document}

可以看出,“当前点”未正确更新,因此循环中的节点全部重叠。我该如何修复?

在此处输入图片描述

答案1

基于原文foreach,所有字母均相同tikzpicture

\documentclass{scrartcl}

\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{lmodern}

\pagestyle{empty}

\begin{document}
\begin{tikzpicture}[%
    every node/.style={draw, anchor=base, line width=1pt,
        font=\fontsize{100pt}{0pt}\selectfont}%
    ]
    \node (A) {A};
    \foreach \g [remember=\g as \lastg (initially A)] in {b, s, t, r, a, c, t}
        \node[right=-1pt of \lastg.base east, anchor=base west] (\g) {\g};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

新解决方案:

这是一个宏,用于框选参数的字符。xstring使用了该包以及 tikzpositioning库。

在此处输入图片描述

该宏\boxtext接受一个必需参数(文本)和一个可选参数(tikz 选项)。上面的图像是使用代码创建的

`\boxtext{Abstract}\quad\boxtext[fill=red!30]{abcdefg}`

关键是使用base right=of nodename.base east将每个节点与前一个节点的基线定位。node distance=-\pgflinewidth与边界重叠。node distance=0pt如果不希望这样,您可以设置。

完整代码如下:

\documentclass{scrartcl}

\usepackage{tikz,xstring}
\usetikzlibrary{positioning}
\tikzset{boxnode/.style={anchor=base, draw, line width=1pt}}

\newcommand{\boxtext}[2][]{\StrLen{#2}[\strlen]\begin{tikzpicture}[baseline, node distance=-\pgflinewidth]
    \node[boxnode,#1](L1){\fontsize{100pt}{0pt}\selectfont\StrChar{#2}{1}};
    \foreach \n[count=\m] in {2,...,\strlen}{
        \node[boxnode, base right=of L\m.base east,#1](L\n){\fontsize{100pt}{0pt}\selectfont\StrChar{#2}{\n}};
    }\end{tikzpicture}}

\begin{document}

\boxtext{Abstract}\quad\boxtext[fill=red!30]{abcdefg}

\end{document}

以前的解决方案:

将 放在tikzpicturefor 循环内。添加%以避免每个字符之间有空格。

在此处输入图片描述

\documentclass{scrartcl}

\usepackage{tikz}

\pagestyle{empty}

\begin{document}
\foreach \g in {A, b, s, t, r, a, c, t}{% <-- need this.
\begin{tikzpicture}
  \draw node [anchor=base,
              draw,
              line width=1pt]
             {\fontsize{100pt}{0pt}\selectfont
              \g};
\end{tikzpicture}}
\end{document}

答案3

此解决方案不使用字距调整或连字。若要获得紧凑的框,请使用inner sep=0pt。此处的所有内容都在一个tikzpicture

\documentclass[tikz, border=1cm]{standalone}
\begin{document}
\begin{tikzpicture}[
letter box/.style={draw, inner sep=1pt, anchor=base west}
]
\node[letter box] (A) {A};
\node[letter box] (b) at (A.base east) {b};
\node[letter box] (s) at (b.base east) {s};
\node[letter box] (t) at (s.base east) {t};
\node[letter box] (r) at (t.base east) {r};
\node[letter box] (a) at (r.base east) {a};
\node[letter box] (c) at (a.base east) {c};
\node[letter box] at (c.base east) {t};
\end{tikzpicture}
\end{document}

“Abstract” 一词的方框字母

解决方案如下chain

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary {chains}
\begin{document}
\begin{tikzpicture}[start chain=going {at=(\tikzchainprevious.base east)}, every node/.style={anchor=base west, draw, inner sep=1pt, on chain}]
\foreach \g in {A, b, s, t, r, a, c, t}
\node {\g};
\end{tikzpicture}
\end{document}

带方框字母的“抽象”

答案4

这是一个可以与\fboxs 一起使用的解决方案(尽管/utils/TeX/ifx钥匙\usetikzlibrary只能使用 TikZ/ ) 或 TikZ正确加载。

它的核心是遍历一堆字符,并对它们进行相同的操作。对它们所做的就是 的任务/boxes/place letter

这可能只是\fbox

\boxesset{place letter/.code=\fbox{#1}}

但它也可以位于\nodeTikZpicture 内部。

值键at startat end用于将整个放置包裹在某物里面。

我定义了两种风格:

  1. fbox
    这会将每个字母放在 中\fboxat start键用于设置 的字体大小和长度\fbox

  2. tikz
    这会将每个字母放置为 ,这是node向右的链的一部分。at startat end值用于将整个内容放置在tikzpicture具有适当设置的 内。

这使得你能够简单地做

\boxes[fbox]{Text}
% or
\boxes[tikz]{Text}

或者您可以定义自己的宏来使用其中一个,这样您不必每次都指定它。

由于查看给定字母的算法不是很智能,因此需要特别考虑重音或变音符号的字符。只需将它们放在括号中即可{ä}。使用 LuaLaTeX,不再需要这样做(但这也没什么坏处)。

诸如此类的事情\textit{r}总是需要括号:{\textit{r}}。否则,算法会假定\textit它是自己的角色,并且会失败,因为它错过了它的参数。

文字空格将被忽略。该\fbox方法只需要~\␣,而 TikZ 解决方案需要{~~}{\␣\␣}

TikZ 解决方案使用baseline,使得字母的基线位于文本的实际基线和trim lefttrim right并且outer sep=0pt使得没有线宽对边界框产生贡献(顶部和底部线除外)。


/utils/TeX/ifxwithout的定义ext.misc是:

\makeatletter
\pgfkeys{
  /utils/TeX/ifx/.code n args={4}{%
    \ifx#1#2\relax\expandafter\pgfutil@firstoftwo\else\expandafter\pgfutil@secondoftwo\fi
    {\pgfkeysalso{#3}}{\pgfkeysalso{#4}}}}
\makeatother

代码

\documentclass{scrartcl}
\usepackage{tikz}\usetikzlibrary{chains,ext.misc}
\pagestyle{empty}
\newcommand*\boxesStop{boxesStop}
\newcommand*\boxesset{\pgfqkeys{/boxes}}
\boxesset{
  .code=\boxesset{#1},
  at start/.initial=,
  at end/.initial=,
  place letter/.code={#1},
  place letters/.style={@place letters={#1\boxesStop}},
  @place letters/.style 2 args={place letter={#1},
    /utils/TeX/ifx={\boxesStop}{#2}{}{@place letters={#2}}}}
\newcommand*{\boxes}[2][]{%
\begingroup
  \boxesset{#1}%
  \pgfkeysvalueof{/boxes/at start}%
  \boxesset{place letters={#2}}%
  \pgfkeysvalueof{/boxes/at end}%
\endgroup}
\boxesset{
  fbox/.style={
    at start=%
      \fontsize{100pt}{0pt}\selectfont
      \setlength{\fboxsep}{-.1pt}%
      \setlength{\fboxrule}{.1pt},
    place letter/.code=\fbox{##1}},
  tikz/.style={
    at start={%
      \begin{tikzpicture}[baseline=(chain-begin.base),
         trim left=(chain-begin.west), trim right=(chain-end.east),
         node distance=+0cm, start chain=going base right,
         nodes={draw, line width=+.1pt, inner sep=+0pt, outer sep=+0pt,
           font=\fontsize{100pt}{0pt}\selectfont}]},
    at end=\end{tikzpicture},
    place letter/.code=\node[on chain]{##1};},
}
\newcommand*{\dblSpc}{\ \ }
\begin{document}
\begin{tabular}{rll}
        & \texttt{fbox}                        & \texttt{tikz}                        \\
plain   & \boxes[fbox]{Abstract}               & \boxes[tikz]{Abstract}               \\
special & \boxes[fbox]{Abstr{ä}ct{\textit{r}}} & \boxes[tikz]{Abstr{ä}ct{\textit{r}}} \\
overlapping & \multicolumn{2}{c}{\rlap{\boxes[fbox]{Abstract}}\boxes[tikz]{Abstract}} \\
spaces & \boxes[fbox]{S p a c e s}             & \boxes[tikz]{S p a c e s}            \\
       & \boxes[fbox]{S\ p~a\ c~e\ s}          & \boxes[tikz]{S{\ \ }p{~~}a\dblSpc c{~~}e{\ \ }s}
\end{tabular}
\end{document}

输出

在此处输入图片描述

相关内容