diff --git a/TODOS.md b/TODOS.md index 7f7d6c7..ead6ee8 100644 --- a/TODOS.md +++ b/TODOS.md @@ -1,6 +1,7 @@ - README.md - [ ] "Zero is beautiful" - [ ] Content-hash fingerprinting for CSS and JS cache busting +- [ ] Enable configuration to opt-out of features, particular pre/post processors. - [ ] proper date/time/now object. - [ ] Block attributes on code fences (`{ #ex-1 }`) — hello-world.md - [x] Emoji shortcodes (`:shrug:` etc.) — 2 instances @@ -17,6 +18,10 @@ guide - [ ] Search for grammars in multiple places - [ ] Download missing grammars. +- [ ] Syntax highlighting in production: CI (`nix build` on ubuntu-latest) has no grammar `.so`s and a machine-specific `QUERIES_PATH` nix store hash, so the deployed site renders unhighlighted. Provide grammars + queries as nix build inputs and pass paths to thor at runtime (env vars/flags). +- [ ] Durable highlight paths: read `GRAPHS_PATH`/`QUERIES_PATH` from env vars set by the flake instead of hardcoded nix store hashes, so they survive `nix flake update` and let the grammar/query version-mismatch detector fire automatically. +- [ ] Unit tests for highlighting helpers: `capture_name_to_css`, `escape_html`, `unescape_html`, `extract_query_token`, `helix_version_from_path`. +- [ ] Dark `
` code-block background — atom-one-dark colors are tuned for a dark bg but currently render on the light `--color-body`. (See "Theme selector" item.)
 - [ ] Review every file in thor
   - [ ] Review alerts.odin
   - [ ] Review content.odin
diff --git a/content.odin b/content.odin
index eb3fa00..c35ec1c 100644
--- a/content.odin
+++ b/content.odin
@@ -32,15 +32,15 @@ Page :: struct {
 // (or all pages if include_drafts is true).
 //
 // TODO: What is the lifetime of pages?
-walk_content :: proc(content_path: string, include_drafts: bool) -> []Page {
+walk_content :: proc(content_path: string, include_drafts: bool, sectionate: bool) -> []Page {
 	pages: [dynamic]Page
 
-	collect_home(&pages, content_path)
-	collect_standalone(&pages, content_path)
+	collect_home(&pages, content_path, sectionate)
+	collect_standalone(&pages, content_path, sectionate)
 
 	posts_path := fmt.tprintf("%s/posts", content_path)
 	if os.exists(posts_path) {
-		collect_posts(&pages, posts_path)
+		collect_posts(&pages, posts_path, sectionate)
 	}
 
 	if include_drafts {
@@ -57,10 +57,10 @@ walk_content :: proc(content_path: string, include_drafts: bool) -> []Page {
 	}
 }
 
-collect_home :: proc(pages: ^[dynamic]Page, content_path: string) {
+collect_home :: proc(pages: ^[dynamic]Page, content_path: string, sectionate: bool) {
 	html_path := fmt.tprintf("%s/index.html", content_path)
 	if os.exists(html_path) {
-		page, ok := load_page(html_path, .Home, "")
+		page, ok := load_page(html_path, .Home, "", sectionate)
 		if ok {
 			page.permalink = "/"
 			append(pages, page)
@@ -70,7 +70,7 @@ collect_home :: proc(pages: ^[dynamic]Page, content_path: string) {
 
 	md_path := fmt.tprintf("%s/index.md", content_path)
 	if os.exists(md_path) {
-		page, ok := load_page(md_path, .Home, "")
+		page, ok := load_page(md_path, .Home, "", sectionate)
 		if ok {
 			page.permalink = "/"
 			append(pages, page)
@@ -78,7 +78,7 @@ collect_home :: proc(pages: ^[dynamic]Page, content_path: string) {
 	}
 }
 
-collect_standalone :: proc(pages: ^[dynamic]Page, content_path: string) {
+collect_standalone :: proc(pages: ^[dynamic]Page, content_path: string, sectionate: bool) {
 	entries, err := os.read_all_directory_by_path(content_path, context.allocator)
 	if err != nil {
 		log.warnf("thor: cannot read %s: %v", content_path, err)
@@ -98,14 +98,14 @@ collect_standalone :: proc(pages: ^[dynamic]Page, content_path: string) {
 		}
 
 		slug := strip_extension(entry.name)
-		page, ok := load_page(entry.fullpath, .Standalone, slug)
+		page, ok := load_page(entry.fullpath, .Standalone, slug, sectionate)
 		if ok {
 			append(pages, page)
 		}
 	}
 }
 
-collect_posts :: proc(pages: ^[dynamic]Page, posts_path: string) {
+collect_posts :: proc(pages: ^[dynamic]Page, posts_path: string, sectionate: bool) {
 	entries, err := os.read_all_directory_by_path(posts_path, context.allocator)
 	if err != nil {
 		log.warnf("thor: cannot read %s: %v", posts_path, err)
@@ -120,7 +120,7 @@ collect_posts :: proc(pages: ^[dynamic]Page, posts_path: string) {
 				continue
 			}
 			slug := strip_extension(entry.name)
-			page, ok := load_page(entry.fullpath, .Post, slug)
+			page, ok := load_page(entry.fullpath, .Post, slug, sectionate)
 			if ok {
 				append(pages, page)
 			}
@@ -132,7 +132,7 @@ collect_posts :: proc(pages: ^[dynamic]Page, posts_path: string) {
 			if !os.exists(index_path) {
 				continue
 			}
-			page, ok := load_page(index_path, .Post, entry.name)
+			page, ok := load_page(index_path, .Post, entry.name, sectionate)
 			if ok {
 				page.bundle_dir = entry.fullpath
 				append(pages, page)
@@ -146,6 +146,7 @@ load_page :: proc(
 	file_path: string,
 	page_type: Page_Type,
 	slug: string,
+	sectionate: bool,
 ) -> (
 	page: Page,
 	ok: bool,
@@ -178,7 +179,11 @@ load_page :: proc(
 		expanded := expand_emoji(body)
 		clean_body, defs := strip_definitions(expanded)
 		html := cm.markdown_to_html_from_string(clean_body, {.Unsafe})
-		page.body_html = highlight_code(inject_alerts(inject_sidenotes(html, defs)), file_path)
+		html = highlight_code(inject_alerts(inject_sidenotes(html, defs)), file_path)
+		if sectionate {
+			html = wrap_sections(html)
+		}
+		page.body_html = html
 	}
 
 	switch page_type {
diff --git a/highlight.odin b/highlight.odin
index e09db44..63d7859 100644
--- a/highlight.odin
+++ b/highlight.odin
@@ -187,14 +187,22 @@ find_first_error_line :: proc(root: TSNode) -> int {
 
 capture_name_to_css :: proc(name: string) -> string {
 	sb := strings.builder_make()
-	strings.write_string(&sb, "hl-")
+	seg := strings.builder_make()
+	first := true
 	for i in 0.. string {
+	H2 :: " pos {
+			append(&parts, "
") + append(&parts, html[pos:idx]) + append(&parts, "
") + } + + pos = idx + search_pos = idx + len(H2) + } + + if pos < len(html) { + append(&parts, "
") + append(&parts, html[pos:]) + append(&parts, "
") + } + + if len(parts) == 0 { + return html + } + return strings.join(parts[:], "") +} diff --git a/site.odin b/site.odin index 56777e4..9f11ce9 100644 --- a/site.odin +++ b/site.odin @@ -19,6 +19,7 @@ Site :: struct { layouts_dir: string, author: string, params: json.Value, + sectionate: bool, drafts: bool `args:"name=drafts"`, }