There's nothing quite so simple. However, you can give your own macro as the argument to identifierstyle
and that can examine the \lst@token
token list to see if the list starts with an uppercase letter. I'm not sure how robust this solution is though.
\lstset{identifierstyle=\idstyle}
\makeatletter
\newcommand*\idstyle{%
\expandafter\id@style\the\lst@token\relax
}
\def\id@style#1#2\relax{%
\ifcat#1\relax\else
\ifnum`#1=\uccode`#1%
\bfseries
\fi
\fi
}
\makeatother
I only tested it on the QuickSort example on Wikipedia.
This answer is slightly difficult to figure out exactly what it's doing so let me try to explain. The listings
package will use the execute the \idstyle
macro whenever it is trying to typeset an identifier and the actual text will be in the \lst@token
token register. So all \idstyle
does is it expands the token register using \the\lst@token
and then \id@style
will expand.
\is@style
has a delimited argument (#2
) which will scoop up every thing up to the \relax
token. That is, #1
will contain the first token and #2
will contain all of the rest. Then, the category code of #1
will be compared to that of \relax
. This is true if #1
is a control sequence and false otherwise. The second if checks that the token matches its own uppercase code; that is, it checks if the token is an uppercase character. If it is, then \bfseries
executes.
It's almost a year later, but as the OP has not yet accepted an answer, I still see my chance :-)
In the following, I use the same basic principle as in my other answer, that is, employ listings
moredelim=**
option to define delimiters, which styles then apply on top of all other formattings, so that the syntax formatting is kept.
However, instead of being limited to a standard font command for the delimiter style, I now use an lrbox
to grab the content of the current group. The resulting box holds the (syntax-formatted) output of listings
, which can be used to implement more fancy highlighting styles.
In the example code, the implementation of the \btHL
command employs TikZ to typeset the lrbox
into a TikZ node. Additional TikZ/PGF options to both, the tikzpicture and the node can be given in the optional argument (such as \btHL[fill=red!20,draw=red]
), which provides for pretty flexible highlighters.
(Note: when the optional argument is used inside some listings
argument, the whole \btHL[<key>=<value>,...]
command has to be put into curly braces in order to not confuse the listings
key=value parser.)
The \btHL
command can as well be used inside normal text. It does, however, not work across line breaks, which is a possible disadvantage compared to the approach that culminated from Bens answer. Insides of listings, however, this usually is not an issue.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{listings,xcolor,beramono}
\usepackage{tikz}
\makeatletter
\newenvironment{btHighlight}[1][]
{\begingroup\tikzset{bt@Highlight@par/.style={#1}}\begin{lrbox}{\@tempboxa}}
{\end{lrbox}\bt@HL@box[bt@Highlight@par]{\@tempboxa}\endgroup}
\newcommand\btHL[1][]{%
\begin{btHighlight}[#1]\bgroup\aftergroup\bt@HL@endenv%
}
\def\bt@HL@endenv{%
\end{btHighlight}%
\egroup
}
\newcommand{\bt@HL@box}[2][]{%
\tikz[#1]{%
\pgfpathrectangle{\pgfpoint{1pt}{0pt}}{\pgfpoint{\wd #2}{\ht #2}}%
\pgfusepath{use as bounding box}%
\node[anchor=base west, fill=orange!30,outer sep=0pt,inner xsep=1pt, inner ysep=0pt, rounded corners=3pt, minimum height=\ht\strutbox+1pt,#1]{\raisebox{1pt}{\strut}\strut\usebox{#2}};
}%
}
\makeatother
\lstdefinestyle{SQL}{
language={SQL},basicstyle=\ttfamily,
moredelim=**[is][\btHL]{`}{`},
moredelim=**[is][{\btHL[fill=green!30,draw=red,dashed,thin]}]{@}{@},
}
\begin{document}
A listing with {\btHL highlighting of all \textbf{important} elements} looks as follows:
\begin{lstlisting}[style=SQL]
SELECT name, password `FROM` users @WHERE@ name=@UNION SELECT@
\end{lstlisting}
Best Answer
It seems you want to escape from the
lstlisting
just to silently re-enter it again for highlighting keywords or other syntax parts in your comment later. So why not just stay in thelstlisting
? You can define a new delimited environment withmordelim=**[is]
that removes the delimiters from the output but still applies all other styles to the text between them. With that a new comment environment[*@ ... @*]
might look like this: