English | 简体中文
A command-line dictionary that turns the senses you pick into a Markdown vocabulary notebook.
Built for close reading — foreign-language articles, papers, original-language books — when you want to collect words as you go. Look a word up once, pick the senses you care about, and the result is appended straight to a .md file. Open it in Obsidian / Typora and you have a tidy vocabulary table.
Ships with a skill so agents like Claude Code can call it directly. See Deploying the skill.
- Three sources in one shot: Cambridge (definitions + pronunciation), Wiktionary (inflections / plurals), and FreeThesaurus (synonyms) fetched concurrently — about as fast as hitting one source alone.
- Only what you want: senses are grouped by part of speech and listed with indices you pick by hand, so the notebook never fills up with whole dictionary pages.
- Ready to read: Markdown tables with clickable IPA-as-audio links and a jump to the Cambridge source page.
Terminal interaction:
word> serendipity
--------------------
serendipity
noun: 0 the fact of finding interesting or valuable things by chance
pick> 0
word> /q
The resulting vocab.md:
| Word | Pos | Def | Syn | Verbs | Pron | Web |
|---|---|---|---|---|---|---|
| serendipity | noun | the fact of finding interesting or valuable things by chance | chance; fortune | serendipities | US: /ˌser.ənˈdɪp.ə.t̬i/ | ^_^ |
Requires Python 3.10+.
git clone <repo-url>
cd dictionary_pro
pip install -e .Verify:
dictpro --help
# or: python main.py --helpdictpro -o vocabThen:
- Type a word at the
word>prompt and hit enter. - When the sense list appears, type the index of the sense(s) you want at the
pick>prompt (e.g.0). - Back at
word>, type the next word, or/qto quit. - Open
./vocab.mdto see the result.
Two prompts:
word>— enter a word to look uppick>— enter the sense index(es) to save
| Prompt | Input | Meaning |
|---|---|---|
word> |
word |
Look up one word |
word> |
w1,w2,w3 |
Look up several at once (comma-separated) |
word> |
/q |
Quit |
pick> |
0 / 0,2,5 |
Save the N-th sense; multi-select with commas |
pick> |
/x |
Skip the current word, save nothing |
| Option | What it does |
|---|---|
-o, --output PATH |
Output md path. .md is auto-appended if missing; the parent directory must already exist. |
--no-audio |
Drop the pronunciation column. |
--no-synonym |
Drop the synonym column. |
--rewrite-header |
Force-write the header row (by default it's written only once when appending to an existing file). |
If you omit -o, dictpro asks for a filename interactively at startup.
Want to call it from an agent or script? See Deploying the skill below.
Header fields:
- Word — the word
- Pos — part of speech
- Def — the selected sense
- Syn — synonyms for the same part of speech
- Verbs — inflections (past tense, plurals, etc.)
- Pron — US / UK pronunciations; the IPA text itself is the audio link
- Web — jump to the Cambridge source page
You can run dictpro against the same file any number of times; the header is written only once.
# Build a vocab list for a book
dictpro -o gatsby
# Keep definitions and synonyms, drop pronunciations
dictpro -o quick --no-audio
# Continue appending to an old file, but rewrite the header
dictpro -o gatsby --rewrite-headerThe project bundles a skill so agents know how to call dictpro.
# Link the skill into Claude Code's skills directory
ln -s "$(pwd)/skills/use-dictpro" ~/.claude/skills/use-dictproAfter that, any Claude Code session will auto-discover it and use dictpro -q / -b without you having to explain the interface.
Two flags:
| Flag | What it does |
|---|---|
-q WORD |
Look up one word; writes a JSON object to stdout. |
-b FILE |
Batch lookup. FILE is a path or - (stdin), one word per line, streamed out as NDJSON. |
Typical invocations:
# Single word
dictpro -q serendipity
# Batch from a file
dictpro -b words.txt
# Batch from stdin
cat words.txt | dictpro -b -JSON on stdout (for -q serendipity):
{
"word": "serendipity",
"ok": true,
"senses": [{"i": 0, "pos": "noun", "text": "the fact of finding ..."}],
"inflections": {"noun": ["serendipities"]},
"synonyms": {"noun": ["chance", "fortune"]},
"pronunciations": {"noun": [[{"region": "US", "ipa": "/...", "audio": "..."}]]}
}The errors field appears only when a source fails; inflections, synonyms, and pronunciations are omitted when empty.
Exit codes come in three flavors:
0— at least one word was found1— IO error2— no word was found at all (lets the agent tell "word doesn't exist" apart from "network is down")
Batch output is NDJSON and each line is flushed as soon as its word is ready, so it can be consumed as a stream. stdout is always machine-readable (JSON / NDJSON); human-readable diagnostics go to stderr.
Word not found
None of the three sources had it. Check the spelling, or the word may be a proper noun / internet slang.
Network timeout Retries are built in; transient failures usually clear up on the next try. If failures persist, check your proxy.
Too many senses to pick from
Indices are globally continuous and span parts of speech, so you can mix them: to save both noun: 0 and verb: 3, type 0,3.
dictpro/
cli.py # interactive entry / argument dispatch
agent.py # JSON output for -q / -b
fetchers.py # HTTP layer with retries
concurrent.py # concurrent fan-out across the three sources
parsers/ # cambridge / wiktionary / thesaurus parsers
renderer.py # Markdown table rendering
models.py # data structures
Adding a data source: drop a new parser into parsers/ and register it in concurrent.py.