Contributing
Thank you for your interest in contributing to mk2html! This document provides guidelines and instructions for contributing.
Table of Contents
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Testing
- Submitting Changes
- Style Guide
- Release Process
Code of Conduct
Please be respectful and constructive in all interactions. We welcome contributions from everyone regardless of experience level.
Getting Started
Prerequisites
- Python 3.9 or higher
- Git
- (Optional) uv for fast package management
Fork and Clone
- Fork the repository on GitHub
- Clone your fork:
bash git clone https://github.com/YOUR_USERNAME/mk2html.git cd mk2html - Add upstream remote:
bash git remote add upstream https://github.com/km1790/mk2html.git
Development Setup
Using pip
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode with all dependencies
pip install -e ".[all]"
# Install Chromium for PDF tests
playwright install chromium
Using uv (Recommended)
# Create virtual environment and install
uv venv
source .venv/bin/activate
# Install with all dependencies
uv pip install -e ".[all]"
# Install Chromium
playwright install chromium
Verify Setup
# Check versions
./mk2html.py --version
./mk2pdf.py --version
# Run tests
pytest
Making Changes
Branch Naming
Create a branch for your changes:
git checkout -b feature/your-feature-name
git checkout -b fix/bug-description
git checkout -b docs/documentation-update
Commit Messages
Follow conventional commit format:
type(scope): description
[optional body]
[optional footer]
Types:
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting, etc.)
- refactor: Code refactoring
- test: Adding or updating tests
- chore: Maintenance tasks
Examples:
feat(mk2html): add support for custom CSS injection
fix(mk2pdf): handle special characters in filenames
docs: update API reference with new parameters
test: add tests for offline mode edge cases
Testing
Running Tests
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/test_mk2html.py
# Run specific test
pytest tests/test_mk2html.py::TestConverter::test_basic_conversion
# Run with coverage
pytest --cov=mk2html --cov=mk2pdf --cov-report=html
Test Structure
tests/
├── __init__.py
├── test_mk2html.py # HTML converter tests
└── test_mk2pdf.py # PDF converter tests
Writing Tests
import pytest
from mk2html import convert_markdown_to_html
class TestNewFeature:
"""Tests for the new feature."""
def test_feature_basic(self):
"""Test basic functionality."""
result = convert_markdown_to_html("# Test")
assert "<h1" in result
def test_feature_edge_case(self):
"""Test edge case handling."""
result = convert_markdown_to_html("")
assert "<!DOCTYPE html>" in result
@pytest.mark.parametrize("input,expected", [
("# H1", "<h1"),
("## H2", "<h2"),
("### H3", "<h3"),
])
def test_feature_parametrized(self, input, expected):
"""Test multiple inputs."""
result = convert_markdown_to_html(input)
assert expected in result
Test Requirements
- All new features must have tests
- All bug fixes should include a regression test
- Maintain or improve code coverage
- Tests should be fast (mock external calls when possible)
Submitting Changes
Before Submitting
-
Run tests: Ensure all tests pass
bash pytest -
Check formatting: Review code style
bash # If using ruff ruff check . ruff format --check . -
Update documentation: If adding features, update docs
-
Update version: If needed, bump version in:
-mk2html.py(__version__)
-mk2pdf.py(__version__)
-pyproject.toml(version)
Pull Request Process
-
Push your branch:
bash git push origin feature/your-feature-name -
Create a Pull Request on GitHub
-
Fill in the PR template:
- Description of changes
- Related issues
- Testing performed
- Screenshots (if UI changes) -
Wait for review and address feedback
-
Once approved, maintainers will merge
Style Guide
Python Style
- Follow PEP 8
- Use type hints for function parameters and returns
- Maximum line length: 100 characters
- Use descriptive variable names
def convert_file(
input_path: Path,
output_path: Optional[Path] = None,
enable_feature: bool = True
) -> bool:
"""Convert a file with optional feature.
Args:
input_path: Path to input file
output_path: Path for output (default: input with new extension)
enable_feature: Whether to enable the feature
Returns:
True if successful, False otherwise
"""
...
Documentation Style
- Use Markdown for all documentation
- Include code examples
- Keep explanations clear and concise
- Update docs when changing functionality
Commit Style
- Keep commits atomic (one logical change per commit)
- Write clear commit messages
- Reference issues when applicable (
Fixes #123)
Release Process
For maintainers:
Version Bump
- Update versions:
```python
# mk2html.py
version = "1.4.0"
# mk2pdf.py
version = "1.2.0"
# pyproject.toml
version = "1.4.0"
```
-
Update CHANGELOG.md
-
Commit:
bash git add -A git commit -m "chore: release v1.4.0" git tag v1.4.0 git push origin main --tags
Build and Publish
# Clean previous builds
rm -rf dist/ build/ *.egg-info/
# Build
python -m build
# Check
twine check dist/*
# Upload to TestPyPI (optional)
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*
Getting Help
- Questions: Open a GitHub Discussion
- Bugs: Open a GitHub Issue
- Security: Email maintainers directly
Recognition
Contributors will be recognized in:
- GitHub contributors page
- CHANGELOG.md for significant contributions
- README.md for major features
Thank you for contributing! 🎉