这个问题的第一个答案描述了一种突出显示所有以 at 符号开头的标识符的方法。我想做同样的事情,只是用下划线代替。我已经相应地修改了那里给出的代码
\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},
}[keywords,strings,comments]
% --- patch to automatically highlight identifier starting by @
% (only outside strings and comments, though) ---
\lst@AddToHook{Output}{\@ddedToOutput}
\lst@AddToHook{Endgroup}{\incommentfalse\instringfalse}
% 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]
# This is an example
@Blueword(foo) _Blueword bar
\end{lstlisting}
\end{document}
但是,此代码给出了以下错误:
! Improper alphabetic constant.
<to be read again>
\lst@um_
l.62 @Blueword(foo) _Blueword
bar
?
! Missing = inserted for \ifnum.
<to be read again>
\char
l.62 @Blueword(foo) _Blueword
bar
?
! Missing number, treated as zero.
<to be read again>
\char
l.62 @Blueword(foo) _Blueword
bar
?
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./t.aux) )
(\end occurred when \ifnum on line 62 was incomplete)
(\end occurred when \iftrue on line 62 was incomplete)
(\end occurred when \ifnum on line 62 was incomplete)
(\end occurred when \iffalse on line 62 was incomplete)
(\end occurred when \ifnum on line 62 was incomplete)
(\end occurred when \iftrue on line 62 was incomplete)
(\end occurred when \ifnum on line 62 was incomplete)
(\end occurred when \iftrue on line 62 was incomplete)
(\end occurred when \ifnum on line 61 was incomplete)
(\end occurred when \iftrue on line 61 was incomplete)
(\end occurred when \ifnum on line 61 was incomplete)
(\end occurred when \iffalse on line 61 was incomplete)
(\end occurred when \ifnum on line 61 was incomplete)
(\end occurred when \iffalse on line 61 was incomplete)
(\end occurred when \ifnum on line 61 was incomplete)
(\end occurred when \iffalse on line 61 was incomplete)
答案1
这是另一种方法,它重新定义所有标识符的样式,即以字母、 或 开头,后跟更多这些字符或数字的字符序列@
。$
我们_
设置了一种特殊的标识符样式\@identifierstyle
,它动态地决定应该为当前标识符应用什么实际样式。
如果第一个 token 是\lst@token
equals \lst@um_
(用于在列表中表示的内部宏) ,则在此示例中我们将样式更改为红色;所有其他标识符都以蓝色排版。请注意,此钩子不会干扰关键字的样式,关键字是(此处为绿色)_
中的一种特殊类型的标识符。listings
完整示例:
\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\makeatletter
\lstdefinestyle{mybash}
{%
language = bash,
basicstyle = \ttfamily,
keywordstyle = \color{green},
identifierstyle = \@identifierstyle,
}[keywords,strings,comments]
\def\@headtoken#1#2\end{\noexpand#1}
\def\@identifierstyle{%
\edef\@tempa{\expandafter\@headtoken\the\lst@token\end}%
\edef\@tempb{\expandafter\noexpand\csname lst@um_\endcsname}%
\ifx\@tempa\@tempb
% apply special style for identifies staring with '_'
\color{red}%
\else
% normal identifier style
\color{blue}%
\fi
}
\makeatother
\begin{document}
\begin{lstlisting}[style=mybash]
# This is an example for _Blueword
@Blueword(foo) _Blueword bar
'_Blueword in string'
if _cond then __this__ else __that__
\end{lstlisting}
\end{document}