Commit Graph

245 Commits

Author SHA1 Message Date
Timothy DeHerrera
d24e4a0246 feat(sitemap): integrate sitemap generation into build 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.
2026-01-31 22:03:48 -07:00
Timothy DeHerrera
4d869a85f7 feat(sitemap): add XML sitemap generation module
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.
2026-01-31 22:00:20 -07:00
Timothy DeHerrera
eaf09c1c7d fix: nrd.sh -> sukr 2026-01-31 21:50:14 -07:00
Timothy DeHerrera
b271a3a0c8 fix: correct netlify dir 2026-01-31 19:23:10 -07:00
Timothy DeHerrera
6ab3e5a3bd chore: update netlify config 2026-01-31 19:19:49 -07:00
Timothy DeHerrera
893c2fee45 chore: remove personal site for sukr 2026-01-31 19:18:07 -07:00
Timothy DeHerrera
50116d8e8e docs: avoid redundant headers 2026-01-31 19:16:31 -07:00
Timothy DeHerrera
9869da554b chore: make logo transparent 2026-01-31 19:13:19 -07:00
Timothy DeHerrera
6dac743dfa feat(docs): add footer, favicon, and logo branding
- 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
2026-01-31 18:38:31 -07:00
Timothy DeHerrera
e0fe45330d feat(docs): add footer, favicon, and GitHub link
- 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
2026-01-31 18:35:29 -07:00
Timothy DeHerrera
1dd91a407b fix(math): add KaTeX CDN and fallback for radical SVG overflow
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).
2026-01-31 18:06:27 -07:00
Timothy DeHerrera
013786faa6 style(highlight): complete Dracula color coverage for all syntax tokens
Expand syntax highlighting CSS from 15 to 31 highlight classes, ensuring
all tree-sitter captures have assigned colors. Organized into logical
sections with comments.

Coverage added:
- type-builtin, function-builtin, constant-builtin (variants)
- variable-builtin, variable-parameter (orange, italic)
- constructor, embedded, escape
- string-special, string-special-path, string-special-uri
- punctuation-special

Color palette (Dracula-inspired):
- Pink (#ff79c6): keywords, operators, tags, punctuation-special
- Yellow (#f1fa8c): strings
- Green (#50fa7b): functions, constructors
- Cyan (#8be9fd): types, properties, attributes
- Purple (#bd93f9): numbers, constants
- Orange (#ffb86c): builtins, parameters, escapes
- Muted (#6272a4): comments
2026-01-31 17:38:54 -07:00
Timothy DeHerrera
10fd93452b doc(highlight): add examples 2026-01-31 17:30:35 -07:00
Timothy DeHerrera
ea9830f04b feat(highlight): add TOML syntax highlighting
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
2026-01-31 17:27:53 -07:00
Timothy DeHerrera
905897b3c4 fix(highlight): complete markdown syntax highlighting with injections
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
2026-01-31 17:24:27 -07:00
Timothy DeHerrera
352b3c1941 docs: add content organization and feature documentation
- Add content-organization.md explaining filesystem-to-URL mapping
- Add feeds.md for Atom feed generation
- Add css.md for CSS minification
- Fix em dash in css.md

Documents core implicit behavior: directory structure → site layout.
2026-01-31 17:14:56 -07:00
Timothy DeHerrera
4aa07d6079 docs(features): add feeds and css minification documentation
- 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.
2026-01-31 17:12:10 -07:00
Timothy DeHerrera
99987bd057 doc(AGENTS): activate integral fragment 2026-01-31 16:52:30 -07:00
Timothy DeHerrera
26e3b1c2ba chore: remove old site structure 2026-01-31 16:49:03 -07:00
Timothy DeHerrera
8ba4d76a64 chore: update predicate submodule 2026-01-31 16:48:07 -07:00
Timothy DeHerrera
8c54882118 feat(highlight): add markdown syntax highlighting with injection
Add tree-sitter-md for markdown parsing with injection support for
fenced code blocks. Code inside markdown code fences (```rust, ```bash,
etc.) is now fully syntax highlighted.

Key fix: Use `#set! injection.include-children` directive in the
injection query to override tree-sitter-md's internal tokenization
of code_fence_content, allowing proper language injection.

- Add tree-sitter-md v0.5.2 dependency
- Add Markdown variant to Language enum (md, markdown aliases)
- Create queries/md-highlights.scm (minimal markdown highlights)
- Create queries/md-injections.scm (with include-children directive)
- Add test: test_markdown_injection_rust
2026-01-31 16:41:11 -07:00
Timothy DeHerrera
69cd81621f feat(docs): create sukr documentation site with fixes
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
2026-01-31 16:14:04 -07:00
Timothy DeHerrera
8c806d1654 feat(docs): create sukr documentation site
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
2026-01-31 15:58:37 -07:00
Timothy DeHerrera
0516bfc600 refactor: move personal site to sites/nrd.sh/
Reorganize for monorepo structure:
- Move content/, templates/, static/, site.toml → sites/nrd.sh/
- Frees root for sukr docs site
- Build with: sukr -c sites/nrd.sh/site.toml
2026-01-31 15:47:47 -07:00
Timothy DeHerrera
e1ee18ca8a feat: rename project from nrd-sh to sukr
sukr = suckless + Rust. Minimal static site compiler.

- Update Cargo.toml name and description
- Update main.rs USAGE and doc comments
- Update AGENTS.md with new name, Tera architecture
- Create README.md with quick start guide
2026-01-31 15:46:26 -07:00
Timothy DeHerrera
4c2c3d5495 feat(cli): add configurable paths and --config flag
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.
2026-01-31 15:26:22 -07:00
Timothy DeHerrera
0d2c460f52 chore(fmt): add html formatting 2026-01-31 15:13:24 -07:00
Timothy DeHerrera
e200e94583 feat(templates): complete Tera migration, remove maud
Fully migrate from compile-time maud templates to runtime Tera:
- Rewrote main.rs to use TemplateEngine and discover_sections()
- Replaced hardcoded blog/projects with generic section loop
- Added Clone derive to Frontmatter and Content
- Fixed section_type dispatch via Section struct
- Deleted src/templates.rs, removed maud dependency

Users can now add sections without code changes.
2026-01-31 15:10:39 -07:00
Timothy DeHerrera
244b0ce85b feat(content): add Section struct and discover_sections()
Enable generic section processing by adding:
- Section struct with index, name, section_type, path
- Section::collect_items() to gather content in a section
- discover_sections() to find all directories with _index.md

Section type is determined from frontmatter `section_type` field,
falling back to directory name. Includes 5 unit tests.
2026-01-31 15:02:20 -07:00
Timothy DeHerrera
3df7fda26a feat(templates): add Tera runtime template engine
Lay groundwork for user-editable templates by adding Tera as a
runtime template engine alongside the existing maud templates.

Changes:
- Add tera dependency
- Create TemplateEngine struct with render methods
- Add TemplateLoad/TemplateRender error variants
- Add section_type/template fields to Frontmatter
- Create templates/ directory with base, page, section, and content templates

Dead code warnings are expected; TemplateEngine will be wired
in to replace maud in subsequent commits.
2026-01-31 14:59:49 -07:00
Timothy DeHerrera
1bf265f14b fix(feed): derive URLs from content paths
Replace hardcoded "/blog/{slug}.html" URL pattern with dynamic
path derivation using Content.output_path(). This ensures feed
URLs work correctly for any content location, not just blog posts.
2026-01-31 13:59:05 -07:00
Timothy DeHerrera
a5c56c2b2f feat(templates,main): wire dynamic nav through pipeline
Update all template functions to accept nav parameter and iterate
over discovered NavItem slice instead of hardcoded links.

Refactor main.rs:
- Call discover_nav() early in run()
- Thread nav to all template renders
- Replace hardcoded page list with dynamic discovery

Navigation is now fully driven by filesystem structure.
2026-01-31 13:56:16 -07:00
Timothy DeHerrera
b978edf4f2 feat(content): add filesystem-driven nav discovery
Add NavItem struct and discover_nav() function to scan content
directory and automatically build navigation from:
- Top-level .md files (pages)
- Directories with _index.md (sections)

Navigation is sorted by frontmatter weight, then alphabetically.
Custom nav_label field allows overriding title in nav menu.

Includes 5 unit tests covering page/section discovery, weight
ordering, and nav_label support.
2026-01-31 13:52:21 -07:00
Timothy DeHerrera
88b53b7a7b fix(mermaid): switch to crates.io and patch dagre_rust panic
Switch mermaid-rs-renderer from git dependency to crates.io 0.1.

Vendor and patch dagre_rust 0.0.5 to fix upstream panic in
remove_edge_label_proxies() where unwrap() is called on None
when processing edge label proxies without edge references.

This enables sequence diagrams and state diagrams that previously
crashed the build.
2026-01-28 20:52:05 -07:00
Timothy DeHerrera
d417e1c535 feat(mermaid): integrate diagram rendering into markdown pipeline
Intercept 'mermaid' code blocks in render.rs and call
mermaid::render_diagram() to convert to inline SVG.

- Use catch_unwind to handle upstream dagre_rust panics gracefully
- Graceful fallback: show raw code with mermaid-error class on failure
- Flowcharts render correctly; some diagram types hit upstream bugs
2026-01-28 20:36:45 -07:00
Timothy DeHerrera
abe465723c feat(mermaid): add mermaid-rs-renderer diagram module
Add src/mermaid.rs with render_diagram() wrapper around
mermaid-rs-renderer for build-time Mermaid-to-SVG conversion.

- Use mermaid-rs-renderer git dependency (SVG-only, no PNG)
- Configure with RenderOptions::modern() theme
- Include unit tests for flowchart and sequence diagrams
2026-01-28 20:31:40 -07:00
Timothy DeHerrera
eeec4a999b feat(render): integrate katex-rs math rendering
Enable ENABLE_MATH in pulldown-cmark options and implement
InlineMath/DisplayMath event handlers in the render pipeline.

- Inline math ($...$) renders via render_math(_, false)
- Display math ($$...$$) wrapped in <div class="math-display">
- Graceful degradation: errors logged to stderr, raw LaTeX shown
  with class="math-error" for styling
2026-01-28 20:18:36 -07:00
Timothy DeHerrera
ebe1fd3b6e feat(math): add katex-rs math rendering module
Add src/math.rs with render_math() wrapper around katex-rs for
build-time LaTeX to HTML conversion. Wire module into main.rs.

- Use KatexContext::default() for standard LaTeX function registry
- Settings: display_mode toggle, throw_on_error=false for graceful
  degradation
- Include unit tests for inline/display math rendering
2026-01-28 20:16:25 -07:00
Timothy DeHerrera
a7338f5418 feat: add Nix injection queries for embedded language highlighting
Adapted Helix nix/injections.scm for tree-sitter-highlight:
- Removed Helix-specific predicates
- Recognizes bash in buildPhase/installPhase, python in testScript,
  json in fromJSON, etc.
2026-01-26 23:54:59 -07:00
Timothy DeHerrera
b16246fba6 feat: use custom Nix highlight queries for richer syntax colors
- queries/nix-highlights.scm: Adapted from Helix editor queries.
  Properly identifies functions, properties, variable parameters,
  escape sequences, and string interpolation. Much richer than
  the bundled tree-sitter-nix query (99 lines vs 113 lines).

- src/highlight.rs: Load custom Nix query via include_str!
  instead of using bundled HIGHLIGHTS_QUERY.

- static/style.css: Fix variable (#e36209) and punctuation (#586069)
  colors to be distinct from text color.

Results: hl-function now appears (6 occurrences), hl-property
visible (17), hl-variable reduced from 43 to 17. Functions like
mkShell now render in purple/blue instead of orange.
2026-01-25 20:18:48 -07:00
Timothy DeHerrera
5b7805d753 fix: expand highlight captures for better Nix support
- src/highlight.rs: Add 7 new captures to HIGHLIGHT_NAMES:
  embedded, escape, function, punctuation.special, string.special,
  string.special.path, string.special.uri. Now 27 total captures.

- static/style.css: Add CSS variables and class rules for new
  captures in both light and dark themes. escape gets bold
  styling, string-special uses distinct color.

These captures are used by tree-sitter-nix but were previously
missing, causing sparse highlighting. Now functions, escapes,
and paths are properly highlighted.
2026-01-25 17:29:18 -07:00
Timothy DeHerrera
acb0ff3e15 feat: add syntax highlighting for 9 additional languages
- Cargo.toml: Add tree-sitter grammars for Nix, Python, JavaScript,
  TypeScript, Go, C, CSS, HTML, YAML. Upgrade tree-sitter-highlight
  to 0.26 for language version 15 compatibility.

- src/highlight.rs: Add Language enum variants and get_config()
  match arms for all new languages. Update render() callback for
  0.26 API (writes attributes to buffer). Add tests for Nix and
  Python highlighting.

TOML excluded due to incompatible API (tree-sitter 0.20 vs 0.26).
2026-01-25 17:20:00 -07:00
Timothy DeHerrera
a73359098e docs: humanize documentation and update architecture
- content/about.md: Rewrite with first-person voice, remove
  "next-generation" and "craft tools that emphasize" patterns.
  Add personality ("probably more than it should").

- content/collab.md: More direct language, remove "find value in"
  and "broader community" hedging. Shorter bullet lists.

- AGENTS.md: Remove "state-of-the-art", update architecture tree
  to reflect current modules (config, feed, templates), fix
  stale config section to show actual site.toml usage.
2026-01-24 22:28:38 -07:00
Timothy DeHerrera
3a36c2a909 chore: add Netlify deployment configuration
- netlify.toml: Configure cargo build --release and run compiler.
  Publish directory set to public/.

- static/_headers: Add security headers (X-Frame-Options, CSP, etc.)
  and cache control for static assets (1 year for css/images,
  1 hour for HTML, 1 hour for feed).
2026-01-24 22:17:59 -07:00
Timothy DeHerrera
51b947256d feat: add Atom feed generation
- src/feed.rs: New module with generate_atom_feed() that produces
  Atom 1.0 XML from blog posts. Uses config.base_url for absolute
  entry URLs. Includes xml_escape() helper.

- src/main.rs: Wire mod feed and call generate_feed() after blog
  index generation. Outputs to public/feed.xml.

- src/templates.rs: Add <link rel="alternate" type="application/atom+xml">
  autodiscovery link to page head using config.base_url.

Feed includes title, author, updated timestamp, and entries with
title, link, id, updated, and summary for each blog post.
2026-01-24 22:01:59 -07:00
Timothy DeHerrera
675050fd56 fix: correct depth calculation for relative paths
- src/templates.rs: Add path_depth() helper that counts directory
  segments minus filename, not raw slash count.
  "/blog/slug.html" → depth=1 (one directory level)
  "/index.html" → depth=0 (root level)

This fixes relative path generation after adding canonical URLs.
file:// navigation now works correctly alongside absolute
canonical URLs.
2026-01-24 21:52:12 -07:00
Timothy DeHerrera
d166e86435 feat: add TOML site config for metadata
- Cargo.toml: Add toml and serde dependencies
- site.toml: New config with title, author, base_url
- src/config.rs: SiteConfig struct with load() function
- src/error.rs: Add Error::Config for parse errors
- src/main.rs: Load site.toml, thread config and page paths
  through generators
- src/templates.rs: Use config.title in nav/titles,
  config.author in footer, config.base_url for canonical URLs.

All three config fields verified in generated HTML output.
2026-01-24 21:47:47 -07:00
Timothy DeHerrera
71d5ac1e37 refactor: switch to flat .html output (suckless style)
- src/content.rs: output_path() now returns slug.html instead of
  slug/index.html for regular content.

- src/templates.rs: All hrefs use explicit .html extension.
  Nav links point to index.html, blog.index.html, about.html.
  Blog post links use ./slug.html format.

- src/main.rs: Adjust depth values (root=0, blog posts=1).

No more directory-per-page overhead. file:// navigation works
without directory listings. True suckless structure.
2026-01-24 21:36:58 -07:00
Timothy DeHerrera
b9be21156d feat: implement relative paths for IPFS/decentralization
- src/templates.rs: Add depth parameter to all template functions.
  Add relative_prefix() helper that generates "./", "../", "../..", etc.
  All hrefs now use relative paths instead of absolute.
  Unit test for relative_prefix() added.

- src/main.rs: Pass depth to templates based on output location.
  Root=0, blog index/pages=1, blog posts=2.

Navigation works correctly when viewed via file:// protocol.
Site is now IPFS-compatible.
2026-01-24 21:22:03 -07:00
Timothy DeHerrera
7fa60d9b07 feat: add CSS minification via lightningcss
- Cargo.toml: Add lightningcss 1.0.0-alpha.70 dep
- src/css.rs: New module with minify_css() function.
  Uses StyleSheet::parse() + minify() + to_css() pipeline.
  3 unit tests: whitespace removal, comment removal, selector merge.
- src/main.rs: Integrate minification into copy_static_assets().
  CSS files minified before writing; size delta logged.

Result: style.css 5670→4165 bytes (~27% smaller)
2026-01-24 21:07:56 -07:00