@byteatatime/mdstream 0.0.2 → 0.0.3
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/package.json +1 -1
- package/src/index.ts +47 -9
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -3,6 +3,28 @@ import remarkParse from "remark-parse";
|
|
|
3
3
|
import type { Node, Root } from "mdast";
|
|
4
4
|
import type { PluggableList } from "unified";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* A function that fixes up incomplete markdown syntax so it renders correctly.
|
|
8
|
+
* Applied only to the pending (active) block — finalized blocks are never mended.
|
|
9
|
+
*
|
|
10
|
+
* The `remend` package is the recommended choice:
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import remend from "remend";
|
|
15
|
+
* const parser = createStreamingParser({ mend: remend });
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @example With options:
|
|
19
|
+
* ```ts
|
|
20
|
+
* import remend from "remend";
|
|
21
|
+
* const parser = createStreamingParser({
|
|
22
|
+
* mend: (source) => remend(source, { links: false }),
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
type MendFunction = (source: string) => string;
|
|
27
|
+
|
|
6
28
|
type Block = {
|
|
7
29
|
readonly ast: Node;
|
|
8
30
|
readonly start: number;
|
|
@@ -18,10 +40,21 @@ type ParserState = {
|
|
|
18
40
|
|
|
19
41
|
type ParserOptions = {
|
|
20
42
|
plugins?: PluggableList;
|
|
43
|
+
/**
|
|
44
|
+
* A mending function that fixes incomplete markdown syntax in the active block.
|
|
45
|
+
* Only applied to the pending block — finalized blocks are never touched.
|
|
46
|
+
*
|
|
47
|
+
* The `remend` package is the recommended mending function:
|
|
48
|
+
* ```ts
|
|
49
|
+
* import remend from "remend";
|
|
50
|
+
* const parser = createStreamingParser({ mend: remend });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
mend?: MendFunction;
|
|
21
54
|
};
|
|
22
55
|
|
|
23
56
|
const createStreamingParser = (options: ParserOptions = {}) => {
|
|
24
|
-
const { plugins = [] } = options;
|
|
57
|
+
const { plugins = [], mend } = options;
|
|
25
58
|
const state: ParserState = {
|
|
26
59
|
buffer: "",
|
|
27
60
|
finalizedBlocks: [],
|
|
@@ -60,10 +93,12 @@ const createStreamingParser = (options: ParserOptions = {}) => {
|
|
|
60
93
|
const secondToLastPosition = secondToLastNode?.position;
|
|
61
94
|
const lastPosition = lastNode?.position;
|
|
62
95
|
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
96
|
+
if (
|
|
97
|
+
secondToLastNode?.type === "paragraph" &&
|
|
98
|
+
secondToLastPosition &&
|
|
99
|
+
lastPosition &&
|
|
100
|
+
secondToLastPosition.end.offset === lastPosition.start.offset
|
|
101
|
+
) {
|
|
67
102
|
finalizableNodes = finalizableNodes.slice(0, -1);
|
|
68
103
|
}
|
|
69
104
|
}
|
|
@@ -101,7 +136,9 @@ const createStreamingParser = (options: ParserOptions = {}) => {
|
|
|
101
136
|
const getPendingBlock = (): Block | undefined => {
|
|
102
137
|
if (!state.buffer) return undefined;
|
|
103
138
|
|
|
104
|
-
const
|
|
139
|
+
const mendedBuffer = mend ? mend(state.buffer) : state.buffer;
|
|
140
|
+
|
|
141
|
+
const ast = processor.parse(mendedBuffer) as Root;
|
|
105
142
|
const tree = processor.runSync(ast) as Root;
|
|
106
143
|
const children = tree.children;
|
|
107
144
|
|
|
@@ -113,13 +150,14 @@ const createStreamingParser = (options: ParserOptions = {}) => {
|
|
|
113
150
|
if (!firstNode || !position) return undefined;
|
|
114
151
|
|
|
115
152
|
const start = state.totalOffset + position.start.offset!;
|
|
116
|
-
|
|
153
|
+
// end offset is relative to the original (unmended) buffer length
|
|
154
|
+
const end = state.totalOffset + state.buffer.length;
|
|
117
155
|
|
|
118
156
|
return {
|
|
119
157
|
ast: firstNode,
|
|
120
158
|
start,
|
|
121
159
|
end,
|
|
122
|
-
source:
|
|
160
|
+
source: mendedBuffer.slice(position.start.offset!, position.end.offset!),
|
|
123
161
|
};
|
|
124
162
|
};
|
|
125
163
|
|
|
@@ -135,4 +173,4 @@ const createStreamingParser = (options: ParserOptions = {}) => {
|
|
|
135
173
|
};
|
|
136
174
|
|
|
137
175
|
export { createStreamingParser };
|
|
138
|
-
export type { Block, ParserOptions };
|
|
176
|
+
export type { Block, ParserOptions, MendFunction };
|