我正在尝试使用该listings
包排版 SuperCollider 代码。
任何以大写字母开头的“独立”标识符都是类名,应该突出显示;我说的“独立”是指字符串或注释之外listings
。如果可以让您根据正则表达式定义标识符,我会非常高兴,例如[A-Z][A-Za-z0-9_]*
,但手册并未表明这种可能性。
SuperCollider 有大约 2300 个类别... 我真的不想在序言中逐字逐句地列出所有类别。我想我可以手动提取每个单独的列表,但我宁愿不必这样做。
有没有办法做到这一点而不需要大量的morekeywords
表达?(也许使用另一个包?)
超级对撞机代码示例:
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;
Impulse
并TGrains
应以蓝色突出显示。我还有数十个其他列表使用不同的大写关键字。
答案1
编辑: 看https://tex.stackexchange.com/a/166159/21891以获得更完整的listings
SuperCollider 语言定义。
通过正则表达式对标识符进行语法高亮显示不是 的功能listings
,但可以解析标识符以检查它们是否通过了某个测试,然后有条件地对它们应用某种样式。
在下面的代码中,表单的所有标识符[A-Z][A-Za-z0-9_]*
都以用户定义的“类样式”突出显示。下面的类样式由粗体和绿色组成。您可以通过将适当的声明(例如\bfseries\color{red}
)传递给classstyle
键来自定义类的排版方式,我已为方便起见定义了该键。
如果一切按预期运行,您就不必再逐一指定 SuperCollider 类了。祝您好运 :) 此外,您仍然可以定义以大写字母开头的关键字;关键字样式将覆盖这些关键字的类样式。
参考:该解决方案结合了Marco Daniel 的回答, 和大卫·卡莱尔的回答。我在本例中使用的 SuperCollider 示例改编自那里。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{listings}
\usepackage{xcolor}
\renewcommand{\ttdefault}{pcr}
% patch to detect SuperCollider classes (i.e. identifiers starting by A-Z)
% and apply the corresponding class style
% ----- ugly internals -----
\makeatletter
% custom keys for controlling the styles of SuperCollider classes,
% symbols, and global variables
\lst@Key{classstyle}{}{\def\classstyle@supcol{#1}}
% local variables
\newcount\currentchar
\def\@testChar%
{%
\ifnum\lst@mode=\lst@Pmode%
% copy the first token in \the\lst@token to \@testChar
\expandafter\splitfirstchar\expandafter{\the\lst@token}%
% test for characters A through Z
\currentchar=65
\loop
\expandafter\ifnum\expandafter`\@testChar=\currentchar%
\let\lst@thestyle\classstyle@supcol%
\let\iterate\relax
\fi
\advance \currentchar by 1
\unless\ifnum\currentchar>90
\repeat
\fi
% ...but override by keyword style if a keyword is detected!
\lsthk@DetectKeywords%
}
% helper macros
\def\splitfirstchar#1{\@splitfirstchar#1\@nil}
\def\@splitfirstchar#1#2\@nil{\gdef\@testChar{#1}}
% apply patch to perform test on each identifier
\lst@AddToHook{Output}{\@ddedToOutput}
\let\@ddedToOutput\@testChar
\makeatother
% ----- end of ugly internals -----
% language definition
\lstdefinelanguage{SuperCollider}
{%
alsoother = @\$,
morecomment = **[l]{//},
morecomment = **[s]{/*}{*/},
morestring = **[s]{"}{"},
}[keywords,strings,comments]
% color definition
\definecolor{SCclasscolor}{RGB}{000,127,000}
\definecolor{SCcommentcolor}{RGB}{063,127,127}
\definecolor{SCstringcolor}{RGB}{186,034,034}
\colorlet{framerulecolor}{black}
% style definition
\lstdefinestyle{SupColSty}
{%
language = SuperCollider,
basicstyle = \ttfamily\footnotesize,
stringstyle = \color{SCstringcolor},
commentstyle = \color{SCcommentcolor}\itshape,
classstyle = \color{SCclasscolor}\bfseries,
breaklines = true,
showstringspaces = false,
frame = single,
rulecolor = \color{framerulecolor},
}
% --- write source code to external file (for this example) ---
\usepackage{filecontents}
\begin{filecontents*}{Atari2600.scd}
/*
// Fredrik Olofsson
A quick demo of Fredrik Olofsson's Atari 2600 plugin, which can be downloaded from:
www.fredrikolofsson.com/pages/code-sc.html
This lovely 8-bit tune is based on an example in the helpfile.
*/
// Simple synth definition using the Atari2600 UGen:
(
SynthDef(\atari2600, {|out= 0, gate= 1, tone0= 5,
tone1= 8, freq0= 10, freq1= 20, amp= 1, pan= 0|
var e, z;
e= EnvGen.kr(Env.asr(0.01, amp, 0.05), gate, doneAction:2);
z= Atari2600.ar(tone0, tone1, freq0, freq1, 15, 15);
Out.ar(out, Pan2.ar(z*e, pan));
}).add;
)
"Test: Pseq SynthDef, etc. don't get highlighted as classes in strings"
// And a pattern to play it:
(
Pbind(
\instrument, \atari2600,
\dur, Pseq([0.25, 0.25, 0.25, 0.45], inf),
\amp, 0.8,
\tone0, Pseq([Pseq([2, 5], 32), Pseq([3, 5], 32)], inf),
\tone1, 14,
\freq0, Pseq([Pbrown(28, 31, 1, 32),
Pbrown(23, 26, 3, 32)], inf),
\freq1, Pseq([Pn(10, 16), Pn(11, 16)], inf)
).play
)
\end{filecontents*}
\begin{document}
\lstinputlisting[style=SupColSty]{Atari2600.scd}
\end{document}
答案2
根据 Jubobs 的说法,我所要求的是不可能的。
我通过在 SuperCollider 中编写代码来解决这个限制,以查找类名并删除任何“误报”(通过检查 SC 自己的内省提供的类列表)。
https://github.com/jamshark70/scweek2014/blob/master/shows/scan-class-keywords.scd
这没有我希望的那么方便,但是类名现在在我的文档中是蓝色的,这比在我只使用 50 个左右的类名时将 2000 多个类名插入列表中要好。