commit b87043a2c121acdaf44479e46ea794d2d75d8ce7
parent dc948cbb854f4728b32940afcaeb245412c6ba43
Author: Andrew Laack <andrew@laack.co>
Date: Thu, 27 Aug 2026 22:33:51 -0500
Hidden text
Diffstat:
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 %}