3

Getting bold typed text

I have been using listings to format my code, and have occasionally been using the following solution to make some typed text bold:

\DeclareFontShape{OT1}{cmtt}{bx}{n}{<5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88>cmttb10}{}

(I have no idea how this works, but is suggested here and here).

However, I usually use this with black text, but have just noticed that this does not preserve the colour the listings package gives when highlighting.

It doesn't work within a coloured listings

enter image description here

MWE

\documentclass[10pt]{extarticle}
\usepackage{color}
\usepackage{listings}
\lstset{stringstyle=\color[rgb]{.627,.126,.941}, basicstyle={\fontfamily{cmtt}\selectfont\footnotesize},showstringspaces=false} 
\DeclareFontShape{OT1}{cmtt}{bx}{n}{<5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88>cmttb10}{}
\begin{document}
\ttfamily Something in \textbf{bold}. {\color{red} Something else in \textbf{bold}.}
\begin{lstlisting}[escapechar=@]
Something @\textbf{important}@ right here. 
\end{lstlisting}
\begin{lstlisting}[language=C, escapechar=@]
int main() 
{
    int = 1;
    char * s = "@something@ @\textbf{important}@ right @\color[rgb]{.627,.126,.941} \bfseries here@" 
               "and a normal string for comparison";
}
\end{lstlisting}
\end{document}

Is it possible to have @\textbf{...}@ inherit the colour listings wants to give it?

3

One way to get the desired result is to redefine strings as delimiters. We define a new language based on the C language. Then we delete the default string definition with deletestring=[b]" and replace it with a new delimited environment with moredelim=**[s][...]{"}{"}. The ** tells listings to accumulate styles inside this environment such that we can define @...@ as another one that sets the bold font inside it. There's no need to escape listings now anymore.

The disadvantage of the ** delimiter type is that it also accumulates styles of keywords and other special syntax elements that occur inside of string literals. To prevent that, we have to define a new toggle that keeps track of whether we currently are inside a string literal or not. The toggle is set to true as part of the string literal style and reset via the EndGroup hook, which is executed everytime listings leaves a delimiter.

A new command \nostringstyle is defined that has to be used whenever a style is set for the various syntax elements (like in keywordstyle). Based on the toggle state, the style then is only applied if that element occurs outside of string literals.

Full example code (also note the bold "int" keyword):

\documentclass[10pt]{article}
\usepackage{xcolor}
\usepackage{listings}

\makeatletter
\newif\if@instring
\@instringfalse

\newcommand\nostringstyle[1]{\if@instring\else#1\fi}
\lst@AddToHook{EndGroup}{\global\@instringfalse}

\lstset{
    basicstyle={\fontfamily{cmtt}\selectfont\footnotesize},
}
\DeclareFontShape{OT1}{cmtt}{bx}{n}{<5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88>cmttb10}{}

\lstdefinelanguage{myC}[ANSI]{C}{
    deletestring=[b]",
    keywordstyle={\nostringstyle{\color{blue}}},
    moredelim=**[s][{\global\@instringtrue\color[rgb]{.627,.126,.941}}]{"}{"},
    moredelim=**[is][{\bfseries}]{@}{@},
    showstringspaces=false
}

\makeatother

\begin{document}
\noindent\ttfamily Something in \textbf{bold}. {\color{red} Something else in \textbf{bold}.}

\begin{lstlisting}[language=myC]
int main()
{
    @int@ = 1;
    char * s = "something @important@ right @here@" 
               "and a normal string for comparison";
}
\end{lstlisting}
\end{document}

enter image description here

| improve this answer | |
  • This is almost what I was after, but I was hoping to have @...@ be some escape that allowed for some extra formatting, so while in my example I may use bold, I an/could instead choose @\textit{something}@, or even @$something$@. In what I am expecting to use it for though I am mostly expecting to use either bold, italics, underline, strikethrough, etc. (nothing too exotic, bit to support a few features, mostly bold though). – oliversm May 16 '19 at 14:44
  • listings' capabilities are really limited here. For bold and italics text my solutions works fine. For underline or strikethrough you can use the approach presented in this answer. I'm not sure how a solution for math mode could look like, as listings executes the EndGroup hook when it escapes the listing, so all information about the \@instring toggle ist lost. – siracusa May 16 '19 at 23:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.