4

I have already found some similar solutions, but I was not able to adapt them to my requirements:

  • A text fragment (e.g., source code) surrounded by other text should be highlighted with a background color. The background should have slightly rounded corners. A border for the background is nice to have, but not required.
  • We can assume, that the text fragment is never longer than a complete line. However, it might happen, that the text fragment does not fit in the remaining width of the current line. I hoped to find one of these solutions for the problem:
    1. As usual text the not fitting part of the text fragment is wrapped to the next line (desired output example: as in the 1st image below, but with rounded corners).
    2. LaTeX determines that the text fragment does not fit in the current line and automatically places the whole text fragment in the next line. Does not look so nice, because it is not perfectly justified anymore, but it is OK. (desired output example: as in the 2nd image below, but with rounded corners).

Related solutions:

Using the suggestions from the 1st link (via soul or via the complex solution) I can get this output. It is almost perfect, but has no rounded corners. This question tells me that it is probably not possible using soul. Any way to modify the other solution? enter image description here

Combining soul with the solution from the 3rd link works, but without rounded corners, either (\lword is defined in the 3rd link):

\newcommand{\inlinecode}[1]{{\lword{\sethlcolor{veryLightGray}\hl{\small\ttfamily#1}}}}

enter image description here

1
  • Could you add the code you used to make the tests? Nov 27, 2016 at 14:23

2 Answers 2

2

Here's an answer that gives oval highlighting with linebreaking by combining the rounded corners code and the soul linebreaking.

Edit: Added logic to not round the highlight around linebreaks.

\documentclass{article}
\parindent0pt
\usepackage{fullpage}
\usepackage{tikz}
\usepackage{soul}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes.misc}
\usetikzlibrary{fit}

\makeatletter
\newbox\mybox
\newcount\test
\test0
\newcommand{\defhighlighter}[3][]{%
    \tikzset{every highlighter/.style={color=#2, fill opacity=#3, #1}}%
}

\defhighlighter[font=\ttfamily]{blue!20}{.3}

\newcommand{\highlight@DoHighlight}[1]{
    \node[outer sep = -13pt, inner sep = 0pt,
        fit=(begin highlight) (end highlight),
        every highlighter, this highlighter,
        rounded rectangle,#1,
        fill
    ]{} ;
}

\newcommand{\highlight@BeginHighlight}[1]{
  \coordinate[yshift=-\dp\mybox-1pt,#1] (begin highlight) at (0,0) ;
}

\newcommand{\highlight@EndHighlight}[1]{
  \coordinate[yshift=\ht\mybox+1pt,#1 ] (end highlight) at (0,0) ;
}

\newdimen\highlight@previous
\newdimen\highlight@current

\DeclareRobustCommand*\highlight[2][]{%
  \setbox\mybox\hbox{#2}
  \tikzset{this highlighter/.style={#1}}%
  \SOUL@setup
  %
  \gdef\ht@possiblenoleftround{}
  \def\SOUL@preamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@BeginHighlight{xshift=3pt}
      \highlight@EndHighlight{xshift=-3pt}
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@postamble{%
    \begin{tikzpicture}[overlay, remember picture]
      \highlight@EndHighlight{xshift=-3pt}
      \expandafter\highlight@DoHighlight\expandafter{\ht@possiblenoleftround}
    \end{tikzpicture}%
  }%
  %
  \def\SOUL@everyhyphen{%
    \discretionary{%
      \SOUL@setkern\SOUL@hyphkern
      \SOUL@sethyphenchar
      \tikz[overlay, remember picture] \highlight@EndHighlight{} ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everyexhyphen##1{%
    \SOUL@setkern\SOUL@hyphkern
    \hbox{##1}%
    \discretionary{%
      \tikz[overlay, remember picture] \highlight@EndHighlight{} ;%
    }{%
    }{%
      \SOUL@setkern\SOUL@charkern
    }%
  }%
  %
  \def\SOUL@everysyllable{%
    \begin{tikzpicture}[overlay, remember picture]
      \path let \p0 = (begin highlight), \p1 = (0,0) in \pgfextra
        \global\highlight@previous=\y0
        \global\highlight@current =\y1
      \endpgfextra (0,0) ;
      \ifdim\highlight@current < \highlight@previous
        \expandafter\highlight@DoHighlight\expandafter{\ht@possiblenoleftround,rounded rectangle right arc=none}
        \gdef\ht@possiblenoleftround{rounded rectangle left arc=none}
        \highlight@BeginHighlight{}
      \fi
    \end{tikzpicture}%
    \ttfamily \the\SOUL@syllable
    \tikz[overlay, remember picture] \highlight@EndHighlight{} ;%
  }%
  \SOUL@{#2}
}

\begin{document}
as suggested in a comment, justifies the text within the environment. this would work if there are more ordinary words than long ones, and the long ones don't occur in inconvenient locations within the lines. a test with the affected material, \highlight{trying both techniques side by side, will quickly make it clear which is preferable in a given situation.}s


this is some text \highlight{var files = Directory.EnumerateFiles(myDirectory,''*.txt*);} text
this is some text box text this is some text this is some text texttext \highlight{var files = Directory.EnumerateFiles(myDirectory, ''*.txt*);} hello
\end{document} 
5
  • Great! As you said, in some situations with long words inside \inlinecode it overflows the line. In such situations I would prefer forcing a line break. I had some success with adding this code tex.stackexchange.com/a/171308/61241. However, it seems to not work in some situations and I could not find a working solution to get a \hookleftarrow as hyphenation char. Nov 27, 2016 at 15:55
  • To see that a single \inlinecode was split up to multiple lines, it would be good if the box in the 1st line had only rounded borders on the left side and the box in the 2nd line only on the right side. Shapes as you can see them in this answer: tex.stackexchange.com/a/28118/61241 It should be possible because it is similar to this tex.stackexchange.com/a/164431/61241 I do not know how to translate it in code, but you could create a not rounded box covering the rounded corners before and after each hyphen. Or is there even a solution to directly change the highlighter style? Nov 27, 2016 at 16:26
  • I guess I can try. Nov 27, 2016 at 17:20
  • Would be very kind of you. I do not need it right now, so there is no rush. Nov 27, 2016 at 17:31
  • I did the not rounded around linebreaks thing. Can I have an upvote? Nov 27, 2016 at 18:54
2

Here is a straight forward combination of David Carlisle's linebreaking code and the rounded corners macro:

\documentclass{article}
\parindent0pt
\usepackage{fullpage}
\usepackage{tikz}

\newenvironment{foo}
{\par
\hyphenpenalty=10000
\exhyphenpenalty=10000
}
{\par}

\newcommand\lword[1]{\leavevmode\nobreak\hskip0pt plus\linewidth\penalty50\hskip0pt plus-\linewidth\nobreak #1}
\newcommand\inlinecode[2][]{\lword{\tikz[overlay]\node[fill=blue!20,inner sep=1pt, anchor=text, rectangle, rounded corners=1mm,#1] {\ttfamily #2};\phantom{\ttfamily #2}}}
\begin{document}
\begin{foo}
this is some text \inlinecode{var files = Directory.EnumerateFiles(myDirectory,''*.txt*);} 
text as suggested in a comment, justifies the text within the environment. this would work 
if there are more ordinary words than long ones, and the long ones don't occur in 
inconvenient locations within the lines. a test with the affected material, 
\inlinecode{trying both techniques side by side, will quickly} make it clear which is 
preferable in a given situation.s
this is some text box text this is some text this is some text texttext 
\inlinecode{var files = Directory.EnumerateFiles(myDirectory, ''*.txt*);} hello
\end{foo}
\end{document} 
2
  • It is not the perfect solution, but still better than mine. Or maybe it is even the perfect solution, because reading a line of code split up to multiple lines is not that nice, either. Thanks. However, I would still be interested in a solution supporting line breaks. I will accept your answer if no other solution is provided within the next few days. Nov 27, 2016 at 15:28
  • Wait I'm confused. You want oval text with full line breaking? Nov 27, 2016 at 15:30

You must log in to answer this question.

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