Add scrollable container rules for .mermaid-diagram in mobile
media query. SVG diagrams now scroll horizontally within their
container instead of extending the page width and obscuring
the hamburger menu.
- Highlight heading with accent border-left when targeted via URL hash
- Show pilcrow anchor visibly on targeted headings
- Add scroll-margin-top for better scroll positioning
- Add pilcrow (¶) anchor link after heading text for deep-linking
- CSS: hidden by default, visible on heading hover, user-overridable
- Add strip_parens Tera filter for cleaner nav anchor labels
- Update test expectations for new heading format
- Add toc: bool to [nav] config section (default: false)
- Frontmatter toc: true/false overrides global config
- If frontmatter toc is not specified, falls back to config.nav.toc
- Enable nav.toc = true in docs/site.toml for global TOC
- Pass extracted anchors through template context
- Render anchor links under active page when page.toc is true
- Hierarchical indentation by heading level (h2-h6)
- CSS styling: smaller font, muted color, border-left indicator
- Add toc: true to templates.md as example
- Add Anchor struct with id, label, level fields
- markdown_to_html() now returns (String, Vec<Anchor>) tuple
- Headings h2-h6 are extracted with slugified IDs
- Add toc: bool frontmatter field for per-page TOC opt-in
- All heading tags now include id attributes for anchor links
Extend NavItem struct with children field to support nested navigation.
discover_nav() now populates children for section items by collecting
section pages via Section::collect_items() and mapping them to child
NavItem entries. Children are sorted by weight then alphabetically.
Add responsive table rules: horizontal scroll within container,
word-break for inline code, and constrained max-width. Fixes
hamburger menu being pushed off-screen on pages with wide tables.
Implement pure CSS mobile navigation with the following features:
- Collapsible sidebar nav hidden behind hamburger toggle on mobile
- Animated hamburger → X icon morph using CSS transforms
- Smooth slide-down transition for nav reveal (max-height/opacity)
- Hamburger positioned on right side of header via absolute positioning
- Uses :has() selector to detect checkbox state without JavaScript
- Overflow fixes to prevent horizontal scroll on mobile devices
The implementation follows suckless principles with zero JavaScript.
pulldown-cmark emits alt text as Text events between Image start/end
tags. Previously, images were rendered immediately on the Start event
with empty alt text, losing the user-provided description.
Refactored to accumulate alt text using the same pattern as code block
handling: state variables track image attributes and alt content, then
the full <img> tag is rendered on the End event.
Also omits the title attribute entirely when no title is provided,
producing cleaner HTML output.
Fixes Lighthouse "Image elements have [alt] attributes" audit issue.
Add docs/content/features/sitemap.md documenting the automatic
XML sitemap generation feature:
- Output location and contents
- Auto-generation behavior
- lastmod date handling
- Linking and validation tips
Follows established pattern from feeds.md.
Eliminate redundant Content::from_path call by using the pre-discovered
manifest.homepage content. Also uses manifest.nav directly.
- Removes dead_code warning on SiteManifest.homepage field
- Reduces I/O by reusing discovered content
- Simplifies function signature (4 args vs 5)
Replace separate discover_nav + discover_sections calls with single
SiteManifest::discover() in run() pipeline:
- Update generate_feed() to accept &SiteManifest
- Update generate_sitemap_file() to accept &SiteManifest
- Simplify process_pages() to return Result<()>
- Remove redundant all_posts collection (now in manifest.posts)
- Remove unused discover_nav and discover_sections imports
All 49 tests pass, site builds identically.
Introduce SiteManifest struct that aggregates all site content from a
single discovery pass:
- homepage: content/_index.md
- sections: directories with _index.md
- pages: top-level standalone .md files
- posts: blog section items (sorted by date for feed)
- nav: navigation menu items
Add discover_pages() helper and 5 unit tests covering homepage,
sections, pages, posts, and nav discovery.
Not yet integrated into main.rs pipeline.
Wire generate_sitemap() into main.rs pipeline:
- Refactor process_pages() to return discovered pages
- Add generate_sitemap_file() helper function
- Generate sitemap.xml after homepage (Step 5 in pipeline)
- All 44 tests pass, sitemap contains 12 URLs
The sitemap includes homepage, section indices, section items,
and standalone pages following XML Sitemap 1.0 protocol.
Implement src/sitemap.rs with generate_sitemap() for SEO-compliant
XML sitemap generation. Follows the feed.rs pattern:
- SitemapEntry struct for URL metadata
- build_sitemap_xml() for XML construction
- xml_escape() for special character handling
- 5 unit tests covering single/multiple entries, lastmod, escaping
Module declared in main.rs but not yet integrated into pipeline.
- Add sidebar footer with GitHub repo link and MIT copyright
- Generate geometric logo for project branding
- Add logo as favicon in browser tab
- Add logo to sidebar header (32x32) next to "sukr" text
- Add centered logo (128px) at top of README
- Add sidebar footer with GitHub repo link and MIT copyright
- Position footer at bottom of sidebar using flexbox
- Generate geometric logo and add as favicon
- Update base.html template with footer and favicon link
KaTeX renders square roots using a 400em-wide SVG that relies on CSS
`overflow: hidden` to clip to the correct length. Without the KaTeX
stylesheet, this SVG extends across the entire page.
Changes:
- Add KaTeX CDN stylesheet link to base.html for fonts and layout
- Add .katex-display local margin/overflow overrides
- Add .hide-tail svg max-width fallback for file:// CORS blocking
The CDN provides full KaTeX styling when accessible. The SVG constraint
serves as a fallback when CDN is blocked (e.g., local file:// access).
Use tree-sitter-toml-ng v0.7.0 from tree-sitter-grammars, which is
compatible with tree-sitter 0.26 (unlike the older tree-sitter-toml).
- Add tree-sitter-toml-ng dependency
- Add Toml variant to Language enum
- Add TOML_CONFIG with crate's HIGHLIGHTS_QUERY
Fix markdown code block highlighting to properly support both markdown
structure (headings, frontmatter) and language injection (rust, bash).
The key fix uses `#set! injection.include-children` in the injection
query to override tree-sitter-md's internal tokenization, enabling
proper highlighting of embedded languages within code fences.
Changes:
- Use crate's HIGHLIGHT_QUERY_BLOCK for base markdown highlighting
- Add custom injection query with include-children directive
- Add YAML/TOML frontmatter and HTML block injection rules
- Add text.* highlight names (title, literal, uri, reference)
- Add string.escape highlight name
- Add CSS styles for new highlight classes
- Remove unused custom md-highlights.scm
- Add Atom feed generation docs (feeds.md)
- Add CSS minification docs (css.md)
- Fix em dash usage in css.md for natural prose
Completes AI audit (4 layers passed) and documentation gap analysis.
All 39 tests pass, docs site builds successfully.
Self-documenting docs site built with sukr itself (dogfooding):
Core changes:
- Rename package from nrd-sh to sukr
- Move personal site to sites/nrd.sh/
- Update AGENTS.md and README.md
Documentation site (docs/):
- Add site.toml with sukr.io base URL
- Create docs-specific templates with sidebar navigation
- Add dark theme CSS with syntax highlighting colors
- Document all features: templates, sections, syntax highlighting,
mermaid diagrams, and LaTeX math rendering
Bug fixes:
- Render individual pages for all sections (not just blog type)
- Add #[source] error chaining for Tera template errors
- Print full error chain in main() for better debugging
Self-documenting docs site built with sukr itself (dogfooding):
- docs/site.toml with sukr.io base URL
- docs-specific templates with sidebar navigation
- Dark theme CSS, responsive layout
- Documentation: getting-started, configuration, features
Also: improved error chaining for better template debugging
Enable monorepo support with CLI configuration:
- Add PathsConfig struct with serde defaults for content, output,
static, and templates directories
- Add optional [paths] table to site.toml (backward compatible)
- Add -c/--config <FILE> flag to specify config file path
- Add -h/--help flag with usage information
- Resolve all paths relative to config file location
Users can now run multiple sites from a single repo:
nrd-sh # uses ./site.toml
nrd-sh -c sites/blog/site.toml # looks in sites/blog/
Includes 2 new unit tests for path configuration parsing.