Skip to content

Latest commit

 

History

History
250 lines (200 loc) · 8.68 KB

File metadata and controls

250 lines (200 loc) · 8.68 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Microdocs is a Python tool that transforms Markdown files (README.md and CHANGELOG.md) into a self-contained HTML documentation site. It converts markdown to HTML with syntax highlighting, tables of contents, and other extensions, then injects the content into an HTML template.

Development Commands

Setup

# Install dependencies (requires Python 3.11+)
uv sync

# Install with dev dependencies
uv sync --dev

Running the Tool

# Basic usage - convert markdown files to HTML
microdocs README.md CHANGELOG.md

# Specify output file
microdocs README.md CHANGELOG.md -o docs/index.html

# Use custom template
microdocs README.md -t custom-template.html

# Run as Python module
python -m microdocs README.md CHANGELOG.md

Code Quality

# Run linter (Ruff with "ALL" rules enabled)
ruff check .

# Auto-fix linting issues
ruff check --fix .

# Format code
ruff format .

Template Development

Templates are built using Vite, which compiles HTML, CSS (Tailwind), and JavaScript into single-file outputs.

Template Structure:

  • Source: templates_src/{template_name}/ (root level, not in microdocs/)
    • {template_name}.html - HTML template with Jinja2 markup
    • {template_name}.css - Tailwind CSS source
    • {template_name}.js - JavaScript source
  • Output: microdocs/templates/{template_name}/{template_name}.html (single file with inlined CSS/JS)

Development workflow:

# Start dev server with hot-reloading
npm run dev

# Build all templates for production
npm run build

# Preview built templates
npm run preview

IMPORTANT:

  • Never edit files in microdocs/templates/ directly - they are auto-generated by Vite!
  • Always edit source files in templates_src/ (at project root)
  • Run npm run build to compile templates after making changes
  • The build process automatically discovers all template directories and builds them
  • templates_src/ is excluded from PyPI package builds (only compiled templates are distributed)

Testing

Test Organization

  • Tests are located in microdocs/tests/
  • Tests are organized by module type:
    • test_builder.py - Low-level functions (markdown conversion, title extraction, etc.)
    • test_cli.py - CLI interface functionality
    • test_templates.py - Template rendering and integration

Test Style

  • Use pytest functions, NOT TestCase classes
  • Use pytest fixtures for reusable test data
  • Focus on testing OUR code, not external libraries (e.g., don't test that markdown conversion works, test that our builder uses it correctly)

Running Tests

# Run all tests
pytest

# Run tests with verbose output
pytest -v

# Run tests with coverage
pytest --cov=microdocs

# Run tests across all Python versions (3.11-3.14)
./runtests.sh

CI/CD

  • .github/workflows/test.yml - Runs tests on Python 3.11, 3.12, 3.13, 3.14
  • .github/workflows/lint.yml - Runs ruff check and ruff format --check

Release Process

When creating a new release, follow these steps in order:

  1. Build templates - Ensure templates are up to date

    npm run build
  2. Run full test suite - Verify everything passes before releasing

    pytest && ruff check . && ruff format --check .
  3. Update version in pyproject.toml

    • Bump version number
    • Update development status classifier if needed (Alpha → Beta → Production/Stable)
  4. Update CHANGELOG.md

    • Move "Unreleased" section to new version heading with date
    • Add summary of changes (Added, Changed, Fixed, etc.)
    • Include deployment instructions with new version number
  5. Commit changes

    git add pyproject.toml CHANGELOG.md
    git commit -m "Release version X.Y.Z"
  6. Create git tag

    git tag -a vX.Y.Z -m "Release vX.Y.Z: brief description"
  7. Build the package

    uv build
  8. Publish to PyPI

    uv publish
  9. Push changes and tags

    git push
    git push --tags
  10. Update floating major version tag (for GitHub Action compatibility)

# For v1.x.x releases, update the v1 tag
git tag -f v1 vX.Y.Z
git push origin v1 --force

Important Notes:

  • Always run tests BEFORE building and publishing
  • Never build before creating git commit and tag
  • Always create git tag BEFORE building
  • Update CHANGELOG with actual release date
  • Include deployment instructions in CHANGELOG
  • Update floating major version tag (v1, v2, etc.) after pushing tags so GitHub Actions can use @v1 for latest v1.x release

Architecture

Core Components

  1. Entry Points (microdocs/init.py, main.py, cli.py)

    • Package exposes main() function that invokes the Typer CLI app
    • Registered as microdocs CLI command in pyproject.toml
    • CLI accepts multiple markdown files as arguments
    • Options: --output (default: index.html), --template (custom HTML template), --repo-url, --title
  2. Builder (microdocs/builder.py)

    • Clean, well-documented module with comprehensive docstrings
    • All functions have proper type hints using modern Python syntax
    • Passes all ruff linting checks
    • No legacy/backward compatibility code
    • build_documentation(input_files, output_path, template_path, *, repo_url, title): Main build function
      • Accepts list of markdown files to convert
      • Converts markdown to HTML using python-markdown with extensions: extra, codehilite, fenced_code, tables, toc
      • Extracts title from first file using parsed TOC tokens (from toc extension) or uses provided title
      • Extracts and flattens TOC for each section
      • Reads HTML template (default: templates/default.html)
      • Uses Jinja2 for template rendering with title, sections, inlined_css, and repo_url variables
      • Writes final HTML to specified output path
      • Always prints progress messages to stdout
    • convert_markdown_to_html(md_content): Returns tuple of (html, markdown_instance)
      • The markdown instance provides access to parsed metadata like toc_tokens
    • extract_title_from_markdown_instance(md): Extracts first H1 from parsed tree
    • flatten_toc_tokens(tokens): Recursively flattens nested TOC structure
      • TOC tokens from markdown are nested (children in 'children' key)
      • Returns flat list with level/id/name for each heading
    • convert_plain_text_to_html(text_content): Converts plain text to HTML with line breaks
  3. Template System

    • Build Process: Templates are built using Vite (see Template Development section)
    • Source Location: microdocs/templates_src/{template_name}/
      • {template_name}.html - Jinja2 template with embedded template tags
      • {template_name}.css - Tailwind CSS source
      • {template_name}.js - JavaScript (Alpine.js initialization)
    • Output Location: microdocs/templates/{template_name}/{template_name}.html
      • Single-file HTML with all CSS/JS inlined by Vite
    • Default Template (templates/default/default.html):
      • Single-page HTML template with Tailwind CSS and Alpine.js
      • Uses CDN for Alpine.js 3.x and Tocbot
      • Two-column layout:
        • Main content area (left, flex-1)
        • TOC sidebar (right, fixed 16rem width, sticky)
      • Page-based navigation: sections act like pages, only one visible at a time
      • Alpine.js state: activeSection tracks which section is displayed
      • Smooth transitions between sections
      • Dynamic navigation with active state highlighting
      • Table of Contents (TOC):
        • Shows all headings (H1-H6) for current section
        • Automatically indented based on heading level
        • Sticky positioning (follows scroll)
        • Each section has its own TOC
    • Template Variables (Jinja2):
      • {{ title }} - Extracted from first H1 or provided via CLI
      • {{ sections }} - List of sections with id, name, html attributes
      • {{ repo_url }} - Optional repository URL
      • {{ build_timestamp }} - Build timestamp in UTC

Important Notes

  • Uses uv for dependency management
  • Title extraction:
    • Automatically extracted from first H1 heading in first markdown file
    • Uses parsed TOC tokens from markdown library (not regex)
    • Falls back to "Documentation" if no H1 found
  • Section IDs are generated from filenames (lowercase stem) for anchor links

Ruff Configuration

  • Target Python 3.11+
  • Uses "ALL" rules with specific exclusions for common conflicts (COM812, E501, D203, D212, etc.)
  • FBT (boolean trap), FIX (TODO/FIXME), and ERA001 (commented code) rules are ignored
  • Test files have relaxed rules (allow assert statements, magic values)