一个用 TikZ 实现的简易文本框

在知乎上看到一个问题,求一个简易的文本框。恰好之前在群里用 TikZ 给朋友实现过一个类似的,所以就做了一个回答。一些值得说的东西,记录在这里。

首先是代码。

simple-block.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
\documentclass[UTF8]{ctexart}
\usepackage{tikz}
\usepackage{calc}
\usetikzlibrary{calc}

\newlength{\framelinewidth}
\newlength{\horizonextendwidth}
\newlength{\verticalextendwidth}
\setlength{\framelinewidth}{2pt}
\setlength{\horizonextendwidth}{3pt}
\setlength{\verticalextendwidth}{3pt}
\newenvironment{tblock}
{\par\medskip\noindent
\begin{tikzpicture}
\node[inner sep = 0pt] (box) \bgroup%
\begin{minipage}[t]{\textwidth-\framelinewidth-2\horizonextendwidth}%
}{%
\end{minipage}%
\egroup;
\draw[black, line width=\framelinewidth]
( $ (box.north east) + (\horizonextendwidth,-\verticalextendwidth) $ ) -- ( $ (box.north east) + (\horizonextendwidth,\verticalextendwidth) $ ) -- ( $ (box.north west) + (-\horizonextendwidth,\verticalextendwidth) $ ) -- + (0,-2\verticalextendwidth);
\draw[black, line width=\framelinewidth]
( $ (box.south east) + (\horizonextendwidth,\verticalextendwidth) $ ) -- ( $ (box.south east) + (\horizonextendwidth,-\verticalextendwidth) $ ) -- ( $ (box.south west) + (-\horizonextendwidth,-\verticalextendwidth) $ ) -- + (0,2\verticalextendwidth);
\end{tikzpicture}
\par\medskip}

\usepackage{mwe}
\begin{document}

\begin{tblock}
\blindtext
\end{tblock}

\end{document}

有几个地方值得一说。

主体当然是用 \newenvironment{tblock} 定义的 tblock 环境。这个环境里的文本部分是 tikzpicture 里用 \node 实现的,内里的换行用了 minipageminipage 的宽度是 \textwidth-\framelinewidth-2\horizonextendwidth,这里利用了 calc 宏包提供的特性——直接做长度运算。为了让整个文本框宽度恰好是 \textwidth,内里的文本部分宽度必须减去框线两边延伸的宽度(2\horizonextendwidth)以及两边框线本身的粗细(2 * 0.5\framelinewidth)。

再就是 \node[inner sep = 0pt] (box) {} 的形式被修改为 \node[inner sep = 0pt] (box) \bgroup \egroup 的形式。这是为了避免在定义新环境时花括号不匹配的问题。详细可以看 TeX.sx 上的讨论

最后就是引入了 \usetikzlibrary{calc},这个库允许我们在 TikZ 里对点的坐标做运算。因此我们可以写出类似 ( $ (box.south east) + (\horizonextendwidth,\verticalextendwidth) $ ) 的代码,来表示 box 右下角偏移 (\horizonextendwidth,\verticalextendwidth) 的那个点。

大体就是如此了。


您的鼓励是我写作最大的动力

俗话说,投资效率是最好的投资。 如果您感觉我的文章质量不错,读后收获很大,预计能为您提高 10% 的工作效率,不妨小额捐助我一下,让我有动力继续写出更多好文章。


撰写评论

写了这么多年博客,收到的优秀评论少之又少。在这个属于 SNS 的时代也并不缺少向作者反馈的渠道。因此,如果你希望撰写评论,请发邮件至我的邮箱并注明文章标题,我会挑选对读者有价值的评论附加到文章末尾。