Welcome!
-
-
- Learn Home
- Core Concepts
- Companies and Departments
- Courses
- Course Status and Visibility
- Modules
- Video Activities
- Reading Activities
- Document Activities
- Enrolling People in a Course
- Bulk Enroll With CSV
- Roles in a Course
- How Progress Is Tracked
- Course Reports
- Knowledge Base Overview
- Libraries and Folders
- Uploading Content Items
- Library Visibility
- AI Agent per Library
- My Courses
- Platform People
-
- Project Structure Template
- Table of Contents (TOC)
- Content Folder
- Introduction to Markdown
- Markdown Basics
- Markdown Lists
- Markdown Links
- Markdown Images
- Markdown Code
- Markdown Tables
- Markdown Equations
- Markdown Videos
- Markdown Embedded HTML
- VS Code Snippets
- Introduction to Styles
- Framed Narrations
- Markdown Configuration
- Editor Setup
-
-
-
Authoring in Markdown
This page is part of the advanced authoring path — a special case the Lupo team sets up on request. Most people don't need it.
TL;DR; Each section referenced from toc.yml is one Marp Markdown file,
rendered one slide at a time. Standard Markdown covers formatting, lists,
links and tables; a handful of extensions — background images, timed
narration, and video embedding — are specific to Lupo and are the part
actually worth learning here.
Before you start
See toc.yml reference for how a section file is wired into the project.
The header every file needs
A section file is a Marp deck, and Lupo checks that
before it does anything else. The file must open with a front-matter
block that sets marp: true; a file without it fails with "Marp header
not found", and any other value for marp fails with "Invalid Marp
header". theme is the only other free key; anything else in the header
has to be one of the Marp directives listed in
Styling and themes,
and an unknown one is reported as a warning.
---
marp: true
---
# First slide
---
# Second slide
Slides are separated by a line containing only ---.
Basic formatting
Standard Markdown: **bold**, *italic* (or __bold__ / _italic_),
`inline code`, and # Heading through ###### Heading. Escape any
character with a backslash, e.g. \*not italic\*.
# This is a Title
## This is a subtitle
You can write **bold**, *italic*, [links](https://lupo.ai), and `code`.
Blockquotes use >, and nest with > >. A blank line inside a quote
needs a bare > to stay part of the same block:
> First line
>
> > Nested line
>
> Last line
HTML comments (<!-- ... -->) render as nothing — they're where
narration text lives, covered below.
Lists
Unordered lists use *, +, or -. Ordered lists don't need to be
numbered sequentially in the source — 1. 1. 1. still renders as
1. 2. 3., and starting at 5. starts the rendered list at 5. Nest by
indenting two spaces or one tab.
* First item
* First sub-item
* First sub-sub-item
1. First
2. Second
Links
Inline: [link text](url). Reference-style, useful when the same link
is reused or you want to keep URLs out of the prose:
[Lupo][lupo]
[lupo]: https://lupo.ai/ "Go to Lupo"
There's no special syntax for linking between sections of the same
project — that structure is defined by toc.yml, not by links inside
the Markdown itself.
Images
Basic syntax:  — no space between ] and (.
Two extensions beyond standard Markdown:
Resizing — set a width and/or height on the image:

Full-slide background images — the bg keyword turns an image into
the slide's background instead of an inline image. Multiple background
images on one slide lay out side by side automatically; vertical
stacks them instead. left or right (optionally with a percentage)
splits the slide, reserving the rest for your regular content:



Code
Inline code uses backticks. Fenced code blocks take a language tag for syntax highlighting:
```csharp
public int Area(int a, int b);
```
Tables
Standard GFM pipe syntax, with alignment set by colons in the separator row:
| Left | Center | Right |
| :--- | :----: | ----: |
| Text | Text | Text |
Equations
LaTeX syntax — inline with single $...$, block/display with double
$$...$$:
Inline: $F_{0}=0$
Block:
$$ I_{xx}=\int\int_R y^2 f(x,y) \, dy\,dx $$
Embedding video
Markdown has no native video syntax, so video is embedded as raw HTML5
<video>, with a few Lupo-specific attributes controlling how it times
against narration:
video-duration— the slide's length matches the video's own duration.audio-duration— the slide's length matches the narration audio's duration instead.repeat— the video loops until the narration audio finishes.muted/no-muted— drop or keep the video's own soundtrack.
<video src="../universe.mp4" controls audio-duration muted>
Your device does not support video playback.
</video>
Narration and timing
Narration text for a slide goes inside an HTML comment. By default, lines are read in order. Prefixing a line with a time marker starts that narration at a specific moment instead of wherever it would otherwise fall — useful for syncing narration to an embedded video or an animation. One narration per line, no line breaks inside a single narration line:
((5))— start at 5 seconds((5.5))— start at 5.5 seconds((1:30))— start at 1 minute 30 seconds((1:02:03))— start at 1 hour 2 minutes 3 seconds
<!--
((5)) Welcome to this course.
((12)) In this section, we'll cover the fundamentals.
-->
Timed and untimed lines can mix — an untimed line just follows immediately after whichever timed line came before it. An empty comment is treated as a slide with no narration.
The narrator's voice, speed, pitch and speaking style are not set in the
Markdown at all — they come from toc.yml (style at course level,
emotion at chapter or section level), so every slide in a section is
read the same way. There is no per-line style tag.
A comment whose first word starts with _ and is followed by a colon is
not narration but a per-slide directive — <!-- _backgroundColor: #2288C9 -->
restyles just that slide. See
Styling and themes.
Raw HTML
Inline HTML is supported directly in the Markdown — tables, custom markup, and anything else HTML can express.