6

I have data (generated from a database, not manually typed in) that mostly fits into a table cell with fixed width, but sometimes overflows because there are long words for which no hyphenation is found.

The problem can be demonstrated with the following example:

\documentclass{article}
\usepackage[utf8]{inputenc}
\begin{document}
\begin{tabular}{|p{1cm}|p{4cm}|}
1 & Cell where normal hyphenation is possible ÄÖÜ \\
2 & CellwherenormalhyphenationisnotpossiblebutshouldwrapinsteadofoverflowÄÖÜ
\end{tabular}
\end{document}

My requirements are:

  1. Text never overflows the cell (assuming some minimum width such that at least a handful characters have place)
  2. First priority measure to achieve 1. is the normal hyphenation
  3. If 2. fails, it is allowed to break the word at any character, so fill the line and break just before overflow would happen (disregarding normal hyphenation rules)

In the example, the overflow in cell 1 is prevented by measure 2., the normal hyphenation. The second cell overflows. I would like to have this cell treated by measure 3.

For the answer please consider:

  • Package seqsplit didn't help me
  • The custom macro \wrap proposed in the answer to seqsplit - keep spaces comes near my wish, but can't handle the non-ascii characters ÄÖÜ (independent if they are input with utf8 input encoding or with \"A\"O\"U)
  • As the text comes from a database, no manual editing of the cell content is wanted.

One of my ideas was to insert \linebreak[0] after every character, to tell LaTeX that a break can be made if no better opportunities exist. But this doesn't work like intended.

Thanks for your suggestions!

1
  • I suspect you need to play with the penalties and glue. Oct 14, 2014 at 15:39

2 Answers 2

4

You can make a trial setting , see if you have any over large boxes, then if so loop through character by character adding \penalty0 and re-set.

enter image description here

\documentclass{article}
\usepackage[utf8]{inputenc}
\makeatletter
\def\foo#1{%
\setbox0\vbox{%
\global\let\foonext\foohyph
\hbadness\maxdimen
\hfuzz\maxdimen
#1\par
  \loop
  \unskip\unpenalty\unskip\unpenalty
  \setbox\z@\lastbox
  \ifvoid\z@
  \else
   \setbox\z@\hbox{\unhbox\z@}%
   \ifdim\wd\z@>\dimexpr\hsize+4pt\relax% compensate for hfuzz and not checking for shrink
    \global\let\foonext\foowrap
   \fi
  \repeat}%
\foonext{#1}%
}
\def\foohyph#1{#1}
\def\foowrap#1{\foowrap@#1\foowrap@}

\def\foowrap@{\futurelet\tmp\foowrap@@}

\def\foowrap@@{%
\let\next\relax
\ifx\tmp\foowrap@
\let\foowrap@\relax
\else\ifx\tmp\lbrace
\else\ifx\tmp\@sptoken
\let\next\foowrap@sp
\else\ifcat\noexpand\tmp\active% only active character utf8 chars
\let\next\foowrap@aa
\else
\let\next\foowrap@a
\fi\fi\fi\fi
\next
}

\def\foowrap@sp{\afterassignment\foowrap@\let\tmp= }

\def\foowrap@a#1{%
\leavevmode\penalty\z@#1\foowrap@}

\def\foowrap@aa#1#2{%
\leavevmode\penalty\z@#1#2%
\foowrap@}
\makeatother

\begin{document}
\begin{tabular}{|p{1cm}|p{4cm}|}
1 & \foo{Cell where normal hyphenation is possible ÄÖÜ}\\
2 & \foo{CellwherenormalhyphenationisnotpossiblebutshouldwrapinsteadofoverflowÄÖÜ}
\end{tabular}




\end{document}
1

You can use \text_map_inline:nn that respects Unicode characters.

\documentclass{article}
\usepackage[T1]{fontenc}

\newcommand{\breakandspace}{%
  \nobreak
  \hspace{0pt plus 1fil}% add a filling space
  \allowbreak
  \hspace{0pt plus -1fil}% remove the filling space
}

\ExplSyntaxOn
\NewDocumentCommand{\longcell}{m}
 {
  \text_map_inline:nn { #1 } { ##1\breakandspace }
  \unskip\unpenalty\unskip\unpenalty
 }
\ExplSyntaxOff

\begin{document}
\begin{tabular}{|p{1cm}|p{4cm}|}
1 & Cell where normal hyphenation is possible ÄÖÜ \\
2 & \longcell{CellwherenormalhyphenationísnotpossiblébutshöuldwrapinsteadofoverflowÄÖÜ}
\end{tabular}
\end{document}

enter image description here

(See history for an older answer)

You must log in to answer this question.

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