LLazyEmail / LLazyEmail/markdown-regex

deepseek

Open
#350 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.