Configuration
earmark.toml lives inside the library and marks the folder it sits in as one. earmark config opens it in $EDITOR; earmark config --show prints every value in effect and where it came from.
Every setting is a default. A command-line flag always wins.
There is no library key and there never will be: the library is the folder this file sits in.
Top-level settings
| Key | Type | Default | Accepts | Read by |
|---|---|---|---|---|
voice |
string | "af_heart" |
any name from earmark voices |
audio, publish |
speed |
number | 1.0 |
0.5 to 2.0 |
audio, publish |
lang |
string | "en-us" |
a language code | audio, publish |
profile |
string | "article" |
article, paper, book |
text, audio, publish |
model |
string | "full" |
full, fp16, int8 |
audio, publish |
engine |
string | "kokoro" |
kokoro, say |
audio, publish, voices |
bitrate |
string | "64k" |
any ffmpeg bitrate | audio, publish |
sample_rate |
integer | 44100 |
a positive whole number | audio, publish |
after_publish |
string | none | a shell command | publish |
voice = "af_bella"
speed = 1.1
profile = "paper"after_publish
One line of shell, run inside the library once the feed is written. Only needed if your library is not already a folder that syncs to the web.
after_publish = "git add -A && git commit -m 'earmark' && git push"It is a config key rather than a plugin system on purpose: it covers every host without earmark knowing the name of one. Recipes: Publishing anywhere.
[feed]
| Key | Type | Default | Means |
|---|---|---|---|
base_url |
string | none | the public URL the library folder is served at |
title |
string | "earmark" |
podcast title |
author |
string | none | podcast author |
description |
string | none | show description |
link |
string | none | a website for the show |
language |
string | none | RSS language code, e.g. en-us |
category |
string | none | iTunes category |
cover |
string | none | a file in this folder; earmark normalizes it |
image |
string | none | a URL to artwork hosted elsewhere; passed through |
[feed]
base_url = "https://filedn.com/XXXX/audio"
title = "John's Reading Pile"
author = "John Helveston"
description = "Things I meant to read."
cover = "cover.jpg"base_url must start with http:// or https://. Publishing without it stops with a message telling you to run earmark config.
cover and image are not interchangeable: image disables the cover pipeline rather than racing it. See Cover art.
[replace]
Fix a mispronunciation once instead of every time. Matched on word boundaries, longest key first.
[replace]
BEV = "battery electric vehicle"
NIMBY = "nimby"Keep [feed] last
TOML puts a key you add at the bottom of a file into whichever table came before it. An unknown key under [feed] warns loudly; an extra entry under [replace] would look exactly like a word you wanted respoken, and would be silently accepted.
So [feed] is the last table in the file the template writes, and it is worth keeping it there.
Warnings and errors
Loading a config never fails, because a broken file must stay inspectable with earmark config --show. Problems are sorted into two kinds.
Warnings print to stderr and the offending key is ignored:
| Warning | Cause |
|---|---|
unknown section [x] ignored |
a table that is not [feed] or [replace] |
unknown setting 'k' ignored |
a top-level key not in the table above |
unknown setting 'feed.k' ignored |
a key not in the [feed] table above |
[replace] must be a table of strings; ignored |
[replace] is not a table |
Errors stop the command that was about to use the settings, reported as earmark: config problem in <path>: with one line per problem:
| Error | Cause |
|---|---|
speed = … is not a number |
non-numeric speed |
speed = … is not between 0.5 and 2.0 |
out of range |
profile = … is not one of article, paper, book |
unknown profile |
model = … is not one of full, fp16, int8 |
unknown model |
engine = … is not one of kokoro, say |
unknown engine |
voice / lang / bitrate = … is not a non-empty string |
wrong type or empty |
sample_rate = … is not a positive whole number |
wrong type or < 1 |
after_publish = … is not a shell command string |
wrong type |
feed.base_url is not a URL string |
wrong type |
feed.base_url = … must start with http:// or https:// |
wrong scheme |
not valid TOML: … |
the file does not parse |
The file init writes
# earmark configuration
#
# This file marks the folder it lives in as an earmark library. Everything
# earmark makes -- markdown in text/, MP3s, feed.xml -- lands beside it.
#
# Every setting here is a default; a command-line flag always wins.
# voice = "af_heart" # see: earmark voices
# speed = 1.0 # 0.5 to 2.0
# profile = "article" # article | paper | book
# lang = "en-us"
# model = "full" # full | fp16 | int8
# engine = "kokoro" # kokoro | say
# bitrate = "64k"
# sample_rate = 44100
# Run this after every publish, from inside the library. Only needed if your
# library is not already a folder that syncs to the web -- a git push, say.
# after_publish = "git add -A && git commit -m 'earmark' && git push"
# Fix a mispronunciation once instead of every time. Matched on word
# boundaries, longest key first.
[replace]
# BEV = "battery electric vehicle"
# [feed] is last on purpose. TOML puts a key you add at the bottom of the file
# into whichever table came before it, and an unknown key here warns, while an
# extra entry under [replace] would look like a word you wanted respoken.
[feed]
base_url = ""
title = "earmark"
# author = "Your Name"
# description = "Things I meant to read."
# cover = "cover.jpg" # a file in this folder; square PNG or JPEG
# image = "https://..." # or artwork already hosted somewhere; this winsWhat is not in the library
Three things are deliberately stored outside it, because they must not sync to a public folder:
- the 354 MB Kokoro model
- the per-chunk synthesis cache
- a one-line pointer naming your default library
earmark config --show prints where each of them actually is.