simple-learning

Simple learning web program
git clone git://git.laack.co/simple-learning.git
Log | Files | Refs | README | LICENSE

commit b87043a2c121acdaf44479e46ea794d2d75d8ce7
parent dc948cbb854f4728b32940afcaeb245412c6ba43
Author: Andrew Laack <andrew@laack.co>
Date:   Thu, 27 Aug 2026 22:33:51 -0500

Hidden text

Diffstat:
Mcourses/ocaml/0_ocaml.sl | 8+++++++-
Mdocs/sl.sl | 2+-
Mlearning/bin/main.ml | 6++++--
Mlearning/static/styles.css | 14++++++++++++++
Mlearning/templates/course_page.jingoo | 4++++
5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/courses/ocaml/0_ocaml.sl b/courses/ocaml/0_ocaml.sl @@ -18,6 +18,12 @@ let factorial x = in go 1 x;; print_endline (string_of_int(factorial 6));; ``` -=>i em.png + =>v out.webm + +=>i em.png + +When was ocaml created? + +?? OCaml was created in 1984 diff --git a/docs/sl.sl b/docs/sl.sl @@ -19,4 +19,4 @@ Outside of preformatted blocks, there are seven line types: - Heading lines - List items - Quote lines -- Embedding lines +- Hidden Lines diff --git a/learning/bin/main.ml b/learning/bin/main.ml @@ -16,13 +16,15 @@ type page_line = { is_embedded_video: bool; is_embedded_image: bool; is_preformatted: bool; + is_hidden: bool; } let parse_simple_line line preformatted = + let hidden = if not preformatted && String.length(line) > 2 && line.[0] = '?' && line.[1] = '?' then true else false in let hash_count = if not preformatted then countPrefix '#' line else 0 in let embedded_video = if not preformatted && String.length(line) > 3 && line.[0] = '=' && line.[1] = '>' && line.[2] = 'v' then true else false in let embedded_image = if not preformatted && String.length(line) > 3 && line.[0] = '=' && line.[1] = '>' && line.[2] = 'i' then true else false in - {header_level = hash_count; content = (if embedded_video || embedded_image then (String.sub line 4 (String.length(line) - 4)) else line); is_embedded_image = embedded_image; is_embedded_video = embedded_video; is_preformatted = preformatted} + {header_level = hash_count; content = (if embedded_video || embedded_image then (String.sub line 4 (String.length(line) - 4)) else line); is_embedded_image = embedded_image; is_embedded_video = embedded_video; is_preformatted = preformatted; is_hidden = hidden} let is_format_line cl = String.length cl = 3 && cl.[0] = '`' && cl.[1] = '`' && cl.[2] = '`' @@ -65,7 +67,7 @@ let to_tval value = Jg_types.Tobj [("name", Jg_types.Tstr value);] let page_line_to_tobj line = - Jg_types.Tobj [("header_level", Jg_types.Tint line.header_level); ("content", Jg_types.Tstr line.content); ("is_embedded_video", Jg_types.Tbool line.is_embedded_video); ("is_embedded_image", Jg_types.Tbool line.is_embedded_image); ("is_preformatted", Jg_types.Tbool line.is_preformatted)] + Jg_types.Tobj [("header_level", Jg_types.Tint line.header_level); ("content", Jg_types.Tstr line.content); ("is_embedded_video", Jg_types.Tbool line.is_embedded_video); ("is_embedded_image", Jg_types.Tbool line.is_embedded_image); ("is_preformatted", Jg_types.Tbool line.is_preformatted); ("is_hidden", Jg_types.Tbool line.is_hidden)] let get_courses = let arr = Sys.readdir course_dir in diff --git a/learning/static/styles.css b/learning/static/styles.css @@ -42,6 +42,20 @@ pre-formatted { word-wrap: break-word; } +summary { + list-style: none; +} + +summary { + cursor: pointer; + filter: blur(6px); + transition: filter 0.2s ease; +} + +details[open] summary { + filter: none; +} + content-block { display: block; color: #222222; diff --git a/learning/templates/course_page.jingoo b/learning/templates/course_page.jingoo @@ -2,6 +2,10 @@ {% for line in lines %} {% if line.is_preformatted %} <pre><pre-formatted>{{line.content}}</pre-formatted></pre> + {% else if line.is_hidden %} + <details> + <summary>{{line.content}}</summary> + </details> {% else if line.header_level >= 1 %} <h{{line.header_level}}>{{line.content}}</h{{line.header_level}}> {% else if line.is_embedded_image %}