/

Syntax of a function call

Functions are the key feature of Quarkdown, distinguishing it from other Markdown dialects and many other markup languages. They are loaded from external libraries, either native (e.g., standard library) or defined in a Quarkdown source, and come in different categories:

CategoryExamples
Layout rulesrow, column, grid, center
Utility viewstableofcontents, whitespace
Mathematical and logical operationssum, divide, pow, sin, isgreater
Control structures and statementsif, foreach, repeat, var, let, function
File datainclude, csv, read
Alteration of document metadatadocname, docauthor, doctype, theme, pageformat

Basic syntax

When called from a Quarkdown source, the function name is preceded by a . (dot) and each argument is wrapped in curly brackets.

.myfunction {arg1} {arg2}

Example 1

.multiply {6} {3}

18

Positional and named arguments

In the previous snippet, arg1 and arg2 refer to the first and second parameter of the function signature respectively. These are called positional arguments because their meaning is determined by their position in the call.

An argument can also refer to a parameter by name. These named arguments use the syntax name:{arg}.

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

Example 2

You can mix positional and named arguments to improve readability of the function call, as long as all arguments that follow a named argument are named as well.

.multiply {6} by:{3}

18

Multi-line arguments

Arguments can span over multiple lines. Indentation is optional and arbitrary.

Example 3

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

-0.33333334

Nested function calls

Function calls can be nested in arguments, allowing you to compose complex expressions.

Example 4

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

28.274334

Chaining calls

Although Quarkdown exclusively relies on top-level declarations, it exploits some OOP-like syntactic sugar that greatly increases the readability of nested function calls.

Consider the following call:

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

This performs (3^2 - 1) + 2 = 10. As simple as it is, it could not be harder to write and read! The following call is totally equivalent:

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

Much better. It now resembles the way we naturally read math.

To understand how chaining works, consider this simpler example (see Variables to learn more about variables):

.myvar::uppercase

Behind the scenes, the compiler transforms this call into:

.uppercase {.myvar}

Example 5

.var {myvar} {hello!}

.myvar::uppercase

HELLO!

Generally speaking, .a::b is transformed into .b {.a}, .a::b::c into .c {.b {.a}}, and so on.

You can append additional arguments to any function in the chain. Just keep in mind that the chained value is always the first argument, positionally speaking, of the next call.

Example 6

.a {x}::b {y} is transformed into .b {.a {x}} {y}:

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

30

Many core functions are designed to be called in a chain, for example None operations.

Block vs. inline function calls

Function calls can appear in two contexts: inline or block.

Inline calls

An inline function call is preceded and/or followed by other inline content, such as text. The output of an inline function call is simply replaced in the parent’s block.

Example 7

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.

Block calls

A block function call is an isolated one. For context, in Markdown, a block is a paragraph, a code snippet, a quote, a list, and so on.

Paragraph 1

.myfunction {arg1} {arg2}

Paragraph 2

The body argument

The main difference between inline and block function calls is a special argument called body argument. This argument always refers to the last parameter of the signature (even if named arguments were used).

A body argument expands over multiple lines, is not wrapped by brackets, and requires each line to be indented by at least two spaces or one tab:

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

The whole body must share the same indentation. The following produces unexpected results, as indentation is inconsistent:

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

        and line 2. <!-- This is a 4-spaces indented code block! -->

Nesting functions in body arguments

Other functions, block or inline, can be nested inside body arguments:

.row alignment:{center}                    <!-- Block  -->
    This document was made by .docauthor   <!-- Inline -->

    .column                                <!-- Block  -->
        The document name is .docname      <!-- Inline -->

        .loremipsum                        <!-- Block  -->

Body arguments and inline calls

When nested inside inline arguments, function calls are always inline. Thus, the following is invalid since body arguments are accepted only in block calls:

.center {
    .row
        Hi
}

While this is valid as .row is called within a body argument:

.center
    .row
        Hi