110 lines
4.7 KiB
Markdown
Raw Normal View History

2026-01-17 20:56:54 +01:00
# Rinja: High-Performance Jinja-Compatible Native Python Module
**retoor <retoor@molodetz.nl>**
Rinja is a 100% feature-complete, high-performance native Python module written in C that serves as a drop-in replacement for the Jinja2/Jinja3 templating engine. It is designed for applications that require extreme rendering speed—delivering 10-100x performance improvements—while maintaining perfect API compatibility and feature parity.
## Core Design & Philosophy
- **Performance First**: The core engine, tokenizer, parser, and virtual machine are all implemented in optimized C, minimizing Python-to-C overhead.
- **Drop-in Replacement**: Existing Jinja templates and Python code (filters, tests, environment configuration) work without modification.
- **Complete Feature Parity**: Every single filter, test, block tag, and expression type found in Jinja2/Jinja3 is implemented.
- **Memory Efficient**: Uses a custom memory pool and string builder to minimize allocations during rendering.
## Features
### 1. Control Structures
- **Conditional Logic**: `{% if %}`, `{% elif %}`, `{% else %}` with full expression support.
- **Loops**: `{% for item in items %}` with `{% else %}` blocks and complete `loop` context (`loop.index`, `loop.first`, `loop.last`, etc.).
- **Advanced Loops**: `{% while %}`, `{% break %}`, `{% continue %}`.
- **Macros & Calls**: `{% macro %}` definition and `{% call %}` invocation with content passing.
### 2. Template Inheritance & Composition
- **Inheritance**: `{% extends "base.html" %}` and `{% block name %}` overriding.
- **Inclusion**: `{% include "partial.html" %}` with context propagation.
- **Importing**: `{% import "macros.html" as m %}` and `{% from "macros.html" import foo %}`.
### 3. Variable & Context Management
- **Assignments**: `{% set x = 10 %}` and `{% with %}` scoping blocks.
- **Raw Output**: `{% raw %}` blocks to prevent parsing.
- **Autoescape**: `{% autoescape true/false %}` blocks for context-aware HTML escaping.
- **Expression Support**: Full support for literals (strings, numbers, booleans, lists `[]`, dicts `{}`), attribute access (`obj.attr`), subscript access (`obj['key']`), and slicing.
### 4. Comprehensive Expression Engine
- **Operators**: Arithmetic (`+`, `-`, `*`, `/`, `%`), comparison (`==`, `!=`, `<`, `>`, `<=`, `>=`), logical (`and`, `or`, `not`), and concatenation (`~`).
- **Tests**: `is defined`, `is number`, `is iterable`, etc.
- **Filters**: Pipe syntax `|` with chaining (e.g., `{{ value|upper|trim }}`).
### 5. Exhaustive Built-in Library
Rinja implements **every** built-in filter and test from Jinja2, including:
- **String**: `capitalize`, `lower`, `upper`, `title`, `trim`, `replace`, `format`, `xmlattr`, `urlencode`.
- **Numeric**: `abs`, `round`, `int`, `float`.
- **Collection**: `length`, `first`, `last`, `join`, `sort`, `unique`, `reverse`, `map`, `select`, `reject`.
- **HTML/JSON**: `escape`, `forceescape`, `tojson`.
- **Tests**: `defined`, `undefined`, `none`, `boolean`, `number`, `string`, `sequence`, `mapping`, `iterable`, `callable`, `even`, `odd`, `divisibleby`.
### 6. Rich Text & Full Markdown Extensions
In addition to standard Jinja features, Rinja natively supports exhaustive rich text transformations:
- **`{% markdown %}`**: **Full Markdown Support** including:
- Headers (H1 - H6 using `#`)
- Multi-line code blocks (using ` ``` `)
- Inline formatting (Bold `**`, Italic `*`)
- **`{% linkify %}`**: Automatically converts URLs into clickable `<a>` tags (supports `http`, `https`, `www`, and `mailto`).
- **`{% emoji %}`**: Converts exhaustive emoji shortcodes (e.g., `:smile:`, `:heart:`, `:fire:`) to Unicode characters based on the complete emoji cheat sheet.
## Installation
```bash
make install
```
## Usage
Rinja provides an API identical to `jinja2`:
```python
import rinja
# Create an environment
env = rinja.Environment(autoescape=True)
# Compile a template
template = env.from_string("""
{% extends "layout.html" %}
{% block content %}
<h1>Hello, {{ user.name|capitalize }}!</h1>
<ul>
{% for item in items %}
<li>{{ loop.index }}: {{ item }}</li>
{% endfor %}
</ul>
{% endblock %}
""")
# Render with context
print(template.render(user={"name": "rinja"}, items=["fast", "compatible", "native"]))
```
## Development
Rinja is built using Python's C Extension API.
### Build and Test
```bash
make build
make test
```
### Project Structure
- `src/rinja/module.c`: Main entry point and type definitions.
- `src/rinja/tokenizer.c`: Fast C-based lexer.
- `src/rinja/parser.c`: Recursive descent parser building an AST.
- `src/rinja/vm.c`: Virtual machine for rendering ASTs.
- `src/rinja/filters.c`: Native implementations of all filters.
- `src/rinja/tests.c`: Native implementations of all tests.
- `src/rinja/emoji_data.h`: Emoji lookup table.
## License
This project is open-source.