xidoc

This is a reference of all xidoc commands. A question mark ? before a parameter means that it's optional. An asterisk * before a parameter means that it can take any number of values.

Top-level commands

These commands can be used anywhere within xidoc, unless overridden by other commands.

Basic constructs

[# anything]

Comment. Always returns nothing, ignoring what's inside.
ExampleOutput
I [# don't] like xidoc.
I like xidoc.

[(]

Returns a left square bracket.
ExampleOutput
I'm a sad robot :[(]
I'm a sad robot :[

[)]

Returns a right square bracket.
ExampleOutput
I'm a happy robot :[)]
I'm a happy robot :]

[() text]

Wraps text in square brackets.
ExampleOutput
[() this-is-not-a-command]
[this-is-not-a-command]

[;]

Returns a semicolon. Useful for “escaping” semicolons in commands that take multiple arguments.
ExampleOutput
[list This[;] is[;] only[;] one[;] item]
  • This; is; only; one; item

[space]

Returns a space character. Useful in commands that strip whitespace.

[raw text]

Returns the given text without expanding it.
ExampleOutput
[raw [I can use [as many brackets [as I want]], but [they] still have to [[be balanced]]].]
[I can use [as many brackets [as I want]], but [they] still have to [[be balanced]]].
[\ text]
Removes the least common indentation from all lines of text, then returns it without expanding. A “smarter” version of [raw].
ExampleOutput
[code-block nim; [\
  for word in ["This", "correctly", "removes", "indentation"]:
    echo word
]]
for word in ["This", "correctly", "removes", "indentation"]:
  echo word

[pass code]

Directly produces the given code without escaping it. Useful if you want to go outside the capabilities of xidoc. The code is still expanded so you can parametrize it, see the [pass-raw] command if you don't want this.
ExampleOutput
[pass <em>Haha!</em> I'm in! <code>'; DROP TABLE xidoc;</code> Oh no, this is a static site…]
Haha! I'm in! '; DROP TABLE xidoc; Oh no, this is a static site…
[pass-raw code]
Directly produces the given code without escaping it. Useful if you want to go outside the capabilities of xidoc. Works as a combination of [pass] and [raw].

[hide text]

Expands text for its side effects, but doesn't return anything.

[expand text]

After expanding text, expands it again. Useful for complex command definitions.

[render text]

After expanding text, renders it. Useful for complex command definitions.
ExampleOutput
[render [raw [it This will be italic despite being inside [ms raw].]]]
This will be italic despite being inside raw.

[add-to-head directive]

Adds the directive to the head of the document. Returns nothing.

Inline formatting

[bf text]

Renders text in bold face.
ExampleOutput
xidoc is [bf awesome]!
xidoc is awesome!

[code ?language; code]

Renders the code in monospace font. If the language is specified and the target is HTML, the code is syntax-highlighted during compilation using Prism. See the list of supported languages to know how to specify the language. xidoc is also supported under the name xidoc. For generic monospace text, use the [ms] command.
ExampleOutput
[code python; [raw print(f"The answer to the universe and stuff is {6 * 7}.")]]
print(f"The answer to the universe and stuff is {6 * 7}.")

[color color text]

Colors the text in the given CSS-style color.
ExampleOutput
You can use [color red; names] or [color #00f; codes]!
You can use names or codes!

[it text]

Renders text in italics.
ExampleOutput
xidoc is [it fantastic!]
xidoc is fantastic!

[lang language; text]

Renders text with the conventions of the specified language.
ExampleOutput
[" Hello!] [lang czech; [" Ahoj!]]
“Hello!” „Ahoj!“

[ms text]

Renders text in monospace. If you want to show code, it's recommended to use the [code] or [code-block] command instead.
ExampleOutput
In HTML, this will produce [ms <code>]. In [LaTeX], this will produce [ms \texttt].
In HTML, this will produce <code>. In LaTeX, this will produce \texttt.

[term phrase]

Introduces phrase as a new term. Useful in definitions.
ExampleOutput
A [term group] is a monoid where every element has an inverse.
A group is a monoid where every element has an inverse.

[unit ?number; unit]

Renders a unit or a quantity expressed with a number and unit. Also works inside math commands.
ExampleOutput
[unit 6378; km], [$ [unit 60; [/ km; h]]]
6378 km, 60kmh60\,\frac{\mathrm{km}}{\mathrm{h}}

Block formatting

[block-quote text]

Creates a block quote.
ExampleOutput
[p The first rule in the Zen of Nim is:] [block-quote Copying bad design is not good design.]

The first rule in the Zen of Nim is:

Copying bad design is not good design.

[checkboxes items]

Renders a list of items with checkboxes. Use [-] for an unchecked item, [v] for a checked item and [x] for a crossed item.
ExampleOutput
[checkboxes [v Kill the friend] [- Bury the body] [x Get caught by the police]]
  • Kill the friend
  • Bury the body
  • Get caught by the police

[code-block ?language; code]

Renders the code as a block in monospace font. If the language is specified and the target is HTML, the code is syntax-highlighted during compilation using Prism. See the list of supported languages to know how to specify the language. xidoc is also supported under the name xidoc.
ExampleOutput
[code-block javascript; [raw
const factorial = (n) => {
  let result = 1n;
  for (let i = 1; i <= n; i++) {
    result *= BigInt(i);
  }
  return result;
}
]]
const factorial = (n) => {
  let result = 1n;
  for (let i = 1; i <= n; i++) {
    result *= BigInt(i);
  }
  return result;
}

[list *items]

Creates an unordered list of items.
ExampleOutput
Supported targets: [list HTML; [LaTeX]; Gemtext]
Supported targets:
  • HTML
  • LaTeX
  • Gemtext

[ordered-list *items]

Creates an ordered list of items.
ExampleOutput
TOP 5 LIST OF SMALLEST POSITIVE INTEGERS: [ordered-list 1; 2; 3; 4; 5]
TOP 5 LIST OF SMALLEST POSITIVE INTEGERS:
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5

[p text]

Creates a paragraph with the given text.

[section ?title; text]

Creates a section with the given title and text (or without a title if not given). If it's inside another section, it will be a subsection. If it's inside a subsection, it will be a subsubsection. In HTML, this nesting can continue further.
ExampleOutput
[section Inception; Are we going too deep?]
Inception
Are we going too deep?

[spoiler visible; secret]

Hides the secret text until the visible text is clicked. Works only in environments that support interactivity.
ExampleOutput
[spoiler In the series [it The Simpsons], the surname of the main characters is; [it Simpson]]
In the series The Simpsons, the surname of the main characters isSimpson

[table ?spec; content]

Creates a table with the given content, which should consist of [row] commands. The spec is used to help LaTeX align the table.
ExampleOutput
[table
  [header-row xidoc; HTML; [LaTeX]]
  [row [code xidoc; [() table]]; [code html; <table></table>]; [code latex; \begin{table}{[...]}\end{table}]]
]
xidocHTMLLaTeX
[table]<table></table>\begin{table}{}\end{table}
[row *fields]
Creates a row for a table with the given fields. Has to be used inside a [table] command.
[header-row *fields]
Creates a header row for a table with the given fields. Has to be used inside a [table] command.

[title title; ?author]

Renders the given title and sets it as the title of the document. If an author is specified, their name is mentioned under the title.
[show-title title]
Renders the given title without setting it as the title of the document.

Unicode characters

[" text]

Puts the given text in quotation marks appropriate for the current language.
ExampleOutput
[" Hello!] [lang czech; [" Ahoj!]]
“Hello!” „Ahoj!“

[--]

Returns an en dash:
ExampleOutput
80[--]100% of people don't know the difference between a dash and a hyphen.
80–100% of people don't know the difference between a dash and a hyphen.

[---]

Returns an em dash:
ExampleOutput
Em dash [---] the character many people don't know how to write.
Em dash — the character many people don't know how to write.

[...]

Returns an ellipsis:
ExampleOutput
You can't just substitute three dots for an ellipsis[...]
You can't just substitute three dots for an ellipsis…

Math

In HTML, LaTeX math is rendered using KaTeX. This requires a stylesheet and fonts, which are downloaded from the jsDelivr CDN by default. If you'd like to use a different CDN or self-hoost the files, use [set katex-stylesheet-path; path/to/katex.min.css] to point xidoc to the stylesheet.

[$ latex]

Renders LaTeX inline math.
ExampleOutput
Einstein's famous equation is [$ E = m c^2].
Einstein's famous equation is E=mc2E = m c^2.

[$$ latex]

Renders LaTeX block math.
ExampleOutput
[$$ (A+B)^n = \sum_{k=0}^n {n \choose k} A^{n-k} B^k]
(A+B)n=k=0n(nk)AnkBk(A+B)^n = \sum_{k=0}^n {n \choose k} A^{n-k} B^k
[$$& latex]
Renders LaTeX aligned block math (with the align environment).
ExampleOutput
[$$& ((f \circ g) \circ h)(x) &= f(g(h(x))) \\ &= (f \circ (g \circ h))(x)]
((fg)h)(x)=f(g(h(x)))=(f(gh))(x)\begin{align*}((f \circ g) \circ h)(x) &= f(g(h(x))) \\ &= (f \circ (g \circ h))(x)\end{align*}

[matext latex]

Renders the given LaTeX math using maTeXt and presents it as preformatted text.
ExampleOutput
[matext \vec x \cdot \vec y = \sum_{i=0}^n x_i \cdot y_i]
          𝑛          
𝑥⃗ ⋅ 𝑦⃗ =   ∑   𝑥  ⋅ 𝑦 
        𝑖 = 0  𝑖    𝑖

[dfn ?name; text]

Renders a mathematical definition paragraph with an optional name.
ExampleOutput
[dfn An [term inertial system] is a system where the law of inertia holds.]

[theorem ?name; text]

Renders a mathematical theorem paragraph with an optional name.
ExampleOutput
[theorem Pythagorean; In a right triangle with legs [$ a,b] and hypotenuse [$ c], [$ a^2 + b^2 = c^2].]

[proof ?name; text]

Renders a mathematical proof paragraph with an optional name.
ExampleOutput
[proof Left as an exercise to the reader.]

[example ?name; text]

Renders a mathematical example paragraph with an optional name.

[exercise ?name; text]

Renders a mathematical exercise paragraph with an optional name.
ExampleOutput
[exercise Determine if the Collatz sequence reaches [$ 1] for every initial value.]

[lemma ?name; text]

Renders a mathematical lemma paragraph with an optional name.

[solution ?name; text]

Renders a paragraph with the solution to a mathematical problem with an optional name.
[spoiler-solution ?name; text]
Renders a paragraph with the solution to a mathematical problem with an optional name. In environments that support interactivity, the text is hidden inside a spoiler (see the [spoiler] command).

[props *properties]

Creates a list of mathematical properties. Currently the same as [list].
ExampleOutput
[props [$ \forall x,y,z \in G: (xy)z = x(yz)]; [$ \exists e \in G, \forall x \in G: ex = x = xe]; [$ \forall x \in G, \exists x^{-1} \in G: xx^{-1} = e = x^{-1}x]]
  • x,y,zG:(xy)z=x(yz)\forall x,y,z \in G: (xy)z = x(yz)
  • eG,xG:ex=x=xe\exists e \in G, \forall x \in G: ex = x = xe
  • xG,x1G:xx1=e=x1x\forall x \in G, \exists x^{-1} \in G: xx^{-1} = e = x^{-1}x

Logos

[LaTeX]

Renders the LaTeX logo.
ExampleOutput
[LaTeX]
LaTeX

[xidoc]

Renders the xidoc logo. Note that the logo might change in the future.
ExampleOutput
[xidoc]

Modularity

[inject file]

Pastes the content of file and renders it.

[include file; *(name; value)]

Renders the content of file as a separate document and pastes it. You can give arguments to the subdocument, which can be retrieved with the [template-arg] command.
[template-arg name]
In a document included with [include], returns the given argument passed to [include].

Settings

[set key; value]

Changes the value of a setting. All settings are global. Currently the only setting is katex-stylesheet-path, which is explained in the Math section.
[reset key]
Resets the value of a setting to the default.

[set-doc-lang language]

Sets the global language of the document. Returns nothing.

[set-syntax-highlighting-theme theme]

Sets the theme for syntax highlighting with the [code] and [code-block] commands. The available themes are default, dark, funky, okaidia, twilight, coy, solarized-light, and tomorrow-night. You can try out these themes on the Prism website. There is also funky-x, a modification of funky with a black background instead of weird stripes.

[set-title title]

Sets the given title as the title of the document.

Custom commands

[def name; ?params; body]

Defines a command with the given name that expands to body. If params, which should be space-separated words, are given, the command can take arguments, which can be accessed using the [arg] command and its variants ([arg-expand], [arg-raw], [arg-raw-escape]). The command will only be visible in the scope where it was defined; if you want it to be visible everywhere, use [def-global].
ExampleOutput
[def greet; name; Hello, [arg name]!][greet reader]
Hello, reader!
[def-global name; ?params; body]
Defines a command with the given name that expands to body. If params, which should be space-separated words, are given, the command can take arguments, which can be accessed using the [arg] command and its variants ([arg-expand], [arg-raw], [arg-raw-escape]). The command will be visible everywhere; if you want it to be visible only in the scope where it was defined, use [def].
ExampleOutput
[hide [def-global greet; name; Hello, [arg name]!]][greet reader]
Hello, reader!

[arg parameter]

Inside a command definition ([def]), renders the argument given to the parameter.
ExampleOutput
[def greet; name; Hello, [arg name]!][greet reader]
Hello, reader!
[arg-expand parameter]
Inside a command definition ([def]), expands the argument given to the parameter, but doesn't render it.
[arg-raw parameter]
Inside a command definition ([def]), returns the argument given to the parameter, but doesn't expand it.
[arg-raw-escape parameter]
Inside a command definition ([def]), returns the argument given to the parameter, but doesn't expand it; however, the raw string is rendered.

Target detection

[if-html text]

Evaluates text only if the target is HTML, otherwise returns nothing.
ExampleOutput
[if-html You can see this only if you're in HTML!]
You can see this only if you're in HTML!

[if-latex text]

Evaluates text only if the target is LaTeX, otherwise returns nothing.
ExampleOutput
[if-latex You can see this only if you're in [LaTeX]!]

[if-gemtext text]

Evaluates text only if the target is Gemtext, otherwise returns nothing.
ExampleOutput
[if-gemtext You can see this only if you're in Gemtext!]

List manipulation

[for-each name; list; template]

Applies the template to each item of the list, making it available as name.
ExampleOutput
[join [space]; [for-each lang; HTML [LaTeX] Gemtext; xidoc compiles to [lang].]]
xidoc compiles to HTML. xidoc compiles to LaTeX. xidoc compiles to Gemtext.

[join separator; list]

Joins the list using the given separator.
ExampleOutput
[join [space]; [for-each lang; HTML [LaTeX] Gemtext; xidoc compiles to [lang].]]
xidoc compiles to HTML. xidoc compiles to LaTeX. xidoc compiles to Gemtext.

File manipulation

[get-doc-path-absolute]

Gets the absolute path of the current document.

[get-doc-path-relative-to-containing name]

Gets the path of the current document, relative to the nearest ancestor that contains a file/directory/symlink with the given name.
ExampleOutput
Within the Git repository of xidoc, the command reference is located at [ms [get-doc-path-relative-to-containing .git]].
Within the Git repository of xidoc, the command reference is located at docs/commands.xd.

[list-dirs pattern]

Lists all directories that match the glob pattern, relative to the current file.
ExampleOutput
The subdirectories of the [ms src] directory of xidoc are: [join ,[space]; [list-dirs ../src/*]].
The subdirectories of the src directory of xidoc are: ../src/duktape, ../src/janet, ../src/katex, ../src/pkgs, ../src/prism, ../src/xidocpkg.

[list-files pattern]

Lists all files that match the glob pattern, relative to the current file.
ExampleOutput
The xidoc sources of this documentation are: [join ,[space]; [list-files *.xd]].
The xidoc sources of this documentation are: commands.xd, head.xd, index.xd, manual.xd, playground.xd, todo.xd.

Programming

[janet-call function; *arguments]

Calls the given Janet function with the given arguments as strings and returns the result, which has to be a string. Useful for doing complex logic when xidoc's built-ins don't suffice. Note that all Janet is evaluated in the same context, which you can make use of, but be careful!
ExampleOutput
The circumference of a circle with radius 6 is [janet-call [raw (fn [radius] (describe (* 2 math/pi (scan-number radius))))]; 6].
The circumference of a circle with radius 6 is 37.6991.

[janet-eval code; *(name; value)]

Evaluates the given Janet code. If some pairs of name and value are given, the code will have access to global definitions with the given names and values. Useful for doing complex logic when xidoc's built-ins don't suffice. Note that all Janet is evaluated in the same context, which you can make use of, but be careful!
ExampleOutput
The greatest common divisor of 128 and 168 is [janet-eval [raw (do
    (defn gcd [a b]
      (if (= b 0)
        a
        (gcd b (% a b))))
    (describe (gcd
      (scan-number a)
      (scan-number b))))
      ]; a;128 ; b;168].
The greatest common divisor of 128 and 168 is 8.

[js-call function; *arguments]

Calls the given JavaScript function with the given arguments as strings and returns the result as a string. Useful for doing complex logic when xidoc's built-ins don't suffice. Note that the JavaScript engine currently used by xidoc is Duktape, which supports only ES5 and certain ES6 features. Notably, it doesn't support arrow functions, so for an anonymous function, you need to use the old (function() {}) syntax. Also note that all JavaScript is evaluated in the same context, which you can make use of, but be careful!
ExampleOutput
The area of a circle with radius 6 is [js-call [raw (function(radius) { return Math.PI * radius * radius; })]; 6].
The area of a circle with radius 6 is 113.09733552923255.

[js-eval code; *(name; value)]

Evaluates the given JavaScript code. If some pairs of name and value are given, the code will have access to global variables with the given names and values. Useful for doing complex logic when xidoc's built-ins don't suffice. Note that the JavaScript engine currently used by xidoc is Duktape, which supports only ES5 and certain ES6 features. Notably, it doesn't support arrow functions, so for an anonymous function, you need to use the old (function() {}) syntax. Also note that all JavaScript is evaluated in the same context, which you can make use of, but be careful!
ExampleOutput
The roots of the polynomial [$ 3x^2 - 18x + 24] are [js-eval [raw {
  var discriminant = b*b - 4*a*c;
  var root1 = (-b + Math.sqrt(discriminant)) / (2 * a);
  var root2 = (-b - Math.sqrt(discriminant)) / (2 * a);
  root1 + ", " + root2
}]; a;3 ; b;-18 ; c;24].
The roots of the polynomial 3x218x+243x^2 - 18x + 24 are 4, 2.

HTML-specific

[html-add-attrs attrs; cmd]

If the target is HTML, adds the given attributes to the tag produced by cmd. Supports the .foo and #foo syntax for specifying classes and IDs.
ExampleOutput
[html-add-attrs style="color:pink"; [bf Real men don't fear colors.]]
Real men don't fear colors.

[js-module code]

If the target is HTML, adds the given JavaScript code to the page as a JavaScript module. If you don't need to use any xidoc commands inside the code, it's recommended to use [js-module-raw].
[js-module-raw code]
Works as a combination of [js-module] and [raw].
ExampleOutput
[<span> #change-me; I will be changed] [js-module-raw document.getElementById("change-me").innerText = "I was changed"]
I will be changed

[style stylesheet]

Styles an HTML document using xidoc's custom syntax for CSS.
ExampleOutput
[style [rule .golden-frame; [: border; 3px solid gold]]][<div> .golden-frame; This text is a work of art!]
This text is a work of art!

Other top-level commands

[draw ?width; ?height; description]

[Experimental] Draws a vector image with the given dimensions based on the description. The description format won't be documented until it's stabilized.
ExampleOutput
[draw 80; 80;
  [Rcu 180,240; 120,120;;; yellow]
  [Lab 60,120; 180,0; 10; red]
  [Lab 180,0; 300,120; 10; red]
  [Rau 180,260; 60,100;;; brown]
]

HTML commands

When compiling to HTML, you can use tag commands to generate arbitrary tags. For example, [<> a; .click-here; href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"; CLICK HERE] produces a link with the class click-here and the text CLICK HERE. Default tags have a shorthand, so this could also be written as [<a> .click-here; href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"; CLICK HERE]. However, the latter syntax doesn't work for custom tags.

CSS commands

xidoc includes a simple set of commands that can be used to generate CSS without having to embed a completely different syntax in your document. It can be included using the [style] command. (If you prefer normal CSS, use [add-to-head [<style>]].)

[: property; value]

Creates a CSS declaration: property: value;.

[:! property; value]

Creates an important CSS declaration: property: value !important;. Please don't overuse this.

[rule selector; declarations]

Creates a CSS rule: selector { declarations }.

[var name; ?value]

If a value is given, declares a CSS variable: --name: value;. If used outside a [rule], it's assigned to :root. If used without a value, it gets the value of the given variable: var(--name).

Math commands

These commands are available in LaTeX math. That is, inside the [$], [$$] and [$$&] commands. They are meant to make certain common combinations of LaTeX commands easier to type.

[_ something]

Produces literal square brackets in the LaTeX code.
ExampleOutput
[$ \sqrt[_ 3]{2}]
23\sqrt[3]{2}

The following commands should be self-explanatory from the examples:

CommandOutput
[/ q]1q\frac{1}{q}
[/ p; q]pq\frac{p}{q}
[. \frac{p}{q}](pq){\left(\frac{p}{q}\right)}
[() \frac{p}{q}][pq]{\left[\frac{p}{q}\right]}
[{} \frac{p}{q}]{pq}{\left\{\frac{p}{q}\right\}}
[<> \frac{p}{q}]pq{\left\langle \frac{p}{q}\right\rangle}
[| \frac{p}{q}]pq{\left\lvert \frac{p}{q}\right\rvert}
[|| \frac{p}{q}]pq{\left\lVert \frac{p}{q}\right\rVert}
[v. \frac{p}{q}]pq{\overgroup{\undergroup{\frac{p}{q}}}}
[floor \frac{p}{q}]pq{\left\lfloor \frac{p}{q}\right\rfloor}
[ceil \frac{p}{q}]pq{\left\lceil \frac{p}{q}\right\rceil}
[dd x]dx{\mathrm dx}
[dv x]ddx\frac{\mathrm d}{\mathrm dx}
[dv f; x]dfdx\frac{\mathrm df}{\mathrm dx}
[dv^ 2; x]d2dx2\frac{\mathrm d^{2}}{\mathrm dx^{2}}
[dv^ 2; f; x]d2fdx2\frac{\mathrm d^{2}f}{\mathrm dx^{2}}
[pdv x]x\frac{\partial}{\partial x}
[pdv f; x]fx\frac{\partial f}{\partial x}
[pdv^ 2; x]2x2\frac{\partial^{2}}{\partial x^{2}}
[pdv^ 2; f; x]2fx2\frac{\partial^{2}f}{\partial x^{2}}
[mat a&b\\c&d]abcd\begin{matrix}a&b\\c&d\end{matrix}
[.mat a&b\\c&d](abcd)\begin{pmatrix}a&b\\c&d\end{pmatrix}
[(mat) a&b\\c&d][abcd]\begin{bmatrix}a&b\\c&d\end{bmatrix}
[|mat| a&b\\c&d]abcd\begin{vmatrix}a&b\\c&d\end{vmatrix}
[||mat|| a&b\\c&d]abcd\begin{Vmatrix}a&b\\c&d\end{Vmatrix}
[lim]limn\lim_{n\to \infty}
[lim m]limm\lim_{m\to \infty}
[lim x; 0]limx0\lim_{x\to 0}
[liminf]lim infn\liminf_{n\to \infty}
[limsup]lim supn\limsup_{n\to \infty}
[int x; t]xdt\int x\,\mathrm dt
[int T; x; t]Txdt\int_{T}x\,\mathrm dt
[int t_1; t_2; x; t]t1t2xdt\int_{t_1}^{t_2}x\,\mathrm dt