Writing pages

The Markdown that smalldocs reads, each feature with its source and its result.

A page is a Markdown file. smalldocs reads CommonMark, the standard form of Markdown. It also reads some additions to Markdown, which this page describes:

Each section below shows the source of a feature, and then the result.

.md and .qmd files

A page can be a .md file or a .qmd file. smalldocs reads both in the same way. A .qmd file is a Markdown file that uses the additions above. The name .qmd comes from Quarto, and the additions come from the Markdown of Pandoc, as Quarto uses it. So name a page .qmd to show that it uses them. A Markdown viewer that does not know them, such as the file view of GitHub, shows them as plain text.

A page can also be a Jupyter notebook, a .ipynb file. See Notebooks.

Front matter

Front matter is a block of YAML between two --- lines at the top of a page. It holds the options of the page:

---
title: Writing pages
description: The Markdown that smalldocs reads.
order: 3
---

The title goes at the top of the page and in the sidebar. The configuration lists the other options.

Text

smalldocs changes some characters in text. To keep them as you type them, set the option from: markdown-smart:

You write The page shows
"quoted" “quoted”
-- –
--- —
... …

Footnotes get numbers[1]. Text can be struck out, and code keeps its own characters.

A subscript goes between tildes, and a superscript goes between carets. So H~2~O shows H2O, and x^2^ shows x2. A subscript or a superscript cannot hold a space. To put a space in one, write a backslash before the space, as in P~a\ b~. Two tildes on each side still strike text out.

Term
A definition list gives each term its definition.
  • A task list
  • with boxes

Lists

A numbered list can count with letters or with roman numerals. Write each item with a letter or a numeral, and then a period or a parenthesis:

a. One
b. Two

i) First
ii) Second

(c) A list can start at a letter other than a.
(d) And it goes on from there.
  1. One
  2. Two
  1. First
  2. Second
  1. A list can start at a letter other than a.
  2. And it goes on from there.

A capital letter with a period needs two spaces after it, as in A. Text. With one space, the line is text, so a name such as “B. Smith” at the start of a line stays as it is. The same rule holds for the capital roman numerals I., V. and X..

Headings and attributes

Each heading has an id, so a link can point at it, as in config.qmd#globs. smalldocs makes the id from the text of the heading. The id is in lower case, with a - between the words. It keeps letters, digits, _, - and ., and it drops other punctuation and anything before the first letter. So ## A _quarto.yml gets the id a-_quarto.yml. Pandoc makes ids by the same rules, so a link written for Pandoc or Quarto still works.

To give your own id and classes, put them in braces:

## Install it {#install .important}

A link, a picture, a span and inline code take attributes too. A span is text in brackets with attributes after it. Write [text](url){.btn .btn-primary}, ![alt](pic.png){width="50%"} or [red]{.text-danger}. Here is a button and a span with a class.

Divs

A div is a block of the page with its own attributes. A line of three or more colons starts or ends a div. A line with attributes starts a div, and a line of colons only ends the innermost div. So divs can nest, with lines of the same length:

::: {.border .p-3}
Outer.

::: {.text-center}
Inner, in the centre.
:::
:::

Outer.

Inner, in the centre.

Callouts

A callout is a box that sets off a note, a tip or a warning:

::: {.callout-note}
A note, with the default title.
:::

::: {.callout-tip}
## A tip with its own title
The first heading in a callout becomes its title.
:::

::: {.callout-warning title="Folded" collapse="true"}
This warning opens when you click its title.
:::
Note

A note, with the default title.

A tip with its own title

The first heading in a callout becomes its title.

This warning opens when you click its title.

Important

An important callout. A caution callout comes next.

Caution

A caution with appearance="simple".

The attribute appearance takes default, simple or minimal, and icon=false removes the icon. To set them for each callout of a page, use the options callout-appearance and callout-icon in the front matter or in the config. The attributes of one callout still win over the options:

callout-appearance: simple
callout-icon: false

Tabs

A tabset is a group of tabs. In a div with the class panel-tabset, each heading becomes a tab:

def greet(name: str) -> str:
    "Say hello."
    return f"Hello, {name}!"
for name in Ann Bo; do echo "Hello, $name!"; done

A tab can hold any Markdown.

Tabsets with the same group attribute switch together. If you choose the tab “Shell” in one tabset, each other tabset of the group shows its tab “Shell” too. The browser keeps the choice for the next page that has the group. Click a tab below, and then look at the tabset above it:

::: {.panel-tabset group="language"}
## Python
...
## Shell
...
:::
print("Hello from a tabset of the group language.")
echo "Hello from a tabset of the group language."

Code

smalldocs colours code with Pygments, in the light theme and in the dark theme. See Themes. A copy button shows when the pointer is on the code. A filename goes above the code:

hello.py
import sys

def main() -> int:
    for arg in sys.argv[1:]:
        print(arg.upper())  # one line each
    return 0

A diff block shows a change to files, as git diff prints it. As on GitHub, smalldocs shows each removed line in red and each added line in green. The --- and +++ lines that name the files are red and green too. A hunk header, the line that starts with @@, is grey on a blue band. A diff --git or index line is grey and bold. The other lines keep their text as written, with the space at their start.

The names udiff and patch do the same. In a combined diff from a merge, smalldocs colours only the lines that start with + or -. Quarto and Pandoc colour a diff in the colours of strings and variables, and not in red and green.

--- a/hello.py
+++ b/hello.py
@@ -3,3 +3,3 @@
 def main() -> int:
-    for arg in sys.argv:
+    for arg in sys.argv[1:]:
         print(arg.upper())  # one line each

A code block whose fence names a language in braces, such as {python} or {r}, is a cell. A cell is code that is meant to run when the page is built, with its output in the page. smalldocs does not run code. It shows the cell as code, and the page shows no output. The build gives a warning for each page with cells.

A cell can start with option lines that begin with #|. smalldocs removes these lines. It hides the cell for #| echo: false or #| include: false. To hide every cell of a page, set echo: false in its front matter.

Line numbers, long lines and folded code

To number the lines of a code block, give it the attribute code-line-numbers="true". To number the lines of every block of a page, set the option code-line-numbers: true. A link to a line, such as #cb1-2, goes to that line:

def area(width: float, height: float) -> float:
    "Give the area of a rectangle."
    return width * height

A long line scrolls to the side. To wrap it onto the next line, set code-overflow: wrap for the page, or give one block the attribute code-overflow="wrap":

message = "This line is too long for the column of text, so it wraps onto the next line and does not scroll to the side."

To fold the code of a cell, set code-fold: true. The page then shows a line with the word “Code”, and the code opens when you click the line. With code-fold: show, the code starts open. code-summary gives other words for the line. A cell can set both options for itself in its #| lines. smalldocs folds only cells, and not other code blocks:

```{python}
#| code-fold: true
#| code-summary: "Show the code"
import math

print(math.pi)
```

The folded cell looks like this:

Show the code
import math

print(math.pi)

A cell of a notebook takes these options only from its own #| lines. The options of the page do not apply to it. See Folded code and line numbers.

Raw HTML

HTML in the Markdown goes into the page unchanged. A block marked {=html} also goes in unchanged:

This paragraph came from a raw HTML block.

Figures

A picture alone in its paragraph becomes a figure, if it has alt text. The alt text becomes the caption:

The smalldocs mark, drawn as an SVG.

The smalldocs mark, drawn as an SVG.

A figure starts at the left of the column, and its picture is in the centre of the figure, over the caption. Quarto puts the whole figure in the centre of the column. The attribute fig-align puts the figure at the left or the right. The option fig-align does the same for each figure of a page.

A screen reader reads the alt text of a picture. The attribute fig-alt gives an alt text that differs from the caption:

![The mark at the right.](../images/mark.svg){width=80px fig-align="right" fig-alt="A small logo."}

A small logo.

The mark at the right.

Figures side by side

A div with layout-ncol puts its blocks in columns. Each block, such as a figure or a paragraph, goes in a cell of its own. layout-nrow gives the number of rows. layout gives the width of each cell in each row. So layout="[[1,1],[1]]" makes two cells in the first row and one wide cell in the second. smalldocs does not read a negative width, which Quarto reads as an empty space.

On a phone, the cells go one under the other:

::: {layout-ncol=2}
![Left](../images/mark.svg){width=60px}

![Right](../images/mark.svg){width=60px}
:::

Left

Left

Right

Right

Tables

A table has a row of headings, a row of dashes, and a row for each line of the table. A | goes between the cells:

Feature Written as Note
A column | a | Put | at both ends of each row
Alignment |:---|---:| A colon sets the side
| in a cell \| A backslash before it

smalldocs does not read the grid tables of Pandoc, which are drawn with + and -.

Table captions

A paragraph that starts with : or Table: is the caption of the table directly before it or directly after it. Attributes in braces at the end of the caption belong to the table. The classes .striped, .hover, .bordered and .sm give the Bootstrap styles of the same names:

| Shortcode | Kind |
|---|---|
| `kbd` | Inline |
| `video` | Block |

: Two shortcodes. {#tbl-shortcodes .striped}
Two shortcodes.
Shortcode Kind
kbd Inline
video Block

A caption with an id, such as #tbl-shortcodes, puts the table in a figure with that id. A link to #tbl-shortcodes goes to the table. smalldocs does not number tables. The caption goes above the table. The option tbl-cap-location moves it to the bottom, or into the margin. The attribute tbl-cap-location in the braces does the same for one table.

Content for some builds only

smalldocs shows or leaves out a div or a span with the class .content-visible or .content-hidden, by these attributes:

Attribute Holds when
when-format="html" The page is built as HTML. smalldocs builds only HTML, so html, html:js and html5 hold, and other formats, such as pdf, do not
when-meta="key" The option of the page with that key is true. A key such as book.draft reads a nested option
when-profile="name" The environment variable QUARTO_PROFILE, a list of names with commas, has the name
unless-format, unless-meta, unless-profile The same test does not hold

smalldocs shows a .content-visible div when all its attributes hold. It leaves out a .content-hidden div when all its attributes hold. Content that it leaves out is not in the HTML, and the search box does not find it:

::: {.content-visible when-format="html"}
smalldocs shows this paragraph.
:::

::: {.content-visible when-format="pdf"}
smalldocs leaves this paragraph out.
:::

smalldocs shows this paragraph.

The margin and wide content

The margin is the column at the right of the text, where the table of contents is. A note in the margin stands beside the text that it belongs to. smalldocs reads the classes of Quarto for it.

This note is in a .column-margin div. It stands beside the paragraph below it.

A div with the class .column-margin goes in the margin. It starts level with the next paragraph, and it can hold any Markdown:

::: {.column-margin}
A note in the margin.
:::

A span with the class .aside goes in the margin, level with its line. Write it as [a short note]{.aside}, for example a note from a span in this paragraph.

Footnotes in the margin

To put each footnote in the margin, set reference-location in the config or in the front matter:

reference-location: margin

Each footnote then goes beside the paragraph that cites it first, and not to the end of the page. The links to the footnotes keep their anchors, #fn1 and #fnref1, as in Quarto.

Captions in the margin

To put the caption of each figure in the margin, set fig-cap-location: margin. For one figure, give the attribute fig-cap-location=margin to the picture. A figure with the class .column-margin goes in the margin itself, with its caption under it.

Content wider than the text

A div with one of these classes is wider than the text:

Class Width
.column-body-outset A little wider than the text, on both sides
.column-page From a little left of the text to the right side of the margin
.column-page-inset A little narrower than .column-page
.column-screen The whole width of the window
.column-screen-inset The width of the window, less a small space at each side
.column-screen-inset-shaded The same, with a shaded background

Each class except .column-page-inset and .column-screen-inset-shaded also has a -left and a -right form, which is wide on one side only. A figure in such a div fills its width if the figure has width=100%.

On a narrow screen, the content of the margin goes into the text, after the paragraph it belongs to. Content for a wide column takes the width of the text. If margin or wide content passes under the sidebar or the table of contents, that panel is hidden until the content has passed.

Maths

Inline maths goes between dollars, as in \(e^{i\pi} + 1 = 0\). Display maths goes between double dollars:

\[\int_0^1 x^2 \, dx = \frac{1}{3}\]

Double dollars inside a sentence also give display maths, on a line of its own, as in Quarto.

KaTeX, a JavaScript library, draws the maths. smalldocs loads KaTeX only on pages that have maths.

smalldocs reads a dollar as the start of maths when it has no digit before it and no space after it. The maths ends at the next dollar in the paragraph. If that dollar has a space before it or a digit after it, the first dollar is only a dollar. So the text “it costs $5 and $10” stays as it is. To keep one dollar as a dollar, write \$.

For text with many prices, set the option from: markdown-tex_math_dollars, in the front matter or in _smalldocs.yml. Then each dollar is a dollar, and smalldocs draws no maths written with dollars.

Diagrams

The JavaScript library mermaid.js draws a mermaid block. smalldocs loads it only on pages that have a diagram:

flowchart LR
  A[_smalldocs.yml] --> B(smalldocs render)
  C[pages] --> B
  B --> D[_site]

Shortcodes

A shortcode is a tag in double braces that smalldocs replaces before it reads the Markdown. smalldocs replaces these shortcodes everywhere except in code blocks:

Shortcode Becomes
{{< include _part.qmd >}} The file, without its front matter
{{< meta title >}} An option of the page: Writing pages
{{< var version >}} A value from _variables.yml, a YAML map of names to values at the root of the project
{{< env HOME >}} An environment variable
{{< kbd Shift-Ctrl-P mac=Shift-Command-P >}} Keys to press: Shift-Ctrl-P. mac, win and linux give the keys on each system, which show when the pointer is on the keys
{{< video https://www.youtube.com/watch?v=ID >}} A video. A YouTube, Vimeo or Brightcove address becomes a player from that site. A file becomes a <video> with controls, and smalldocs copies the file into the site. title, width, height, aspect-ratio and start set the video
{{< lipsum 2 >}} Two paragraphs of placeholder text
{{< placeholder 120 40 >}} A grey box of 120 by 40 pixels, in place of a picture:

To show a shortcode as it is, put /* and */ inside its braces. The left column of the table does so in its source.


  1. A footnote goes to the end of the page. ↩︎