LaTeX is set up to avoid this if possible but sometimes there just isn't a good alternative. You can suppress widow lines entirely with \widowpenalty=10000
but you'll want to have \raggedbottom
enabled.
Avoiding widow words isn't as directly straightforward. You cannot automatically suppress them but you can specify that you want a final line of at least some certain length with
\parfillskip 0pt plus 0.75\textwidth
where "some certain length" is, in this case, one quarter of the text width of the document.
By using one of Jake's previous answers, I tried to fit the points in an ellipse and the result is not so bad. Also it reduces the manual labor. But there are a few issues which can be improved but I am not able to type \pgfmathparse
stuff as others do. (I wish I have time!) Anyway, here is the code and some explanation after it.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,fit,shapes}
\makeatletter
\tikzset{
through point/.style={
to path={%
\pgfextra{%
\tikz@scan@one@point\pgfutil@firstofone(\tikztostart)\relax
\pgfmathsetmacro{\pt@sx}{\pgf@x * 0.03514598035}%
\pgfmathsetmacro{\pt@sy}{\pgf@y * 0.03514598035}%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\pgfmathsetmacro{\pt@ax}{\pgf@x * 0.03514598035 - \pt@sx}%
\pgfmathsetmacro{\pt@ay}{\pgf@y * 0.03514598035 - \pt@sy}%
\tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
\pgfmathsetmacro{\pt@ex}{\pgf@x * 0.03514598035 - \pt@sx}%
\pgfmathsetmacro{\pt@ey}{\pgf@y * 0.03514598035 - \pt@sy}%
\pgfmathsetmacro{\pt@len}{\pt@ex * \pt@ex + \pt@ey * \pt@ey}%
\pgfmathsetmacro{\pt@t}{(\pt@ax * \pt@ex + \pt@ay * \pt@ey)/\pt@len}%
\pgfmathsetmacro{\pt@t}{(\pt@t > .5 ? 1 - \pt@t : \pt@t)}%
\pgfmathsetmacro{\pt@h}{(\pt@ax * \pt@ey - \pt@ay * \pt@ex)/\pt@len}%
\pgfmathsetmacro{\pt@y}{\pt@h/(3 * \pt@t * (1 - \pt@t))}%
}
(\tikztostart) .. controls +(\pt@t * \pt@ex + \pt@y * \pt@ey, \pt@t * \pt@ey - \pt@y * \pt@ex) and +(-\pt@t * \pt@ex + \pt@y * \pt@ey, -\pt@t * \pt@ey - \pt@y * \pt@ex) .. (\tikztotarget)
}
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node(a) {\(A\)};
\node(b1) at ($(a)+(1,-0.5)$){\(B_1\)};
\node(b2) at ($(b1)+(0,0.5)$){\(B_2\)};
\node(b3) at ($(b2)+(0,0.5)$){\(B_3\)};
\node(c1) at ($(b1)+(2,0)$){\(C_1\)};
\node(c2) at ($(c1)+(0,0.5)$){\(C_2\)};
\node(c3) at ($(c2)+(0,0.5)$){\(C_3\)};
\node(d) at ($(c2)+(1,0)$){\(D\)};
%all the points
\node [draw,ellipse,thick,inner sep=0,fit={(b1) (b2) (b3) (c1) (c2) (c3)}] (avoid1) {};
\draw[->,thick] (a) to[through point={(avoid1.north west) (avoid1.north east)}] (d);
%just the c group
\node [draw,ellipse,blue,inner sep=0,fit={(c1) (c2) (c3)}] (avoid2) {};
\draw[->,blue] (a) to[through point={(avoid2.north)}] (d);
%just the b group
\node [draw,ellipse,yellow,thick,inner sep=1,fit={(b1) (b2) (b3)}] (avoid3) {};
\draw[->,yellow,thick] (a) to[through point={(avoid3.north)}] (d);
\end{tikzpicture}
\end{document}
This is drawing the bounding ellipses and trying to avoid them. The resulting curves grouped by color. As you can see Andrew's code is still doing a fine job. What is needed is to select the north or the south of the dummy nodes avoid
which define the curve to pass from below or above. Also I had to define two control nodes to pass through when all obstacles were included see the avoid1
case. (I am really surprised that it accepted two nodes, superb!). If you think that the resulting curve is overshooting you can decrease the inner sep
of the ellipse node.
I think TikZ needs this kind of a, say around
, library. I tried to get the control points of a Beziér curve and other angle computation stuff but I can't understand the math syntax of pgf
yet. So hope this can help a bit.
EDIT : I have tried to simplify the whole fitting process then I realized that the fit is not necessary if we can smoothen the path. I checked the manual and only thing that is almost what we want is the smooth
option with the extra freedom of tension
parameter.
I have tried it out with the following
\begin{tikzpicture}
\matrix (o) [matrix of nodes, column sep=2cm,nodes=draw,draw=red]{
$A_1$&$B_1$ &$C_1$ &$D_1$\\
$A_2$&$B_2$ &$C_2$ &$D_2$\\
$A_3$&$B_3$ &$C_3$ &$D_3$\\
};
\node (s) at (-6,0) {S};
\node (f) at (6,0) {F};
\draw[blue] plot [smooth, tension=0.5] coordinates{%
(s.east) (o-2-1.south) (o-2-2.north) (o-1-3.north) (o-1-4.south) (f.west)};
\draw plot [smooth, tension=0.8] coordinates{%
(s.east) (o-2-1.north) (o-1-2.north) (o-1-4.north) (f.west)};
\draw[yellow,thick] plot [smooth, tension=0.5] coordinates{%
(s.east) (o-3-1.south) (o-3-4.south) (f.west)};
\end{tikzpicture}
This gives the following result:
The tension
parameter adjusts how smooth the corners should be rendered. Default is reported as 0.55
. So one can still fit some nodes into a bigger shape and use it to avoid but this node-by-node connection seems easier. Also, this introduces new issues such as the out and in angles are slightly awkward and I couldn't make the arrows look normal. I would be glad if someone teaches me how to do it properly.
Best Answer
Without an example it is hard to say but if you add
Then TeX will try as hard as it can to avoid widows. The tolerance settings probably are not doing very much in your case as with such short paragraphs there is very little flexibility in line breaking anyway.
If there is any vertical stretch in your page (as in the default parskip spacing in standard classes) then probably preventing widows will pull the last couple of lines over to the next page. If there is no vertical stretch then you will get an underfull page on the previous page, in which case you could potentially detect that in the output routine and put the text back after enlarging the page but such interactions are very delicate and depend greatly on the content you have as it's very hard to make things work in general.