If I understand correctly the problem, you need to have the +
symbols evenly spaced, and the text "as near as possible" to each +, but avoiding the paragraphs being too close. So you allow for small shifts of particular paragraphs, leaving the others untouched.
So, an acceptable output would be:
I'll draw a box around each paragraph to clarify. As you see, the paragraph B was shifted and the + is not longer vertically centered in this paragraph. But distance among + is constant.
How it was done
As you guessed, this required two passes. In the first pass all paragraphs are drawn as rectangluar nodes, vertically centered with its corresponding +
symbol, but they were typeset with white ink, so they are not visible.
In the second pass, the distance between each node and the next one is measured. If the distance is below 1mm, the node is raised 1.5mm. I've found this heuristic to produce good results.
In order to simplify the coding of the figure, all the texts are saved in a list, which is reused in each pass.
\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}
In the next figure, I've drawn in pink the nodes in the first pass, so you can see the original position of the nodes and how much they were shifted.
Typically one would include a \strut
at the beginning. Note also that you have some spurious spaces in your macro definition (you need some strategic placements of %
). See What is the use of percent signs (%
) at the end of lines? I'm also guessing your use of .96\textwidth
results from some overfull \hbox
es. You can adjust this width to fit perfectly within the text block as well...
Here's perhaps something that you're after:
\newcommand{\field}[1]{%
\noindent%
\framebox[\linewidth][l]{%
\parbox[t]{\dimexpr\linewidth-2\fboxsep-2\fboxrule}{%
\raggedright\strut#1%
}%
}%
}
Here is its use in a MWE:
\documentclass{article}
\newcommand{\field}[1]{%
\noindent%
\framebox[\linewidth][l]{%
\parbox[t]{\dimexpr\linewidth-2\fboxsep-2\fboxrule}{%
\raggedright\strut#1%
}%
}%
}
\begin{document}
\field{Some test}
\field{}
\field{I'm trying to draw a vertical box around one or more lines of
text (for a field in a pre-filled form), but some of the fields may
be empty and in these cases, the box should be the same vertical
height as when there is only one line (or even just one character)
of content within the box.}
\end{document}
Depending on your usage, you may also consider ending with a \strut
, allowing for adequate space if the last line has no descender.
Best Answer