The input dialect that actually matters is GitHub's, not bare CommonMark: READMEs, issues and every .md in the wild carry tables, task lists, ~~struck~~ text and bare www. links. The vendored commonmark.js (LITE-030) implements none of them — GFM's reference implementation is the C cmark-gfm, with no official JS port. This ticket adds the four extensions on top of the vendored parser, layered as separate files wherever the upstream hook allows, so re-vendoring an upstream bump stays a script re-run.
The GFM spec is 0.29-gfm (2019-04-06), based on CommonMark 0.29 — older than the 0.31.2 core the vendored parser implements; the extensions are additive, the base differences are not this ticket's business. A text dump of the spec sits at ~/tmp/gfm.txt (fetched 2026-08-14; the live page is https://github.github.com/gfm/).
<del>; three or more yield nothing; a paragraph break stops the scan — an emphasis delimiter run, so it belongs in processEmphasis.[ + (space | x | X) + ] + at least one whitespace char. A post-pass over the parsed list, not a parser change.www. or http(s):// + valid domain (dot-separated alnum/_/- segments, at least one dot, no _ in the last two), then non-space non-< chars; trailing ?!.,:*_~ trimmed, unbalanced trailing ) trimmed only when the link ENDS in ), a trailing &name; shaped tail excluded, < ends it. Emails: alnum/./-/_/+, @, dotted alnum/-/_ domain, last char not -/_. Only at line start, after whitespace, or after *, _, ~, (.: for alignment, then data rows; cells hold inlines only, never blocks; the header and delimiter cell counts must match or it is not a table.The vendored parser accepts GFM and produces AST nodes the LITE-032 emitter can walk, with cmark-gfm agreeing on the rendered HTML for every ported example.
lite/mark/gfm-*.js; edits inside the five vendored files kept to the minimum hook and marked with the ticket code, so vendor.sh re-runs stay reviewable.cmark-gfm is the HTML oracle, never a second JS parser: a JS oracle would share the emitter's bugs.-[v], unchecked to -[ ], and GFM's [x] never maps to StrictMark's -[x] (which means wontfix).test/now leg-4 failure did NOT reproduce: that leg passes in both this worktree and LITE-030's, 42 checks. Nothing filed.Staged in work/LITE-031, 9 files, nothing posted. Orchestrator verification: test/mark/gfm/run.sh PASS at 49 checks, LITE-030's test/mark/run.sh still PASS at 66, and a document carrying all four extensions parses into the same node inventory cmark-gfm -t xml reports for it.
mark/gfm.js; the four parts are mark/gfm-{strike,table,tasklist,autolink}.js, 512 lines together.node.js 1 (the four node types become containers), blocks.js 4 (|/: in reMaybeSpecial, the fast-path opt-out, table_cell inlines), inlines.js 8 (tilde delimiter runs in processEmphasis).* or a backtick inside a bare URL ends it where cmark-gfm swallows it. Every ported spec example still agrees.LITE-031: GFM strikethrough, task lists, autolinks, tables