10

Below is my minimum working example:

\documentclass[10pt,a4paper,draft]{article}
\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{lipsum}
\begin{document}
Thisisaverylongtexttosimulateerror “firstterm*[title/abstract] AND (secondterm*[title/abstract] OR thirdterm*[title/abstract])” \lipsum[2]
\end{document}

And this is the output:
enter image description here

I tried using the hyphenat package with the \fshyp command to hyphenate the word at the forward slash, but this adds a hyphen as well, which I don't want. How do I break the word either at the * or at the / without adding a hyphen?

1

3 Answers 3

11

Manual Solution:

You could also do it manually, by inserting a \BreakableChar at the appropriate points:

Thisisaverylongtexttosimulateerror “firstterm*[title/abstract] AND 
(secondterm*\BreakableChar{}[title/abstract] OR thirdterm*[title/abstract])”

One small complication here is that I have defined \BreakableChar with an optional parameter, and since your subsequent text begins with a [, it necessitated the use of {}.

Automated Solution:

You could adapt the solution from Automatic line breaking of long lines of text too automatically insert a breakable char at the points where you want it. To use this just pass the entire string to \AddBreakableChars{}:

Thisisaverylongtexttosimulateerror “firstterm*[title/abstract] AND 
\AddBreakableChars{(secondterm*[title/abstract]} OR thirdterm*[title/abstract])”

The current definition of it will insert a \BreakableChar following any * or \ . This can be extended to apply to additional characters as well. I have also shown in commented code what to do for cases where there is a character where you want to break and do want to insert a hyphen.

Results:

Here is the original text followed by the text where the term is given to the automated, \AddBreakableChars{} macro, and the one with a \BreakableChar manually inserted at the appropriate point:

enter image description here

Code:

\documentclass{article}

\usepackage{showframe}
\usepackage{hyphenat}
\usepackage{xstring}
\usepackage{forloop}

\newsavebox\MyBreakChar%
\sbox\MyBreakChar{}% char to display the break after non char
\newsavebox\MySpaceBreakChar%
\sbox\MySpaceBreakChar{\hyp}% char to display the break after space
\makeatletter%
\newcommand*{\BreakableChar}[1][\MyBreakChar]{%
  \leavevmode%
  \prw@zbreak%
  \discretionary{\usebox#1}{}{}%
  \prw@zbreak%
}%
\makeatother

\newcounter{index}%
\newcommand{\AddBreakableChars}[1]{%
  \StrLen{#1 }[\stringLength]%
  \forloop[1]{index}{1}{\value{index}<\stringLength}{%
    \StrChar{#1}{\value{index}}[\currentLetter]%
    \IfStrEqCase{\currentLetter}{%
        % All the characters where you don't want hypen
        {*}{\currentLetter\BreakableChar[\MyBreakChar]}%
        {/}{\currentLetter\BreakableChar[\MyBreakChar]}%
        % All the charactes where a break should have a hypen
        %{ }{\currentLetter\BreakableChar[\MySpaceBreakChar]}%
    }[\currentLetter]%
  }%
}%

\begin{document}
\noindent\textbf{Original Text}:
\par\noindent
Thisisaverylongtexttosimulateerror “firstterm*[title/abstract] AND 
(secondterm*[title/abstract] OR thirdterm*[title/abstract])”

\medskip
\noindent\textbf{Use automated} \verb|\AddBreakableChars|:
\par\noindent
Thisisaverylongtexttosimulateerror “firstterm*[title/abstract] AND 
\AddBreakableChars{(secondterm*[title/abstract]} OR thirdterm*[title/abstract])”

\medskip
\noindent\textbf{Use manual} \verb|\BreakableChar|:
\par\noindent
Thisisaverylongtexttosimulateerror “firstterm*[title/abstract] AND 
(secondterm*\BreakableChar{}[title/abstract] OR thirdterm*[title/abstract])”
\end{document}
2
  • Thank you for your excellent answer; it works! I am using your manual solution although I don't understand a thing from your macro :) Thanks for the showframe package too (which I hadn't seen before).
    – ilakast
    May 1, 2012 at 21:04
  • Thank you. Who would not need this? Why don't we have a package for it? I've made a repo with a .sty for it: github.com/white-gecko/hyphenathack.sty Oct 25, 2019 at 12:48
5

I know this is an old thread, but just in case:

If you use \slash{} instead of / a break can occur after the slash.

By analogy we could define \sta based on Peter Grill's code above:

\newsavebox\MyBreakChar%
\sbox\MyBreakChar{}% char to display the break after non char
\newsavebox\MySpaceBreakChar%
\sbox\MySpaceBreakChar{\hyp}% char to display the break after space
\makeatletter%
\newcommand*{\BreakableChar}[1][\MyBreakChar]{%
  \leavevmode%
  \prw@zbreak%
  \discretionary{\usebox#1}{}{}%
  \prw@zbreak%
}%
\makeatother
\newcommand{\sta}{*\BreakableChar{}}

This would be handy if you're used to using \slash in terms where you do want it to break.

2

one possibility is that the "word" that overflows the margin can't be hyphenated in the most desirable place. in this example, that happens to be true -- "secondterm" is hyphenated by tex only as "sec-ondterm". adding this command

\hyphenation{sec-ond-term}

to the preamble will provide another hyphenation possibility.

i also don't see that you've selected a language, so it's possible that no hyphenation patterns are being called on. but i don't think that's the problem, because if you specify \begin{sloppypar} ... \end{sloppypar} as a wrapper to the paragraph, it does indeed hyphenate as "sec-ondterm".

this won't work with non-letter strings, but you can check the letter strings you do have for acceptable hyphenation points by running tex with these commands:

tex
\relax
\showhyphens{secondterm and other words to be looked at}
\bye

then you can add your own \hyphenation{...} exceptions.

1
  • Thank you for your contribution, but maybe my minimum working example needs clarification: the words 'firstterm', 'secondterm' and 'thirdterm' are not the ones that I need to break, because in my actual document these are proper words that tex knows to hyphenate. It's the symbols * or / that I need the line break to happen.
    – ilakast
    May 1, 2012 at 21:23

You must log in to answer this question.

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