# How to highlight all identifiers starting by '@'?

I would like to highlight any expression made of letters and that starts with one @. The use of moredelim=*[s][\color{blue}]{@}{\ } works only in case like @name is followed by one space. The following code nearly works except that I do not want the parenthesis to be colored in case like @decorator(x=3, y='some text') because that is @decorator( which is caught.

moredelim=[s][\bfseries\color{gray}]{@}{\ },
moredelim=[s][\bfseries\color{gray}]{@}{(},


The use of moredelim=[s][\bfseries\color{gray}]{@}{(} is not a good solution because the search is done on several lines... :-(

-
In text editors capable of regular expression identification, just search and highlight this string: ^@.*? But how is this a tex question? Do you want LaTeX to do this as it compiles? –  Ariel Apr 11 '12 at 16:38
listings is one LaTeX package. –  projetmbc Apr 11 '12 at 16:49
ah - thanks for the clarification and this is good to know. –  Ariel Apr 11 '12 at 17:19

I followed the same approach as in my answer to Can the listings package highlight by regexp?.

\documentclass{article}

\usepackage{xcolor}
\usepackage{listings}

\makeatletter

% state variables''
\newif\ifincomment\incommentfalse
\newif\ifinstring\instringfalse

% language and style definition
\lstdefinestyle{mybash}
{%
language = bash,
basicstyle   = \ttfamily,
keywordstyle = \color{blue},

% --- patch to automatically highlight identifier starting by @
% (only outside strings and comments, though) ---

% local variables
\newif\if@identifierStartsByAt@
\newcount\currentchar

\def\splitfirstchar#1{\@splitfirstchar#1\@nil}
\def\@splitfirstchar#1#2\@nil{\gdef\@testChar{#1}}

\def\@testChar%
{%
% copy the first token in \the\lst@token to \@testChar
\expandafter\splitfirstchar\expandafter{\the\lst@token}%
%
% reset switch
\@identifierStartsByAt@false
%
% equality test
\expandafter\ifnum\expandafter\@testChar=@%
\@identifierStartsByAt@true % if equality, set switch to true
\fi
%
% apply class style if not within string or comment
\if@identifierStartsByAt@
\ifincomment
\else
\ifinstring
\else
\def\lst@thestyle{\lst@keywordstyle}%
\fi
\fi
\fi
}
\let\@ddedToOutput\@testChar
\makeatother

\begin{document}
\begin{lstlisting}[style=mybash]{text.txt}
# This is an example
@Blueword(foo) @Blueword bar
\end{lstlisting}
\end{document}

-
Thanks. I will try to understand the code... –  projetmbc Mar 1 at 22:54

This is possible. The package provides the command morecomments, which can be used to declare a sequence of arbitrarily delimited symbols to be a comment, and set up its unique formatting. The command

\lstset{morecomment=[s][\color{blue}]{@}{\ }}


means that any sequence of symbols ([s]) delimited by @ and space, will be typeset in blue.

\documentclass{article}
\usepackage{listings,xcolor}
\pagestyle{empty}
\lstset{language=bash}
\lstset{morecomment=[s][\color{blue}]{@}{\ }}
\begin{document}
\begin{lstlisting}
# This is an example
@Blueword # This will be done properly
for x in *~; do
echo $x; done # This too @Blueword x for x in *~; do echo$x;
done
# And this one
@Blueword
for x in *~; do
echo \$x;
done
\end{lstlisting}
\end{document}


-
Thanks for {\ }. That's what I've been looking for... –  projetmbc Apr 11 '12 at 17:15
I've updated my question because there are some drawbacks... –  projetmbc Apr 11 '12 at 17:31
Unfortunately listings does not accept multiletter delimiters (yet?), so in your example you need to write @decorator (arg). By the way, I know at least one company, where a space between function name and opening bracket is required by the coding style. –  Boris Apr 11 '12 at 17:40