LLazyEmail / LLazyEmail/markdown-regex
deepseek
- Dominant language
- JavaScript
- Stars
- 11
- Forks
- 3
- Avg merge
- 4h 51m
- Merged PRs (30d)
- 20
Description
# Repository Review: `markdown-regex`
This is a small, focused TypeScript library that exports RegExp constants for parsing Markdown. It's already been modernized (TS + tsup, dual ESM/CJS, zero deps), so most improvements below are about **correctness, robustness, and developer experience** rather than a rewrite.
---
## 1. Correctness / Regex Quality (highest priority)
These are the issues most likely to bite real users, because regex-only Markdown parsing is fragile.
- **No `g` / `m` flag strategy documented.** The README's quick start uses `md.match(REGEXP_LINK)` — but exported regexes without the `g` flag return only the first match, and with `g` they change return shape (`match` → array of full matches, no capture groups). Document which flags each export carries and why. Consider exporting a helper like `matchAll(re, str)` to smooth this over.
- **Regex-based Markdown is fundamentally leaky.** Inline code (`` ` ``), fenced code blocks (```` ``` ````), and HTML should *not* be scanned for other syntax (e.g. `**` inside a code block is not bold). Since this lib exports individual patterns, users will inevitably apply them to raw text and get false positives. Two options:
- Add a `REGEXP_FENCED_CODE` and document that it must be extracted first.
- Ship a minimal `parse()` that tokenizes code spans/blocks first, then applies the rest.
- **`REGEXP_PARAGRAPH` / `REGEXP_BR` are underspecified.** "text between newlines" and "2+ consecutive newlines" will produce surprising results on lists, code fences, and blockquotes. Add examples of edge cases in tests and README.
- **`REGEXP_Q` (`:"quoted":`) is non-standard.** Fine as a custom tag, but it should live under the "addons" concept the README mentions rather than next to core Markdown exports — otherwise users assume it's Markdown syntax.
- **Nested/overlapping emphasis.** `***bold italic***`, `**bold _italic_**`, escaped `\*not italic\*` — add explicit tests and document known limitations. The recent commit "simplify HEADER/STRONG/ITALIC regexes" suggests these were already trimmed down; a `KNOWN_LIMITATIONS.md` would prevent bug reports.
- **Link/image regexes and titles.** CommonMark allows `[text](url "title")` and reference links `[text][id]`. Check whether `REGEXP_LINK` handles titles; if not, say so.
## 2. Testing
- The test suite is the backbone of a regex library — invest here heavily.
- Add a **fixture-based test harness**: keep a corpus of real Markdown files (e.g. CommonMark spec examples) and assert extraction results. Regexes drift silently otherwise.
- Add **negative tests** (things that should *not* match) alongside positives.
- Consider running the official **CommonMark spec examples** through the patterns and reporting a pass/fail matrix — even a partial pass is a strong selling point.
- Benchmark note: for large documents, catastrophic backtracking is a real risk with nested quantifiers. Add a test that times patterns against a pathological input.
## 3. API / Package Design
- **`REGEXP_H2` / `REGEXP_H3` but no H4–H6** is inconsistent. Either export all levels or a single `headerRegex(level)` factory.
- **Consider a factory API** in addition to constants: `header(2)`, `list({ ordered: true })`. Constants are fast; factories are ergonomic and avoid combinatorial exports.
- **Types for the constants** are just `RegExp` — fine. But if you later add `parse()`, publish a clear result shape.
- **Dual ESM/CJS + IIFE is great.** Add `"exports"` field verification (e.g. `arethetypeswrong`) to CI to catch consumer resolution issues.
- **Node 20+ minimum** is fine, but the README still lists `rollup.config.mjs` in the repo — if tsup is now the build tool, remove the rollup config to avoid confusion about which one is authoritative.
## 4. Repo Hygiene
- **Two Jest configs** (`jest.config.cjs` and `jest.config.js`) — pick one. The latter looks like a leftover.
- **`source-fullcodetest.md`** at root looks like a scratch file; move to `tests/fixtures/` or delete.
- **`HYGIENE.md`** is great — link it from README and CONTRIBUTING.
- **Commit messages like "trying to make yml work"** on `.gitignore` — fine historically, but add a `CONTRIBUTING.md` note on commit conventions (Conventional Commits) so future history is scannable.
- **Renovate is configured** — good. Consider grouping minor/patch dependency updates and enabling auto-merge for dev deps to reduce noise.
## 5. Documentation
The README is already strong. Add:
- **A "Limitations" section** up front: regex-only parsing can't do nesting, code-fence awareness, or full CommonMark. Set expectations before users file issues.
- **Flags column in the API table** — specify `g`, `m`, `i` for each export. This is the #1 thing users need to know.
- **A "before/after" example** showing a Markdown string and what each regex extracts, so users can sanity-check their understanding.
- **Migration notes for v1 → v2** (the README calls v2 beta; a changelog link is there but a short "what changed" section helps).
- **A note on ordering**: if you extract links first, then bold, etc., overlapping matches can conflict. Document a recommended pipeline.
## 6. CI / Publishing
- **CI matrix on Node 20/22/24** is good. Add:
- `npm run typecheck` (already exists) — ensure it runs in CI.
- `eslint` in CI (config exists but isn't shown running).
- A **bundle size check** (e.g. `size-limit`) — "lightweight" is a selling point; enforce it.
- **`publint`** and **`arethetypeswrong`** on the built package.
- **Publish workflow uses Node 24** — verify that's a stable release, not a preview, before relying on it for releases.
- **Provenance**: add `npm publish --provenance` for supply-chain transparency.
## 7. Feature Ideas (if scope allows)
- **`REGEXP_FENCED_CODE`** and **`REGEXP_INLINE_CODE`** exports (currently only inline `REGEXP_CODE`).
- **`REGEXP_HTML`** for raw HTML blocks, since they interact with everything else.
- **A tiny `extract(md)` function** returning a structured `{ headers, links, images, ... }` object — this is what most consumers actually want, and it lets you handle ordering/code-fence issues internally.
- **Addon registry**: make good on the "Future: Custom Tag Addons" section with a documented pattern and one example addon.
---
## TL;DR — prioritized action list
1. Document regex flags and known limitations (README + `KNOWN_LIMITATIONS.md`).
2. Add fixture-based tests, including negative cases and CommonMark spec samples.
3. Clean up duplicate `jest.config.*` and stray root files.
4. Add `publint` / `arethetypeswrong` / size-limit to CI.
5. Consider a `parse()` or `extract()` helper that handles code fences first.
6. Unify header exports (`REGEXP_H*` or a factory).
7. Remove `rollup.config.mjs` if tsup is the sole build tool.
The library is in good shape — the biggest wins are **honest documentation of regex limitations** and **a strong test corpus**, since regex-based Markdown parsing is where users will get surprised.
Contributor guide
Research direction
Start by reading the README, package configuration, Jest configs, and existing test suite; then inspect the CI and build configuration, including rollup.config.mjs and the files named in the review. Run the current tests and typecheck to establish a baseline. This review needs to be split into a focused change; completion depends on the selected action, its tests or documentation, and the relevant CI checks passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, markdown, node.js, typescript
- Domain
- build-system, ci-cd, documentation, testing, tooling
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100