Difference between revisions of "Cropping text"

From Wiki
Jump to navigation Jump to search
(add link to \startTEXpage)
(10 intermediate revisions by 4 users not shown)
Line 2: Line 2:
  
 
== Cropping text ==
 
== Cropping text ==
There are some rare cases in which it is useful to crop a given
+
There are some rare cases in which it is useful to truncate a line of text and discard some of it.
text line and loose part of its information.
 
  
 
=== <tt>\doboundtext</tt> ===
 
=== <tt>\doboundtext</tt> ===
Line 20: Line 19:
  
 
<texcode>
 
<texcode>
\doboundtext{My entire inheritance goes to my beloved cat Pussy!}{70mm}{...}
+
\doboundtext{My entire inheritance goes to my beloved cat Pussy!}{60mm}{...}
 
</texcode>
 
</texcode>
  
Line 26: Line 25:
  
 
<context>
 
<context>
\doboundtext{My entire inheritance goes to my beloved cat Pussy!}{70mm}{...}
+
\ss\x\doboundtext{My entire inheritance goes to my beloved cat Pussy!}{60mm}{...}
 
</context>
 
</context>
 
  
 
=== <tt>\limitatetext</tt> ===
 
=== <tt>\limitatetext</tt> ===
Line 38: Line 36:
 
\limitatetext {text}  {width} {sentinel}
 
\limitatetext {text}  {width} {sentinel}
 
\limitatetext {text} {-width} {prelude}
 
\limitatetext {text} {-width} {prelude}
 +
\limitatetext {text} {width1 , width2} {symbol}
 
</texcode>
 
</texcode>
  
 
When no <tt>width</tt> is given, the whole <tt>text</tt> becomes available.
 
When no <tt>width</tt> is given, the whole <tt>text</tt> becomes available.
 
A negative value crops the beginning and the text starts with
 
A negative value crops the beginning and the text starts with
the <tt>prelude</tt>. Sentinel and prelude are optional.
+
the <tt>prelude</tt>. Sentinel and prelude are both optional.
 +
Just look at the example, to see what happens, if you call the macro with
 +
two positive dimensions...
  
 
Example:
 
Example:
  
 
<texcode>
 
<texcode>
\limitatetext {Pussy is the name of the cat!}{50mm}{...}\par
+
\limitatetext {Pussy is the name of the cat!}{38mm}{...}\par
\limitatetext {Pussy is the name of the cat!}{-50mm}{...}
+
\limitatetext {Pussy is the name of the cat!}{-38mm}{...}\par
 +
\limitatetext {Pussy is the name of the cat!}{12mm, 12mm}{...}
 
</texcode>
 
</texcode>
  
Line 54: Line 56:
  
 
<context>
 
<context>
\limitatetext {Pussy is the name of the cat!}{50mm}{...}\par
+
\limitatetext {\ss\x Pussy is the name of the cat!}{38mm}{...}\par
\limitatetext {Pussy is the name of the cat!}{-50mm}{...}
+
\limitatetext {\ss\x Pussy is the name of the cat!}{-38mm}{...}\par
 +
\limitatetext {\ss\x Pussy is the name of the cat!}{10mm, 10mm}{...}
 
</context>
 
</context>
  
Line 63: Line 66:
 
<tt>\underbar</tt> is possible), while <tt>\doboundtext</tt> works better
 
<tt>\underbar</tt> is possible), while <tt>\doboundtext</tt> works better
 
on text that cannot be hyphenated.
 
on text that cannot be hyphenated.
 
  
 
=== <tt>\limitatefirstline</tt> ===
 
=== <tt>\limitatefirstline</tt> ===
Line 72: Line 74:
 
so it shares the problem with nonbreakable text.
 
so it shares the problem with nonbreakable text.
 
But in contrast to <tt>\limitatetext</tt> it has a second mechanism, that is only used,
 
But in contrast to <tt>\limitatetext</tt> it has a second mechanism, that is only used,
if the prior one fails.
+
if the prior one fails or if the result of breaking is wasting too much space.
This fail safe mechanism "simply" clips (no breaking at all) the text to the disired
+
This fail safe mechanism "simply" clips (no breaking at all) the text to the desired
 
measures. This is done without any consideration to character boundaries.
 
measures. This is done without any consideration to character boundaries.
 
So you must live with the fact, that the last character can be cut off at any possible
 
So you must live with the fact, that the last character can be cut off at any possible
Line 86: Line 88:
 
<texcode>
 
<texcode>
 
\limitatefirstline {\underbar{Mr.~Drofnats was happiest when he was at work%
 
\limitatefirstline {\underbar{Mr.~Drofnats was happiest when he was at work%
  typesetting beautiful documents.}{110mm}{\unknown}
+
  typesetting beautiful documents.}{109mm}{\unknown}
 
</texcode>
 
</texcode>
 +
  
 
<context>
 
<context>
 
\unprotect
 
\unprotect
 +
  
 
\def\limitatefirstline#1#2#3%
 
\def\limitatefirstline#1#2#3%
{\hbox\bgroup\strut
+
{\hbox\bgroup\strut\dontcomplain
\setbox\scratchbox\hbox{#1}%
+
  \setbox\scratchbox\hbox{\begstrut#1\endstrut}%
\ifdim\wd\scratchbox>#2\relax
+
  \ifdim\wd\scratchbox>#2\relax
  \setbox\scratchbox\hbox{#3}%
+
    \setbox\scratchbox\hbox{#3}%
  \hsize#2\relax
+
    \hsize#2\relax
  \advance\hsize-\wd\scratchbox
+
    \advance\hsize-\wd\scratchbox
  \setbox\scratchbox\vbox{\forgetall\veryraggedright#1}%
+
    \setbox\scratchbox\vbox{\forgetall\veryraggedright#1}%
  \setbox\scratchbox\vsplit\scratchbox to \lineheight
+
    \setbox\scratchbox\vsplit\scratchbox to \lineheight
  \vbox
+
    \vbox
    {\unvbox\scratchbox
+
      {\unvbox\scratchbox
      \global\setbox\plusone\lastbox
+
      \global\setbox\plusone\lastbox
      \global\setbox\plusone\hbox{\unhbox\plusone}%
+
      \global\setbox\plusone\hbox{\strut\unhbox\plusone}%
      \hbox to #2
+
      \hbox % to #2
        {\ifx\clip\undefined
+
        {\ifx\clip\undefined
          \box\plusone
+
            \box\plusone
        \else\ifdim\wd\plusone>\hsize
+
          \else\ifdim\wd\plusone>\hsize
          \clip[\c!width=\hsize,\c!height=\lineheight,\c!voffset=-4pt]{\box\plusone}%
+
            \lower\strutdepth\hbox{\clip[\c!width=\hsize,\c!height=\lineheight]{\hbox{\raise\strutdepth\box\plusone}}}%
        \else
+
          \else\ifdim\wd\plusone<\dimexpr\hsize-6ex\relax% tolerance for "successful" breaking
          \box\plusone
+
            \lower\strutdepth\hbox{\clip[\c!width=\hsize,\c!height=\lineheight]{\hbox{\raise\strutdepth\hbox{\begstrut#1\endstrut}}}}%
        \fi\fi
+
          \else
        \removeunwantedspaces\hss#3}}%
+
            \box\plusone
\else
+
          \fi\fi\fi
  #1%
+
          \removeunwantedspaces#3}}% \removeunwantedspaces\hss#3}}%
\fi
+
  \else
\egroup}  
+
    #1%
 +
  \fi
 +
  \egroup}
  
 
\protect
 
\protect
  
\limitatefirstline {\underbar{Mr.~Drofnats was happiest when he was at work typesetting beautiful documents.}}{110mm}{\unknown}
+
 
 +
\limitatefirstline {\ss\x\underbar{Mr.~Drofnats was happiest when he was at work typesetting beautiful documents.}}{107mm}{\unknown}
 
</context>
 
</context>
  
 +
 +
In this example breaking is successful (right after the word typesetting),
 +
but the gap between the breaking point and the given width is too big.
 +
So clipping is used here.
  
 
=== A direct comparison ===
 
=== A direct comparison ===
Line 148: Line 159:
 
|<context>\ss\x\limitatefirstline{\underbar{In a bar, under the sea}}{31mm}{...}</context>
 
|<context>\ss\x\limitatefirstline{\underbar{In a bar, under the sea}}{31mm}{...}</context>
 
|}
 
|}
 +
 +
== Fitting text ==
 +
You can fit text into a box by:
 +
 +
<texcode>
 +
\def\HowStrange#1{#1\ifx#1\blankspace\else\allowbreak\fi}
 +
 +
\framed
 +
[width=2cm,align={normal,verytolerant,stretch}]
 +
{\handletokens There are some rather long titles that needs to be typeset.\with\HowStrange}
 +
</texcode>
 +
 +
<context>
 +
\def\HowStrange#1{#1\ifx#1\blankspace\else\allowbreak\fi}
 +
 +
\framed
 +
[width=2cm,align={normal,verytolerant,stretch}]
 +
{\handletokens There are some rather long titles that needs to be typeset.\with\HowStrange}
 +
</context>
 +
 +
There is also similar facility for verbatim text in [[Verbatim_with_line_breaks]] section.
 +
 +
== See also ==
 +
 +
* If you meant to crop a page ''to'' some text, see {{cmd|startTEXpage}}
 +
 +
{{Getting started navbox}}

Revision as of 12:26, 14 September 2017

< Visuals |

Cropping text

There are some rare cases in which it is useful to truncate a line of text and discard some of it.

\doboundtext

Sometimes there is not enough room to show the complete (line of) text. In such a situation we can strip of some characters by using

\doboundtext {text} {width} {sentinel}

When the text is wider than the given width, it's split and the third argument (sentinel) is appended. As much text as possible is printed.

An example

\doboundtext{My entire inheritance goes to my beloved cat Pussy!}{60mm}{...}

and it's result

\limitatetext

A bit more beautiful alternative for the previous command is \limitatetext. This command takes care of word boundaries, so that only complete words will appear in the final (cropped) text.

\limitatetext {text}  {width} {sentinel}
\limitatetext {text} {-width} {prelude}
\limitatetext {text} {width1 , width2} {symbol}

When no width is given, the whole text becomes available. A negative value crops the beginning and the text starts with the prelude. Sentinel and prelude are both optional. Just look at the example, to see what happens, if you call the macro with two positive dimensions...

Example:

\limitatetext {Pussy is the name of the cat!}{38mm}{...}\par
\limitatetext {Pussy is the name of the cat!}{-38mm}{...}\par
\limitatetext {Pussy is the name of the cat!}{12mm, 12mm}{...}

leads to


Both commands have their range of application. \limitatetext is more robust (using grouping tokens like \underbar is possible), while \doboundtext works better on text that cannot be hyphenated.

\limitatefirstline

In ConTeXt versions newer than 07.09.2005 there is also a command called \limitatefirstline, which acts nearly like \doboundtext, but at a more robust level. This macro first tries to break the given text at character level. It uses nearly the same breaking mechanism as \limitatetext, so it shares the problem with nonbreakable text. But in contrast to \limitatetext it has a second mechanism, that is only used, if the prior one fails or if the result of breaking is wasting too much space. This fail safe mechanism "simply" clips (no breaking at all) the text to the desired measures. This is done without any consideration to character boundaries. So you must live with the fact, that the last character can be cut off at any possible place.

\limitatefirstline {text} {width} {sentinel}

Example:

\limitatefirstline {\underbar{Mr.~Drofnats was happiest when he was at work%
 typesetting beautiful documents.}{109mm}{\unknown}



In this example breaking is successful (right after the word typesetting), but the gap between the breaking point and the given width is too big. So clipping is used here.

A direct comparison

It's all in the garden. 0123456789 \underbar{In a bar, under the sea}
\doboundtext not possible
\limitatetext
\limitatefirstline

Fitting text

You can fit text into a box by:

\def\HowStrange#1{#1\ifx#1\blankspace\else\allowbreak\fi}

\framed
 [width=2cm,align={normal,verytolerant,stretch}]
 {\handletokens There are some rather long titles that needs to be typeset.\with\HowStrange}

There is also similar facility for verbatim text in Verbatim_with_line_breaks section.

See also

Template:Getting started navbox