diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
new file mode 100644
index 0000000..0d45294
--- /dev/null
+++ b/.github/workflows/test.yaml
@@ -0,0 +1,39 @@
+name: Test
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ["3.10", "3.11", "3.12"]
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -e ".[dev,watch]"
+
+ - name: Run linting
+ run: |
+ ruff check simplymarkdown tests
+
+ - name: Run type checking
+ run: |
+ mypy simplymarkdown --ignore-missing-imports
+
+ - name: Run tests
+ run: |
+ pytest --cov=simplymarkdown --cov-report=term-missing
diff --git a/.gitignore b/.gitignore
index b6e4761..0298d1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,3 +127,10 @@ dmypy.json
# Pyre type checker
.pyre/
+
+# Ruff
+.ruff_cache/
+
+# SimplyMarkdown
+.simplymarkdown/
+output/
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..4dcc775
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,80 @@
+# Changelog
+
+All notable changes to SimplyMarkdown will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [2.0.0] - Unreleased
+
+### Added
+
+- **New package structure**: Reorganized as a proper Python package (`simplymarkdown/`)
+- **CLI with Click**: New command-line interface with subcommands
+ - `simplymarkdown build` - Build the site
+ - `simplymarkdown serve` - Start development server
+ - `simplymarkdown init` - Initialize a new project
+ - `simplymarkdown new` - Create a new blog post
+- **Configuration file support**: YAML configuration via `simplymarkdown.yaml`
+- **Watch mode**: Auto-rebuild on file changes with `--watch` flag
+- **Development server**: Built-in HTTP server with `--serve` flag
+- **Incremental builds**: Only rebuild changed files with `--incremental` flag
+- **Draft support**: Mark posts as drafts with `draft: true` frontmatter
+- **Search index generation**: JSON search index for client-side search
+- **Related posts**: Show related posts based on tags
+- **Pagination**: Paginate post listings with `% posts:paginate:10`
+- **TOC module**: Table of contents via `! toc` tag
+- **Type hints**: Full type annotations throughout codebase
+- **Unit tests**: Comprehensive test suite with pytest
+- **Integration tests**: End-to-end rendering tests
+- **CI/CD pipeline**: GitHub Actions for testing and building
+
+### Changed
+
+- **Dependencies**: Updated and expanded requirements
+ - Added: `click`, `pyyaml`, `watchdog` (optional)
+ - All dependencies now have version constraints
+- **Code quality**:
+ - Removed wildcard imports
+ - Consistent snake_case naming
+ - Added docstrings to all functions
+- **File structure**: Moved to `simplymarkdown/` package directory
+- **Configuration**: New `Config` dataclass with nested configs
+
+### Fixed
+
+- **File handle leak**: Fixed unclosed file in `render.py`
+- **Extension parsing**: `get_extension()` now returns without leading dot
+- **Debug statements**: Removed print statements from `generateSitemap.py`
+
+### Deprecated
+
+- Direct usage of `render.py` as script (use `simplymarkdown build` instead)
+
+## [1.0.0] - 2023-07-03
+
+### Added
+
+- Initial release
+- Markdown to HTML conversion
+- Module system (navbar, footer, custom modules)
+- Frontmatter support (title, date, tags, emoji, image)
+- Special tags for post listings (`% directory`)
+- Detailed preview mode (`% directory:detailed`)
+- RSS feed generation
+- Sitemap generation
+- SEO meta tags (Open Graph, Twitter Cards)
+- GitHub Pages integration workflow
+- Syntax highlighting with Pygments
+- Multiple theme support
+
+---
+
+## Version History Summary
+
+| Version | Date | Highlights |
+|---------|------|------------|
+| 2.0.0 | Unreleased | Package restructure, CLI, watch mode, tests |
+| 1.0.0 | 2023-07-03 | Initial release |
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..76bd5fd
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,245 @@
+# Contributing to SimplyMarkdown
+
+Thank you for your interest in contributing to SimplyMarkdown! This document provides guidelines and instructions for contributing.
+
+## Table of Contents
+
+- [Code of Conduct](#code-of-conduct)
+- [Getting Started](#getting-started)
+- [Development Setup](#development-setup)
+- [Making Changes](#making-changes)
+- [Code Style](#code-style)
+- [Testing](#testing)
+- [Submitting Changes](#submitting-changes)
+
+## Code of Conduct
+
+Please be respectful and considerate in all interactions. We aim to maintain a welcoming and inclusive environment for everyone.
+
+## Getting Started
+
+1. Fork the repository on GitHub
+2. Clone your fork locally:
+ ```bash
+ git clone https://github.com/YOUR-USERNAME/SimplyMarkdown.git
+ cd SimplyMarkdown
+ ```
+3. Add the upstream repository:
+ ```bash
+ git remote add upstream https://github.com/cemreefe/SimplyMarkdown.git
+ ```
+
+## Development Setup
+
+### Prerequisites
+
+- Python 3.10 or higher
+- pip
+
+### Installation
+
+1. Create a virtual environment:
+ ```bash
+ python -m venv venv
+ source venv/bin/activate # On Windows: venv\Scripts\activate
+ ```
+
+2. Install the package in development mode with all dependencies:
+ ```bash
+ pip install -e ".[all]"
+ ```
+
+3. Verify the installation:
+ ```bash
+ simplymarkdown --version
+ pytest
+ ```
+
+## Making Changes
+
+### Branching Strategy
+
+1. Create a new branch for your feature or bugfix:
+ ```bash
+ git checkout -b feature/your-feature-name
+ # or
+ git checkout -b fix/your-bugfix-name
+ ```
+
+2. Make your changes in small, focused commits
+
+3. Keep your branch up to date with upstream:
+ ```bash
+ git fetch upstream
+ git rebase upstream/main
+ ```
+
+### Commit Messages
+
+Use clear, descriptive commit messages:
+
+```
+type: short description
+
+Longer description if needed. Explain what and why,
+not how (the code shows how).
+```
+
+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: add pagination support for post listings
+
+fix: resolve file handle leak in render.py
+
+docs: improve README with more examples
+```
+
+## Code Style
+
+### Python Style
+
+We follow PEP 8 with some modifications. Use the following tools:
+
+- **Ruff** for linting and formatting:
+ ```bash
+ ruff check simplymarkdown tests
+ ruff format simplymarkdown tests
+ ```
+
+- **MyPy** for type checking:
+ ```bash
+ mypy simplymarkdown
+ ```
+
+### Key Guidelines
+
+1. **Type hints**: Use type hints for all function parameters and return values
+ ```python
+ def process_file(path: str, options: dict[str, Any]) -> str:
+ ...
+ ```
+
+2. **Docstrings**: Use Google-style docstrings for all public functions
+ ```python
+ def convert_to_html(content: str, base_path: str = "") -> tuple[str, dict]:
+ """Convert markdown content to HTML.
+
+ Args:
+ content: Raw markdown string.
+ base_path: Base path for resolving relative links.
+
+ Returns:
+ Tuple of (html_content, metadata_dict).
+ """
+ ```
+
+3. **Imports**: Use explicit imports, avoid wildcards
+ ```python
+ # Good
+ from simplymarkdown.utils import read_file_content, get_extension
+
+ # Avoid
+ from simplymarkdown.utils import *
+ ```
+
+4. **Constants**: Use UPPER_CASE for module-level constants
+ ```python
+ DEFAULT_TEMPLATE = "templates/base.html"
+ MAX_PREVIEW_LENGTH = 160
+ ```
+
+## Testing
+
+### Running Tests
+
+Run the full test suite:
+```bash
+pytest
+```
+
+Run with coverage:
+```bash
+pytest --cov=simplymarkdown --cov-report=html
+```
+
+Run specific tests:
+```bash
+pytest tests/test_utils.py
+pytest tests/test_utils.py::TestGetExtension
+pytest tests/test_utils.py::TestGetExtension::test_simple_extension
+```
+
+### Writing Tests
+
+1. Place tests in the `tests/` directory
+2. Name test files `test_*.py`
+3. Name test functions `test_*`
+4. Use pytest fixtures for common setup
+5. Aim for high coverage of new code
+
+Example test:
+```python
+import pytest
+from simplymarkdown.utils import sanitize_filename
+
+
+class TestSanitizeFilename:
+ """Tests for sanitize_filename function."""
+
+ def test_spaces_to_dashes(self) -> None:
+ assert sanitize_filename("my file name") == "my-file-name"
+
+ def test_no_changes_needed(self) -> None:
+ assert sanitize_filename("already-clean") == "already-clean"
+```
+
+## Submitting Changes
+
+### Pull Request Process
+
+1. Ensure all tests pass:
+ ```bash
+ pytest
+ ruff check simplymarkdown tests
+ mypy simplymarkdown
+ ```
+
+2. Update documentation if needed
+
+3. Push your branch:
+ ```bash
+ git push origin feature/your-feature-name
+ ```
+
+4. Create a Pull Request on GitHub:
+ - Provide a clear title and description
+ - Reference any related issues
+ - Include screenshots for UI changes
+
+5. Wait for review and address any feedback
+
+### PR Checklist
+
+- [ ] Tests added/updated for new functionality
+- [ ] All tests pass
+- [ ] Linting passes
+- [ ] Type checking passes
+- [ ] Documentation updated if needed
+- [ ] CHANGELOG.md updated for notable changes
+
+## Questions?
+
+If you have questions, feel free to:
+- Open an issue on GitHub
+- Start a discussion
+
+Thank you for contributing!
diff --git a/README.md b/README.md
index fb65c3a..127e2f1 100644
--- a/README.md
+++ b/README.md
@@ -1,121 +1,368 @@
-# SimplyMarkdown - Convert your Markdown into a Website
+# SimplyMarkdown
-Welcome to SimplyMarkdown, the simplest framework for creating websites from your Markdown files! With SimplyMarkdown, you can easily and quickly turn your directory of Markdown files into a stunning website without having to deal with any complicated configurations or bloated features.
+[](https://www.python.org/downloads/)
+[](https://opensource.org/licenses/MIT)
-As a solo developer who enjoys creating fun and easy-to-use tools in my free time, I wanted to make something that was both lightweight and effective. And that's exactly what SimplyMarkdown is all about! It's a simple and straightforward framework that lets you focus on your content, not the technical details.
+**SimplyMarkdown** is a lightweight static site generator that transforms your Markdown files into a beautiful, fully-functional website. No complex configurations, no bloated featuresβjust simple, effective content management.
-So whether you're a blogger, writer, or just someone who wants to share their thoughts and ideas with the world, SimplyMarkdown has got you covered. With its easy-to-setup environment, you'll be up and running in no time!
+## β¨ Features
-# Setup
+- π **Simple & Fast** β Convert Markdown to HTML with minimal configuration
+- π **Module System** β Reusable components for navbar, footer, and custom modules
+- π·οΈ **Frontmatter Support** β Rich metadata with title, date, tags, and more
+- π° **Auto-generated Feeds** β RSS and sitemap out of the box
+- π **Search Index** β JSON search index for client-side search
+- π¨ **Syntax Highlighting** β Beautiful code blocks with Pygments
+- π **Watch Mode** β Auto-rebuild on file changes
+- π **Dev Server** β Built-in development server
+- π¦ **Incremental Builds** β Only rebuild changed files
-To setup SimplyMarkdown locally, the only thing you need to do is to clone the repository. Read further for automated github pages integration.
+## π¦ Installation
-# How to use
+Clone the repository and install locally:
-## How to run
+```bash
+git clone https://github.com/cemreefe/SimplyMarkdown.git
+cd SimplyMarkdown
+pip install -e .
+```
-You can create a new directory with your desired structure to form your website. See example input directory in `/example`.
+Or install with development dependencies:
+```bash
+pip install -e ".[all]"
```
-example/input/
-βββ about.md
-βββ index.md
-βββ blog/
-β βββ blog.md
-β βββ posts/
-β βββ coding.md
-β βββ hogwarts.md
-βββ modules/
-β βββ navbar.md
-β βββ footer.md
-β βββ custom-module.md
-β βββ head_extras.html
-βββ static/
-β βββ images/
-β βββ css/
+
+## π Quick Start
+
+### Initialize a New Project
+
+```bash
+simplymarkdown init my-blog
+cd my-blog
+simplymarkdown build -i source -o output --serve
```
-This will form the basis of your website. SimplyMarkdown will clone your directory and process each file to form your website. Markdown files will be rendered as html files.
+### Or Start from Scratch
+1. Create your content structure:
-In SimplyMarkdown, `modules/` is a reserved directory.
-- `modules/navbar.md` will be used to render the navigation bar for all html files.
-- `modules/footer.md` will be used to render the footer for all html files.
-- `modules/head_extras.html` can be used to add extra tags to the `