/

函数调用语法

函数是 Quarkdown 的核心特性,正是它使 Quarkdown 有别于其他 Markdown 变体以及许多其他标记语言。函数从外部库中加载,这些库既可以是原生的(例如 标准库),也可以是在 Quarkdown 源文件中定义的,它们分为不同的类别:

类别示例
布局规则rowcolumngridcenter
实用视图tableofcontentswhitespace
数学与逻辑运算sumdividepowsinisgreater
控制结构与语句ifforeachrepeatvarletfunction
文件数据includecsvread
文档元数据的修改docnamedocauthordoctypethemepageformat

基础语法

当从 Quarkdown 源文件中调用函数时,函数名前需加一个 .(点),每个参数都用花括号包裹。

.myfunction {arg1} {arg2}

示例 1

.multiply {6} {3}

18

位置参数与命名参数

在前面的代码片段中,arg1arg2 分别指代函数签名中的第一个与第二个参数。这些被称为位置参数,因为它们的含义由其在调用中的位置决定。

参数也可以按名称来指代某个参数。这些命名参数使用 name:{arg} 语法。

.myfunction firstparam:{arg1} secondparam:{arg2}

示例 2

你可以混合使用位置参数与命名参数,以提高函数调用的可读性,只要所有跟在命名参数之后的参数同样也是命名的即可。

.multiply {6} by:{3}

18

多行参数

参数可以跨越多行。缩进是可选且任意的。

示例 3

.divide {
    .cos {.pi}
} by:{
    .sum {2} {1}
}

-0.33333334

行续接

当一个函数调用包含许多参数时,行末的反斜杠(\)会将参数列表延续到下一行。

.container alignment:{center} \
           background:{red} \
           padding:{1px}

反斜杠与换行符会被编译器消费掉,续接行开头可选的空白会被忽略。你可以根据需要用任意多个续接行。

行续接在块级与行内函数调用中均受支持。

嵌套函数调用

函数调用可以嵌套在参数内部,从而让你组合出复杂的表达式。

示例 4

.multiply {.pow {3} to:{2}} by:{.pi}

28.274334

链式调用

尽管 Quarkdown 完全依赖顶层声明,它还是利用了一些类 OOP 的语法糖,极大地提升了嵌套函数调用的可读性。

考虑下面这个调用:

.sum {.subtract {.pow {3} {2}} {1}} {2}

它计算的是 (3^2 - 1) + 2 = 10。尽管简单,写起来和读起来却再难不过!下面这个调用完全等价:

.pow {3} {2}::subtract {1}::sum {2}

好多了。现在它读起来就像我们自然地阅读数学的方式。

要理解链式调用的工作原理,考虑这个更简单的例子(请参阅变量 以了解更多关于变量的内容):

.myvar::uppercase

在底层,编译器会将此调用转换为:

.uppercase {.myvar}

示例 5

.var {myvar} {hello!}

.myvar::uppercase

HELLO!

一般而言,.a::b 会被转换为 .b {.a}.a::b::c 转换为 .c {.b {.a}},依此类推。

你可以向链中的任意函数追加额外参数。只需记住:从位置上看,被链式的值始终是下一个调用的第一个参数

示例 6

.a {x}::b {y} 会被转换为 .b {.a {x}} {y}

.sum {10} {5}::multiply {2}

30

许多核心函数被设计成以链式方式调用,例如None 的操作

紧凑函数调用

一个函数调用通常必须被空白、符号,或一行的开头/结尾所包围。这意味着与单词字符直接相邻的一个调用不会被识别:

示例 7

H.text {2} script:{sub}O

H.text {2} script:{sub}O

将整个函数调用用花括号包裹,可以让它出现在任何位置,而不受周围字符的影响。包裹的花括号会被编译器消费掉,不会出现在输出中:

示例 8

H{.text {2} script:{sub}}O

H2O

行内与块级函数调用

函数调用可以出现在两种上下文中:行内或块级。

行内调用

一个行内函数调用,其前后带有其他行内内容,例如文本。行内函数调用的输出会被简单地替换到父块中。

示例 9

Ever wondered what **26+16** equals? It's .sum {26} {16}. Here you go.

Ever wondered what 26+16 equals? It’s 42. Here you go.

块级调用

一个块级函数调用是孤立的。作为背景,在 Markdown 中,是指一个段落、一段代码片段、一段引用、一个列表,等等。

Paragraph 1

.myfunction {arg1} {arg2}

Paragraph 2

主体参数

函数最多接受一个主体参数,它指向函数的主体参数:通常是签名中的最后一个参数,不过有些函数会将另一个参数指定为主体(在其文档中以Likely body 显示)。

主体参数跨越多行,不使用括号包裹,并且要求每一行都缩进至少两个空格或一个制表符:

.myfunction {arg1} {arg2}
    Body argument, line 1
    and line 2.

整个主体必须共享相同的缩进。下面这个例子由于缩进不一致,会产生意外结果:

.myfunction {arg1} {arg2}
    Body argument, line 1

        and line 2. <!-- 这是一个 4 空格缩进的代码块! -->

在主体参数中嵌套函数

其他函数,无论是块级还是行内,都可以嵌套在主体参数内部:

.row alignment:{center}                    <!-- 块级  -->
    This document was made by .docauthor   <!-- 行内 -->

    .column                                <!-- 块级  -->
        The document name is .docname      <!-- 行内 -->

        .loremipsum                        <!-- 块级  -->