yunmin25 downloadsCount with traditional five-stroke Zheng tallies inline in Obsidian and resume them later.
A native-feeling 正 tally counter for Obsidian. Count stroke by stroke, keep it inline, and resume anytime.

Press Alt+Z, tap Space to count, Enter to commit. The tally renders as a
real inline 正 built from canonical stroke vectors, and it stays that way:
committed tallies remain vector chips you can click to resume.
Counting with 正 tallies in Markdown usually means typing characters by hand and losing count halfway. Zheng Tally turns it into a tight loop: start anywhere in a note, watch each stroke appear, commit a portable plain-text tally, and pick it back up later without retyping. The editor shows vectors; the file stays readable text.
Alt+Z drops an inline counter at the cursor.Space adds one canonical stroke (一 → … → 正), grouped in fives.Enter writes 正正正·3<!--zt:18--> — visible text plus a count marker.Alt+Z) to resume from 18. Esc never writes.正 vectors at every step — never a substituted characterFrom a release:
main.js and manifest.json from
Releases.<vault>/.obsidian/plugins/zheng-tally/.From source:
git clone https://github.com/yunmin311/zheng-tally-obsidian.git
cd zheng-tally-obsidian
npm install
npm run build
Copy dist/main.js, manifest.json, and styles.css into your vault's
plugin folder. (styles.css carries the chip and hover-badge styling.)
Alt+Z to start tally mode at the cursor.Space / + to count up, Backspace / - to count down.Enter to commit a persistent vector chip.Alt+Z) to resume; Esc cancels cleanly.One session at a time; switching leaves ends it without writing.
| Key | Action |
|---|---|
Alt+Z |
Start, or resume the tally under the caret |
Space / + / NumpadAdd / Shift+= |
+1 |
Backspace / - / _ / NumpadSubtract |
−1 (floors at 0) |
Enter |
Commit (single edit) |
Esc |
Cancel, zero document changes |
Ctrl/Alt/Meta chords pass through untouched.
Committed tallies keep rendering as vector chips — same strokes, same metrics,
quieter chrome — across note reopens, plugin reloads, and restarts, derived
purely from the note text. This holds in reading view too (src/reading-tally.ts):
a registerMarkdownPostProcessor pass renders the chip there, because the
editor's CodeMirror decorations never reach Obsidian's MarkdownRenderer.
Reading-view chips are read-only; counting stays an editor action.
Enter rewrites text + marker in one edit
(正正正正·3<!--zt:23-->).Esc changes nothing; the original chip returns.Enter removes the tally and its marker.

| Count | Stored |
|---|---|
| 1 | ·1<!--zt:1--> |
| 5 | 正<!--zt:5--> |
| 18 | 正正正·3<!--zt:18--> |
The <!--zt:N--> comment is the integer source of truth and ownership marker.
A marker counts only when it re-serializes to exactly the visible text;
mismatches fail closed. Unmarked legacy tallies (正正正·3) still get a
conservative hover badge and can be resumed once, upgrading on next Enter.
A lone 正 never auto-resumes.
Up to four group slots render in full; beyond that the preview compacts while always keeping the most-recent finished group and the live partial slot:
18 -> 正 正 正 [state3]
20 -> 正 正 正 正
21 -> 正 正 … 正 [state1]
83 -> 正 正 … 正 [state3]
The right-hand total is always exact. Active and persisted chips share one grouping algorithm, so committing never jumps visually.


src/zheng-strokes.ts — vendored canonical 5-stroke vectors (Arphic data)src/renderer.ts — native-measured glyph cells + tally chipssrc/cm6-widget.ts — live inline Decoration.widgetsrc/persistent-tally.ts — marker replace decorations + resume lookupsrc/editor-session.ts — keyboard capture, lifecycle, single-edit commitssrc/tally-hover.ts — legacy parser + transient count badgesrc/tally-state.ts — counts plus stable/marked serializationsrc/editor-host.ts — the single CodeMirror access point正
never badge or resume.npm install # install dependencies
npm run dev # watch mode build
npm run build # production build (dist/main.js + dist/manifest.json)
npm test # 143 passing
npm run lint # eslint
npm run typecheck # tsc --noEmit
正 stroke vectors: Arphic Public License, not MIT —
via Hanzi Writer Data / Make Me a Hanzi, extracted from Arphic Technology
fonts. Full text: vendor/ARPHICPL.txt, notes:
vendor/README.md.