Configuration¶
Every setting has up to three spellings: a command-line flag, an environment
variable, and a key in wudict.toml. The name is the same in the environment
and in the file.
Priority¶
Flag beats environment. Environment beats the config file. The file beats the built-in default.
This is the answer to "I edited wudict.toml and nothing changed": something
above it sets the same value. wuDict knows where each value came from, and the
setup page refuses to pretend that saving to the file will take effect.
Where the config file lives¶
wuDict reads the first file it finds.
- the
--configflag, or theCONFIG_PATHenvironment variable wudict.tomlnext to the executable - see portable mode~/.wudict/wudict.toml/etc/wudict/wudict.toml
The first serve run creates ~/.wudict/wudict.toml, fully commented. Every
start prints the file in effect.
~/.wudict/state.json holds your dictionary order and your on/off switches.
That file is written by the app, not by you.
Every file wuDict owns¶
| What | macOS and Linux | Windows | Android |
|---|---|---|---|
| Config | ~/.wudict/wudict.toml |
%USERPROFILE%\.wudict\wudict.toml |
Android/data/com.legbehindneck.wudict/files/wudict.toml |
| Installed lemma data | ~/.wudict/lemmas |
%USERPROFILE%\.wudict\lemmas |
Android/data/com.legbehindneck.wudict/files/lemmas |
| Prepared library | ~/.wudict/db |
%USERPROFILE%\.wudict\db |
Android/data/com.legbehindneck.wudict/files/db |
| State (order, switches) | ~/.wudict/state.json |
%USERPROFILE%\.wudict\state.json |
as above |
| Log, when there is no console | ~/Library/Logs/wudict.log on macOS, ~/.wudict/wudict.log on Linux |
%LOCALAPPDATA%\wudict\wudict.log |
Android's own log |
Your dictionary files are not in this list. wuDict reads them where they are
and leaves them alone until you ask it not to — the only thing that touches
them is Remove, which deletes what it says it deletes.
DB_DIR moves the library; the rest of the table follows the config
file.
Portable mode¶
Put a wudict.toml next to the executable. It then wins over every user
location, and settings are saved back to it. Use this for a USB stick or a
self-contained folder.
wuDict never creates that file by itself. An executable's folder usually
belongs to someone else, such as ~/go/bin or /opt/homebrew/bin.
Everyday settings¶
DICT_DIR¶
Folders holding your dictionary files, scanned including every subfolder.
| Flag | --dict-dir <path>, repeat for several folders |
| Default | ~/Dictionaries |
wudict --dict-dir ~/Dictionaries --dict-dir /Volumes/Ext/Dicts
DICT_DIR="~/Dictionaries:/Volumes/Ext/Dicts" wudict # ";" on Windows
The config file spells several folders as an array. The : and ; separators
belong to the environment only, where they follow the convention of PATH.
A dictionary found in two folders is listed once, and the first folder wins. A missing folder is reported, and the others still work.
DB_DIR¶
The library folder: one subfolder per prepared dictionary.
| Flag | --db-dir <path> |
| Default | ~/.wudict/db |
It must not be the same folder as DICT_DIR. wuDict refuses to start when they
are the same.
SERVER_IP and SERVER_PORT¶
| Flags | --ip <address>, --port <port> |
| Defaults | 127.0.0.1, 6888 |
127.0.0.1 is the loopback address, reachable from your machine only. Set
0.0.0.0 to accept connections from your network. Only do that on a network
you trust; wuDict has no login. Deleting a dictionary is the one thing those
visitors cannot do — ALLOW_REMOTE_DELETE is off
unless you turn it on.
NO_BROWSER¶
Do not open a browser tab at startup.
| Flag | --no-browser |
| Default | off, a tab opens |
AUTO_INDEX¶
Prepare each dictionary in the background on its first search.
| Flag | none, environment and file only |
| Values | on, off |
| Default | on |
off leaves every dictionary in preview, searched through its own format.
Contains, full-text and media stay per-dictionary choices either way.
USE_CACHED¶
Also list prepared dictionaries whose original files are gone.
| Flag | --use-cached |
| Default | off |
The setup page sets this when you click Use these dictionaries.
ALLOW_REMOTE_DELETE¶
Whether a browser on another machine may delete a dictionary.
| Flag | --allow-remote-delete <0\|1> |
| Default | off |
Deleting from the machine running wuDict is always allowed — it is your library and your disk, and 🗑 Remove… in the ☰ panel is how you do it. This setting is only about the other case: a browser somewhere else on the network.
With SERVER_IP set to 0.0.0.0 anyone who can
reach the port can use the page. Set ALLOW_REMOTE_DELETE = "1" if you
want to allow LAN users to delete dictionaries.
There is no undo
Removal is irreversible! The files do not go to the Trash or the Recycle Bin, and
nothing in wuDict brings them back. wudict rm without -f prints
exactly what would go, which is the way to check before committing.
VERBOSE¶
Log requests, dictionary opens, preparation and audio conversion.
| Flag | --verbose |
| Default | off |
--verbose works for every command, not only serve. The short -v means
--version.
Audio¶
SPEEX_BACKEND¶
Which decoder converts .spx audio to WAV.
| Flag | none, environment and file only |
| Values | internal (built-in libspeex), external (the speexdec program) |
| Default | internal |
internal needs a -cgo build. A -purego build always uses the external
program.
SPEEXDEC¶
Path to the external speexdec program.
| Flag | --speexdec <path> |
| Default | found next to the executable, then on PATH |
wuDict prints which decoder it resolved at startup, or an install hint when it found none.
Desktop integration¶
TRAY¶
Show a tray icon on Windows, or a menu-bar icon on macOS.
| Flags | --tray, --no-tray |
| Values | 1 always, 0 never, unset for automatic |
| Default | unset: an icon appears only when started from the desktop |
Given both flags, --no-tray wins. Between two contradictory instructions, the
one that changes nothing about the process is the safe reading.
Tuning¶
These change speed and memory, never results - with one marked exception. The defaults are right for a desktop. Open a section only if you want to change it.
INDEX_WORKERS¶
How many dictionaries may be prepared at once.
Values, default, and when to raise it
| Flag | --index-workers <n> |
| Values | a number, or auto (also 0) for every core |
| Default | 1 |
Preparing one dictionary saturates one core and holds a few hundred bytes per headword. The default is one, so background work never takes the machine away from you.
Raise it when you want a large collection prepared quickly and do not mind the machine being slow while it happens.
PREVIEW_MEMORY¶
How much RAM dictionaries that are not yet prepared may hold open.
Values, default, and what it does not apply to
| Flag | none, environment and file only |
| Values | a size such as 1GB, or 0 for no limit |
| Default | 1GB; on Android a third of MEMORY_LIMIT, which is 64MB on a small device and 128MB on a large one |
Each dictionary in preview holds about 350 bytes per headword open. Above this limit, the least recently used are closed.
Prepared dictionaries answer from disk. They cost nothing here and are never closed for this reason.
SEARCH_MEMORY¶
How much RAM one search may claim by opening dictionaries that are not yet prepared.
Values, default, and the results it can change
| Flag | none, environment and file only |
| Values | a size such as 512MB, or 0 for no cap |
| Default | no cap; on Android, the value of MEMORY_LIMIT |
This is the one setting here that changes what a search returns. Past the cap, the remaining dictionaries are reported as not searched instead of being opened. They are not errors, and asking for one of them by itself still answers.
It never applies to prepared dictionaries, which cost nothing to search, and never to a search naming a single dictionary.
MEMORY_LIMIT¶
A soft ceiling for the whole process.
Values and default
| Flag | none, environment and file only |
| Values | a size such as 4GB, or 0 for none |
| Default | none; on Android, a fraction of the device's RAM |
Go collects more often, and drops its caches, rather than growing past this. It is a ceiling, not a hard limit.
NO_COMPRESS¶
Store article text plain instead of compressed.
Values and what it costs
| Flag | --no-compress |
| Default | off, text is compressed |
Prepared databases become roughly three times larger. Reads get marginally faster. Worth it only with disk to spare.
Lemmatization¶
When you enable lemmatization for a language wuDict will be able to find inflected forms,
for example search for knew will find know, fuiste will find ser, идет will find идти.
IMPORTANT
For lemmatization to work, wuDict must be able to detect the dictionary language. Babylon (.bgl) contains data about the headword language, which is sufficient. Most other dictionaries do no declare any headword language metadata. wuDict applies a best guess strategy in the given order:
- if the dictionary file starts with e.g.
es-esorspa-eng(for example, spa-eng-oxford.mdx) then the first language code will be used for lemmatization - if the dictionary title contains a valid language code then that is used
- if the dictionary parent folder is a valid language
code such as
esorspathen this will be used as the lemmatization language. - if none of the previous checks found a language code then English is used by default,
which means that for English dictionaries you do not need to rename your files or the parent
subfolders to match
enoreng.
MORPH_CACHE¶
How many languages of lemma data stay in memory.
Values, default, and what a language costs
| Flag | none, environment and file only |
| Values | a count, or 0 to switch lemmatization off entirely |
| Default | 2; 1 on Android |
English is built in. Every other language is a file you install — see
LEMMA_DIR. Nothing is loaded at startup: a language is read
on the first search that needs it, and the least recently used is dropped
above this count.
A loaded language costs from 7 MB (English) to 65 MB (Russian). 0 never
loads any lemmatizers, and disables lemmatization.
LEMMA_DIR¶
The folder where lemmatization files are stored (except English which is embedded OOTB into the binary).
Values, default, and the file format
| Flag | none, environment and file only |
| Values | a folder path |
| Default | ~/.wudict/lemmas |
You do not have to fill this folder by hand. Open 🔤 Lemmatization on
the settings page (or in the ⚙ panel beside the search box) and tick a
language: it downloads, installs, and takes effect immediately — no
restart. That page is the only route on Android, which has no shell. From
a terminal, wudict lemmas download fr de es it ru does the same; see
the lemmas command.
One file per language, named after the language: pl.txt, pol.tsv,
polish.txt.gz. The extension must be .txt or .tsv, optionally
.gz-compressed; anything else in the folder is ignored.
Each line is a lemma followed by its forms, separated by tabs and written in lower case:
The lists at
michmech/lemmatization-lists
are already in this shape — one lemma/form pair per line — and work as
downloaded. Blank or malformed lines are skipped rather than failing the
file.
An en.txt replaces the English wuDict ships, if you have a better
list than the one built in.
The folder is indexed at startup and again whenever the lemmatization page installs or removes something, so a language installed via the web ui is already enabled; if you place a file manually it will be picked up after wuDict is restarted.
LEMMA_URL¶
By default wuDict installs lemmatization languages from https://github.com/wuweidict/lemmas.
Values, default, and using your own
| Flag | -url on the lemmas commands |
| Used by | wudict lemmas, and the 🔤 Lemmatization page |
| Values | a URL, or the path of a manifest.json on disk |
| Default | the published wuDict lemma catalogue |
The -url parameter can be used to override the lemmas source and can point
either to a custom URL e.g. https://example.com/manifest.json
OR to a local folder such as /path/to/lemmas/manifest.json.
So, for example, if you cloned the lemmas site locally you can use:
The lemma data itself is published under the
ODbL and derived from
michmech/lemmatization-lists;
see ATTRIBUTION.txt in the default lemmas site.
Access¶
BROWSER_EXTENSIONS¶
Configures browser extensions that can access the wuDict server.
| Flag | none, environment and file only |
| Default | blank: any installed extension |
BROWSER_EXTENSIONS = ["chrome-extension://abcdefghijklmnopabcdefghijklmnop"]
An extension can access three read-only endpoints: /api/dicts, /api/search and
/res/. It cannot access wuDicts settings, and wuDict internal endpoints.
Firefox generates a new moz-extension:// origin per installation, so there is
no stable origin to list there.
WEB_ORIGINS¶
Which web pages may look words up in this server with JavaScript.
| Flag | none, environment and file only |
| Default | blank: CORS restrictions enforced all any domain |
Whitelisted domain only read only operations are allowed -
/api/dicts, /api/search and /res/. No access to
settings, library internals, or operations that modify state.
Writing an origin¶
An origin is a scheme, a host and a port. Nothing else.
WEB_ORIGINS = ["http://localhost:3000"] # correct
WEB_ORIGINS = ["http://localhost:3000/app"] # wrong: a path is not part of an origin
WEB_ORIGINS = ["localhost:3000"] # wrong: no scheme
http:// and https:// are the only schemes accepted. A different port is a
different origin, and so is a different scheme: http://localhost:3000 does not
allow https://localhost:3000. The default port may be written or left out -
https://x.example and https://x.example:443 mean the same thing, because
that is what the browser means by them.
The wildcard¶
With * every site you visit may read every dictionary you have, when wuDict serveris running. That is useful while you are developing a page and know
what is open in the browser. Only use it if know what you are doing.
The server prints the setting on every start:
address http://127.0.0.1:6888
web origins any website may read your dictionaries (WEB_ORIGINS = "*")
What this does not cover¶
Anything that is not a browser page ignores all of it. curl, a Node or Python
script, an Electron main process, a native app: none of them send an Origin
header, none of them enforce CORS, and all of them can already reach every
endpoint. CORS is a rule browsers apply to pages, not a lock on the server. The
lock is SERVER_IP, which keeps the server on the
loopback address.
CONFIG_PATH¶
The config file to read, instead of searching the four locations.
| Flag | --config <path> |
| Default | unset |
This one exists as a flag and an environment variable only.