如何完成

如何完成

我是 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}

我想

  1. 使文本块尽可能与+ 锚点对齐,使用anchor=west
  2. 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

在此处输入图片描述

相关内容