22

I need to format extremely long strings of text. I would like to be able to specify their width, and have them wrap, with or without some special symbol to indicate that the line is wrapped. The problem is, however, that these strings do not contain any spaces. Here's an example of what I would like:

\foo{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}

So I would like to get an hbox containing this long number, but spanning several lines, so that I get a rectangle 2in wide.

Does anyone know of a package/trick/macro that does this?

1
  • Welcome to tex.sx! A tip: If you indent a line by 4 spaces, then it's marked as a code sample. Nov 29, 2010 at 19:17

5 Answers 5

17

You may try the seqsplit package.

5
  • 2
    Nice! There was bound to be a package that does it; I'd never heard of seqsplit before. For completeness I add a compilable example in a separate answer (hope you don't mind). Nov 30, 2010 at 13:10
  • I tend to give the user some credit for basic intelligence. The package is very easy to handle. In case of problems I'm sure we will see follow-ups. Dec 1, 2010 at 17:02
  • 4
    Agreed, it's very easy. Nevertheless, if one has time to post it, then some code for copy and paste is always nice. (By the way, if you had used "@Hendrik" in your comment, then I'd found it much earlier.) Dec 13, 2010 at 19:03
  • Just click the envelope symbol on the left of your name at the top of the page when logged in to get new replies. Furthermore I know when it is suggestive to post code. Trying to rule others how to post is not a good idea. Dec 17, 2010 at 22:25
  • 4
    Just found your comment. (Again, as I said, if you had used "@Hendrik", then I'd found it much earlier. I do know about the (now gone) envelope and the inbox, but they rely on the use of "@"!) Concerning posting code: I'm not trying to rule others, I'm just suggesting that it's nice to post code. I've actually upvoted your answer a long time ago since it is very useful (and my suggestion was about how to make it even more useful). Mar 17, 2011 at 9:36
13

Something along these lines perhaps:

\def\breaknumberanywhere{\hskip0pt\futurelet\next\breaknumberi}
\def\breaknumberi{\ifcat\next9\expandafter\breaknumberii\fi}
\def\breaknumberii#1{#1\breaknumberanywhere}

\def\foo#1#2{\vtop{\hsize=#1\rightskip=0pt plus 1fil \leftskip=0pt
  \noindent\breaknumberanywhere#2}}

Here is a long number:
\foo{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}
\bye

(Edited to become a minimal working example, as requested in a comment. LaTeXifization left to the interested reader. I also set \leftskip in order to make \foo a bit more robust.)

11
  • Nice! Could you make an MWE out of that? One possible simplification: Replace \discretionary{}{}{} with \hskip0pt or \hspace{0pt}. (I just wanted to post an answer, too, but mine was very inefficient.) Nov 29, 2010 at 18:42
  • I've been looking for a good example that explains \futurelet; this might be it. Nov 29, 2010 at 18:59
  • @Hendrik: What is an MWE? Nov 29, 2010 at 19:07
  • @Harald: Oops, sorry: Minimal working example, i.e., a code that compiles as is. Nov 29, 2010 at 19:13
  • Okay, MWE provided. Nobody said I couln't use plain TeX. Oh, and I changed the \discretionary into \hskip. Good suggestion; thanks. Nov 29, 2010 at 19:27
13

Thorsten told you what package to use; just for completeness I give a compilable example:

\documentclass{article}
\usepackage{seqsplit}
\newcommand\foo[2]{%
    \begin{minipage}{#1}
    \seqsplit{#2}
    \end{minipage}
    }
\begin{document}
\foo{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}
\end{document}
6

A general solution with expl3; the command \foo has an optional argument that can be any character or box to mark the splitting point. With varwidth we round the box width to what is really necessary.

\documentclass{article}
\usepackage{varwidth}
\usepackage{xparse}

\setlength{\parindent}{0pt} % just for the example

\ExplSyntaxOn

\NewDocumentCommand{\foo}{ O{} m m }
 { 
  % some setup for the particular problem
  \begin{varwidth}[t]{#2}
  % some padding on the right
  \skip_set:Nn \rightskip { 0pt plus .5em }
  % just in case
  \skip_set:Nn \leftskip { 0pt }
  % a strut to set the first row height
  \strut

  % the main routine
  \mayer_foo:nnn { #1 } { #2 } { #3 }

  % finish off with a strut (attached from the last digit)
  \strut
  \end{varwidth}
 }

\seq_new:N \l_mayer_input_seq

\cs_new_protected:Npn \mayer_foo:nnn #1 #2 #3
 {
  % split the input into pieces
  \seq_set_split:Nnn \l_mayer_input_seq { } { #3 }

  % between any two pieces insert a discretionary
  \seq_use:Nn \l_mayer_input_seq { \discretionary{#1}{}{} }
 }

\ExplSyntaxOff

\begin{document}

\rule{2in}{0.4pt}

\foo{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}

\foo[-]{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}

\foo[*]{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}

\bigskip
The box doesn't take more than the stated space\\
(but it can be slightly less wide)

\medskip

\fbox{\foo{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}}


\end{document}

enter image description here

For completeness, a version where the normal text width is used, without boxing.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\foo}{ O{} m }
 {% #1 = discretionary, #2 = number to split
  \mayer_foo:nn { #1 } { #2 }
 }

\cs_new_protected:Nn \mayer_foo:nn
 {
  \tl_map_inline:nn { #2 }
   {
    ##1 \nobreak\hspace{0pt plus 0.1pt}\discretionary{#1}{}{}
   }
 }

\ExplSyntaxOff

\begin{document}

\noindent
\foo{
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
}

\noindent
\foo[-]{
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
}

\noindent
\foo[\hbox{$*$}]{
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
  17823 94123 74908 12347 12390 47123 89407 12340 89172 34890 
  12374 89120 34712 98571 23890 12351 12374 89120 34712 98571
}

\end{document}

enter image description here

The example shows that if the discretionary to be used is something more complex than a character, it should be enclosed in \hbox.

4

This is a very old post. I am adding one solution, thinking that this answer may be helpful for any one who arrives here:

\documentclass{article}
\begin{document}

\makeatletter
\def\foo#1#2{%
  \parbox{#1}{\strut\@tfor\xx:=#2\do{%
    \xx\linebreak[0]%
  }\strut}%
}

\foo{2in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}

\foo{3in}
{17823941237490812347123904712389407123408917234890123748912034712985712389012351}
\end{document}

You must log in to answer this question.

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