From 0700c35310c63a4713eb2589b8610166500ab915 Mon Sep 17 00:00:00 2001 From: Scott Scoble Date: Fri, 15 May 2026 21:18:04 -0700 Subject: [PATCH] feat: add Typst lesson template with Jellyfin media frontmatter - 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 --- templates/example-lesson.typ | 83 +++++++++++++++++++++++++++++++++ templates/lesson.typ | 90 ++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 templates/example-lesson.typ create mode 100644 templates/lesson.typ diff --git a/templates/example-lesson.typ b/templates/example-lesson.typ new file mode 100644 index 0000000..44122e7 --- /dev/null +++ b/templates/example-lesson.typ @@ -0,0 +1,83 @@ +// example-lesson.typ — Complete example demonstrating the lesson template +// ============================================================ +// Frontmatter: +// title: God's Creation: The Water Cycle +// grade: 3 +// subject: Science +// date: 2026-01-15 +// media: jellyfin://uuid-water-cycle, jellyfin://uuid-cloud-formation +// description: Learn how God designed water to move through His creation — +// evaporation, condensation, and precipitation working together to sustain life. + +#import "lesson.typ": lesson-template, media-ref + +#show: doc => lesson-template( + doc, + title: "God's Creation: The Water Cycle", + grade: "3", + subject: "Science", + date: "2026-01-15", + media: ( + ("uuid-water-cycle", "The Water Cycle Explained"), + ("uuid-cloud-formation", "Cloud Formation and Weather"), + ), + description: "Learn how God designed water to move through His creation — evaporation, condensation, and precipitation working together to sustain life on Earth.", +) + += What Is the Water Cycle? + +Water is one of God's most amazing creations! The water cycle is how water moves +all around our planet. It never runs out — it just keeps going around and around. +There are four main steps: evaporation, condensation, precipitation, and collection. + +== Evaporation + +When the sun shines on oceans, lakes, and rivers, the water gets warm and turns +into a gas called *water vapor*. This gas rises up into the sky. You can't see it, +but it's there! Evaporation happens every day, especially on warm, sunny days. + +== Condensation + +When the water vapor goes high up where it's cold, it turns back into tiny water +droplets. These droplets come together to make clouds. Have you ever looked at +clouds and seen shapes? Those shapes are made of millions of tiny water droplets +sticking together! + +== Precipitation + +When the clouds get too heavy with water droplets, the water falls back down to +Earth. This is called *precipitation*. It can be: + +- Rain — liquid water falling from the sky +- Snow — frozen crystals that fall in cold weather +- Sleet — tiny ice pellets that bounce when they land +- Hail — hard balls of ice that form in big storms + +God sends precipitation to water the plants and fill the rivers, lakes, and oceans. + +== Collection + +The water that falls onto the ground collects in rivers, lakes, and oceans. Some +of it soaks into the ground and becomes *groundwater* — water stored underground +that plants can reach with their roots. Then the sun warms the water, and the +whole cycle starts all over again! + += Why Is the Water Cycle Important? + +God designed the water cycle to do important work: + +- Give plants the water they need to grow +- Provide fresh water for animals and people to drink +- Keep our rivers and lakes full of water +- Help control the temperature of our whole planet +- Clean the water naturally as it moves through the cycle + +*"He causes the vapors to ascend from the ends of the earth; He makes lightning +for the rain; He brings the wind out of His treasuries."* — Psalm 135:7 + += Think About It + +1. What happens to water when the sun shines on a lake? +2. Why do clouds form high up in the sky? +3. What are the four types of precipitation? +4. How does the water cycle show God's care for His creation? diff --git a/templates/lesson.typ b/templates/lesson.typ new file mode 100644 index 0000000..a85cab3 --- /dev/null +++ b/templates/lesson.typ @@ -0,0 +1,90 @@ +// lesson.typ — Typst template for homeschool lessons +// ============================================================ +// This template produces clean, structured lesson documents. +// Designed to compile to HTML for rendering inside Jellyfin. +// +// Frontmatter convention (documented as comments at top of each lesson): +// // title: The Lesson Title +// // grade: 3 +// // subject: Science +// // date: 2026-01-15 +// // media: jellyfin://uuid-1, jellyfin://uuid-2 +// // description: Short description of the lesson +// +// Usage: +// #import "lesson.typ": lesson-template, media-ref +// #show: doc => lesson-template( +// doc, +// title: "The Water Cycle", +// grade: "3", +// subject: "Science", +// date: "2026-01-15", +// media: (), +// description: "Learn about evaporation and condensation.", +// ) + +// Render a single Jellyfin media reference. +// Produces a element in HTML output +// that the Jellyfin plugin can parse and link to the player. +#let media-ref(id, title) = { + raw(lang: "jellyfin-media", id + "|" + title) +} + +// Render a list of media references as a formatted section. +#let media-section(media-items) = { + if media-items.len() > 0 { + heading(level: 2)[Media] + for item in media-items { + list.item(media-ref(item.at(0), item.at(1))) + } + } +} + +// The main lesson template. +// - body: The lesson content (passed via show rule) +// - title: Lesson title (string) +// - grade: Grade level (string, e.g. "3") +// - subject: Subject name (string) +// - date: Lesson date in YYYY-MM-DD format +// - media: Array of (id, title) pairs for linked Jellyfin media +// - description: Short description of the lesson +#let lesson-template( + body, + title: "Untitled Lesson", + grade: none, + subject: none, + date: none, + media: (), + description: none, +) = { + // Document metadata for PDF output + set document(title: title) + + // Title — prominent heading + heading(level: 1, title) + + // Metadata line: Grade X — Subject — Date + let meta-parts = () + if grade != none { meta-parts.push([Grade ] + grade) } + if subject != none { meta-parts.push(subject) } + if date != none { meta-parts.push(date) } + if meta-parts.len() > 0 { + let sep = [ — ] + let meta-text = meta-parts.first() + for i in range(1, meta-parts.len()) { + meta-text += sep + meta-parts.at(i) + } + par(text(style: "italic", size: 0.9em, meta-text)) + } + + // Description paragraph + if description != none { + par([*Description:* ] + description) + } + + // Lesson body content (renders user-authored sections, paragraphs, lists, etc.) + body + + // Media references section — listed with identifiable jellyfin-media codes + media-section(media) +}