Skip to content

Code Blocks Demo

This page demonstrates all the advanced code block features available in Material for MkDocs, including annotations, line highlighting, custom themes, and interactive elements.

Feature Showcase

Line Numbers and Highlighting

def advanced_data_processor(data_source: str, options: dict) -> dict:
    # Configuration and validation (highlighted)
    if not data_source or not isinstance(options, dict):
        raise ValueError("Invalid input parameters")

    # Initialize processing pipeline
    processor = DataProcessor(options)  # Important line

    # Process data in chunks (highlighted section)
    results = []
    for chunk in processor.chunk_data(data_source):
        processed_chunk = processor.transform(chunk)
        results.append(processed_chunk)

    # Aggregate and return results
    return processor.aggregate(results)

Rich Annotations

# Multi-stage Docker build for production
FROM node:18-alpine AS builder  # (1)!

WORKDIR /app  # (2)!

# Copy package files
COPY package*.json ./  # (3)!
RUN npm ci --only=production  # (4)!

# Copy source code and build
COPY . .  # (5)!
RUN npm run build  # (6)!

# Production stage
FROM nginx:alpine  # (7)!

# Copy built application
COPY --from=builder /app/dist /usr/share/nginx/html  # (8)!

# Copy custom nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf  # (9)!

EXPOSE 80  # (10)!

CMD ["nginx", "-g", "daemon off;"]  # (11)!
  1. Base Image Selection

Using Node.js 18 Alpine for smaller image size and security.

# Check image sizes
docker images node:18-alpine
docker images node:18  # Compare with full image
  1. Working Directory

Sets the working directory inside the container where all operations will occur.

  1. Package Files First

Copy package files before source code to leverage Docker layer caching:

!!! tip "Docker Layer Caching" Package files change less frequently than source code, so copying them first allows Docker to cache the npm install step.

  1. Production Dependencies

npm ci is faster and more reliable than npm install for production builds.

  1. Source Code Copy

Copy all source files. Uses .dockerignore to exclude unnecessary files.

  1. Build Process

Compile TypeScript, bundle assets, optimize for production.

  1. Production Server

Nginx Alpine provides a minimal, secure web server for serving static files.

  1. Multi-stage Copy

Copy built assets from builder stage to production stage, keeping final image small.

  1. Custom Configuration

Custom nginx.conf for optimized serving:

server {
    listen 80;
    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }
}
  1. Port Exposure

    Expose port 80 for HTTP traffic.

  2. Container Command

    Start nginx in foreground mode for proper container lifecycle management.

Code Groups with Tabs

components/UserProfile.tsx
import React, { useState, useEffect } from 'react';
import { User, UserService } from '../services/UserService';

interface UserProfileProps {
    userId: string;
}

export const UserProfile: React.FC<UserProfileProps> = ({ userId }) => {
    const [user, setUser] = useState<User | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
        const fetchUser = async () => {
            try {
                setLoading(true);
                const userData = await UserService.getUser(userId);
                setUser(userData);
            } catch (err) {
                setError(err instanceof Error ? err.message : 'Unknown error');
            } finally {
                setLoading(false);
            }
        };

        fetchUser();
    }, [userId]);

    if (loading) return <div className="spinner">Loading...</div>;
    if (error) return <div className="error">Error: {error}</div>;
    if (!user) return <div className="not-found">User not found</div>;

    return (
        <div className="user-profile">
            <h1>{user.name}</h1>
            <p>Email: {user.email}</p>
            <p>Status: {user.isActive ? 'Active' : 'Inactive'}</p>
        </div>
    );
};
api/users.py
from fastapi import FastAPI, HTTPException, Depends
from sqlalchemy.orm import Session
from typing import List, Optional
from models import User, UserCreate, UserResponse
from database import get_db

app = FastAPI(title="User Management API")

@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: str, db: Session = Depends(get_db)):
    """Retrieve a specific user by ID."""
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

@app.post("/users/", response_model=UserResponse, status_code=201)
async def create_user(user_data: UserCreate, db: Session = Depends(get_db)):
    """Create a new user."""
    # Check if user already exists
    existing_user = db.query(User).filter(User.email == user_data.email).first()
    if existing_user:
        raise HTTPException(status_code=400, detail="Email already registered")

    # Create new user
    db_user = User(**user_data.dict())
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

@app.get("/users/", response_model=List[UserResponse])
async def list_users(
    skip: int = 0,
    limit: int = 100,
    active_only: bool = False,
    db: Session = Depends(get_db)
):
    """List users with optional filtering."""
    query = db.query(User)

    if active_only:
        query = query.filter(User.is_active == True)

    users = query.offset(skip).limit(limit).all()
    return users
migrations/001_users.sql
-- Create users table with comprehensive fields
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    name VARCHAR(100) NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    is_active BOOLEAN DEFAULT true,
    is_verified BOOLEAN DEFAULT false,
    profile_image_url TEXT,
    last_login_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create optimized indexes
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_active ON users(is_active) WHERE is_active = true;
CREATE INDEX idx_users_created_at ON users(created_at);

-- Create user roles table
CREATE TABLE user_roles (
    id SERIAL PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role_name VARCHAR(50) NOT NULL,
    granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    granted_by UUID REFERENCES users(id)
);

-- Create index for role lookups
CREATE INDEX idx_user_roles_user_id ON user_roles(user_id);
CREATE INDEX idx_user_roles_role_name ON user_roles(role_name);

-- Add trigger for updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER update_users_updated_at
    BEFORE UPDATE ON users
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();
tests/test_users.py
    import pytest
    from fastapi.testclient import TestClient
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from api.main import app
    from database import get_db, Base

    # Test database setup
    SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
    engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
    TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

    def override_get_db():
        """Override database dependency for testing."""
        try:
            db = TestingSessionLocal()
            yield db
        finally:
            db.close()

    app.dependency_overrides[get_db] = override_get_db
    client = TestClient(app)

    @pytest.fixture(autouse=True)
    def setup_database():
        """Create and clean up test database."""
        Base.metadata.create_all(bind=engine)
        yield
        Base.metadata.drop_all(bind=engine)

    def test_create_user():
        """Test user creation endpoint."""
        user_data = {
            "name": "Test User",
            "email": "test@example.com",
            "password": "testpassword123"
        }

        response = client.post("/users/", json=user_data)

        assert response.status_code == 201
        data = response.json()
        assert data["email"] == user_data["email"]
        assert data["name"] == user_data["name"]
        assert "id" in data
        assert "password" not in data  # Ensure password is not returned

    def test_get_user():
        """Test user retrieval endpoint."""
        # First create a user
        user_data = {
            "name": "Test User",
            "email": "test@example.com",
            "password": "testpassword123"
        }

        create_response = client.post("/users/", json=user_data)
        user_id = create_response.json()["id"]

        # Then retrieve it
        response = client.get(f"/users/{user_id}")

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == user_id
        assert data["email"] == user_data["email"]

    def test_list_users():
        """Test user listing with pagination."""
        # Create multiple users
        for i in range(5):
            user_data = {
                "name": f"User {i}",
                "email": f"user{i}@example.com",
                "password": "testpassword123"
            }
            client.post("/users/", json=user_data)

        # Test pagination
        response = client.get("/users/?skip=2&limit=2")

        assert response.status_code == 200
        data = response.json()
        assert len(data) == 2
    ```
</div>

### Configuration Files

```yaml title="docker-compose.yml" linenums="1" hl_lines="5-7 12-14 25-27"
version: '3.8'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://app_user:secure_password@db:5432/app_db
      - REDIS_URL=redis://redis:6379/0
      - SECRET_KEY=${SECRET_KEY}
      - DEBUG=false
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./logs:/app/logs
    restart: unless-stopped
    networks:
      - app-network

  db:
    image: postgres:14-alpine
    environment:
      POSTGRES_DB: app_db
      POSTGRES_USER: app_user
      POSTGRES_PASSWORD: secure_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app_user -d app_db"]
      interval: 10s
      timeout: 5s
      retries: 5
    ports:
      - "5432:5432"
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - web
    networks:
      - app-network

volumes:
  postgres_data:
  redis_data:

networks:
  app-network:
    driver: bridge

Advanced Highlighting

utils/performance.js
class PerformanceMonitor {
    constructor(options = {}) {
        this.metrics = new Map();
        this.observers = [];

        // Initialize performance observers
        if ('PerformanceObserver' in window) {
            this.initResourceObserver();
            this.initNavigationObserver();
            this.initMeasureObserver();
            this.initLongTaskObserver();
        }

        // Configuration options
        this.config = {
            enableUserTiming: true,
            enableResourceTiming: true,
            sampleRate: options.sampleRate || 0.1,
            maxEntries: options.maxEntries || 1000,
            ...options
        };

        // Automatically collect Core Web Vitals
        this.collectCoreWebVitals();
    }

    initResourceObserver() {
        const observer = new PerformanceObserver((list) => {
            for (const entry of list.getEntries()) {
                this.recordResourceTiming(entry);
            }
        });

        observer.observe({ entryTypes: ['resource'] });
        this.observers.push(observer);
    }

    initNavigationObserver() {
        const observer = new PerformanceObserver((list) => {
            for (const entry of list.getEntries()) {
                this.recordNavigationTiming(entry);
            }
        });

        observer.observe({ entryTypes: ['navigation'] });
        this.observers.push(observer);
    }

    collectCoreWebVitals() {
        // Largest Contentful Paint (LCP)
        new PerformanceObserver((entryList) => {
            const entries = entryList.getEntries();
            const lastEntry = entries[entries.length - 1];
            this.recordMetric('LCP', lastEntry.startTime);
        }).observe({ entryTypes: ['largest-contentful-paint'] });

        // First Input Delay (FID)
        new PerformanceObserver((entryList) => {
            for (const entry of entryList.getEntries()) {
                const fid = entry.processingStart - entry.startTime;
                this.recordMetric('FID', fid);
            }
        }).observe({ entryTypes: ['first-input'] });

        // Cumulative Layout Shift (CLS)
        let clsValue = 0;
        new PerformanceObserver((entryList) => {
            for (const entry of entryList.getEntries()) {
                if (!entry.hadRecentInput) {
                    clsValue += entry.value;
                }
            }
            this.recordMetric('CLS', clsValue);
        }).observe({ entryTypes: ['layout-shift'] });
    }

    recordMetric(name, value, labels = {}) {
        const timestamp = performance.now();
        const metric = {
            name,
            value,
            timestamp,
            labels,
            url: window.location.href,
            userAgent: navigator.userAgent
        };

        if (!this.metrics.has(name)) {
            this.metrics.set(name, []);
        }

        const metrics = this.metrics.get(name);
        metrics.push(metric);

        // Limit the number of stored metrics
        if (metrics.length > this.config.maxEntries) {
            metrics.shift();
        }

        // Send to analytics if sample rate allows
        if (Math.random() < this.config.sampleRate) {
            this.sendToAnalytics(metric);
        }
    }

    async sendToAnalytics(metric) {
        try {
            await fetch('/api/analytics/performance', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(metric),
                keepalive: true
            });
        } catch (error) {
            console.warn('Failed to send performance metric:', error);
        }
    }

    getMetrics(name) {
        return this.metrics.get(name) || [];
    }

    getAllMetrics() {
        const result = {};
        for (const [key, value] of this.metrics) {
            result[key] = value;
        }
        return result;
    }

    destroy() {
        // Clean up observers
        this.observers.forEach(observer => observer.disconnect());
        this.observers = [];
        this.metrics.clear();
    }
}

// Initialize performance monitoring
const performanceMonitor = new PerformanceMonitor({
    sampleRate: 0.1,
    maxEntries: 500
});

// Export for global use
window.performanceMonitor = performanceMonitor;

Custom Styling Examples

Dark Theme Code Block

/* Custom dark theme for code blocks */
[data-md-color-scheme="slate"] .highlight {
  background-color: #0d1117;
  color: #c9d1d9;
}

[data-md-color-scheme="slate"] .highlight .hll {
  background-color: #1c2128;
}

[data-md-color-scheme="slate"] .highlight .c {
  color: #8b949e;
  font-style: italic;
}

[data-md-color-scheme="slate"] .highlight .k {
  color: #ff7b72;
}

[data-md-color-scheme="slate"] .highlight .s {
  color: #a5d6ff;
}

Interactive Elements

The code blocks on this page demonstrate:

  1. Copy Functionality - Click the copy button to copy code
  2. Responsive Design - Horizontal scroll on mobile devices
  3. Keyboard Navigation - Tab through interactive elements
  4. Search Integration - All code content is searchable
  5. Print Optimization - Clean printing without interactive elements

These features work together to create an excellent developer experience for code documentation.

Performance Considerations

  • Lazy Loading - Code highlighting loads on demand
  • Efficient Rendering - Pygments generates optimized HTML
  • Mobile Optimization - Touch-friendly interactions
  • Accessibility - Screen reader compatible structure
  • Cache Friendly - Generated HTML caches well