4

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.

3 Answers 3

3

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.

2
  • 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, 2010 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. Aug 26, 2010 at 21:10
0

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).

4
  • 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, 2010 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? Aug 26, 2010 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. Aug 26, 2010 at 19:26
  • I clarified the problem a bit in an edit to the question (see above).
    – ESultanik
    Aug 26, 2010 at 20:59
-1

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

3
  • 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... Aug 26, 2010 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, 2010 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, 2010 at 19:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .