基本类型
上一章学会了调用函数,以及按顺序或按名字填写参数。这一章专门回答一个问题:参数里面可以填什么?
速度需要一个数字,文字需要一段文本,给音符加减时线则需要一段乐谱。参数接受哪一类值,叫作参数的类型。jpFun 有六种基本类型:数值、字符串、布尔值、长度、内容和标签。
数值:普通的数字
Section titled “数值:普通的数字”数值就是普通的数字(有限实数),可以是整数、小数或负数,例如 100、0.7、-12。填写时不加引号,也不带单位。比如设置播放速度:
@tempo(120)这里的 120 表示每分钟 120 个四分音符。
类型是数值,不代表任何数字都合适。比如速度需要正数,乐器编号需要 0 到 127 的整数;具体范围仍要看相应函数的说明。也不要把计算式当作数值填写,例如要表示一半,应写 0.5,而不是 1/2。
字符串:一段文字
Section titled “字符串:一段文字”字符串就是一段文本,可以是中文、英文、标点,甚至是一串数字。用一对英文双引号 " 把它包起来,引号本身不属于要显示的文字:
@text("稍快, 有活力") @text("123")@text 的第一个参数是字符串,所以 "123" 会显示为文字,不会变成三个音符,也不是一个数字。即使你写 @text(123),也会按照 @text 的要求,把第一个参数视为字符串。
在不会引发歧义的时候,字符串类型的引号可以去掉,比如 @text(轻快地)。那什么时候必须保留引号呢?比如文本中包含逗号:@text("hi, jpFun"),如果不加引号,里面的英文逗号就会被解析器认为是参数的分隔符,导致解析为“第一个参数是 hi,第二个参数是 jpFun”。不要用单引号代替,因为单引号已经用于升高八度。
如果要在字符串中包含双引号本身,可以用反斜杠
\转义,例如@text("他说:\"你好\"")。“转义”的意思是,下一个字符会被当作普通字符处理,而不是语法的一部分。如果要包含\本身呢?用\\就行啦。
如果想要换行呢?直接换行就可以了!jpFun 并不支持\n这样的写法。
此外,在乐谱内容中,直接写 "轻快地" 还是 @text("轻快地") 的简写。
布尔值:真/假,开/关
Section titled “布尔值:真/假,开/关”有些参数只需要在两种状态中选一个,例如是否自动连接减时线。这类值叫作布尔值,只有两种写法:
true:表示“是”,通常用来开启选项。false:表示“否”,通常用来关闭选项。
直接写这两个小写英文单词,不加引号,也不要换成 是、否、1 或 0。例如:
@div({1}, 1, autobeam=false)autobeam=false 关闭这次减时线处理与其他 @div 之间的自动连接。先关注这个开关的写法,前面的 {1} 稍后在“内容”类型里解释。
长度:填写大小和距离
Section titled “长度:填写大小和距离”字号、间距、页面尺寸等参数需要长度,通常写成“数字 + 单位”,中间不加空格。例如 20px、0.8em。
| 单位 | 含义 | 示例 |
|---|---|---|
px | 固定大小,不随基准字号改变 | 20px |
em | 当前基准字号的多少倍 | 0.8em 表示基准字号的 0.8 倍 |
比如基准字号为默认的 22px 时,1em 就是 22px,0.5em 就是 11px。这里的“基准字号”是统一的尺寸基准,不是某一段文字单独设置后的大小;它的修改方法见系统设置。
@text("固定大小", size=20px) @text("相对大小", size=0.5em) @text("默认大小")长度参数不写单位时,默认按 px 处理。因此 @text("轻快地", size=20) 中的 20 会作为 20px 使用。刚开始写时,建议保留单位,读起来更清楚,也能明确这是长度类型而不是数字类型。
内容:填写一段乐谱
Section titled “内容:填写一段乐谱”有些函数需要接收一段乐谱,再对它做处理。这类参数的类型叫作内容,用英文花括号 {} 把乐谱包起来。例如给 do 和 re 各加2条减时线:
@div({1 2}, 2)这里有两个参数:{1 2} 是要处理的内容,逗号后面的 2 是减时线的条数,类型为数值。
花括号包起来的一组内容叫作内容块,里面可以写任意乐谱内容。和字符串的引号一样,花括号本身不会添加任何记号。在没有歧义的时候,花括号可以省略(系统会按照内容块的规则解析该参数);但是例如 @div({1, 2}, 2) 这样的写法,花括号是必须的——不然低八度的 , 就会被认为是参数的分隔符啦!
实际上,整个 jpFun 脚本,就是一个巨大的内容块。由于这里没有歧义,所以不用给整个脚本加上大括号。你可以在内容块中继续调用函数。比如想写一个附点八分音符,可以先用 @div 加减时线,再把这段内容交给 @dot 加附点;最后我还想包一个框框:
@box({
@dot({
@div({
@note("1,")
}, 1)
}, 1)
@note(2')
})一层一层看:首先我们调用了 @box 函数,作用是加上边框。那给什么内容加上边框呢?是一个 @dot 函数(和一个音符),它的作用是给内容加附点。那给什么内容加上附点呢?是一个 @div 函数,它的作用是给内容加减时线。那给什么内容加上减时线呢?是一个音符 @note("1,")(注意这里的引号不能少)。
内容块也有分组、划分作用域的作用,能限制设置的生效范围,这部分在《系统设置》中再讲。
标签:引用已经标记的对象
Section titled “标签:引用已经标记的对象”内容参数交给函数的是一段乐谱,标签参数则告诉函数“使用前面已经写好的哪个对象”。比如想画一条从 do 到 mi 的连音线,需要先标记起点和终点:
1@start 2 3@end @tie(start, end)这行乐谱可以分成三部分看:
1@start:写 do,并给它贴上名为start的标签。2 3@end:接着写 re、mi,并给 mi 贴上名为end的标签。@tie(start, end):在这两个标签标记的音符之间画连音线。
start 和 end 是我们自己取的名字,不会印在谱面上。@tie 的这两个参数类型都是标签,不是显示用的文字。贴标签时写 @start,在参数里引用时只写 start,不加 @,也不加引号。
记住以下规则:
- 先贴标签,再调用引用它的函数;名字可以自己取,但两处必须写得一样。
- 把标签紧跟在目标音符后面,在标签名后留空格或换行。
1@start 2是两个音符;连写成1@start2,2就会变成标签名的一部分。 - 标签名后不加小括号。
@start是标签,@start()则会被当作函数调用。这也是上一章中@br和@br()不一样的原因。
《数鸭子》中还有 2/ 1/ @tie() 的写法。那是 @tie 非常智能,会自动选择最靠近的两个可标记对象;并不是所有标签参数都能这样省略。
站在开发者的角度
“标签”是 jpFun 独有的特殊类型。之所以提出“标签”这个概念,主要是因为“内容块”天生是连续的,而音乐中却有连音线这种可以跨元素的存在,甚至连音线能跨行、跨声部。“内容”这个类型注定无法处理这种情况。于是 jpFun 提出了“标签”——类似于“变量”,用来引用已经存在的对象。
| 类型 | 填写示例 | 用途 |
|---|---|---|
| 数值 | 100、0.7 | 数量、速度、比例等 |
| 字符串 | "轻快地"、"#f00" | 文字、名称、选项等 |
| 布尔值 | true、false | 是或否、开启或关闭 |
| 长度 | 20px、0.8em | 字号、间距、页面尺寸等 |
| 内容 | {1 2} | 要处理的一段乐谱 |
| 标签 | start、end | 已经标记过的对象 |
参数的类型由函数预先规定,不是只看填进去的字符长什么样。 例如 @tempo(20) 中的 20 是数值,@text("轻快地", size=20) 中的 20 按长度处理。写之前先查参数要求,再选择相应的写法。
现在你已经学会了 jpFun 的语法了!如果需要更加精炼、专业的表述,请参看 《jpFun 语法规范》。接下来我们将具体深入常用的函数。