8

I use a modified version of the TikZ-solution in another question to draw rounded rectangles around some text to mark it as a button of a program. It's no problem for single characters, but if I use longer terms (as the buttons are named in my program) I get problems with Overfull \hboxes.

MWE:

\documentclass[a4paper,10pt]{scrartcl}
\usepackage{tikz}

\newcommand*\rectangled[1]{\tikz[baseline=(char.base)]{
    \node[shape=rectangle,draw,inner sep=2pt, rounded corners=4pt, thick] (char) {\sffamily{#1}};}}

\begin{document}
  A rectangled number \rectangled{1}: No problem normally as it is used as normal charakter and TeX can set it in the right position.

  A button with a longer name is marked using the same command and \rectangled{creates an Overfull \textbackslash hbox} if it is set to the end of a line.
\end{document}

The produced output looks like this: Output of MWE

Is there a better solution to avoid such Overfull \hboxes than rearrange the sentence until it produces no problem anymore?

DerJoshi
  • 128
  • 2
    what do you want to happen? Do you want linebreaking within the oval? If so, make two closed ovals, or two half open ovals or..... – David Carlisle Dec 09 '14 at 22:03
  • If possible I would like to avoid linebreaking, but I think that would produce odd spaces between words in the line before... But the idea with two half-opened ovals is good. But I guess an automatic solution would be difficult, right? – DerJoshi Dec 09 '14 at 22:11
  • Try to \usepackage{microtype}. – Astrinus Dec 09 '14 at 22:13
  • 2
    it's probably easy (if you know tikz better than I do) to let linebreaking happen as if the rectangle was not there if that is what you want but that makes more sense if the oval is a "highlight" than if it is a "button" If it is a button then breaking it probably doesn't make sense, but you could set the paragraph \raggedright to void overrunning the margin – David Carlisle Dec 09 '14 at 22:14
  • 1
    @Astrinus microtype can do a lot of things but it can't adjust the size of an unbreakable box. – David Carlisle Dec 09 '14 at 22:15
  • @DavidCarlisle But can adjust text surrounding the box, in order to avoid the overfull hbox. I'll give it a chance: I wrote "Try" in front of "use package", since it could not be useful. – Astrinus Dec 09 '14 at 22:37
  • 1
    Add \sloppy to your document or sloppypar to the paragraph. – Steven B. Segletes Dec 09 '14 at 23:53
  • @Astrinus microtype is already used in my document (not the MWE of course ;)), but unfortunatly doesn't help at this point. – DerJoshi Dec 10 '14 at 06:50
  • @DavidCarlisle As You said, linebreaking is not optimal, so for the moment, the variant of Steven with the sloppypar is my favourite – DerJoshi Dec 10 '14 at 06:54

2 Answers2

7

A sloppypar will momentarily allow you to overcome the problem. This problem arises for any oversized box that wants to be typeset at the end of a line.

The sloppypar feature (or \sloppy for the whole document) changes TeX's penalties to give more emphasis to avoiding margin overruns, at the expense of grossly wide interword spaces. There is no "free lunch."

\documentclass[a4paper,10pt]{scrartcl}
\usepackage{tikz}

\newcommand*\rectangled[1]{\tikz[baseline=(char.base)]{
    \node[shape=rectangle,draw,inner sep=2pt, rounded corners=4pt, thick] (char) {\sffamily#1};}}

\begin{document}
  A rectangled number \rectangled{1}: No problem normally as it is used as normal charakter and TeX can set it in the right position.

\begin{sloppypar}
  A button with a longer name is marked using the same command and \rectangled{creates an Overfull \textbackslash hbox} if it is set to the end of a line.
\end{sloppypar}
\end{document}

enter image description here

  • That was the command I had seen times before, but couldn't remember^^ I suspected a much worse result of word spacing than it looks now, so the option works for my present problem. – DerJoshi Dec 10 '14 at 06:57
5

Here is a version that allows for line breaks and uses an open rectangle on both parts. \tikzmark is used to mark the start and end of the text and the ovals are drawn after the text has been typeset:

enter image description here

Notes:

  • This does require two runs. First one to determine the locations, and the second to do the drawing.

  • This won't work if the text crosses page boundaries.

  • The value of \RoundedCorner can not be any larger that the current value of 2.0pt, otherwise end up with artifacts in the rounded corner. Perhaps a manually drawn arc could be used instead if a larger radius is desired.

  • The value of \InnerSep can be tweaked to adjust the additional horizontal spacing that is added before and after the text.

  • The \tikzmark is from Adding a large brace next to a body of text.

  • You can uncomment the showframe package to see the page margins.

Code:

\documentclass{article}

%\usepackage{showframe}% to see page boundaries

\usepackage{tikz,tikzpagenodes} \usetikzlibrary{decorations.pathreplacing}

\newcommand*{\InnerSep}{1pt}% Only applied to x directions \newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node[inner sep=0] (#1) {};}

%% https://tex.stackexchange.com/questions/33703/extract-x-y-coordinate-of-an-arbitrary-point-in-tikz \newdimen\XCoordA \newdimen\YCoordA \newdimen\XCoordB \newdimen\YCoordB \newcommand*{\ExtractCoordinate}[3]{\path (#3); \pgfgetlastxy{#1}{#2};}%

\newcommand*{\RoundedCorner}{2.0pt}% <-- MUST NOT BE ANY LARGER \tikzset{My Line Style/.style={rounded corners=\RoundedCorner, thick, blue}}

\newcommand\rectangled[2][]{% \tikzmark{Start Mark}#2\tikzmark{End Mark}% \begin{tikzpicture}[overlay,remember picture] \ExtractCoordinate{\XCoordA}{\YCoordA}{Start Mark} \ExtractCoordinate{\XCoordB}{\YCoordB}{End Mark} \ifdim\YCoordA=\YCoordB% Starts and ends on same line \draw[My Line Style,#1] ([shift={(-\InnerSep,-0.3\baselineskip)}]Start Mark.south east) rectangle ([shift={(\InnerSep,0.7\baselineskip)}]End Mark.north west) ; \else% Starts on a different line \coordinate (Right Hand Edge) at (Start Mark -| current page text area.east); \coordinate (Left Hand Edge) at (End Mark -| current page text area.west); \draw [My Line Style,#1]% Draw start of oval rectangle ([yshift=-0.3\baselineskip]Right Hand Edge) -| ([xshift=-\InnerSep]Start Mark.west) |- ([yshift=0.7\baselineskip]Right Hand Edge) ; \draw [My Line Style,#1]% Draw end of oval rectangle ([yshift=-0.3\baselineskip]Left Hand Edge) -| ([xshift=\InnerSep]End Mark.east) |- ([yshift=0.7*\baselineskip]Left Hand Edge) ; \fi% \end{tikzpicture}% }

\begin{document} A rectangled number \rectangled{1}, or \rectangled[magenta]{word}: No problem normally as it is used as normal character and TeX can set it in the right position.

A button with a longer name marked using the same command \rectangled[red]{used to create an Overfull \textbackslash hbox} if it was set to the end of a line.

A button with a even longer name \rectangled[brown]{no longer creates a Overfull \textbackslash hbox when it crosses a line} boundary. \end{document}

Peter Grill
  • 223,288
  • Great solution! Never managed to do this on my own... For other usage than my "buttons" really interesting, but for my momentary usage the answer of Steven fits better. – DerJoshi Dec 11 '14 at 10:43