samemark 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/KNOWN_GAPS.md +84 -0
- package/LICENSE +21 -0
- package/README.md +676 -2
- package/core.d.ts +10 -0
- package/core.js +10 -0
- package/dist/LICENSES.txt +217 -0
- package/dist/core.cjs +7178 -0
- package/dist/stream.cjs +6967 -0
- package/examples/react-chat/StreamMarkdown.jsx +67 -0
- package/index.d.ts +10 -0
- package/index.js +14 -0
- package/lib/api.js +155 -0
- package/lib/probe.js +109 -0
- package/lib/rows.js +47 -0
- package/lib/signature.js +77 -0
- package/lib/types.d.ts +46 -0
- package/lib/verify.js +38 -0
- package/package.json +140 -4
- package/src/block.js +1807 -0
- package/src/inline.js +1597 -0
- package/src/stream.js +178 -0
- package/stream.d.ts +26 -0
- package/stream.js +7 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-10-10)
|
|
4
|
+
|
|
5
|
+
First release.
|
|
6
|
+
|
|
7
|
+
- `samemark`: `parse()` and the `remarkParseFast` unified plugin, same mdast as `mdast-util-from-markdown` with GFM,
|
|
8
|
+
frontmatter and math supported natively, fallback to the real parser for anything else.
|
|
9
|
+
- `samemark/core`: the same without the fallback import.
|
|
10
|
+
- `samemark/stream`: incremental parser for streamed text (LLM chat UIs); after every chunk the tree equals a full parse.
|
|
11
|
+
|
|
12
|
+
Matches mdast-util-from-markdown 2.1.0 + micromark-extension-gfm 3.0.0 + mdast-util-gfm 3.1.0 (plus
|
|
13
|
+
micromark-extension-frontmatter and micromark-extension-math for those plugins). Known gaps: KNOWN_GAPS.md.
|
package/KNOWN_GAPS.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Known gaps
|
|
2
|
+
|
|
3
|
+
samemark is checked against `mdast-util-from-markdown` + `micromark-extension-gfm` + `mdast-util-gfm` (the pinned
|
|
4
|
+
versions in `package.json`) on full trees, positions included. Evidence at the time of writing: 4,780 / 4,780
|
|
5
|
+
corpus READMEs, 652 / 652 CommonMark spec examples, 10,893 / 10,893 held-out non-README markdown files, and
|
|
6
|
+
tens of millions of differential fuzz cases (see `NOTES.md` for the exact CI numbers). This file lists
|
|
7
|
+
every divergence that is known to remain, with a minimal repro for each one. All of them are block-level
|
|
8
|
+
corners around footnote definitions and lists; none was found in any real document. Each repro below is also
|
|
9
|
+
in `bench/known-gaps.json`, so the fuzzer reports (but does not fail on) these shapes.
|
|
10
|
+
|
|
11
|
+
## 1. `spread` of a list item that contains a footnote definition
|
|
12
|
+
|
|
13
|
+
| input | node | micromark | samemark |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| `[^1]:*\n\n\t-` | `listItem.spread` of the `*` item inside the footnote definition | `true` | `false` |
|
|
16
|
+
| `[^1]:-\n\n\t[^1]:` | `listItem.spread` of the `-` item | `true` | `false` |
|
|
17
|
+
| `>- [^1]:\n>` | `listItem.spread` of the item that holds the definition, followed by a `>`-only line | `true` | `false` |
|
|
18
|
+
|
|
19
|
+
Same family with other labels / shapes: `>- [^a]:\n>`, `-\n [^a]:\n\t (` (list `spread` true in micromark) and, without a
|
|
20
|
+
footnote, `>>* 1.\n>>\n>> o` (item `spread` false in micromark, true in samemark: an empty nested item followed by a
|
|
21
|
+
blockquote-prefix-only line and indented content), plus `- - \n\t[x]\t#` (micromark does not treat `[x]` as a task
|
|
22
|
+
check when one tab is shared between two item indents; samemark sets `checked`).
|
|
23
|
+
|
|
24
|
+
Cause: `mdast-util-from-markdown` derives `spread` from `lineEndingBlank` events. Inside a footnote definition the
|
|
25
|
+
footnote prefix events reset its "at marker" state, which changes which blank line counts. samemark computes
|
|
26
|
+
`spread` from blank lines between children and has no rule for this.
|
|
27
|
+
|
|
28
|
+
## 2. Empirical end-position rules (exact on every test input so far, but not derived from micromark's algorithm)
|
|
29
|
+
|
|
30
|
+
micromark places container exits using the `_container` fix in `micromark-util-subtokenize` and the item
|
|
31
|
+
end logic in `mdast-util-from-markdown` (`prepareList`). samemark reproduces the resulting positions with a
|
|
32
|
+
small set of rules found by fuzzing instead of porting those event passes:
|
|
33
|
+
|
|
34
|
+
* a container closed by a new container on the same line, after a blockquote or footnote prefix, exits
|
|
35
|
+
right after that prefix (`>*\n>>`, `>- a\n>>b`, `[^5]:>\n 2.`);
|
|
36
|
+
* an item that is empty or ends in a nested list / blockquote exits there too, depending on the prefix kind
|
|
37
|
+
(`>* *\n>`, `>- >\n>`, `[^1]:*\n 2.`) and a footnote-prefix sibling item ends at the end of the next
|
|
38
|
+
item's prefix (`[^1]:- a\n - b`);
|
|
39
|
+
* a list that ends in two or more blockquote-prefix-only lines is `spread` (`>1.\n>\n>`), a closing new
|
|
40
|
+
container counts one more line, a blank line with its own EOL one less (`>>1.\n>>\n>\n`);
|
|
41
|
+
* unclosed fences / html blocks inside containers (`- ```\n x\n\n> b`, `- ><!--\n -`).
|
|
42
|
+
|
|
43
|
+
Every shape above is in `bench/regressions.json` and passes. Shapes outside what the fuzzer reached (deeply
|
|
44
|
+
nested mixtures of empty items, quotes and footnote definitions ending a document) may still differ in the
|
|
45
|
+
`end` position of a container, never in the content or structure of leaf blocks.
|
|
46
|
+
|
|
47
|
+
## 3. Fenced code / math value with lone-CR line endings
|
|
48
|
+
|
|
49
|
+
`" ~~~\r \n\n"` (an indented fence, a lone `\r` as first line ending, then a whitespace-only line shorter than the
|
|
50
|
+
fence indent): micromark's value regex `/^(\r?\n|\r)|(\r?\n|\r)$/g` sees `\r` followed by an empty line's `\n` as
|
|
51
|
+
one CRLF and strips both, samemark builds the value from lines and keeps one `\n` (`""` vs `"\n"`). Only files that
|
|
52
|
+
use bare `\r` line endings can hit it.
|
|
53
|
+
|
|
54
|
+
## 4. Not a divergence, but different behaviour
|
|
55
|
+
|
|
56
|
+
* Nesting depth: micromark throws `RangeError: Maximum call stack size exceeded` for roughly 10,000 nested
|
|
57
|
+
blockquotes or list items on one line. samemark parses them (`test/depth.test.mjs`).
|
|
58
|
+
* Optional extensions: `remark-frontmatter` (yaml / toml / custom `marker` or `fence` matters, positions and an
|
|
59
|
+
unclosed fence's effect on later containers included) and `remark-math` (`$` / `$$` text math, `$$` flow math,
|
|
60
|
+
`singleDollarTextMath`) are implemented natively (`parse(src, {frontmatter, math})`). Matters with
|
|
61
|
+
`anywhere: true` are not: `frontmatterSupported()` returns false and the plugin must fall back.
|
|
62
|
+
* samemark only implements the stock GFM extension set otherwise. The remark plugin falls back to the real
|
|
63
|
+
`remark-parse` for anything else (extra micromark / mdast extensions, `gfm({singleTilde: false})`, no GFM).
|
|
64
|
+
|
|
65
|
+
## 4. Outside the identity claim, by design (packaging level)
|
|
66
|
+
|
|
67
|
+
* Anything beyond stock GFM (`remark-frontmatter`, `remark-math`, `remark-directive`, MDX, `singleTilde: false`, any
|
|
68
|
+
micromark extension that adds a construct or uses `disable`) is detected and handed to the real parser, so the
|
|
69
|
+
result is micromark's own, at micromark's speed. `strict: true` turns that into an error. See the compatibility
|
|
70
|
+
table in the README.
|
|
71
|
+
* `parse()` and the plugin accept `string`, `Uint8Array` (decoded as UTF-8) and objects with `toString()`. Only
|
|
72
|
+
strings are compared to `fromMarkdown` in the test suite.
|
|
73
|
+
* In browsers a bundler picks the `browser` export of `decode-named-character-reference`, which decodes named
|
|
74
|
+
character references through the DOM instead of a table. micromark does exactly the same in that setting, so
|
|
75
|
+
both parsers agree, but the answer for an unusual reference then depends on the browser. Edge runtimes and Node
|
|
76
|
+
use the table.
|
|
77
|
+
|
|
78
|
+
## 5. Edge inputs checked in the packaging pass (all identical, none found a parser bug)
|
|
79
|
+
|
|
80
|
+
CRLF, lone CR, mixed line endings, BOM (alone, repeated, mid-text), NUL (replaced by U+FFFD) in every construct,
|
|
81
|
+
empty and whitespace-only input, 50k-character lines, nesting 1000 deep, astral characters and combining marks next
|
|
82
|
+
to emphasis markers, lone surrogates, tabs in every construct. The list is `test/edge-cases.mjs`; 10 MB inputs run
|
|
83
|
+
in CI only (`BIG=1`). A new failing input goes in `test/known-gaps.json` (each entry runs as a `todo` test) and in
|
|
84
|
+
a table here.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anzal Abidi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|