We welcome contributions to MD-Book! This document provides guidelines for contributing to the project.
- Rust 1.70+ (check with
rustc --version) - Git
- Basic familiarity with Rust and web technologies
# Clone the repository
git clone https://github.com/terraphim/md-book.git
cd md-book
# Install development dependencies
cargo install cargo-watch
# Run tests to ensure everything works
cargo test --all
# Build the project
cargo build
# Run locally
cargo run -- -i demo-docs -o demo-output --serve --watch# Watch for changes and run tests automatically
cargo watch -x test
# Run integration tests with all features
cargo test --test integration --features "tokio,search,syntax-highlighting"
# Run E2E tests
cargo test --test e2e --features "tokio,search,syntax-highlighting"
# Run quality checks
make qaFound a bug? Please report it by:
- Search existing issues to avoid duplicates
- Create a new issue using the bug report template
- Provide minimal reproduction with:
- MD-Book version (
md-book --version) - Operating system
- Rust version
- Sample code/files
- Expected vs actual behavior
- MD-Book version (
Bug Report Template:
## Bug Description
Brief description of the issue
## Reproduction Steps
1. `md-book -i docs -o output`
2. Open generated site
3. Observe bug
## Expected Behavior
What should happen
## Actual Behavior
What actually happens
## Environment
- MD-Book: 0.1.1
- OS: macOS 13.0
- Rust: 1.70.0Have an idea? We'd love to hear it!
- Check existing issues and feature requests
- Create a new issue using the feature request template
- Describe the use case and proposed solution
Feature Request Template:
## Problem Statement
What problem does this solve?
## Proposed Solution
How should this work?
## Alternatives Considered
What other approaches did you consider?
## Additional Context
Any other relevant information-
Core Features (
src/)- Build process and template rendering
- Search integration and indexing
- Development server and live reload
- Configuration system
-
Templates and Styling (
src/templates/)- UI/UX improvements
- Theme customization options
- Responsive design enhancements
- Web Components
-
Documentation (
demo-docs/,README.md)- User documentation improvements
- API documentation
- Examples and tutorials
- Deployment guides
-
Testing (
tests/)- Unit tests for core functionality
- Integration tests for workflows
- E2E tests for user scenarios
- Performance benchmarks
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Make changes following our coding standards
- Add tests for new functionality
- Run all checks:
make qa - Commit changes using conventional commits
- Push to fork:
git push origin feature/your-feature - Create Pull Request with detailed description
Code Style:
- Use
cargo fmtfor formatting - Follow
clippyrecommendations - Use
Result<T>for error handling - Document public APIs with
///comments
Example:
/// Renders markdown content to HTML
///
/// # Arguments
///
/// * `content` - The markdown content to render
/// * `config` - Rendering configuration options
///
/// # Returns
///
/// Returns `Ok(html)` if rendering succeeds, `Err(error)` if it fails
///
/// # Examples
///
/// ```
/// use md_book::render_markdown;
///
/// let html = render_markdown("# Hello", &config)?;
/// assert!(html.contains("<h1>Hello</h1>"));
/// ```
pub fn render_markdown(content: &str, config: &RenderConfig) -> Result<String> {
// Implementation
}Error Handling:
use anyhow::{Context, Result};
pub fn build_site(config: &Config) -> Result<()> {
// Use context for better error messages
std::fs::create_dir_all(&config.output_dir)
.context("Failed to create output directory")?;
// Use ? operator for error propagation
process_files(&config.input_dir, &config.output_dir)
.context("Failed to process files")?;
Ok(())
}tests/
βββ common/ # Test utilities and fixtures
βββ integration/ # Integration tests
βββ e2e/ # End-to-end tests
βββ integration/
βββ build_test.rs # Build process tests
βββ mdbook_test_book.rs # Compatibility tests
βββ mdbook_compatibility.rs # Feature compatibility
# Unit tests only
cargo test --lib --bins
# Integration tests
cargo test --test integration --features "tokio,search,syntax-highlighting"
# E2E tests
cargo test --test e2e --features "tokio,search,syntax-highlighting"
# All tests with coverage
cargo test --all-features
# Single test
cargo test test_render_markdownUnit Test Example:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_markdown_rendering() {
let result = render_markdown("# Hello", &Config::default());
assert!(result.is_ok());
assert!(result.unwrap().contains("<h1>Hello</h1>"));
}
#[test]
fn test_invalid_input() {
let result = parse_config("invalid::toml");
assert!(result.is_err());
}
}Integration Test Example:
#[tokio::test]
async fn test_full_build_process() -> Result<()> {
let temp_dir = TempDir::new()?;
let input_dir = temp_dir.path().join("input");
let output_dir = temp_dir.path().join("output");
// Create test content
std::fs::create_dir_all(&input_dir)?;
std::fs::write(input_dir.join("index.md"), "# Test")?;
// Run build process
let config = Config::new(&input_dir, &output_dir);
build_site(&config).await?;
// Verify output
assert!(output_dir.join("index.html").exists());
assert!(output_dir.join("pagefind").exists());
Ok(())
}MD-Book follows Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backwards compatible)
- PATCH: Bug fixes
- Update version in
Cargo.toml - Update CHANGELOG.md with release notes
- Run full test suite:
make ci-local - Create Git tag:
git tag v0.x.x - Push tag:
git push origin v0.x.x - Create GitHub Release
- Deploy to crates.io (automated via GitHub Actions)
The project uses GitHub Actions for automated releases:
# .github/workflows/release.yml
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
jobs:
create-release:
# Creates GitHub release
build-release:
# Builds binaries for all platforms
publish-crate:
# Publishes to crates.iomake help # Show all available commands
make qa # Run all quality checks
make dev-check # Complete development check
make ci-local # Simulate CI locally
make test # Run unit tests
make test-integration # Run integration tests
make test-all # Run all tests
make fmt # Check code formatting
make fmt-fix # Fix code formatting
make clippy # Run clippy lints
make clean # Clean build artifactsInstall pre-commit hooks for automatic quality checks:
make install-pre-commit
# or manually:
./scripts/setup-pre-commit.shHooks run:
cargo fmt --all -- --check- Formatting checkcargo clippy --all-targets --all-features -- -D warnings- Lintingcargo test --lib --bins- Unit testscargo check --all-targets --all-features- Compilation check
VS Code (.vscode/settings.json):
{
"rust-analyzer.checkOnSave.command": "clippy",
"rust-analyzer.cargo.loadOutDirsFromCheck": true,
"rust-analyzer.imports.granularity.group": "module",
"rust-analyzer.completion.addCallParentheses": true
}Neovim (.config/nvim/after/plugin/rust.lua):
-- Rust development setup
vim.g.rustaceanvim = {
tools = {
enable = true,
test_runner = "cargo",
cargo_watch = {
enable = true,
},
},
server = {
standalone = true,
},
}-
Documentation Improvements
- Improve README examples
- Add more code examples
- Fix typos and grammar
-
Test Coverage
- Add missing unit tests
- Improve test coverage
- Add edge case tests
-
UI/UX Enhancements
- Improve mobile responsiveness
- Add theme customization options
- Enhance accessibility
Check the GitHub Issues for current opportunities.
Let's walk through adding a new feature:
Example: "Add dark mode toggle to documentation"
# Explore relevant files
find src/templates -name "*.html" | xargs grep -l "theme"
find src/templates -name "*.css" | xargs grep -l "dark"Add CSS variables (src/templates/css/styles.css):
:root {
--bg-color: #ffffff;
--text-color: #333333;
--primary-color: #0066cc;
}
[data-theme="dark"] {
--bg-color: #1a1a1a;
--text-color: #e0e0e0;
--primary-color: #4d94ff;
}Add JavaScript toggle (src/templates/js/theme-toggle.js):
function toggleTheme() {
const current = document.documentElement.getAttribute('data-theme');
const newTheme = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
}
// Initialize theme from localStorage
document.addEventListener('DOMContentLoaded', () => {
const savedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', savedTheme);
});Update template (src/templates/page.html.tera):
<button onclick="toggleTheme()" class="theme-toggle">
<span id="theme-icon">π</span>
</button>
<script src="/js/theme-toggle.js"></script>Unit test (src/tests/theme_tests.rs):
#[test]
fn test_theme_toggle_persistence() {
// Test theme is saved to localStorage
// Test theme is applied correctly
// Test default theme handling
}Add to configuration documentation:
[output.html.theme]
enable-dark-mode = true
default-theme = "light" # light, dark, automake qa
cargo test
cargo clippy## Description
Added dark mode toggle to documentation with:
- CSS custom properties for theme switching
- JavaScript for theme persistence
- Template integration
- Configuration option
- Mobile-friendly toggle button
## Testing
- Manual testing in browsers
- Unit tests for theme logic
- Accessibility testing
## Screenshots
[Add screenshots if applicable]We are committed to providing a friendly, safe, and welcoming environment for all participants. Please read our full Code of Conduct.
- GitHub Issues: Bug reports, feature requests
- GitHub Discussions: General questions, ideas
- Twitter: @terraphim (announcements)
- Discord: For real-time chat (coming soon)
- Documentation: https://md-book.pages.dev
- GitHub Issues: For bugs and feature requests
- Discussions: For questions and ideas
- Email: support@terraphim.io (for support inquiries)
- Enhanced theme system
- MathJax/LaTeX support
- Improved search capabilities
- Plugin system improvements
- Multi-language support
- Advanced search features
- Visual editor integration
- Analytics integration
- Complete mdBook compatibility
- Comprehensive plugin ecosystem
- WebAssembly-based rendering
- Real-time collaboration features
Thank you to all contributors who have helped make MD-Book better:
- Rust Community: For inspiration and feedback
- mdBook Team: For pioneering documentation generation in Rust
- Tera Team: For the excellent templating engine
- Pagefind Team: For the amazing search library
- All Contributors: For bug reports, features, and improvements
By contributing to MD-Book, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to MD-Book! Every contribution, no matter how small, helps make the project better for everyone.
Have questions? Feel free to ask in GitHub Discussions or open an issue.