Frontmatter transformation tool for Obsidian vaults
Project description
rematter
Frontmatter management CLI for Obsidian vaults. Validate metadata against a schema, auto-fix missing fields, sync markdown to external destinations like Astro content collections, rename fields, and prepend dates to filenames -- all async with parallel threads for great performance on large vaults. Every command comes with dry-run support to preview the operations, your notes are precious, and we value that! We're Obsidian weirdos too.
The tool is still very early, there is much more to come.
Install
The easiest way to install if you're a Python user is via uv, but there's also a compiled binary (via PyInstaller) available on Homebrew for macOS and Linux:
# uv (recommended)
uv tool install rematter
# Homebrew
brew install g15r/tap/rematter
Quick start
# Validate frontmatter against a schema
rematter validate ~/vault/notes
# Auto-fix missing fields with defaults
rematter validate ~/vault/notes --fix
# Sync to an Astro content collection
rematter sync ~/vault/notes --dest ~/site/src/content/notes
# Preview any command without writing
rematter sync ~/vault/notes -n
Commands
validate -- Check frontmatter against a schema
rematter validate <directory> [--schema PATH] [--fix] [--recursive] [--dry-run]
Validates every markdown file against the .rematter.yaml schema in the target directory. Report-only by default -- exits 1 on failures. Unrecognized fields always error.
--fix sets defaults for missing properties and reorders keys to match schema order. Combine with --dry-run (-n) to preview what would change.
sync -- Sync vault markdown to an external destination
rematter sync [source] [--dest PATH] [--link-path-prefix PREFIX] [--recursive] [--dry-run]
Syncs publishable markdown files to an external directory. The pipeline per file:
- Skip files where
publishis nottrue - Slugify the filename for the destination
- Skip if dest has the same
modifiedvalue (no changes) - Extract type from capitalized Obsidian tags (
#Book->type: book) - Validate against schema
- Resolve creator wikilinks to
{name, slug}objects - Resolve body wikilinks to markdown links (broken links -> plain text)
- Resolve media references and rewrite hero image paths
- Stamp
syncedtimestamp, settitlefrom source filename - Strip
sync: falsefields from destination output - Write dest file, copy referenced media, stamp
syncedback on source
Requires a .rematter.yaml config with at least dest (or pass --dest). CLI flags override config values.
transform -- Rename a frontmatter field
rematter transform <directory> --field OLD --to NEW [--recursive] [--dry-run]
Renames a field across all markdown files. Key order is preserved. Files where the target name already exists are skipped with an error.
date-extract -- Prepend dates to filenames
rematter date-extract <directory> [--field DATE_FIELD] [--recursive] [--dry-run]
Reads a date field (default: Date), prepends YYYY-MM-DD - to the filename, and removes the field from frontmatter. Already-prefixed files are skipped. Useful for systems like Notion that export a date field, when you want to pull that out into the filename for Obsidian's filesystem-centric approach.
Configuration
Each directory can be given a .rematter.yaml that combines sync config and frontmatter schema:
# Sync config
link_path_prefix: /notes
dest: ~/site/src/content/notes/
ignore:
- draft-*
- private/*
media:
source: _media
dest: src/assets
link_prefix: /assets
# Frontmatter schema
properties:
status:
type: string
required: false
enum: [not_started, in_progress, on_hold, done, cancelled]
default: not_started
creators:
type: list
required: false
own:
type: bool
required: false
default: false
sync: false # validated but stripped from dest
hero:
type: string
required: false
requires: [heroAlt] # co-dependency: both or neither
heroAlt:
type: string
required: false
requires: [hero]
created:
type: timestamp
required: true
default: "%Y-%m-%d %H:%M" # strftime format, stamps current time on --fix
sync: false
modified:
type: timestamp
required: true
default: "%Y-%m-%d %H:%M"
publish:
type: bool
required: true
default: false
sync: false
Property spec fields
| Field | Purpose |
|---|---|
type |
timestamp, bool, string, list, int, float |
required |
Key must exist (null values are valid) |
default |
Value set by --fix when missing. strftime string for timestamps, literal for others, null for explicit null |
enum |
Allowed values (string fields) |
requires |
Companion fields that must also have values (co-dependency) |
sync |
true (default) or false -- field is validated but stripped from dest during sync |
Sync config fields
| Field | Purpose |
|---|---|
dest |
Destination directory (overridable via --dest) |
link_path_prefix |
URL prefix for resolved wikilinks (overridable via --link-path-prefix) |
ignore |
Glob patterns for files to skip |
media.source |
Source media directory name (relative to vault dir) |
media.dest |
Destination media directory (relative to dest root) |
media.link_prefix |
URL prefix for media links in dest output |
Development
uv sync --dev # install deps
uv run pytest -v # run tests
uv run rematter --help # run locally
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rematter-0.1.0.tar.gz.
File metadata
- Download URL: rematter-0.1.0.tar.gz
- Upload date:
- Size: 73.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7afb29b45f219b00f0cdc7292dfcbd5fd8649fc7de47ee47c2c965d30a70548d
|
|
| MD5 |
d0bb9cf98fabf21fd626a8f9db246311
|
|
| BLAKE2b-256 |
9c93e47fe441c54b17ab5c8b4800590820734b9675434613c2440a495636bf17
|
File details
Details for the file rematter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rematter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab16fe8e56b334e84050ccc3942dfc0ead4c85ee62009abf368ba91e8157bd2d
|
|
| MD5 |
e1b7ecfea2aa37132d54adc176347185
|
|
| BLAKE2b-256 |
90113f79a59076026791bf3bb99d129f9f2270e4adda818a3e18c4f11534bb09
|