feat: Typst lesson template with Jellyfin media frontmatter #9

Merged
sscoble merged 2 commits from issue-3-typst-template into main 2026-05-16 04:39:37 +00:00
Contributor

What

Implements the Typst lesson template and example lesson for #3.

Files added

  • templates/lesson.typ — Reusable template with lesson-template() function

    • Accepts title, grade, subject, date, media (array of (id, title) pairs), and description
    • Comment-based frontmatter convention documented at top
    • Renders: title heading → metadata line → description → body content → media section
    • Media references use raw(lang: "jellyfin-media", "uuid|Title") which produces <code data-lang="jellyfin-media"> elements in HTML
    • Exports media-ref() helper for inline media references in lesson body
  • templates/example-lesson.typ — Complete example lesson (The Water Cycle)

    • Demonstrates all template features: title, metadata, multi-section content, media references
    • Christian-homeschool appropriate with Psalm 135:7 reference
    • Includes 2 Jellyfin media references and review questions

Acceptance

  • ✅ typst compile --features html templates/example-lesson.typ produces valid HTML
  • ✅ HTML includes title (<h2>), metadata (Grade 3 — Science — 2026-01-15), and all content sections
  • ✅ Media references rendered as <code data-lang="jellyfin-media">uuid-water-cycle|The Water Cycle Explained</code>
  • ✅ Tested with Typst 0.14.2 (requirement was 0.12+)

Media Reference Format

The plugin can parse <code data-lang="jellyfin-media">uuid|Title</code> elements from the HTML to:

  1. Extract the Jellyfin item UUID
  2. Extract the display title
  3. Link them to the Jellyfin media player

Closes #3

## What Implements the Typst lesson template and example lesson for #3. ### Files added - **`templates/lesson.typ`** — Reusable template with `lesson-template()` function - Accepts title, grade, subject, date, media (array of (id, title) pairs), and description - Comment-based frontmatter convention documented at top - Renders: title heading → metadata line → description → body content → media section - Media references use `raw(lang: "jellyfin-media", "uuid|Title")` which produces `<code data-lang="jellyfin-media">` elements in HTML - Exports `media-ref()` helper for inline media references in lesson body - **`templates/example-lesson.typ`** — Complete example lesson (The Water Cycle) - Demonstrates all template features: title, metadata, multi-section content, media references - Christian-homeschool appropriate with Psalm 135:7 reference - Includes 2 Jellyfin media references and review questions ### Acceptance - ✅ `typst compile --features html templates/example-lesson.typ` produces valid HTML - ✅ HTML includes title (`<h2>`), metadata (`Grade 3 — Science — 2026-01-15`), and all content sections - ✅ Media references rendered as `<code data-lang="jellyfin-media">uuid-water-cycle|The Water Cycle Explained</code>` - ✅ Tested with Typst 0.14.2 (requirement was 0.12+) ### Media Reference Format The plugin can parse `<code data-lang="jellyfin-media">uuid|Title</code>` elements from the HTML to: 1. Extract the Jellyfin item UUID 2. Extract the display title 3. Link them to the Jellyfin media player Closes #3
agent-engineering added 1 commit 2026-05-16 04:19:19 +00:00
- Add templates/lesson.typ: reusable template with lesson-template() function
  - Accepts title, grade, subject, date, media, description parameters
  - Comment-based frontmatter convention documented at top
  - Renders title heading, metadata line, description, body, media section
  - Media references use raw(lang: "jellyfin-media") for identifiable HTML elements
- Add templates/example-lesson.typ: complete example (Water Cycle lesson)
  - Demonstrates all template features
  - Christian-homeschool appropriate content (Psalm 135:7)
  - Includes 2 Jellyfin media references

Closes #3
First-time contributor

Reviewed — looks good overall. Two things:

  1. Media reference format: Using raw(lang: "jellyfin-media", ...) is clever — produces <code data-lang="jellyfin-media"> in HTML which the plugin can reliably parse. 👍

  2. One fix needed: The list.item(media-ref(...)) in media-section() will render as a list item containing a <code> block. In HTML output, Typst wraps raw blocks in <pre><code> which will break inline list rendering. Change raw(lang: "jellyfin-media", id + "|" + title) to emit something inline-friendly. Two options:

    • Use block: false in the raw call if Typst supports it
    • Or use a custom element via #show raw where lang: "jellyfin-media": ... that wraps them in a <span> instead

    Best approach: wrap it as [#raw(lang: "jellyfin-media", id + "|" + title, block: false)] to keep it inline within the list item.

Fix that and this is ship-ready.

Reviewed — looks good overall. Two things: 1. **Media reference format**: Using `raw(lang: "jellyfin-media", ...)` is clever — produces `<code data-lang="jellyfin-media">` in HTML which the plugin can reliably parse. 👍 2. **One fix needed**: The `list.item(media-ref(...))` in `media-section()` will render as a list item containing a `<code>` block. In HTML output, Typst wraps `raw` blocks in `<pre><code>` which will break inline list rendering. Change `raw(lang: "jellyfin-media", id + "|" + title)` to emit something inline-friendly. Two options: - Use `block: false` in the raw call if Typst supports it - Or use a custom element via `#show raw where lang: "jellyfin-media": ...` that wraps them in a `<span>` instead Best approach: wrap it as `[#raw(lang: "jellyfin-media", id + "|" + title, block: false)]` to keep it inline within the list item. Fix that and this is ship-ready.
sscoble added 1 commit 2026-05-16 04:39:31 +00:00
raw() defaults to block mode which wraps output in <pre><code>,
breaking list-item rendering. block: false keeps it inline.

Addresses PR #9 review feedback.
First-time contributor

Fix applied — raw(lang: "jellyfin-media", ..., block: false) keeps it inline in lists. Re-approving.

Fix applied — `raw(lang: "jellyfin-media", ..., block: false)` keeps it inline in lists. Re-approving.
sscoble merged commit 08f040d317 into main 2026-05-16 04:39:37 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: sscoble/jellyfin-lessons#9
No description provided.