Skip to content

Count em-dashes in prose, not in a document's own markup - #80

Merged
peopleworks merged 1 commit into
mainfrom
em-dash-counter
Sep 7, 2026
Merged

peopleworks merged 1 commit into
mainfrom
em-dash-counter

Conversation

@peopleworks

Copy link
Copy Markdown
Owner

The defect

EmDashAnalyzer counted every -- in the raw text as an em-dash. In any document with markup that charges the writer for things nobody typed as punctuation:

  • frontmatter delimiters (---)
  • Markdown table separator rows (|---|---|---| counts as three)
  • command-line flags inside fenced code blocks (--json, --report, --against)
  • a line of hyphens typed above a bibliography

The case that decides it is not ours

pelic-021970.txt in the calibration corpus is an essay by a second-language learner who drew one separator line of forty hyphens above their references. The engine counted twenty em-dashes and printed "Em-dash overuse (20 in 745 words, 2.7/100). LLMs lean on the em-dash as a rhythm crutch" — on a report a teacher might hand back to that student.

It is the same shape as #75: a rule charging a learner for their register, except here the student did not even write the thing being counted.

What moved

File Dashes Density Severity
README.md 139 → 73 3.9 → 2.0 High → Medium
Docs/Calibration/README.md 40 → 15 2.6 → 1.0 Medium → Low
SKILL.md 47 → 31 2.0 → 1.4 Medium → Low
CONTRIBUTING.md 23 → 15 1.7 → 1.1 Medium → Low
pelic-021970.txt 20 → 0 2.7 → — Medium → no finding

What did not move

The published calibration. Re-run over all 296 texts: published-calibration.json is identical except its date — threshold 30, 2 of 296 flagged, rateLow, rateHigh, every language row, the noisiest-rule shares. Corpus fingerprint unchanged (78bda061bde3dc99).

That matters for the house rule about tuning the instrument: this removes a false signal, it does not move the number.

What still counts

Two hyphens between words is how people type an em-dash without the key for it, and it still counts. Three or more is a separator, never a dash between clauses. Dashes inside fenced blocks and inline code spans are markup.

Tests

Six guards, each verified by mutation — all six fail against the old counter — plus two regression guards that the real dash and the ASCII stand-in still count. 424 tests green.

Left alone on purpose

Words inside code blocks still enter the density denominator, which understates density for technical documents. That is a defect in the shared word count, not in this rule, and changing it would touch every analyzer and the corpus. Filed separately.

Provenance

Found from outside the repo, using the skill on a real email and then the rule pack against ourselves (AI_Tasks/Pendientes/OPUS_05_…). That brief concluded "nothing calculates wrong" and proposed rewriting our own suggestion strings. The strings are a separate and much smaller question; rewriting SKILL.md to lower its score is the one thing this project tells everyone never to do — and it drops to Low here on its own, as a consequence rather than a goal.

🤖 Generated with Claude Code

https://claude.ai/code/session_015PEbbiYSNPw7jE3LrPNhyF

`rhet.em-dash` counted every "--" in the raw text. In a Markdown document that
charged the writer for things nobody typed as punctuation:

  - frontmatter delimiters (---)
  - table separator rows (|---|---|---| counts three)
  - command-line flags inside fenced code blocks (--json, --against)
  - a line of hyphens typed above a bibliography

The worst case is not ours. pelic-021970 in the calibration corpus is an essay
by a second-language learner who drew one separator line of forty hyphens above
their references. The engine counted twenty em-dashes and printed "LLMs lean on
the em-dash as a rhythm crutch" on their report. That finding is now gone.

What moved, measured before and after:

  file                          dashes    density      severity
  README.md                    139 -> 73  3.9 -> 2.0   High   -> Medium
  Docs/Calibration/README.md    40 -> 15  2.6 -> 1.0   Medium -> Low
  SKILL.md                      47 -> 31  2.0 -> 1.4   Medium -> Low
  CONTRIBUTING.md               23 -> 15  1.7 -> 1.1   Medium -> Low
  pelic-021970.txt              20 -> 0   2.7 -> none  Medium -> no finding

What did not move: the published calibration. Re-run over all 296 texts,
`published-calibration.json` is identical except its date — threshold 30,
2 of 296 flagged, both bounds, every language row, the noisiest-rule shares.
This removes a false signal; it does not move the number.

Two hyphens between words is still how people type an em-dash without the key
for it, and that still counts. Three or more is a separator, never a dash
between clauses. Each of the six guards was checked by mutation: all six fail
against the old counter.

Found from the outside, using the skill on a real email and then the rule pack
against ourselves. The brief that reported it concluded "nothing calculates
wrong" and proposed rewriting our own strings; the strings are a separate and
much smaller question, and rewriting SKILL.md to lower its score is the one
thing this project tells everyone never to do. It drops to Low on its own.

Known and left alone: words inside code blocks still enter the density
denominator, which understates it for technical documents. That lives in the
shared word count, not in this rule.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PEbbiYSNPw7jE3LrPNhyF
@peopleworks
peopleworks merged commit 1dbf5ee into main Sep 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant