Markdown Syntax
Slides are written within a single markdown file (by default ./slides.md
).
You can use the Markdown features as you normally would, with the additional support of inlined HTML and Vue Components. Styling using UnoCSS is also supported. Use ---
padded with a new line to separate your slides.
# Kolibry
Hello, World!
---
# Page 2
Directly use code blocks for highlighting
//```ts
console.log('Hello, World!')
//```
---
# Page 3
You can directly use Windi CSS and Vue components to style and enrich your slides.
<div class="p-3">
<Tweet id="20" />
</div>
Front Matter & Layouts
Specify layouts and other metadata for each slide by converting the separators into front matter blocks. Each frontmatter starts with a triple-dash and ends with another. Texts between them are data objects in YAML format. For example:
---
layout: cover
---
# Kolibry
This is the cover page.
---
layout: center
background: './images/background-1.png'
class: 'text-white'
---
# Page 2
This is a page with the layout `center` and a background image.
---
# Page 3
This is a default page without any additional metadata.
Refer to customization for more details.
The custom syntax might not be compactible with some formatters like Prettier. To improve that, we also support using a direct
yaml
code block to define the frontmatter:--- layout: cover --- # Kolibry This is the cover page. --- ```yaml # The first yaml block will be treated as the frontmatter of that slide layout: center background: './images/background-1.png' class: 'text-white' ``` # Page 2 This is a page with the layout `center` and a background image.
Code Blocks
One big reason I am building Kolibry is needing to make my code look just right in the slides. So just as you expected, you can use Markdown flavored code block to highlight your code.
//```ts
console.log('Hello, World!')
//```
We support Prism and Shiki as syntax highlighters. Refer to the highlighters section for more details.
Line Highlighting
To highlight specific lines, simply add line numbers within bracket {}
. Line numbers start counting from 1 by default.
//```ts {2,3}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
//```
You can enable line number to all slides by setting lineNumbers: true
on the config or enable each code block individually by setting lines:true
. In case you want to disable the numbering for an specific block when lineNumbers: true
you can set lines:false
for that block:
//```ts {2,3} {lines:true}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
//```
You can also set the starting line for each code block and highlight the lines accordingly, defaults to 1:
//```ts {6,7} {lines:true, startLine:5}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
//```
To change the highlight in multiple steps, you can use |
to separate them. For example
//```ts {2-3|5|all}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
//```
This will first highlight a: Ref<number> | number
and b: Ref<number> | number
, and then return computed(() => unref(a) + unref(b))
after one click, and lastly, the whole block. Learn more in the clicks animations guide.
You can start the highlight at a specific click:
//```ts {2-3|5|all} {at:0}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
//```
This is especially useful when you need to sync different animations (when using two-cols
layout and list animation for instance).
To skip highlighting any lines, you can set the line number to 0
. For example
//```ts {0}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
//```
If the code doesn't fit into one slide, you can pass an extra maxHeight option which will set fixed height and enable scrolling
//```ts {2|3|7|12} {maxHeight:'100px'}
function add(
a: Ref<number> | number,
b: Ref<number> | number
) {
return computed(() => unref(a) + unref(b))
}
/// ...as many lines as you want
const c = add(1, 2)
//```
Monaco Editor
Whenever you want to do some modification in the presentation, simply add {monaco}
after the language id — it turns the block into a fully-featured Monaco editor!
//```ts {monaco}
console.log('HelloWorld')
//```
Learn more about configuring Monaco.
Monaco diff
Monaco can also generate a diff between two code blocks. Use {monaco-diff}
to turn the block into a diff Monaco editor and use ~~~
to separate both original and modified version of the code!
//```ts {monaco-diff}
This line is removed on the right.
just some text
abcd
efgh
Some more text
~~~
just some text
abcz
zzzzefgh
Some more text.
This line is removed on the left.
//```
Embedded Styles
You can use <style>
tag in your Markdown directly to override styles for the current slide.
# This is Red
<style>
h1 {
color: red
}
</style>
---
# Next slide is not affected
<style>
tag in Markdown is always scoped. As an outstanding result, a selector with the child combinator (.a > .b
) is unusable as such; see the previous link. To have global style overrides, check out the customization section.
Powered by UnoCSS, you can directly use nested css and directives (e.g. @apply
)
# Kolibry
> Hello `world`
<style>
blockquote {
code {
@apply text-teal-500 dark:text-teal-400;
}
}
</style>
Static Assets
Just like you would do in markdown, you can use images pointing to a remote or local url.
For remote assets, the built-in vite-plugin-remote-assets
will cache them into the disk at the first run so you can have instant loading even for large images later on.
![Remote Image](https://kolibry.dev/favicon.png)
For local assets, put them into the public
folder and reference them with leading slash.
![Local Image](/pic.png)
For you want to apply custom sizes or styles, you can convert them to the <img>
tag
<img src="/pic.png" class="m-40 h-40 rounded shadow" />
Notes
You can also take notes for each slide. They will show up in Presenter Mode for you to reference during presentations.
In Markdown, the last comment block in each slide will be treated as a note.
---
layout: cover
---
# Page 1
This is the cover page.
<!-- This is a note -->
---
# Page 2
<!-- This is NOT a note because it precedes the content of the slide -->
The second page
<!--
This is another note
-->
Icons
Kolibry allows you to have the accessing to almost all the popular open-source iconsets directly in your markdown. Powered by unplugin-icons
and Iconify.
The naming follows Iconify's conversion {collection-name}-{icon-name}
. For example:
<mdi-account-circle />
- from Material Design Icons<carbon-badge />
- from Carbon<uim-rocket />
- from Unicons Monochrome<twemoji-cat-with-tears-of-joy />
- from Twemoji<logos-vue />
- from SVG Logos- And much more...
Browse and search for all the icons available with Icônes.
Styling Icons
You can style the icons just like other HTML elements. For example:
<uim-rocket />
<uim-rocket class="text-3xl text-red-400 mx-2" />
<uim-rocket class="text-3xl text-orange-400 animate-ping" />
Slots
Some layouts can provide multiple contributing points using Vue's named slots.
For example, in two-cols
layout, you can have two columns left (default
slot) and right (right
slot) side by side.
---
layout: two-cols
---
<template v-slot:default>
# Left
This shows on the left
</template>
<template v-slot:right>
# Right
This shows on the right
</template>
Left
This shows on the left
Right
This shows on the right
We also provide a shorthand syntax sugar ::name::
for slot name. The following example works exactly the same as the previous one.
---
layout: two-cols
---
# Left
This shows on the left
::right::
# Right
This shows on the right
You can also explicitly specify the default slot and provide in the custom order
---
layout: two-cols
---
::right::
# Right
This shows on the right
::default::
# Left
This shows on the left
Configurations
All configurations needed can be defined in the Markdown file. For example:
---
theme: seriph
layout: cover
background: 'https://source.unsplash.com/1600x900/?nature,water'
---
# Kolibry
This is the cover page.
Learn more about frontmatter configurations.
LaTeX
Kolibry comes with LaTeX support out-of-box, powered by KaTeX.
Inline
Surround your LaTeX with a single $
on each side for inline rendering.
$\sqrt{3x-1}+(1+x)^2$
Block
Use two ($$
) for block rendering. This mode uses bigger symbols and centers the result.
$$
\begin{array}{c}
\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &
= \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
\nabla \cdot \vec{\mathbf{B}} & = 0
\end{array}
$$
Learn more: Demo | KaTeX | markdown-it-katex
LaTex line highlighting
To highlight specific lines, simply add line numbers within bracket {}
. Line numbers start counting from 1 by default.
$$ {1|3|all}
\begin{array}{c}
\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &
= \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
\nabla \cdot \vec{\mathbf{B}} & = 0
\end{array}
$$
Diagrams
You can also create diagrams / graphs from textual descriptions in your Markdown, powered by Mermaid.
Code blocks marked as mermaid
will be converted to diagrams, for example:
//```mermaid
sequenceDiagram
Alice->John: Hello John, how are you?
Note over Alice,John: A typical interaction
//```
You can further pass an options object to it to specify the scaling and theming. The syntax of the object is a JavaScript object literal, you will need to add quotes ('
) for strings and use comma (,
) between keys.
//```mermaid {theme: 'neutral', scale: 0.8}
graph TD
B[Text] --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
//```
Multiple Entries
You can split your slides.md
into multiple files and organize them as you want.
slides.md
:
# Page 1
This is a normal page
---
src: ./subpage2.md
---
<!-- this page will be loaded from './subpage2.md' -->
Inline content will be ignored
subpage2.md
:
# Page 2
This page is from another file
Frontmatter Merging
You can provide frontmatters from both your main entry and external markdown pages. If there are the same keys in them, the ones from the main entry have the higher priority. For example
slides.md
:
---
src: ./cover.md
background: https://kolibry.dev/bar.png
class: text-center
---
cover.md
:
---
layout: cover
background: https://kolibry.dev/foo.png
---
# Cover
Cover Page
They will end up being equivalent of the following page:
---
layout: cover
background: https://kolibry.dev/bar.png
class: text-center
---
# Cover
Cover Page
Page Reusing
With the multi-entries support, reusing pages could be straightforward. For example:
---
src: ./cover.md
---
---
src: ./intro.md
---
---
src: ./content.md
---
---
# reuse
src: ./content.md
---
MDC Syntax
Kolibry has and experimental support for MDC (Markdown Components) Syntax powered by markdown-it-mdc
.
You can enable it by add mdc: true
to the frontmatter of your markdown file.
---
mdc: true
---
This is a [red text]{style="color:red"} :inline-component{prop="value"}
![](/image.png){width=500px lazy}
::block-component{prop="value"}
The **default** slot
::
Learn more about the syntax.