listings
can do that, but you have to whisper in its ear :)
First, tell listings
to treat backslash and tilde as "letters", thereby allowing them in identifiers. Then, before each identifier gets printed, check the first character of that identifier and apply a different style depending on that character.
For convenience, I've defined keys to easily specify the styles for SuperCollider classes (starting by A-Z
), symbols (starting by \
), and global variables (starting by ~
).
Update: For convenience to SuperCollider users, I've put together a little package called sclang-prettifier
, now available on CTAN and, soon, in popular TeX distributions.
![enter image description here](https://i.stack.imgur.com/W8Frz.png)
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[framed,numbered]{sclang-prettifier}
% --- write source code to external file (for this example) ---
\usepackage{filecontents}
\begin{filecontents*}{sample.scd}
p.clear;
~grains.addSpec(\tfreq, [1, 40, \exp]);
~grains.addSpec(\overlap, [0.1, 10, \exp]);
~grains.addSpec(\pos, [0, b.duration]); // 3.43 is nice!
~grains.addSpec(\rate, [0.5, 2, \exp]);
~grains = { |tfreq = 25, overlap = 6, pan = 0, amp = 0.2, pos = 3.43,
rate = 1|
var trig = Impulse.ar(tfreq);
TGrains.ar(2, trig, b, rate, pos, overlap / tfreq, pan, amp)
};
~grains.play;
\end{filecontents*}
\begin{document}
\lstinputlisting
[
style = SuperCollider-IDE,
basicstyle = \scttfamily\small,
caption = {SuperCollider sample}
]{sample.scd}
\begin{lstlisting}[
frame = single,
caption = Some code unrelated to SuperCollider,
]
c = a
a = b
b = c
discard c
\end{lstlisting}
\end{document}
Ok, after some thinking about how to do this with listings
while avoiding manually specifying keywords, I suppose a syntax based solution may work.
I.e. I defined a language for listings
using moredelim
and morestring
to handle the most basic syntax of XML
and get the following results:
![enter image description here](https://i.stack.imgur.com/nWjMq.png)
the corresponding code is:
\documentclass{report}
\usepackage{listings}
\usepackage{color}
\lstdefinelanguage{XML_SYNTAX}{%
alsoletter=-,
morestring=[b]",stringstyle=\color[rgb]{0,0,1},
moredelim=*[s][{\color[rgb]{0.75,0,0}}]{<}{>},
moredelim=[s][{\color[rgb]{0,0,0}}]{<!--}{-->},
moredelim=[s][{\color[rgb]{0,0.75,0}}]{\ }{=},
moredelim=[s][{\color[rgb]{0,0.75,0}}]{\ }{=} % here there is \tab
}
\lstset{
% Basic design
backgroundcolor=\color[rgb]{0.9,0.9,0.9},
basicstyle={\small\ttfamily},
breaklines=true,
frame=l,
tabsize=2,
% Line numbers
xleftmargin={0.75cm},
numbers=left,
stepnumber=1,
firstnumber=1,
numberfirstline=true,
% HTML formatting
language=XML_SYNTAX,
}
\begin{document}
\begin{lstlisting}
<!-- with tab -->
<list-component data="angularDataObject"
list-type="dataActor">
</list-component>
<!-- with space -->
<list-component data="angularDataObject"
list-type="dataActor">
</list-component>
<!-- some other tag -->
<div id="test"></div>
\end{lstlisting}
\end{document}
For explanation of what the the code does, refer to sections 3.2, 3.3 and 4.18 onwards of the listings
documentation.
Note: for some reason the list-type
attribute is still wrong, although I told listings
to treat -
as a letter with alsoletter={-}
- maybe you can figure out why that is, otherwise I'll have some time for more testing in a few hours.
This was due to my usage of a tab for indentation, rather than a space. As that is fixed now, more debugging to do, since the closing >
of the list-component
tag has now become green as well..
Thanks to @Jubobs this is fixed as well - it was my bad to have an extra *
in the attribute style line. In addition I fixed things to that indentation with tabs also works.
Best Answer
Solution using LuaTeX callbacks. Library
luacolor.lua
fromluacolor
is also used.First package
luahighlight.sty
:command
\highlight
is provided, with one required and one optional parameters. required is highlighted word, optional is color. Inpre_linebreak_filter
callback, words are collected and when matched, color information is inserted.Lua module,
highlight.lua
:we use
pre_linebreak_filter
callback to traverse the node list, we collect theglyph
nodes (id 37) in a table and when we find a glue node (id 10, mainly spaces), we construct a word from collected glyphs. We have some prohibited characters (such as punctuation), which we strip out. All characters are lowercased, so we can detect even words at the beginning of sentences etc.When a word is matched, we set
attribute
field of word glyphs to value under which is related color saved inluacolor
library. Attributed are new concept in LuaTeX, they enable to store information in nodes, which can be processed later, as in our case, because at the shipout time, ale pages are processed by theluacolor
library and nodes are colored, depending on theirluahighlight
attribute.