simple-learning

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

commit 0c964c7fb55bf58554baaf03c83d07648eae325a
parent d7347cf35d56591b3b805acd70bb475a3fec9d3b
Author: Andrew Laack <andrew@laack.co>
Date:   Fri, 28 Aug 2026 12:29:57 -0500

Updated sl specification to use iframes instead of video / images. added next / previous links, started adding ocaml course

Diffstat:
Mlearning/bin/parser.ml | 19+++++++------------
Mlearning/bin/render.ml | 35++++++++++++++++++++++++++++-------
Mlearning/static/styles.css | 5++++-
Mlearning/templates/course_page.jingoo | 15+++++++++++----
4 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/learning/bin/parser.ml b/learning/bin/parser.ml @@ -1,14 +1,13 @@ type page_line = { header_level: int; content: string; - is_embedded_video: bool; - is_embedded_image: bool; + is_embedded: bool; is_preformatted: bool; is_hidden: bool; } -let permute_line line vid image hidden = - if vid || image then (String.sub line 4 (String.length(line) - 4)) else +let permute_line line embedded hidden = + if embedded then (String.sub line 4 (String.length(line) - 4)) else if hidden then String.sub line 3 (String.length(line) - 3) else line @@ -16,18 +15,14 @@ let permute_line line vid image hidden = let is_hidden line preformatted = if not preformatted && String.length(line) > 2 && line.[0] = '?' && line.[1] = '?' && line.[2] = ' ' then true else false -let is_embedded_video line preformatted = - if not preformatted && String.length(line) > 3 && line.[0] = '=' && line.[1] = '>' && line.[2] = 'v' && line.[3] = ' ' then true else false - -let is_embedded_image line preformatted = - if not preformatted && String.length(line) > 3 && line.[0] = '=' && line.[1] = '>' && line.[2] = 'i' && line.[3] = ' ' then true else false +let is_embedded_link line preformatted = + if not preformatted && String.length(line) > 3 && line.[0] = '=' && line.[1] = '>' && line.[2] = 'e' && line.[3] = ' ' then true else false let parse_simple_line line preformatted = let hidden = is_hidden line preformatted in let hash_count = if not preformatted then Basic_functions.count_prefix '#' line else 0 in - let embedded_video = is_embedded_video line preformatted in - let embedded_image = is_embedded_image line preformatted in - {header_level = hash_count; content = (permute_line line embedded_video embedded_image hidden); is_embedded_image = embedded_image; is_embedded_video = embedded_video; is_preformatted = preformatted; is_hidden = hidden} + let embedded_link = is_embedded_link line preformatted in + {header_level = hash_count; content = (permute_line line embedded_link hidden); is_embedded = embedded_link; is_preformatted = preformatted; is_hidden = hidden} let is_format_line cl = diff --git a/learning/bin/render.ml b/learning/bin/render.ml @@ -6,28 +6,30 @@ let to_tval value = let get_pages_in_order course_name = let arr = Sys.readdir (Shared.course_dir ^ course_name) in Array.sort compare arr; - let lst = List.filter Basic_functions.has_sl_postfix (Array.to_list arr) in + let lst : string list = List.filter Basic_functions.has_sl_postfix (Array.to_list arr) in lst let get_course_home course_name = List.map to_tval (get_pages_in_order course_name) -let get_courses = +let get_course_array = let arr = Sys.readdir Shared.course_dir in Array.sort compare arr; + arr + +let get_courses = + let arr = get_course_array in Jg_types.Tlist - (Array.to_list (Array.map to_tval arr)) + (Array.to_list (Array.map to_tval arr)) let render_course_list = (Jg_template.from_file "./templates/course_list.jingoo" ~models:[("courses", get_courses)]) - - let render_sidebar s = (Jg_template.from_file "./templates/sidebar.jingoo" ~models:[("courses", get_courses)]) ^ s let page_line_to_tobj (line : Parser.page_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); ("is_hidden", Jg_types.Tbool line.is_hidden)] + Jg_types.Tobj [("header_level", Jg_types.Tint line.header_level); ("content", Jg_types.Tstr line.content); ("is_embedded", Jg_types.Tbool line.is_embedded); ("is_preformatted", Jg_types.Tbool line.is_preformatted); ("is_hidden", Jg_types.Tbool line.is_hidden)] let render_course_home course_name = (Jg_template.from_file "./templates/course_home.jingoo" ~models:[("pages", (Jg_types.Tlist (get_course_home course_name)))]) @@ -35,7 +37,26 @@ let render_course_home course_name = let get_path_to_page course page = Shared.course_dir ^ course ^ "/" ^ page +(* + These two functions are called together. This is inefficient bc they both find the current index and then + pull out another page. A good revion would be to pull out the find current logic. + This could also be optimized to use an array instead of a list because there are random seeks happening in both, + but perhaps that's not too consequential. +*) + +let get_previous_page_link course page = + let pages = get_pages_in_order course in + match List.find_index (fun x -> x = page) pages with + | Some current_idx when current_idx - 1 >= 0 -> List.nth pages (current_idx - 1) + | _ -> "" + +let get_next_page_link course page = + let pages = get_pages_in_order course in + match List.find_index (fun x -> x = page) pages with + | Some current_idx when current_idx + 1 < List.length pages -> List.nth pages (current_idx + 1) + | _ -> "" + let render_page course page = let page_lines : Parser.page_line list = Parser.read_simple_learning_file @@ get_path_to_page course page in - (Jg_template.from_file "./templates/course_page.jingoo" ~models:(["lines", Jg_types.Tlist (List.map page_line_to_tobj page_lines)])) + (Jg_template.from_file "./templates/course_page.jingoo" ~models:(["lines", Jg_types.Tlist (List.map page_line_to_tobj page_lines);("previous_page_link", Jg_types.Tstr (get_previous_page_link course page)) ; ("next_page_link", Jg_types.Tstr (get_next_page_link course page))])) diff --git a/learning/static/styles.css b/learning/static/styles.css @@ -1,6 +1,8 @@ body { background-color: #ffffff; - margin: 0; + margin: 5% 5% 5% 5%; + font-size: 25px; + max-width: 1400px; } h1 { color: #480000 ; @@ -59,6 +61,7 @@ details[open] summary { content-block { display: block; color: #222222; + padding: 5px 5px 5px 5px; } .sidenav { diff --git a/learning/templates/course_page.jingoo b/learning/templates/course_page.jingoo @@ -8,12 +8,19 @@ </details> {% else if line.header_level >= 1 %} <h{{line.header_level}}>{{line.content}}</h{{line.header_level}}> - {% else if line.is_embedded_image %} - <img src={{line.content}}> </img> - {% else if line.is_embedded_video %} - <video> <source src="{{line.content}}"> Your browser does not support the video tag. </video> + {% else if line.is_embedded %} + <iframe + style="width: 100%; height: 600px;overflow:auto"; + src="{{line.content}}"> + </iframe> {% else if line.header_level == 0 %} <content-block>{{line.content}}</content-block> {% endif %} {% endfor %} + {% if previous_page_link != "" %} + <a href="{{previous_page_link}}"> previous </a> + {% endif %} + {% if next_page_link != "" %} + <a href="{{next_page_link}}"> next </a> + {% endif %} </div>