我想输出文本字符串“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}
以前的解决方案:
将 放在tikzpicture
for 循环内。添加%
以避免每个字符之间有空格。
\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}
解决方案如下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
这是一个可以与\fbox
s 一起使用的解决方案(尽管/utils/TeX/ifx
钥匙\usetikzlibrary
只能使用 TikZ/ ) 或 TikZ正确加载。
它的核心是遍历一堆字符,并对它们进行相同的操作。对它们所做的就是 的任务/boxes/place letter
。
这可能只是\fbox
:
\boxesset{place letter/.code=\fbox{#1}}
但它也可以位于\node
TikZpicture 内部。
值键at start
可at end
用于将整个放置包裹在某物里面。
我定义了两种风格:
fbox
:
这会将每个字母放在 中\fbox
。at start
键用于设置 的字体大小和长度\fbox
。tikz
:
这会将每个字母放置为 ,这是node
向右的链的一部分。at start
和at end
值用于将整个内容放置在tikzpicture
具有适当设置的 内。
这使得你能够简单地做
\boxes[fbox]{Text}
% or
\boxes[tikz]{Text}
或者您可以定义自己的宏来使用其中一个,这样您不必每次都指定它。
由于查看给定字母的算法不是很智能,因此需要特别考虑重音或变音符号的字符。只需将它们放在括号中即可{ä}
。使用 LuaLaTeX,不再需要这样做(但这也没什么坏处)。
诸如此类的事情\textit{r}
总是需要括号:{\textit{r}}
。否则,算法会假定\textit
它是自己的角色,并且会失败,因为它错过了它的参数。
文字空格将被忽略。该\fbox
方法只需要~
或\␣
,而 TikZ 解决方案需要{~~}
或{\␣\␣}
。
TikZ 解决方案使用baseline
,使得字母的基线位于文本的实际基线和trim left
,trim right
并且outer sep=0pt
使得没有线宽对边界框产生贡献(顶部和底部线除外)。
/utils/TeX/ifx
without的定义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}