markdown-it-abbr

Adds PHP Markdown Extra-style abbreviation definitions to markdown-it, auto-wrapping matched terms in <abbr> tags.

Library
npm
v2.0.0
51stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
35/100Needs Attention
Development Activity28
Maintenance0
Community40
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture68
Code Quality64
Innovation68
Learning Curve35

markdown-it-abbr is an official markdown-it plugin that brings PHP Markdown Extra’s abbreviation syntax to markdown-it’s parser. Authors define an abbreviation once inline, using the *[LABEL]: Definition syntax, and every subsequent occurrence of that label in the document is automatically wrapped in a semantic <abbr title="Definition"> tag — no manual HTML authoring required.

Under the hood the plugin hooks into markdown-it’s rule pipeline at two points: a block-level rule collects abbreviation definitions into the render environment, and a core-level rule (run after linkify) scans all inline text tokens with a combined regex built from the defined labels, splicing in abbr_open/text/abbr_close token triples wherever a label is matched as a whole word. It ships as a zero-dependency, dual ESM/CJS package and follows the same plugin convention (.use(plugin)) as the rest of the markdown-it ecosystem.

What You Get

  • A *[LABEL]: Definition block-level syntax for declaring abbreviations directly inside Markdown source
  • Automatic detection and wrapping of every matching occurrence of a defined label in the rendered HTML
  • Word-boundary-aware matching using Unicode punctuation/space classes so labels are never partially matched inside other words
  • Longest-match-first resolution when abbreviation labels overlap or are substrings of one another
  • Zero runtime dependencies and dual ESM (index.mjs) / CJS (dist/index.cjs.js) builds via the package exports map

Common Use Cases

  • Technical documentation sites that reference recurring acronyms (API, HTTP, W3C) and want hover tooltips without hand-writing <abbr> HTML
  • Static site generators and blog engines built on markdown-it that need semantic, accessible markup for jargon and acronyms
  • Style guides and glossaries where a term should be explained the first time and lightly annotated on every later mention
  • Any markdown-it-based content pipeline (docs generators, CMS renderers, README processors) that wants standards-compliant <abbr> output with no post-processing step

Under The Hood

Architecture The plugin is a single default-exported function that registers two rules on the host markdown-it instance: a block rule (abbr_def) inserted before the reference rule, which recognizes *[LABEL]: Definition lines and records them into state.env.abbreviations (keyed with a : prefix to avoid clashing with Object.prototype members), and a core rule (abbr_replace) appended after linkify, which walks every inline token’s children, runs a dynamically-built regex against each text node, and replaces matched runs in place using markdown-it’s arrayReplaceAt utility. There are no classes or persistent module state — everything lives in the closure created per .use() call and in the per-render state.env, which keeps the plugin composable and side-effect free across multiple markdown-it instances.

Tech Stack The package has zero runtime dependencies, relying only on utilities markdown-it itself exposes (escapeRE, arrayReplaceAt, ucmicro Unicode character-class regexes). It builds dual output formats with Rollup 4 — a CJS bundle (dist/index.cjs.js) and full/minified UMD bundles — using @rollup/plugin-node-resolve, @rollup/plugin-babel, and @rollup/plugin-terser, wired through the package.json exports map so ESM consumers load index.mjs directly and CJS consumers load the built bundle. Tests run on Mocha with markdown-it-testgen for fixture-driven input/output comparisons, coverage is collected with c8, and linting uses ESLint 8 with eslint-config-standard.

Code Quality The test suite is fixture-driven: test/fixtures/abbr.txt contains dozens of input/expected-output Markdown pairs covering the PHP Markdown Extra reference example, empty-abbreviation rejection, overlapping/intersecting labels, and nested-abbreviation edge cases, run through markdown-it-testgen. A separate smoke test confirms the CJS build still resolves to a callable function after bundling. There is no TypeScript and no shipped type declarations, so type safety relies entirely on runtime behavior and the fixture suite rather than a compiler. CI (GitHub Actions) runs lint, build, and test on every push and pull request plus a weekly scheduled run, with coverage uploaded to Coveralls.

API Design Consumption is a single line — markdownit().use(require('markdown-it-abbr')) — with zero configuration options, matching the shared convention of the whole markdown-it plugin family so it composes cleanly alongside other .use() calls. Abbreviation definitions live inline in the same Markdown source rather than behind a separate config object or API call, so there is no setup boilerplate: write Markdown, get <abbr> tags. The trade-off is that there is no way to supply abbreviations programmatically (e.g. from a shared glossary object) without a consumer pre-pending synthetic *[LABEL]: definition lines to their source text themselves.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search