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.

While attempting to answer this question, I re-read Chapter 14 of The TeX Book (on how TeX breaks paragraphs into lines). It got me thinking: Is there a way to restrict the length of a string of text while still allowing that text to be broken across lines? For example, let's say I want to typeset "Lorem Ipsum Dolor" and I want it to be exactly 3cm in length. I could do \hbox to 3cm{Lorem Ipsum Dolor} (with an optional \hfill at the end if I just want to pad the extra length with whitespace). The problem with that is that the \hbox will not be broken across lines. Is there a way to do something similar while allowing for line breaks? In other words, I would be okay with "Lorem Ipsum" being at the end of one line and "Dolor" being at the begging of the next, as long as their total length equals 3cm.

Edit: I don't think I was very clear about for what I'm looking. Consider the line "Ut fermentum pharetra lacus, id ornare dolor pretium tempor" in this example:

Line break example

In this example, that sentence was broken over two lines. I want to be able to explicitly set the total length of the "Ut fermentum..." sentence, regardless of how it is broken across lines. In this example, I might want the sum of the lengths of s_1 and s_2 to be equal to, say, 5in. This could be accomplished by adding glue between words or padding the end with glue. This is easy to do if we know that there will be no line breaks in the string; we can then use either \hbox spread 5in{} or \hbox to 5in{}. The problem occurs when a line break does occur in the string, since the \hbox method would likely force the string to be on a single line. Furthermore, if the natural length of the string is greater than \textwidth, then the \hbox would overfill.

share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

The answer to the question as posted is a bit fuzzy

  • Spaces tend to have a glue component that makes predicting their actual width rather hard unless you remove the glue by using \spaceskip & \xspaceskip

  • Do you really mean 'restrict' or do you mean 'expand'? If there is too much text for 3cm, there is no way to meet the requirements.

  • The three words, when on one line, will have two intermediate spaces. When on two lines, there will be only one space. It will be quite difficult to make sure the total used space in both cases is identical (in fact, I no idea how to do that in TeX82).

  • Do you really want the extra room to be filled with \hfill?

Anyway, you could try something like this:

\newdimen\mydimen
\mydimen=3cm
\setbox0=\hbox {Lorem Ipsum Dolor}\advance\mydimen-\wd0 \unhbox0\hskip\mydimen

which may or may not give you something that is exactly 3cm, depending on the rest of the paragraph.

A much more precise solution would be possible using node processing in LuaTeX, but there are not that many hooks in TeX82's line breaking routine that can really alter its behaviour.

share|improve this answer
    
I forgot about \unhbox; that may be useful! I'll play around with it. Also, I clarified the problem a bit in an edit to the question, above. –  ESultanik Aug 26 '10 at 20:58
    
Because of the disappearing space problem, I think you can't solve this problem in the original TeX. I think you could achieve this effect in multiple passes with pdftex's \pdfsavepos by saving location data to an auxiliary file. –  Taco Hoekwater Aug 26 '10 at 21:10
add comment

I think perhaps you want the simple \parbox{width}{text} command.

share|improve this answer
    
Is \parbox a TeX command? I know it's a LaTeX command, but I checked the index of The TeX Book and the command does not appear. The question is tagged tex-core... –  Arturo Magidin Aug 26 '10 at 18:49
    
Nope, it's LaTeX. However, I guess you can lave a look at latex.ltx and see how it's done :-) –  Joseph Wright Aug 26 '10 at 18:53
    
LaTeX solutions are okay. The problem with \parbox, though, is that it would break its own lines. I want the line breaks to occur at the right margin, as normal. –  ESultanik Aug 26 '10 at 19:03
add comment

One simple (though perhaps heavy-handed) solution, also in Chapter 14 (page 101, the last "dangerous curve" paragraph), is to use \parshape; to summarize, \parshape=n where n is a nonnegative integer, followed by 2n dimension specifications, \parshape=n i1 l1 i2 l2 ... in ln produces a paragraph whose first n lines have lengths l1, l2, ..., ln, and will be indented from the left margin by the amounts i1, ..., in. If you have fewer than n lines the other specifications are ignored, if you have more then the specifications will be repeated. You can cancel the effect by saying \parshape=0.

So to get a paragraph with lines 3cm long, you should be able to do \parshape=1 0 3cm and then type away (replacing the 0 would indent it some).

share|improve this answer
    
I had considered using \parshape, but I don't think it will do exactly what I want. I'd like the entire paragraph to be fully justified as normal; I just want to restrict the lengths of strings of text within the paragraph. I still want each of the lines of text to be \textwidth wide. –  ESultanik Aug 26 '10 at 19:06
    
I'm not sure I understand this at all; if the line will be \textwidth wide, then how can it also be three centimeters wide? Or how are you measuring lengths of a string of text before putting it into a line that is \textwidth wide? Is what you want to take, say, the result of a \parbox or \parshape command, and then stretch it to the usual \textwidth length? –  Arturo Magidin Aug 26 '10 at 19:10
    
Wait... is what you want something like "you can only add the following text here if its length is at most xxx"? What would you want to happen if the text you want is longer than the length you want to specify? If this is what you want, you could first stick it in an hbox, and then compare the dimension with the specified quantity using \ifdim. –  Arturo Magidin Aug 26 '10 at 19:26
    
I clarified the problem a bit in an edit to the question (see above). –  ESultanik Aug 26 '10 at 20:59
add comment

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.