[Tex/LaTex] truncate text from right to left

text manipulation

I would like to have a command that truncates text like

'An example sentence.'

to

'…ple sentence.'.

When called like this

\truncateToLeft{4cm}{An example sentence.}

I have no idea how to implement that (I do not understand /usr/share/texmf-dist/tex/latex/truncate/truncate.sty).

Edit: A (VERY MINOR) thing I noticed with the answers below, is that the text is not cut at 'letter-borders'. Just to ask (I'm no (La)TeX-Expert): Is it possible to cut the text at 'letter-borders'? –> This is solved by Steven B. Segletes second answer!

Best Answer

Just for fun, here is another way. While not specified in meaning, I took your length in argument #1 to be the length that remains, rather than the length that is clipped.

THIS ANSWER HAS TWO PARTS: the first answer clips the string mid-character to the specified length; and the second answer clips to the nearest character boundary inside the specified length (while allowing font declarations in the text).

PART 1

The solution relies on the fact that \ldots is wider than any single character. The approach is to recursively strip off letters from the beginning of the sentence, until the result is less wide than the target width. Then, after an \ldots, one takes the prior result (which is just slightly larger than the target width, and sets it in a right-aligned box of the target width. This will make the extra portion of the left-most character overlap the right end of the \ldots. To take care of this small mismatch, the \ldots are again lapped to the left in a white colorbox, to get rid of the overhang.

Finally, the result is re-kerned to the right to bring you to the end of the printed result (this last phase was an EDIT, upon realizing that I left the current position too far to the left.

EDITED to streamline code and remove a pathological case if null argument was passed to \clip.

\documentclass{article}
\usepackage{xcolor}
\newlength\cliplength
\newcommand\clip[2]{\setlength\cliplength{#1}\cliphelper#2\relax\relax}
\def\cliphelper#1#2\relax{%
  \fboxsep 0pt%
  \setbox0=\hbox{#2}%
  \ifdim\wd0>\cliplength%
    \cliphelper#2\relax%
  \else%
    \setbox0=\hbox{#1#2}%
    \ldots\makebox[\cliplength][r]{\box0}%
    \kern-\cliplength\llap{\colorbox{white}{\strut\ldots}}%
    \kern\cliplength%
  \fi%
}
\parindent 0in
\begin{document}
\ldots\rule{1cm}{1pt}

\clip{1cm}{An example sentence.}

\ldots\rule{2cm}{1pt}

\clip{2cm}{An much longer example sentence.}

\ldots\rule{3cm}{1pt}

\clip{3cm}{An much longer example sentence.}

\end{document}

enter image description here


PART 2

The OP later wondered if the clipping could occur at letter boundaries. That problem is actually easier, can be done without xcolor, and requires but a small change in my routine \cliphelper. In this case, once the test string becomes less wide than the target clip width, I just set \ldots and the test string. Here is the MWE which will clip to the closest letter boundary that is at or slightly smaller than the target clipping width:

REEDITED to support font size/shape declaration macros (that don't take arguments).

\documentclass{article}
\newlength\cliplength
\newcommand\clip[2]{%
  \def\savedmacro{}\setlength\cliplength{#1}\cliphelper#2\relax\relax}
\def\cliphelper#1#2\relax{%
  \setbox0=\hbox{\savedmacro#2}%
  \ifdim\wd0>\cliplength% Is length larger than \cliplength?
    \savethemacros{#1}{#2}% If #1 is a macro, save it
    \cliphelper#2\relax% Recursively clip next letter
  \else%
    \ldots\savedmacro#2% Final typeset, once string length below \cliplength
  \fi%
}
\makeatletter
\def\savethemacros#1#2{%
  \ifcat A\noexpand#1\else\ifcat 1\noexpand#1\else% Skip cat11 and cat12
      \protected@edef\savedmacro{\savedmacro#1}% Save the macro
  \fi\fi%
}
\makeatother
\begin{document}
\ldots\rule{1cm}{1pt}\par
\clip{1cm}{An example sentence.}

\ldots\rule{2cm}{1pt}\par
\clip{2cm}{An much longer example sentence.}

\ldots\rule{3cm}{1pt}\par
\clip{3cm}{An much longer example sentence.}

\ldots\rule{1cm}{1pt}\par
\clip{1cm}{An \bfseries\itshape example sentence.\normalfont}

\ldots\rule{2cm}{1pt}\par
\clip{2cm}{An much longer example \bfseries sentence\normalfont.}

\ldots\rule{3cm}{1pt}\par
\clip{3cm}{\large An much \itshape longer example \bfseries\tiny sentence\normalfont.}

\end{document}

enter image description here