diff --git a/docs/content/features/templates.md b/docs/content/features/templates.md index 153ed90..b36c88c 100644 --- a/docs/content/features/templates.md +++ b/docs/content/features/templates.md @@ -2,6 +2,7 @@ title: Tera Templates description: Customizable templates without recompilation weight: 1 +toc: true --- sukr uses [Tera](https://tera.netlify.app/), a Jinja2-like templating engine. Templates are loaded at runtime, so you can modify them without recompiling sukr. diff --git a/docs/static/style.css b/docs/static/style.css index e202e95..9ad2c87 100644 --- a/docs/static/style.css +++ b/docs/static/style.css @@ -111,6 +111,45 @@ body { font-size: 0.9rem; } +/* Anchor navigation (TOC in sidebar) */ +.sidebar .nav-anchors { + margin-left: 1rem; + padding-left: 0.5rem; + border-left: 1px solid var(--border); + display: flex; + flex-direction: column; + gap: 0.125rem; + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.sidebar .nav-anchors .anchor-link { + font-size: 0.8rem; + color: var(--fg-muted); + padding: 0.125rem 0; +} + +.sidebar .nav-anchors .anchor-link:hover { + color: var(--accent); +} + +/* Indent anchors by heading level */ +.sidebar .nav-anchors .level-3 { + margin-left: 0.5rem; +} + +.sidebar .nav-anchors .level-4 { + margin-left: 1rem; +} + +.sidebar .nav-anchors .level-5 { + margin-left: 1.5rem; +} + +.sidebar .nav-anchors .level-6 { + margin-left: 2rem; +} + .sidebar-footer { margin-top: auto; padding-top: 1rem; diff --git a/docs/templates/base.html b/docs/templates/base.html index a7d9e78..d6b679e 100644 --- a/docs/templates/base.html +++ b/docs/templates/base.html @@ -38,11 +38,25 @@ {% set section_prefix = item.path | replace(from="index.html", to="") %} {% set is_current_section = page_path is starting_with(section_prefix) %} {{ item.label }} + {% if page_path == item.path and page.toc and anchors %} +
+ {% endif %} {% if config.nested_nav and item.children %} {% endif %} diff --git a/src/main.rs b/src/main.rs index 4056a01..e2664ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -142,10 +142,16 @@ fn run(config_path: &Path) -> Result<()> { // Render individual content pages for all sections for item in &items { eprintln!(" processing: {}", item.slug); - let (html_body, _anchors) = render::markdown_to_html(&item.body); + let (html_body, anchors) = render::markdown_to_html(&item.body); let page_path = format!("/{}", item.output_path(&content_dir).display()); - let html = - engine.render_content(item, &html_body, &page_path, &config, &manifest.nav)?; + let html = engine.render_content( + item, + &html_body, + &page_path, + &config, + &manifest.nav, + &anchors, + )?; write_output(&output_dir, &content_dir, item, html)?; } @@ -259,9 +265,10 @@ fn process_pages( eprintln!("processing: {}", path.display()); let content = Content::from_path(&path, ContentKind::Page)?; - let (html_body, _anchors) = render::markdown_to_html(&content.body); + let (html_body, anchors) = render::markdown_to_html(&content.body); let page_path = format!("/{}", content.output_path(content_dir).display()); - let html = engine.render_page(&content, &html_body, &page_path, config, nav)?; + let html = + engine.render_page(&content, &html_body, &page_path, config, nav, &anchors)?; write_output(output_dir, content_dir, &content, html)?; } @@ -278,13 +285,14 @@ fn generate_homepage( ) -> Result<()> { eprintln!("generating: homepage"); - let (html_body, _anchors) = render::markdown_to_html(&manifest.homepage.body); + let (html_body, anchors) = render::markdown_to_html(&manifest.homepage.body); let html = engine.render_page( &manifest.homepage, &html_body, "/index.html", config, &manifest.nav, + &anchors, )?; let out_path = output_dir.join("index.html"); diff --git a/src/template_engine.rs b/src/template_engine.rs index 6649094..f5e02fb 100644 --- a/src/template_engine.rs +++ b/src/template_engine.rs @@ -8,6 +8,7 @@ use tera::{Context, Tera}; use crate::config::SiteConfig; use crate::content::{Content, NavItem}; use crate::error::{Error, Result}; +use crate::render::Anchor; /// Runtime template engine wrapping Tera. pub struct TemplateEngine { @@ -40,11 +41,13 @@ impl TemplateEngine { page_path: &str, config: &SiteConfig, nav: &[NavItem], + anchors: &[Anchor], ) -> Result