跳转到内容

基本语法

jpFun 把排版能力统一写成函数调用。你不需要为每种功能记一套语法,只要认识几种基本类型,并学会把它们作为参数传给函数即可。

函数的参数由下面六种基本类型组成:

类型示例用途
字符串"轻快地"center文字、名称和选项
布尔值truefalse开启或关闭某个选项
数字1000.7-12速度、拍号和其他数值
长度/尺寸12px0.8em字号、间距和页面尺寸;省略单位时默认为 px
内容{1 2 3 4}把一段谱面作为一个整体传入函数
标签startend引用谱面中已经标记的对象

字符串只能使用英文双引号。不会产生歧义时可以省略引号,因此 @text(轻快地)@text("轻快地") 的效果相同。内容也可以在不产生歧义时省略花括号;一旦内容中有多个元素,最好明确写出 {}

@text("稍快,有活力")
@box({1 2 3 4})

第一个字符串中的逗号如果没有引号,会被当作参数分隔符;第二个函数中的四个音符如果没有花括号,则会变成四个参数。引号或花括号的作用,正是告诉解析器这些字符属于同一个值。

函数调用采用 @函数名(参数) 的形式。函数名与左括号之间不能有空格,多个参数之间使用英文逗号分隔:

@tempo(100)
@meter(4, 4)
@text(轻快地, size=0.8em)

前两例使用位置参数,参数含义由顺序决定。最后一例还使用了命名参数 size=0.8em,直接指出要修改哪个选项。位置参数必须写在命名参数之前;没有传入的参数会使用当前设置或函数默认值。

函数的参数也可以是另一个函数调用,这就是函数嵌套。例如下面两种写法会得到相同的减时音符:

@div(@note(1), 1)
@div({@note(1)}, 1)

这里的 @note(1) 先产生音符,再作为内容交给 @div 添加一条减时线。外层函数只关心收到的内容,不需要知道内容是由简写还是另一个函数产生的。

大多数函数会直接产生或改变谱面内容。例如 @note 产生音符,@text 产生文本,@div 缩短内容的时值。这类函数写在哪里,结果就出现在那里,并且可以继续嵌套:

@box({@text(引子) 1 2 3 4}, padding=0.2em)

另一类是关系函数,它们连接相隔较远的对象,例如 @tie 画连音线、@beam 手工连接减时线。关系函数通过标签找到端点,因此不必把整段音乐塞进函数参数中:

用标签连接两个音符
1@start 2 3@end @tie(start, end)
复制代码

@start@end 没有紧跟左括号,所以不是函数调用,而是标签。标签会绑定到它前面最近的可标注对象;关系函数中写 startend,即可引用这两个对象。标签名后的空格很重要,否则后面的字符可能会被当作标签名的一部分。

完整的函数调用统一、明确,但频繁输入会显得冗长。jpFun 因此为常用功能提供了简短记号,称为语法糖。它们只是更方便的写法,并没有引入另一套能力。

例如,1/@div(1, 1) 都表示一个八分音符;1 ^ 3 ^ 5@up(1, 3, 5) 都表示共享时值的和弦。

jpFun 谱例
1/ 2/ @div(3, 1) @div(4, 1) | 1 ^ 3 ^ 5 -
复制代码

花括号只划定内容范围,不会自动换行,也不会创建新声部。学习新功能时,可以先查看它完整的函数形式,再把常用写法记成语法糖。

% 会把从它开始到行末的内容变成注释。注释不会出现在乐谱中,适合记录排版意图:

1 2 3 4 | % 第一小节
5 6 7 1'

函数的完整参数及更多写法见函数速查