@promptctl/rich-js 0.24.0 → 0.25.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.
Files changed (163) hide show
  1. package/README.md +7 -0
  2. package/THIRD-PARTY-NOTICES +29 -1
  3. package/dist/core/anchor.d.ts +5 -0
  4. package/dist/core/anchor.js +11 -4
  5. package/dist/core/animation.d.ts +243 -0
  6. package/dist/core/animation.js +375 -0
  7. package/dist/core/ansi.js +2 -2
  8. package/dist/core/box.d.ts +7 -7
  9. package/dist/core/cell-widths.d.ts +9 -0
  10. package/dist/core/cell-widths.js +140 -0
  11. package/dist/core/cells.d.ts +40 -24
  12. package/dist/core/cells.js +151 -66
  13. package/dist/core/clock.d.ts +2 -2
  14. package/dist/core/clock.js +6 -4
  15. package/dist/core/color.d.ts +27 -10
  16. package/dist/core/color.js +21 -29
  17. package/dist/core/console.d.ts +28 -17
  18. package/dist/core/console.js +48 -43
  19. package/dist/core/easing.d.ts +140 -10
  20. package/dist/core/easing.js +328 -50
  21. package/dist/core/emoji.d.ts +1 -1
  22. package/dist/core/emoji.js +1 -2
  23. package/dist/core/export-html.js +2 -1
  24. package/dist/core/export-lines.js +3 -3
  25. package/dist/core/highlighter.d.ts +9 -8
  26. package/dist/core/highlighter.js +3 -2
  27. package/dist/core/json.js +3 -2
  28. package/dist/core/markup.js +16 -12
  29. package/dist/core/measure.js +3 -3
  30. package/dist/core/memo.d.ts +11 -2
  31. package/dist/core/memo.js +16 -0
  32. package/dist/core/oklch.js +17 -6
  33. package/dist/core/osc8.d.ts +1 -1
  34. package/dist/core/osc8.js +4 -5
  35. package/dist/core/paint.d.ts +2 -1
  36. package/dist/core/paint.js +4 -3
  37. package/dist/core/pattern.d.ts +21 -0
  38. package/dist/core/pattern.js +21 -0
  39. package/dist/core/place.js +2 -1
  40. package/dist/core/pretty.js +11 -12
  41. package/dist/core/protocol.d.ts +136 -21
  42. package/dist/core/protocol.js +203 -16
  43. package/dist/core/render.d.ts +15 -2
  44. package/dist/core/render.js +27 -6
  45. package/dist/core/segment.d.ts +31 -6
  46. package/dist/core/segment.js +68 -53
  47. package/dist/core/spinnerData.d.ts +1 -1
  48. package/dist/core/state.d.ts +53 -0
  49. package/dist/core/state.js +82 -0
  50. package/dist/core/strip.d.ts +11 -13
  51. package/dist/core/strip.js +126 -113
  52. package/dist/core/style.d.ts +47 -14
  53. package/dist/core/style.js +74 -34
  54. package/dist/core/text.d.ts +5 -8
  55. package/dist/core/text.js +133 -133
  56. package/dist/core/timeline.d.ts +109 -0
  57. package/dist/core/timeline.js +180 -0
  58. package/dist/core/tween.d.ts +49 -0
  59. package/dist/core/tween.js +71 -0
  60. package/dist/core/view.d.ts +92 -0
  61. package/dist/core/view.js +83 -0
  62. package/dist/host/app.d.ts +49 -21
  63. package/dist/host/app.js +72 -38
  64. package/dist/host/input.js +3 -4
  65. package/dist/index.d.ts +30 -15
  66. package/dist/index.js +20 -6
  67. package/dist/node/traceback.js +4 -3
  68. package/dist/renderables/change.d.ts +42 -0
  69. package/dist/renderables/change.js +112 -0
  70. package/dist/renderables/columns.d.ts +1 -1
  71. package/dist/renderables/columns.js +3 -3
  72. package/dist/renderables/constrain.js +2 -1
  73. package/dist/renderables/effect.d.ts +155 -92
  74. package/dist/renderables/effect.js +203 -136
  75. package/dist/renderables/effects.d.ts +137 -24
  76. package/dist/renderables/effects.js +276 -113
  77. package/dist/renderables/embed.d.ts +1 -1
  78. package/dist/renderables/embed.js +18 -9
  79. package/dist/renderables/flexStrip.js +2 -1
  80. package/dist/renderables/frames.d.ts +45 -43
  81. package/dist/renderables/frames.js +57 -45
  82. package/dist/renderables/glyph-effect.d.ts +158 -0
  83. package/dist/renderables/glyph-effect.js +237 -0
  84. package/dist/renderables/glyph-effects.d.ts +147 -0
  85. package/dist/renderables/glyph-effects.js +283 -0
  86. package/dist/renderables/group.d.ts +1 -1
  87. package/dist/renderables/group.js +2 -2
  88. package/dist/renderables/html-entities.d.ts +8 -0
  89. package/dist/renderables/html-entities.js +386 -0
  90. package/dist/renderables/layout.d.ts +10 -9
  91. package/dist/renderables/layout.js +42 -35
  92. package/dist/renderables/lifecycle.d.ts +77 -0
  93. package/dist/renderables/lifecycle.js +132 -0
  94. package/dist/renderables/list-view.d.ts +2 -2
  95. package/dist/renderables/list-view.js +11 -8
  96. package/dist/renderables/live.d.ts +36 -21
  97. package/dist/renderables/live.js +89 -42
  98. package/dist/renderables/markdown-parse.d.ts +109 -0
  99. package/dist/renderables/markdown-parse.js +1427 -0
  100. package/dist/renderables/markdown-url.d.ts +19 -0
  101. package/dist/renderables/markdown-url.js +314 -0
  102. package/dist/renderables/markdown.d.ts +5 -7
  103. package/dist/renderables/markdown.js +356 -683
  104. package/dist/renderables/padding.d.ts +7 -20
  105. package/dist/renderables/padding.js +29 -50
  106. package/dist/renderables/panel.d.ts +30 -32
  107. package/dist/renderables/panel.js +65 -109
  108. package/dist/renderables/progress.d.ts +83 -32
  109. package/dist/renderables/progress.js +186 -90
  110. package/dist/renderables/progressBar.d.ts +22 -12
  111. package/dist/renderables/progressBar.js +33 -10
  112. package/dist/renderables/prompt.js +3 -2
  113. package/dist/renderables/python-space.d.ts +13 -0
  114. package/dist/renderables/python-space.js +25 -0
  115. package/dist/renderables/scroll.d.ts +50 -0
  116. package/dist/renderables/scroll.js +106 -0
  117. package/dist/renderables/spinner.d.ts +57 -24
  118. package/dist/renderables/spinner.js +101 -49
  119. package/dist/renderables/status.js +1 -1
  120. package/dist/renderables/syntax.d.ts +10 -9
  121. package/dist/renderables/syntax.js +5 -3
  122. package/dist/renderables/table.d.ts +48 -46
  123. package/dist/renderables/table.js +170 -208
  124. package/dist/renderables/traceback.d.ts +3 -3
  125. package/dist/renderables/traceback.js +12 -10
  126. package/dist/renderables/tree.d.ts +28 -25
  127. package/dist/renderables/tree.js +108 -58
  128. package/dist/renderables/viewport.d.ts +77 -38
  129. package/dist/renderables/viewport.js +156 -72
  130. package/dist/template-bindings/animation-funcs.d.ts +78 -9
  131. package/dist/template-bindings/animation-funcs.js +132 -14
  132. package/dist/template-bindings/index.d.ts +5 -5
  133. package/dist/template-bindings/index.js +7 -6
  134. package/dist/themes/ramp.d.ts +62 -4
  135. package/dist/themes/ramp.js +82 -4
  136. package/dist/themes/registry.js +5 -7
  137. package/dist/widgets/button.js +3 -2
  138. package/dist/widgets/checkbox.js +4 -3
  139. package/dist/widgets/dropdown.d.ts +3 -1
  140. package/dist/widgets/dropdown.js +20 -15
  141. package/dist/widgets/event-router.js +4 -2
  142. package/dist/widgets/focus-manager.d.ts +23 -14
  143. package/dist/widgets/focus-manager.js +34 -33
  144. package/dist/widgets/hit.d.ts +6 -0
  145. package/dist/widgets/hit.js +8 -1
  146. package/dist/widgets/index.d.ts +1 -1
  147. package/dist/widgets/observable.d.ts +23 -0
  148. package/dist/widgets/observable.js +43 -0
  149. package/dist/widgets/slider.d.ts +1 -1
  150. package/dist/widgets/slider.js +12 -3
  151. package/dist/widgets/static-item.d.ts +1 -1
  152. package/dist/widgets/static-item.js +6 -7
  153. package/dist/widgets/text-input.d.ts +53 -47
  154. package/dist/widgets/text-input.js +456 -399
  155. package/dist/widgets/themed-widget.js +2 -1
  156. package/dist/widgets/toggle.js +4 -3
  157. package/dist/widgets/types.d.ts +10 -4
  158. package/dist/widgets/types.js +8 -2
  159. package/dist/widgets/widget-app.d.ts +32 -6
  160. package/dist/widgets/widget-app.js +74 -27
  161. package/dist/widgets/widget-base.d.ts +2 -2
  162. package/dist/widgets/widget-base.js +29 -21
  163. package/package.json +9 -5
@@ -28,33 +28,41 @@ import { frameRate, systemClock } from "../core/clock.js";
28
28
  import { Console } from "../core/console.js";
29
29
  import { Segment } from "../core/segment.js";
30
30
  import { FinalFramePainter, SurfacePainter } from "../core/paint.js";
31
- import { fitHeight } from "../core/protocol.js";
32
- // [LAW:parse-dont-validate] The one shape Live holds: a renderable becomes
33
- // the view that answers it at every t, where it is given, so no frame asks
34
- // which it was.
35
- const viewOf = (view) => view === undefined || typeof view === "function" ? view : () => view;
31
+ import { fitHeight, render } from "../core/protocol.js";
32
+ import { Timeline } from "../core/timeline.js";
33
+ import { drawView, frameTime, hostView, undrawn } from "../core/view.js";
34
+ import { State } from "../core/state.js";
35
+ // Nothing: what a Live made with no view draws until `update` gives it one.
36
+ const NOTHING = { render: () => [] };
36
37
  export class Live {
37
38
  _view;
38
39
  _console;
39
40
  _rate;
40
41
  _clock;
42
+ // The clock moment this host began: what its default timeline plays from,
43
+ // and what a renderable view is drawn for the time since (`HostTime`).
44
+ _epoch;
45
+ _timeline;
41
46
  _autoRefresh;
42
47
  _transient;
43
48
  _verticalOverflow;
44
49
  _painter;
45
- // The one wait for the next auto-refresh frame, armed after each frame.
46
- _waking;
50
+ // The one wait for the next auto-refresh frame, armed after each frame, and
51
+ // the clock moment it is due at.
52
+ _waking = new State(undefined);
47
53
  // [LAW:one-source-of-truth] The console's live region, held from `start()`
48
54
  // to the hand-back — which is what "started" means, so there is no separate
49
55
  // flag to disagree with it.
50
- _held;
56
+ _held = new State(null);
51
57
  constructor(view, options) {
52
- this._view = viewOf(view);
58
+ this._view = new State(hostView(view ?? NOTHING));
53
59
  this._console = options?.console ?? new Console();
54
60
  // [LAW:parse-dont-validate] Parsed whether or not it auto-refreshes, so a
55
61
  // rate that could never tick is refused where it is given.
56
62
  this._rate = frameRate(options?.refreshPerSecond ?? 4);
57
63
  this._clock = options?.clock ?? systemClock();
64
+ this._epoch = this._clock.now();
65
+ this._timeline = new State(options?.timeline ?? Timeline.play(this._epoch));
58
66
  this._autoRefresh = options?.autoRefresh !== false;
59
67
  this._transient = options?.transient ?? false;
60
68
  this._verticalOverflow = options?.verticalOverflow ?? "ellipsis";
@@ -65,7 +73,6 @@ export class Live {
65
73
  this._painter = this._console.isInteractive
66
74
  ? new SurfacePainter(options?.altScreen ? "alternate" : "inline", (bytes) => void this._console.file.write(bytes))
67
75
  : new FinalFramePainter((frame) => this._console.print(linesOf(frame)));
68
- this._held = null;
69
76
  }
70
77
  /**
71
78
  * The console to print through while this Live runs: what it prints lands
@@ -74,20 +81,45 @@ export class Live {
74
81
  get console() {
75
82
  return this._console;
76
83
  }
84
+ /** The clock the auto-refresh waits on: where the host time a `Timeline` operation takes is read. */
85
+ get clock() {
86
+ return this._clock;
87
+ }
88
+ /** The map from the clock to the time the view is drawn for. */
89
+ get timeline() {
90
+ return this._timeline.get();
91
+ }
92
+ /** The time a frame drawn now is drawn for: the clock's now, through the timeline. */
93
+ get frameTime() {
94
+ return frameTime(this._time());
95
+ }
96
+ _time() {
97
+ return { now: this._clock.now(), epoch: this._epoch, timeline: this._timeline.get() };
98
+ }
99
+ /**
100
+ * Replace the timeline and draw the frame for the time it now maps the
101
+ * clock's now to, so a seek shows where it sought, once. Paused, the frame
102
+ * then holds — the auto-refresh waits on nothing until the timeline plays
103
+ * again — while `refresh()` and `update(…, { refresh: true })` still draw.
104
+ */
105
+ set timeline(timeline) {
106
+ this._timeline.set(timeline);
107
+ this.refresh();
108
+ }
77
109
  start() {
78
- if (this._held !== null)
110
+ if (this._held.get() !== null)
79
111
  return;
80
112
  // Claimed before a byte is written, so a console another Live is running
81
113
  // on refuses this one with the terminal untouched.
82
114
  const held = this._console.claimLiveRegion({ around: (text) => this._stepAround(text) });
83
- this._held = held;
115
+ this._held.set(held);
84
116
  this._painter.take();
85
117
  // Nothing is drawn yet, so nothing has said when it changes: the first
86
118
  // auto-refresh frame comes at the rate, from now.
87
- this._wake(held, { t: this._clock.now(), nextChange: Number.POSITIVE_INFINITY });
119
+ this._wake(held, undrawn(this._clock.now()));
88
120
  }
89
121
  stop() {
90
- const held = this._held;
122
+ const held = this._held.get();
91
123
  if (held === null)
92
124
  return;
93
125
  // [LAW:no-silent-failure] A final frame that throws still propagates, and
@@ -106,17 +138,29 @@ export class Live {
106
138
  }
107
139
  update(view, options) {
108
140
  if (view !== undefined) {
109
- this._view = viewOf(view);
141
+ this._view.set(hostView(view));
110
142
  }
111
143
  if (options?.refresh) {
112
144
  this.refresh();
145
+ return;
146
+ }
147
+ const held = this._held.get();
148
+ if (view !== undefined && held !== null) {
149
+ // The last wake was armed for what the old view said; a new view has
150
+ // said nothing yet, so the auto-refresh draws it by the rate's next
151
+ // frame from now — sooner if the wake already armed is, and never
152
+ // later, so updates faster than the rate do not put the frame off.
153
+ const now = this._clock.now();
154
+ const waking = this._waking.get();
155
+ if (waking === undefined || waking.at > now + this._rate.interval)
156
+ this._wake(held, undrawn(now));
113
157
  }
114
158
  }
115
159
  refresh() {
116
160
  // A frame is drawn only while this Live holds the terminal, as in Rich:
117
161
  // before `start()` or after the hand-back it would land on a screen that
118
162
  // belongs to someone else — the main buffer, under the user's own output.
119
- const held = this._held;
163
+ const held = this._held.get();
120
164
  if (held === null)
121
165
  return;
122
166
  // [LAW:no-ambient-temporal-coupling] The frame says when what it shows
@@ -126,30 +170,33 @@ export class Live {
126
170
  // frame not drawn has said nothing.
127
171
  let said;
128
172
  this._paint(() => {
129
- const { t, lines } = this._frame();
130
- said = { t, nextChange: lines.reduce((soonest, row) => Math.min(soonest, Segment.nextChange(row)), Number.POSITIVE_INFINITY) };
131
- return lines;
173
+ const drawn = this._frame();
174
+ said = drawn;
175
+ return drawn.lines;
132
176
  });
133
- this._wake(held, said ?? { t: this._clock.now(), nextChange: Number.POSITIVE_INFINITY });
134
- }
135
- // Arm the one wait for the next auto-refresh frame while `held`: at the
136
- // frame's `nextChange` when that is before the rate's next frame, else at
137
- // the rate — both measured from the frame's own `t`, never from a second
138
- // reading of the clock, so the rate does not stretch by what a frame cost
139
- // to draw, and a change that fell due while it was drawn is drawn at once
140
- // (`Clock.at` fires now for a time already past). Content that changes
141
- // every frame answers `t` itself, and is drawn at the rate.
177
+ this._wake(held, said ?? undrawn(this._clock.now()));
178
+ }
179
+ // Arm the one wait for the next auto-refresh frame while `held`, from what
180
+ // the frame says: at its `nextChange` when it holds until a moment sooner
181
+ // than the rate, and at the rate otherwise — every view is drawn from state
182
+ // that may change without saying so, which the auto-refresh polls, as
183
+ // Rich's does, a paused timeline's included. Every moment is measured from the
184
+ // frame's own `t`, never from a second reading of the clock, so the rate
185
+ // does not stretch by what a frame cost to draw, and a change that fell
186
+ // due while it was drawn is drawn at once (`Clock.at` fires now for a time
187
+ // already past).
142
188
  _wake(held, { t, nextChange }) {
143
- this._waking?.();
144
- this._waking = undefined;
189
+ this._waking.get()?.stop();
190
+ this._waking.set(undefined);
191
+ const rate = t + this._rate.interval;
192
+ const at = nextChange <= t ? rate : Math.min(nextChange, rate);
145
193
  if (!this._autoRefresh)
146
194
  return;
147
- const at = Math.min(t + this._rate.interval, nextChange > t ? nextChange : Number.POSITIVE_INFINITY);
148
195
  // No caller is on the stack to run `stop()` for a frame that throws
149
196
  // here, and in Node the throw ends the process — so the terminal is
150
197
  // handed back first, and the error then goes on to wherever an uncaught
151
198
  // one goes.
152
- this._waking = this._clock.at(at, () => {
199
+ const stop = this._clock.at(at, () => {
153
200
  try {
154
201
  this.refresh();
155
202
  }
@@ -158,15 +205,13 @@ export class Live {
158
205
  throw error;
159
206
  }
160
207
  });
208
+ this._waking.set({ at, stop });
161
209
  }
162
- // The frame at the clock's now, with that time: the one the view was handed, and the one the next wake is measured from.
210
+ // The frame at the clock's now, drawn for the time the timeline maps it to,
211
+ // with when it next changes on the clock: what the next wake is measured from.
163
212
  _frame() {
164
213
  // [LAW:effects-at-boundaries] One read of the clock a frame, handed to
165
214
  // the view as the frame's time.
166
- const t = this._clock.now();
167
- if (!this._view)
168
- return { t, lines: [] };
169
- const renderable = this._view(t);
170
215
  // [LAW:dataflow-not-control-flow] Both modes render under the terminal's
171
216
  // rows and differ only in what those rows are: the alternate screen is a
172
217
  // region the frame stands in, and an inline frame keeps its natural height
@@ -174,8 +219,10 @@ export class Live {
174
219
  // back — its overflow policy, then `fitHeight`, which pads only a region.
175
220
  const options = this._console.options;
176
221
  const height = this._painter.height(options.height.rows);
177
- const lines = Segment.splitLines(renderable.render({ ...options, height }));
178
- return { t, lines: fitHeight(this._overflow(lines, height.rows), height) };
222
+ return drawView(this._view.get(), this._time(), this, { ...options, height }, (renderable, drawn) => {
223
+ const lines = Segment.splitLines(render(renderable, drawn));
224
+ return fitHeight(this._overflow(lines, height.rows), height);
225
+ });
179
226
  }
180
227
  // What the console writes goes where the frame was, and the frame is painted
181
228
  // again under it, as Rich's render hook does — in the bytes the console
@@ -210,9 +257,9 @@ export class Live {
210
257
  // ran or a frame threw with no caller to run it.
211
258
  _release(held) {
212
259
  held();
213
- this._held = null;
214
- this._waking?.();
215
- this._waking = undefined;
260
+ this._held.set(null);
261
+ this._waking.get()?.stop();
262
+ this._waking.set(undefined);
216
263
  this._painter.handBack();
217
264
  }
218
265
  }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Markdown's parse, with no dependency: a source read into blocks, then the
3
+ * text of each block read into inlines — the two passes markdown-it, Rich's
4
+ * parser, makes. Nothing here reads a `RenderOptions`, so a `Markdown` parses
5
+ * its source once, when it is made, as Rich's does, and every render after
6
+ * only walks the tokens.
7
+ *
8
+ * Block structure is read as CommonMark reads it: a blockquote and a list
9
+ * item are both containers, their lines tokenized as Markdown of their own
10
+ * once the container's marker or indentation is cut off. A table, which
11
+ * CommonMark has none of, and an HTML block are read as markdown-it reads
12
+ * them.
13
+ */
14
+ /** Where a table column's cells sit, from the colons on its delimiter cell. None is GFM's no alignment, which Rich leaves to its column: left. */
15
+ export type CellAlign = "left" | "center" | "right" | undefined;
16
+ interface TableColumn<Text> {
17
+ readonly header: Text;
18
+ readonly align: CellAlign;
19
+ }
20
+ /** A heading's level: an ATX heading's count of `#`s, or 1 and 2 for a setext heading's `=` and `-`. */
21
+ export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
22
+ /**
23
+ * A block, its text as `Text`: the source's own text after the block pass,
24
+ * and that text read into inlines after the inline pass, which is what
25
+ * `parseMarkdown` hands back. `Mark` is what the block pass keeps besides:
26
+ * none, once the inline pass has dropped its marks.
27
+ */
28
+ export type MdToken<Text = readonly Inline[], Mark = never> = Readonly<{
29
+ type: "heading";
30
+ level: HeadingLevel;
31
+ text: Text;
32
+ } | {
33
+ type: "paragraph";
34
+ text: Text;
35
+ } | {
36
+ type: "code_block";
37
+ code: string;
38
+ } | {
39
+ type: "hr";
40
+ }
41
+ /** `start` is an ordered list's first number, as its source writes it; a bullet list has none. Each item is its blocks. */
42
+ | {
43
+ type: "list";
44
+ start: number | undefined;
45
+ items: readonly (readonly MdToken<Text, Mark>[])[];
46
+ } | {
47
+ type: "blockquote";
48
+ children: readonly MdToken<Text, Mark>[];
49
+ }
50
+ /** Each row holds one cell per column: a short row filled out with empty cells, a long one cut. */
51
+ | {
52
+ type: "table";
53
+ columns: readonly TableColumn<Text>[];
54
+ rows: readonly (readonly Text[])[];
55
+ }
56
+ /** Kept, though nothing draws it, as Rich exits it like any other block. */
57
+ | {
58
+ type: "html_block";
59
+ } | Mark>;
60
+ /** The element markdown-it makes of a pair of delimiters. */
61
+ type EmphasisTag = "em" | "strong" | "s";
62
+ /**
63
+ * CommonMark's inlines, as one block's text reads: a code span, emphasis or a
64
+ * link holding inlines of its own, an autolink, an image, inline HTML, a line
65
+ * ending, and text — a backslash escape and a character reference already the
66
+ * characters they stand for. Emphasis is named by the element markdown-it
67
+ * makes of it, GFM's strikethrough `s` among them.
68
+ */
69
+ export type Inline = Readonly<{
70
+ kind: "text";
71
+ text: string;
72
+ } | {
73
+ kind: "code";
74
+ code: string;
75
+ } | {
76
+ kind: "emphasis";
77
+ tag: EmphasisTag;
78
+ children: readonly Inline[];
79
+ } | {
80
+ kind: "link";
81
+ children: readonly Inline[];
82
+ url: string;
83
+ }
84
+ /** `text` is the URL as written, normalized as markdown-it shows it, never read as Markdown. */
85
+ | {
86
+ kind: "autolink";
87
+ text: string;
88
+ url: string;
89
+ }
90
+ /** `alt` is as written, never read as Markdown. */
91
+ | {
92
+ kind: "image";
93
+ alt: string;
94
+ src: string;
95
+ }
96
+ /** `content` is the tag as written, markdown-it's `html_inline` content. */
97
+ | {
98
+ kind: "html";
99
+ content: string;
100
+ }
101
+ /** markdown-it's `softbreak` and `hardbreak`: tokens of their own, never joined to the text beside them. */
102
+ | {
103
+ kind: "softbreak";
104
+ } | {
105
+ kind: "hardbreak";
106
+ }>;
107
+ /** `source` read as Markdown: its blocks, and the text in each read into inlines. A line ends at `\r\n`, `\r` or `\n`, as markdown-it normalizes them. */
108
+ export declare function parseMarkdown(source: string): MdToken[];
109
+ export {};