A Typst-based diff viewer with character-level inline highlighting that preserves syntax highlighting.
- ✨ Character-precision highlighting - Highlight specific words or character ranges
- 🎨 Syntax highlighting preservation - Colors from Typst's syntax highlighter are maintained
- 📍 Line range selection - Show only relevant portions of code
- 🔍 Multi-token support - Works across both single-token (strings) and multi-token (code) lines
- 📊 Multiple highlights per line - Support for non-overlapping highlight spans
#import "state-solution.typ": diff
#diff(
```py
def old_function():
return 42
```,
```py
def new_function():
return 42
```,
before-inline: (
(line: 1, start: 4, end: 16, fill: red.transparentize(20%)),
),
after-inline: (
(line: 1, start: 4, end: 16, fill: green.transparentize(30%)),
)
)before: Code block (before version)after: Code block (after version)before-inline: Array of(line: N, start: X, end: Y, fill: color)for highlightingafter-inline: Array of(line: N, start: X, end: Y, fill: color)for highlightingbefore-range: Optional(start, end)- Show only specific line range (1-based, inclusive)after-range: Optional(start, end)- Show only specific line range (1-based, inclusive)
- Line numbers are 1-based (line 1 is the first line)
- Character positions are 0-based (character 0 is the first character)
- Ranges are inclusive -
(2, 4)includes lines 2, 3, and 4
The core breakthrough: Typst's styled elements can be reconstructed while preserving their styling:
styled-elem.func()([#text-slice], styled-elem.styles)This allows us to:
- Extract the styling function and styles from syntax-highlighted tokens
- Slice text at any character position
- Reconstruct styled elements with new content but original colors
- Wrap highlighted portions in colored boxes
See experiments/LEARNINGS.md for the complete discovery process.
Check state-solution.typ for three comprehensive test cases:
- Multi-token highlighting - Keywords and identifiers
- Single-token with ranges - Multiline strings with line selection
- Multiple highlights - Several non-overlapping highlights per line
See CLAUDE.md for:
- Testing procedures
- Debugging techniques
- Common tasks
- Architecture details
Quick test:
typst compile state-solution.typ state-solution.png --format png- Character-level inline highlighting
- Syntax highlighting preservation
- Line range selection
- Basic diff visualization
- Integrate
similarcrate for diff algorithm - Compile to WebAssembly for performance
- Automatic diff calculation from two code blocks
- Smart line matching and alignment
- Hunk-based diff generation
- Side-by-side diff mode
- Word-level diff detection
- Configurable color schemes
- Support for more languages
- Diff statistics and summaries
This project uses a research-driven approach. The experiments/ directory contains the discovery process. When adding features:
- Experiment first in
experiments/ - Document findings in
LEARNINGS.md - Integrate working solutions into
state-solution.typ - Update tests and documentation
MIT
Built with Typst, leveraging its powerful introspection and styling capabilities.
