Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm not optimistic about this since this is a core part of TeX's algorithm, but is there any way to switch to a 'greedy' justification algorithm? That is, instead of working on the paragraph as a whole and optimizing word spacing, fit as much as you can onto one line, hyphenating if necessary, justify, and then move to the next line.

share|improve this question
6  
no​​​​​​​​​​​:) –  David Carlisle Sep 2 '13 at 16:30
    
@DavidCarlisle What's that I'm always hearing about you and one-word answers? ;) Although, in this case, I think a one-word answer is sufficient—but I still have hope! …sort of! –  Sean Allred Sep 2 '13 at 16:31
    
However if you described the end effect that you want to achieve it may be possible to tune the paragraph breaking parameters to get something closer to what you want (cf \sloppy) –  David Carlisle Sep 2 '13 at 16:32
1  
@DavidCarlisle I'm creating a table that compares TeX's default behavior with other solutions'—such as Word. –  Sean Allred Sep 2 '13 at 16:32
2  
LibreOffice would be a free alternative –  David Carlisle Sep 2 '13 at 16:41

3 Answers 3

up vote 12 down vote accepted

no​​​​​​​​​​​:) – David Carlisle 3 hours ago

On the grounds of never say never, this builds the paragraph up line by line (with normal setting first)....

update fixing small error in inserting parindent

enter image description here

\documentclass{article}
\usepackage{kantlipsum}

\begin{document}




\makeatletter
\def\linebyline#1 {%
\ifx\!#1\else
\setbox\z@\vbox{%
  \noindent\unhbox\tw@\unskip\unskip\unpenalty\sporindent#1}%
\let\sporindent\space
\ifdim\ht\z@>\baselineskip
\setbox\z@\vbox{%
\unvbox\z@
\global\setbox1\lastbox
\unskip\unpenalty\unskip\unpenalty
\global\setbox\thr@@\lastbox
      \unskip\unpenalty\unskip\unpenalty%<<<<<
}%
      \ifdim\ht\z@>\z@\box\z@\fi%<<<<<
\hbox to \hsize{\unhbox\thr@@\unskip\unskip\unpenalty}%
\else
\setbox\z@\vbox{%
\unvbox\z@
\global\setbox\@ne\lastbox
}%
\fi
\setbox\tw@\box\@ne
\expandafter\linebyline
\fi}

\def\linebylinepar#1{{%
\par
\finalhyphendemerits\z@
\clubpenalty\z@
\widowpenalty\z@
\def\sporindent{\hskip\parindent}%
\setbox\tw@\hbox{}%
\@firstofone{\expandafter\linebyline#1} \! \relax
\box\tw@
\par}}
\makeatother


\kantdef\zz{1}

\zz\bigskip\linebylinepar\zz


\begin{minipage}[t]{.27\textwidth}\zz\end{minipage}\qquad
\begin{minipage}[t]{.27\textwidth}\linebylinepar\zz\end{minipage}


\end{document}
share|improve this answer
    
This doesn't do hyphenation, though. –  egreg Sep 2 '13 at 22:09
    
@egreg yes it does! see line 3 and 4 of the narrow minipage for example –  David Carlisle Sep 2 '13 at 22:13
    
In the normal width example, rep- fits in the first line. –  egreg Sep 2 '13 at 22:26
1  
Suggestion for long answer: "nooooooooooooooooooooo". :) –  Paulo Cereda Sep 3 '13 at 11:31
1  
@pts still far from convinced you ever need this but I added two lines to fix the issue, see updated answer –  David Carlisle Feb 18 at 22:42

You can make TeX be not so fussy about consecutive visually incompatible lines, prefer hyphenation and be very tolerant about bad spacing.

\documentclass{article}
\usepackage{kantlipsum}

\begin{document}

\kant[1]

\adjdemerits=-1000000 % demerits for consecutive visually incompatible lines
\hyphenpenalty=-5000  % penalty added for hyphenating
\doublehyphendemerits=-1000000 % demerits for consecutive hyphens
\tolerance=10000 % bad lines are OK

\kant[1]

\end{document}

enter image description here


Here is another attempt. The third paragraph has been split manually with the “greedy” approach, taking into account \righthyphenmin=3.

\documentclass{article}
\usepackage{kantlipsum}

\begin{document}

\kant[1]

\adjdemerits=0 % don't be fussy about consecutive visually incompatible lines
\hyphenpenalty=-5000 % prefer hyphenation
\doublehyphendemerits=-1000000 % consecutive hyphens are OK
\tolerance=50 % be strict as regards to spacing
\linepenalty=9999 % as few lines as possible

\kant[1]

\newcommand{\aline}[1]{\hbox to \textwidth{#1}}

\aline{\indent As any dedicated reader can clearly see, the Ideal of practical reason is a rep-}
\aline{resentation of, as far as I know, the things in themselves; as I have shown else-}
\aline{where, the phenomena should only be used as a canon for our understanding.}
\aline{The paralogisms of practical reason are what first give rise to the architectonic of}
\aline{practical reason. As will easily be shown in the next section, reason would}
\aline{thereby be made to contradict, in view of these considerations, the Ideal of prac-}
\aline{tical reason, yet the manifold depends on the phenomena. Necessity depends on,}
\aline{when thus treated as the practical employment of the never-ending regress in the}
\aline{series of empirical conditions, time. Human reason depends on our sense percep-}
\aline{tions, by means of analytic unity. There can be no doubt that the objects in}
\aline{space and time are what first give rise to human reason.\hfill}

\end{document}

enter image description here

The first four lines agree, then TeX's algorithm takes on.

share|improve this answer
    
This is a great answer, but it's a bit too drastic when working with smaller \linewidths. Consider \parbox{6cm}{\hyphenpenalty=-5000\adjdemerits=-1000000\doublehyphendemerits=-10‌​00000\tolerance=10000\lipsum[1]} (Oddly, the same does not happen for \kant[1].) –  Sean Allred Sep 2 '13 at 16:39
    
don't you want the demerits to be 0 so you just tolerate rather than encourage incompatible lines? –  David Carlisle Sep 2 '13 at 16:43
    
@DavidCarlisle Setting the demerits to 0 doesn't seem to have quite enough difference—only one hyphenation is added. –  Sean Allred Sep 2 '13 at 16:45
    
@SeanAllred but that's part of the problem with the whole approach rather than compare Tex to a typical word processor you have to compare tex to tex with settings where tex is not only not trying to optimise over the whole paragraph, it is trying to make things as bad as possible (over the whole paragraph) so it won't surprise anyone to find that the default tex settings make a better appearance. –  David Carlisle Sep 2 '13 at 16:48
    
@DavidCarlisle I agree with you that no setting of the parameters will do as wanted and this can only be done manually. –  egreg Sep 2 '13 at 16:54

fit as much as you can onto one line, hyphenating if necessary, justify, and then move to the next line.

Here is a solution that completely ignores the hyphenation rules, and hyphenates as soon as the the line is full.

\def\greedybreak#1{#1\ifx#1\blankspace\else\discretionary{-}{-}{}\fi}

\setuppapersize[A5]

\showframe
\starttext

\input ward

\bgroup
\setupalign[normal,verytolerant,stretch]
\handletokens 
The Earth, as a habitat for animal life, is in old age and
has a fatal illness. Several, in fact. It would be happening
whether humans had ever evolved or not. But our presence is
like the effect of an old-age patient who smokes many packs
of cigarettes per day---and we humans are the cigarettes.
\with \greedybreak
\endgraf
\egroup
\stoptext

which gives

enter image description here

And here is the result with a slightly different test file.

enter image description here

The algorithm can be made slightly smarter so as not to hyphenate before punctuation :) (and using the \dicretionary command correctly; for now I'll leave the images with hyphen at the beginning of the line as well).

share|improve this answer
1  
Super cool!! Is this answer ConTeXt-specific? –  Sean Allred Sep 3 '13 at 19:37
    
You can copy the definition of \handletokens from ConTeXt. The \setupalign part is just a wrapper around internal TeX macros (but much easier to remember!), so it should not be difficult to translate it into plain TeX or LaTeX. –  Aditya Sep 3 '13 at 23:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.