我是 TikZ 的新手,我正在尝试解决一个应该很容易的问题,我找到了许多相关的例子,但没有一个对我有帮助。
鉴于以下 MWE:
\documentclass{article}
\usepackage{fontspec}
\usepackage{xltxtra}
\usepackage[paperwidth=99mm,paperheight=71mm,margin=0mm,showframe]{geometry}
\usepackage{tikz}
\usepackage[graphics,tightpage,active]{preview}
\PreviewEnvironment{tikzpicture}
\thispagestyle{empty}
\tikzstyle{every node}=[font=\small]
\begin{document}
\begin{tikzpicture}
\draw plot[only marks, mark=+] coordinates{(-23.3mm, 18.6mm) (-23.3mm, 10.8mm) (-23.3mm, 2.3mm ) (-23.3mm, -5.9mm ) (-23.3mm, -14.2mm) (-23.3mm, -14.2mm) (-23.3mm, -22.2mm)};
\draw (-23.3mm, 18.6mm) node[anchor=west, text width=60.3mm ]{A. This is quite short.};
\draw (-23.3mm, 10.8mm) node[anchor=west, text width=60.3mm ]{B. This is already a bit longer, it should be on two lines.};
\draw (-23.3mm, 2.3mm) node[anchor=west, text width=60.3mm ]{C. This is really the longest of all blocks and it will span a whole number of three lines!!!};
\draw (-23.3mm, -5.9mm) node[anchor=west, text width=60.3mm ]{D. This is short};
\draw (-23.3mm, -14.2mm) node[anchor=west, text width=60.3mm ]{E. This is long but not too much but should again span two lines.};
\draw (-23.3mm, -22.2mm) node[anchor=west, text width=60.3mm ]{F. This is short.};
\end{tikzpicture}
\end{document}
我想
- 使文本块尽可能与
+
锚点对齐,使用anchor=west
。 - A最小垂直空间块之间,这会覆盖先前的条件:如果有必要,相邻的块应该垂直位移,为三行块腾出空间。
首选的锚点位置、文本宽度、图像大小和字体都是固定的。
在示例中,B 应该向上移动一点,为 C 腾出空间。
问题是我想在多幅图像上自动执行此操作,使用不同的文本块集,并且我事先不知道三行块是否/在哪里(但我可以确保没有相邻的三行块)。
请注意,如果所有块都有三条线,我会超出边距,因此我不能简单地为所有块设置最小高度。但是我确定每张图片有 6 个块,只有 1 或 2 个是长的,并且它们不相邻。
注意:我使用的是 XeLaTeX
请随意猜一下我想做什么:)
答案1
如果我正确理解了这个问题,你需要让+
符号间距均匀,并且文本“尽可能靠近”每个 +,但要避免段落太近。因此,你允许特定段落发生小幅移动,而其他段落则保持不变。
因此,可接受的输出是:
我将在每个段落周围画一个框来说明。如您所见,段落 B 已移动,并且 + 不再在此段落中垂直居中。但 + 之间的距离是恒定的。
如何完成
正如您所猜测的,这需要两次传递。在第一次传递中,所有段落都绘制为矩形节点,与其对应的+
符号垂直居中,但它们是用白色墨水排版的,因此不可见。
在第二遍中,测量每个节点与下一个节点之间的距离。如果距离小于 1 毫米,则节点升高 1.5 毫米。我发现这种启发式方法可以产生良好的结果。
为了简化图形的编码,所有文本都保存在一个列表中,每次传递时都会重复使用。
\usetikzlibrary{calc, positioning}
% Define the list with the texts:
\def\listoftexts{
{A. This is quite short.},
{B. This is already a bit longer, it should be on two lines.},
{C. This is really the longest of all blocks and it will span a whole number of three lines!!!},
{D. This is short},
{E. This is long but not too much but should again span two lines.},
{F. This is short.}
}
\tikzset{
paragraph/.style = {
font=\small,
inner sep=0pt,
text width=60.3mm
}
}
\begin{tikzpicture}
% First draw the + symbols, evenly spaced spawning a distance of 4cm
% This distance is harcoded because it is the one you used in your
% example.
\coordinate(first) at (0,0);
\coordinate (last) at (0,-4cm);
% The + are at 0%, 20%, 40%, 60%, 80% and 100% of that distance
\foreach[count=\i] \f in {0,0.2,...,1}
{\node[inner sep=0pt] (item\i) at ($(first)!\f!(last)$) {\tiny +}; }
% First pass (invisible nodes)
\foreach[count=\i] \text in \listoftexts
\node[paragraph, anchor=west, right=0.4mm of item\i.east, white] (item\i) {\text};
% A little cheat, fake 7-th node
\coordinate (item7) at ($(item6)+(0,5mm)$);
% Second pass, adjust distances
\foreach[count=\i] \text in \listoftexts {
\path let
\n1={int(\i+1)},
\p2=($(item\i.south)-({item\n1}.north)$),
\n1={veclen(\p2)},
\n1={\n1<1mm?1.5mm:0mm}
in node[paragraph] at ($(item\i)+(0,\n1)$) {\text};
}
\end{tikzpicture}
在下图中,我用粉色画出了第一遍中的节点,这样你就可以看到节点的原始位置以及它们的移动量。
答案2
如果要覆盖这些节点,您仍然可以使用定位库。基本机制是将第一个节点固定在某处,然后使用
below=###mm of <the node above it>
选项。我不知道底层图形是什么样子的,但这里有一个通用模板。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[node distance=0.5cm and 1cm,%Set up the vertical and the horizontal spacing
myblock/.style={draw,text width=60.3mm,label={left:+}},%Create common settings for your nodes and add a + label to the left
]
\node[myblock] (nodeA) {A. This is quite short.}; %Start with the first node and keep placing nodes OR use chain library(see manual)
\node[myblock,below= of nodeA] (nodeB) {B. This is already a bit longer, it should be on two lines.This is short};
\node[myblock,below= of nodeB] (nodeC) {C. This is really the longest of all blocks and it will span a whole number of three lines!!!};
\node[myblock,below= of nodeC] (nodeD) {D. This is short};
\node[myblock,below= of nodeD] (nodeE) {E. This is long but not too much but should again span two lines.};
\node[myblock,below= of nodeE] (nodeF) {F. This is short};
\end{tikzpicture}
\end{document}
您可以看到,我们可以省略语法中的维度below=...
,然后它将假设选项给出的距离 node distance
。