Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Contributors Guide

Architecture

Listsome follows a pipeline architecture: source content → parse → render → output.

projects/*/index.md  ──►  Parser  ──►  Renderer (MiniJinja)  ──►  output/
(frontmatter + MD)        (pulldown-cmark)  +                   (static HTML)
                                              templates/

Modules

ModuleResponsibility
src/cli.rsCommand-line argument parsing with clap
src/commands.rsCommand implementations that wire up the pipeline
src/config.rslistsome.toml loading, default config creation
src/parser/mod.rsFrontmatter extraction, Markdown→HTML, step/BOM parsing
src/render/mod.rsMiniJinja template rendering, context builders
src/generator/mod.rsSite generation orchestration (discover, parse, render, copy assets, generate index + feed)
src/server/mod.rsAxum-based dev server with WebSocket live reload and file watching
src/model/project.rsProject, Step, ProjectMetadata, Difficulty, ProjectStatus
src/model/site.rsSiteConfig, BuildConfig, WebmentionConfig, FediverseConfig
src/error.rsListsomeError enum with typed error variants
src/templates/Built-in MiniJinja templates (base.html, index.html, project.html, feed.atom)

Data Flow

  1. listsome build loads listsome.toml via config::find_and_load_config()
  2. generator::SiteGenerator::discover_projects() walks projects/ looking for index.md
  3. Each file is parsed by parser::parse_project() which extracts frontmatter and renders Markdown to HTML
  4. Headers matching ## Step N: Title become Step structs; BOM tables become MaterialItems
  5. render::TemplateRenderer renders each project into HTML using MiniJinja templates
  6. Assets from projects/<slug>/assets/ are copied to output/<slug>/assets/
  7. output/index.html (project listing) and output/feed.atom are generated

Design Patterns

  • Pure functions with no shared mutable state
  • Result<T, ListsomeError> throughout for error handling
  • Immutable Project and ProjectMetadata structs
  • SiteConfig with sensible defaults via Default trait
  • Template renderer is created once and reused across all projects

Building

cargo build
cargo build --release   # Optimized binary

Testing

cargo test              # Run all tests
cargo test -- --nocapture  # Show test output

Tests are in #[cfg(test)] modules within each source file (parser, render, generator, config, server).

Code Style

  • cargo clippy: Pedantic and nursery lints enabled (warnings during dev, not errors)
  • cargo fmt: 100-character line width, Unix line endings
  • Conventional commit messages for pull requests

How to Contribute

  1. Open an issue to discuss your proposed change
  2. Fork the repository
  3. Make your changes with tests
  4. Run cargo test and cargo clippy
  5. Submit a pull request