A library and command-line utility to deal with YAML front matter.
Project description
felloff
Because, you know, the front.
Description
felloff is a command-line utility (and Python library) to handle YAML Front Matter in text files. It can retrieve it from a file, remove it, or change it based on command-line options.
felloff is using ruamel.yaml to read and write the YAML content, which means that formatting, structure, and comments should be preserved as much as possible when it's editing your files.
Status
felloff is not yet feature complete, but already does a few useful things. See the examples below for whether your particular use case is among them, and see the issues list for what is probably yet to come.
Requirements
felloff requires Python 3.10 or higher, as well as a couple of Python packages that will be auto-installed as dependencies when you install felloff.
The input files currently need to be UTF-8 encoded, with no byte order mark. Other encodings might be supported in the future.
felloff will probably also change your line endings to Unix-style, if they're not already.
Installation
You can install felloff from PyPI using Python's normal packaging tools.
- with uv (recommended):
uv tool install felloffor even directly run it usinguvx felloff - with pipx:
pipx install felloff
CLI Usage
felloff comes with command line help, which can be accessed from the usual -h or --help switches.
For example, use felloff -h to get a list of supported commands, and felloff set -h to get the set command explained to you.
The following sections show you how to use each subcommand based on examples.
We're using the following example document myfile.md:
---
title: An example document
created: 2025-06-06 # Start of the felloff project.
tags: [test, example]
---
This document will be used for **testing**.
Instead of a file, you can also use the special file name - to read from standard input.
front: Retrieve the front matter
Extract the front matter from a Markdown file
$ felloff front myfile.md
title: An example document
created: 2025-06-06 # Start of the felloff project.
tags: [test, example]
Convert the front matter into JSON
$ felloff front -f json myfile.md
{"title": "An example document", "created": "2025-06-06", "tags": ["test", "example"]}
main: Retrieve the main content
Extract the main content from a Markdown file
$ felloff main myfile.md
This document will be used for **testing**.
set: Change the front matter
By default, the modified file will be printed to standard output.
If you'd like to modify the original file instead, use the -i/--in-place argument.
Since you might want to use field names or values that start with a dash, felloff set is quite picky about the order of its arguments.
The input file name has to be supplied before the list of requested changes.
If you don't have field names or values that start with a dash (-), you probably don't need to take any special measures.
If you're calling felloff from a script, however, you should use -- after the file name to stop Python's normal argument processing, and also check out features like --json or --end-list-with to work around ambiguity.
Also, make sure that you understand how to quote arguments in your shell, especially if you're using special characters or spaces. Most of the time, using single quotes should help.
In general, you give felloff set a list of changes that you'd like to do.
These include the TYPE of the operation (which starts with a -), the NAME of the field to modify, and the actual VALUE.
You can request multiple of these changes in one invocation and they will be performed in order.
If you don't specify a TYPE, the default is to set string values (--string) or stay in whatever TYPE you set previously.
Set a string value
$ felloff set myfile.md --string title 'My title'
---
title: My title
created: 2025-06-06 # Start of the felloff project.
tags: [test, example]
---
This document will be used for **testing**.
If the field doesn't exist yet, it will be created.
--string can be shortened to -s.
Since --string is the default, you can also omit it, except when you want to explicitly switch back from a different mode.
Set a JSON value
If you need to set something to a non-string value, you'll need to pass it as JSON.
$ felloff set myfile.md --json draft true id 123 nonsense '{"fruit": "strawberry"}' -s title Messy
---
title: Messy
created: 2025-06-06 # Start of the felloff project.
tags: [test, example]
draft: true
id: 123
nonsense:
fruit: strawberry
---
This document will be used for **testing**.
This example also demonstrates how to set multiple fields, and how to switch back to string fields.
You can shorten --json to -j.
Set or update a modification date
$ felloff set myfile.md --time created 2025-06-07 modified now
---
title: An example document
created: 2025-06-07 # Start of the felloff project.
tags: [test, example]
modified: 2025-06-07 14:03:45.845667+02:00
---
This document will be used for **testing**.
As you can see, you can pass an ISO formatted date (or date and time), or use some special values to get the current time.
You can also use today instead of now to just use the date without a time.
And there's utcnow and utctoday if you'd like to convert the value to UTC instead of having it in your machine's timezone.
Note that this is using native YAML date/datetime values, not strings.
Set to a list of strings
$ felloff set myfile.md --list tags foo bar
---
title: An example document
created: 2025-06-06 # Start of the felloff project.
tags: [foo, bar]
---
This document will be used for **testing**.
The list continues until you specify a new TYPE.
--list can be shortened to -l.
If you'd like felloff to create new lists as multi-line values, you can use --yaml-new-lists block.
The default style is the one with the angle brackets, --yaml-new-lists flow.
Lists that already existed in the original will keep their style.
Edit existing lists
You can use --append (-a) to extend an existing list with new values.
If there is no existing value, a new list with your items will be created.
If there is an existing value, but it's not a list, it will be made into one.
You can use --remove (-r) to remove values from a list.
If there is no existing value, or the existing value is not a list, nothing happens.
Let's do a fancy example:
$ felloff set myfile.md --yaml-new-lists block --append title 'Alternative title or something' -a tags fancy --remove tags example
---
title:
- An example document
- Alternative title or something
created: 2025-06-06 # Start of the felloff project.
tags: [test, fancy]
---
This document will be used for **testing**.
Deleting existing fields
Use --delete (-d) to remove specific fields from the existing set.
$ felloff set myfile.md --delete title created
---
tags: [test, example]
---
This document will be used for **testing**.
Starting from scratch
You can use the --clear option (-c) to drop all existing front matter content before applying your requested changes.
$ felloff set -c myfile.md title 'A fresh start'
---
title: A fresh start
---
This document will be used for **testing**.
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 felloff-0.1.0.tar.gz.
File metadata
- Download URL: felloff-0.1.0.tar.gz
- Upload date:
- Size: 44.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29502d4447949dfaf5ca096ec69b2a205d121af6a7baf5a813ee122b82fa58aa
|
|
| MD5 |
3e7d32628ea7605496362bf174ac620e
|
|
| BLAKE2b-256 |
b4436cc919eea3152b7812aceec6d870232ddad99bc5bbe54d42fa6af8147059
|
File details
Details for the file felloff-0.1.0-py3-none-any.whl.
File metadata
- Download URL: felloff-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fefbe436919ea22635c0ab3d2c5b374e510f517fea554c88622ce3f1b6256dad
|
|
| MD5 |
0a93d4cff3d03f552ed32a2ece1af260
|
|
| BLAKE2b-256 |
ae0504aaf35fb16cdd339a53461568991ded2c1bcb14cc643d8757171a63bde6
|