跳转到内容

设置

函数参数可以单独调整某一次调用;整首曲子反复使用的字号、连音线弧高或多声部连接方案,则适合先设成默认值。播放时切换乐器也是一种设置,但它的生效范围与参数默认值不同。

这一章我们将介绍两个设置函数。先用 @set 统一参数默认值、字号、字体和严格模式,再用 @program 切换播放时的乐器音色。它们本身并不会在谱面中显示,但是会影响后续的谱面内容。

只想修改一段文字时,可以写 @text("轻快地", size=20px)。如果之后的文字都想使用这个大小,可以先设置默认值:

统一字号,个别文字单独调整
@text("默认大小")
@set(text.size=30px)
@text("新的默认值")
@text("单独放大", size=40px)
@text("恢复新的默认")
复制代码

@set(函数名.参数名=值) 为后续调用提供默认值,不覆盖显式传入的参数。这里的文字依次使用内置大小、30px、显式指定的 40px,最后又使用 30px。

text.size 由函数名和参数名组成,中间用英文点号 . 连接。普通具名参数和仅命名参数都可以预设:比如拍号的 den、连音线的 height、多声部的 connect。一次设置多项时,用英文逗号分隔:

@set(
text.align="center",
meter.den=8,
tie.height=0.8em,
voices.connect="{-}"
)

值的类型由参数决定,数字、布尔值、字符串和长度均可使用,内容块和标签不能作为预设。函数别名同样有效;函数或参数名不存在时,会给出诊断并忽略该项。可用参数及其类型见函数速查。

取值顺序是:本次显式传参 → 当前作用域的 @set → 函数内置默认值。显式调用与语法糖的具体覆盖方式由各函数说明,例如 V 声明会单独指定当前多声部块的连接。

在基本类型中,我们用花括号把乐谱划成一组。@set 的设置从它出现的位置开始,在当前内容块以及里面嵌套的子内容块中生效;离开这个内容块,就回到外层的设置。这个范围叫作作用域。

只在一组内容里修改字号
@set(text.size=10px)
@text("外层文字是10px")
{
  @text("这里仍然是10px")
  @set(text.size=20px)
  @text("这里变为20px")
}
@text("回到外层,恢复10px")
复制代码

正如我们之前所说:整个 jpFun 脚本本身就是一个巨大的内容块,我们可以想象为外面套了一层虚拟的花括号。因此写在最外层的 @set 会影响之后的所有脚本。

@set 不仅能修改函数参数的默认值,也能设置影响当前作用域的系统变量。它们的名字不带函数名前缀,目前有四个:

@set(
fontsize=22px,
font="sans-serif",
numberfont="'Cascadia Mono', Consolas, 'Liberation Mono', 'Noto Sans Mono', monospace",
strict=false
)
变量类型默认值作用
fontsize长度22px基准字号,也是 em 长度的换算基准
font字符串sans-serif普通文字字体
numberfont字符串下方的等宽字体栈音符及同类谱面数字字体
strict布尔值false开启严格的语法检查

系统变量与函数预设不同:fontsize 改变基准字号,text.size 只改变 text 的默认参数。

fontsize 接受长度。除了前面见过的 px,还可以使用 em:px 表示固定大小,em 表示基准字号的多少倍。在这里,em 按修改前的基准字号换算:

@set(fontsize=20px)
1 2
{ @set(fontsize=1.5em) 3 4 }
5 6

局部字号为 30px,离开内容块后恢复 20px。各函数可使用基准字号的不同倍数,因此文字、拍号等不一定与音符等高。函数自身的 size 参数仍可单独控制大小。

jpFun 有两类字体,互不覆盖,影响函数有:

  • font:text、voice 的声部名和歌词(含歌词行名)、tempo 文字、page 页码、H 裸文本。
  • numberfont:note(音符)、key(调号)、meter(拍号的数字)、tuplet(多连音上面的数字)、volta(跳房子中的数字)。
@set(font="'Noto Sans SC', sans-serif", numberfont="Consolas, monospace")
@text("轻快地")
1 2 3 4

字体列表含逗号时,整个值必须用 DSL 双引号包裹。列表里的字体名可用 CSS 单引号;若使用双引号,需写成 \"。

这里的 \" 叫作转义:反斜杠告诉 jpFun,后面的引号是文字本身,不是字符串的结束。例如要让谱面上显示带引号的一句话,可以写:

@text("他说:\"你好\"")

如果文字里需要反斜杠本身,就写 \\。这和歌词中的换行转义使用的是同一个符号,但处理的内容不同。

常用配置 @set(font="'Times New Roman', KaiTi, STKaiti, serif") 可让中文使用楷体、英文使用 Times New Roman。

text、page 接受 font 参数,也支持 @set(函数名.font="...");函数别名同样有效。优先级为:显式参数 > 函数预设 > 系统 font。

@set(font="sans-serif", text.font="serif")
@text("使用 serif")
@text("使用 monospace", font="monospace")
@text("使用系统字体", font="")

不过并不是所有有文字的函数都支持设置字体,比如 note、key、meter、tuplet、voice、volta 都没有字体参数,请用内容块中的系统设置实现局部变化;强行使用 @set(note.font=...) 会报错,因为查无此项。之所以这么设计,主要是没必要:这些函数的文字通常与音符、拍号等紧密排版,统一使用系统字体可以保证布局一致性;此外还有函数定义的限制:比如 voice 支持传入的额外命名参数,因此 font=... 只是名为 font 的歌词行。

有些设置只有“开启”和“关闭”两种状态,用 true 表示开启,false 表示关闭。这种值叫作布尔值,直接写这两个英文单词,不需要引号。比如开启严格模式:

@set(strict=true)
1 2 3 4

strict=false 时,一些问题会记录为诊断并继续处理,例如未知函数;strict=true 会让支持严格检查的这些问题抛出错误。

@set(font="", numberfont="", fontsize=0px, strict=false)

空字体字符串恢复对应系统默认字体,零字号恢复 22px,strict=false 关闭严格模式。这是恢复系统默认值,不是恢复外层值;要自动恢复外层设置,请使用局部内容块。

函数参数的空值没有统一的“恢复默认”含义,仍由参数自身解释。例如 @set(voices.connect="") 表示只有细连谱线;要恢复默认括线,应写 @set(voices.connect="[-]")。同样,不要把 0 或 false 一律当成未设置。

同一段旋律可以用钢琴、小提琴、长笛等不同乐器演奏,听起来的差别就是音色。@program 用来选择当前音轨的播放音色,例如:

@program(40)

这里的 40 是小提琴的 MIDI 音色编号。MIDI 是一种记录音符和演奏指令的格式;常用的 General MIDI(简称 GM)标准约定了一套乐器编号,jpFun 使用这套编号选择音色。

@program 接受一个必填的整数,范围是 0 到 127。不能填写小数、负数或乐器名称,也不能留空写成 @program()。它还有一个别名 @instrument,例如 @instrument(40) 与 @program(40) 完全相同。

先记住几个常用编号就够了:

jpFun 中的编号GM 乐器音色
0原声大钢琴
24尼龙弦吉他
40小提琴
56小号
73长笛

注意编号的起点。 有些 GM 音色表从 1 开始,把钢琴列为 1、小提琴列为 41;jpFun 从 0 开始。查到从 1 开始的表时,要把表中的编号减去 1 再填写。上表已经是 jpFun 使用的编号,不用再减。

没有设置音色时,默认使用 0,也就是钢琴。@program 从它出现的位置开始,改变当前音轨后续音符的音色。可以在曲首设置,也可以中途切换:

同一段旋律,三种乐器
@program(0)
1 2 3 5 |
@program(40)
1 2 3 5 |
@program(73)
1 2 3 5 |
复制代码

在编辑器中打开并播放这个谱例:第一小节是钢琴,第二小节是小提琴,第三小节是长笛。三个小节的音高、节奏完全相同,只改变音色。

@program 本身不会在谱面上显示乐器名称,因此只看预览图看不出区别。具体听感取决于播放器使用的音源,同一编号在不同音源中可能听起来有所不同。

这一点与前面的 @set 不同:普通内容块不会让 @program 的设置在结束时自动恢复。 看下面四个音符:

离开内容块后,音色继续生效
@program(0) 1
{
  @program(40) 2
}
3
@program(0) 4
复制代码

do 使用钢琴,re 切换成小提琴;虽然 mi 已经在花括号外面,它仍然使用小提琴。直到再次写下 @program(0),fa 才恢复为钢琴。

多声部时,可以把 @program 放进各自声部的内容里,分别选择乐器。这里的“当前音轨”指独立的演奏分支,单独加一对花括号并不会新建音轨。

试着把“三种乐器”谱例中的 40 改成 24,让第二小节改用尼龙弦吉他,另外两个小节保持不变。更多参数说明可查函数速查中的 program。