@yaebal/rich 0.0.1 → 0.0.2
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/README.md +104 -30
- package/lib/blocks.d.ts +93 -32
- package/lib/blocks.d.ts.map +1 -1
- package/lib/blocks.js +227 -71
- package/lib/blocks.js.map +1 -1
- package/lib/blocks.test.d.ts +2 -0
- package/lib/blocks.test.d.ts.map +1 -0
- package/lib/blocks.test.js +142 -0
- package/lib/blocks.test.js.map +1 -0
- package/lib/document.d.ts +28 -0
- package/lib/document.d.ts.map +1 -0
- package/lib/document.js +46 -0
- package/lib/document.js.map +1 -0
- package/lib/draft.d.ts +46 -9
- package/lib/draft.d.ts.map +1 -1
- package/lib/draft.js +115 -19
- package/lib/draft.js.map +1 -1
- package/lib/draft.test.d.ts +2 -0
- package/lib/draft.test.d.ts.map +1 -0
- package/lib/draft.test.js +122 -0
- package/lib/draft.test.js.map +1 -0
- package/lib/escape.d.ts +8 -0
- package/lib/escape.d.ts.map +1 -1
- package/lib/escape.js +17 -0
- package/lib/escape.js.map +1 -1
- package/lib/escape.test.d.ts +2 -0
- package/lib/escape.test.d.ts.map +1 -0
- package/lib/escape.test.js +28 -0
- package/lib/escape.test.js.map +1 -0
- package/lib/guards.test.d.ts +2 -0
- package/lib/guards.test.d.ts.map +1 -0
- package/lib/guards.test.js +85 -0
- package/lib/guards.test.js.map +1 -0
- package/lib/index.d.ts +18 -9
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +17 -8
- package/lib/index.js.map +1 -1
- package/lib/index.test.js +73 -103
- package/lib/index.test.js.map +1 -1
- package/lib/inline.d.ts +48 -59
- package/lib/inline.d.ts.map +1 -1
- package/lib/inline.js +87 -82
- package/lib/inline.js.map +1 -1
- package/lib/inline.test.d.ts +2 -0
- package/lib/inline.test.d.ts.map +1 -0
- package/lib/inline.test.js +84 -0
- package/lib/inline.test.js.map +1 -0
- package/lib/node.d.ts +25 -0
- package/lib/node.d.ts.map +1 -0
- package/lib/node.js +21 -0
- package/lib/node.js.map +1 -0
- package/lib/plaintext.test.d.ts +2 -0
- package/lib/plaintext.test.d.ts.map +1 -0
- package/lib/plaintext.test.js +100 -0
- package/lib/plaintext.test.js.map +1 -0
- package/lib/render.d.ts +17 -0
- package/lib/render.d.ts.map +1 -0
- package/lib/render.js +30 -0
- package/lib/render.js.map +1 -0
- package/lib/send.d.ts +6 -3
- package/lib/send.d.ts.map +1 -1
- package/lib/send.js +12 -3
- package/lib/send.js.map +1 -1
- package/lib/template.d.ts +46 -0
- package/lib/template.d.ts.map +1 -0
- package/lib/template.js +82 -0
- package/lib/template.js.map +1 -0
- package/lib/template.test.d.ts +2 -0
- package/lib/template.test.d.ts.map +1 -0
- package/lib/template.test.js +78 -0
- package/lib/template.test.js.map +1 -0
- package/package.json +6 -5
- package/src/blocks.test.ts +233 -0
- package/src/blocks.ts +304 -86
- package/src/document.ts +51 -0
- package/src/draft.test.ts +167 -0
- package/src/draft.ts +148 -21
- package/src/escape.test.ts +38 -0
- package/src/escape.ts +20 -0
- package/src/guards.test.ts +138 -0
- package/src/index.test.ts +79 -140
- package/src/index.ts +26 -11
- package/src/inline.test.ts +125 -0
- package/src/inline.ts +131 -97
- package/src/node.ts +43 -0
- package/src/plaintext.test.ts +141 -0
- package/src/render.ts +54 -0
- package/src/send.ts +17 -10
- package/src/template.test.ts +100 -0
- package/src/template.ts +115 -0
- package/lib/message.d.ts +0 -26
- package/lib/message.d.ts.map +0 -1
- package/lib/message.js +0 -31
- package/lib/message.js.map +0 -1
- package/src/message.ts +0 -45
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @yaebal/rich
|
|
2
2
|
|
|
3
|
-
`sendRichMessage` / `sendRichMessageDraft` — telegram's block-tree message format.
|
|
3
|
+
`sendRichMessage` / `sendRichMessageDraft` — telegram's block-tree message format. one dual-dialect builder set, a draft/streaming session that owns the 30s ttl, and full read-side coverage (type guards + plain-text flattening) of everything telegram can hand back on `message.rich_message`.
|
|
4
4
|
|
|
5
5
|
unlike classic `parse_mode`/entities (see [`@yaebal/fmt`](https://www.npmjs.com/package/@yaebal/fmt)), a rich message isn't a flat `{ text, entities }` pair — it's a document: paragraphs, headings, tables, lists, collages, slideshows, block quotes, a collapsible `<details>`, even a `<tg-thinking>` placeholder for streaming an in-progress answer. you write extended html (or markdown), telegram parses it server-side into a `RichMessage.blocks` tree, and that same tree is what you read back.
|
|
6
6
|
|
|
@@ -10,54 +10,109 @@ unlike classic `parse_mode`/entities (see [`@yaebal/fmt`](https://www.npmjs.com/
|
|
|
10
10
|
pnpm add @yaebal/rich
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## one builder, two dialects
|
|
14
|
+
|
|
15
|
+
telegram accepts a rich message as either `InputRichMessage.html` or `.markdown`. most rich-message libraries pick one dialect to build for and bolt the other on as a parallel, hand-duplicated set of functions. `@yaebal/rich` doesn't: every builder — `bold`, `paragraph`, `table`, `list`, all ~40 of them — returns a `RichNode` that doesn't know its own output format yet. it renders itself only when it lands inside a template:
|
|
14
16
|
|
|
15
17
|
```ts
|
|
16
|
-
import {
|
|
18
|
+
import { html, md, heading, paragraph, bold, link, sendRichMessage } from "@yaebal/rich";
|
|
17
19
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
+
const title = "release notes";
|
|
21
|
+
const body = [
|
|
22
|
+
heading(1, title),
|
|
20
23
|
paragraph("yaebal ", bold("0.1"), " is out — see ", link("https://yaeb.al", "the docs"), "."),
|
|
21
|
-
]
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
await sendRichMessage(ctx.api, ctx.chat.id, html(body)); // <h1>…</h1><p>…</p>
|
|
27
|
+
await sendRichMessage(ctx.api, ctx.chat.id, md(body)); // # …\n\n…
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
there is no `md.bold`/`md.paragraph` shadow api to learn, nothing to keep in sync, and nothing that silently drifts between dialects — `bold(...)` is `bold(...)` everywhere. `html`/`md` are tagged templates first:
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
```ts
|
|
33
|
+
const doc = html`
|
|
34
|
+
${heading(1, title)}
|
|
35
|
+
|
|
36
|
+
${paragraph("yaebal ", bold("0.1"), " is out — see ", link("https://yaeb.al", "the docs"), ".")}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
await sendRichMessage(ctx.api, ctx.chat.id, doc);
|
|
24
40
|
```
|
|
25
41
|
|
|
26
|
-
|
|
42
|
+
literal template text passes through unchanged; only `${…}` interpolation is touched:
|
|
43
|
+
|
|
44
|
+
| interpolation | what happens |
|
|
45
|
+
|:----------------------------------|:-----------------------------------------------------------------|
|
|
46
|
+
| `${string}` / `${number}` / `${bigint}` | dialect-escaped — renders literally, can't inject formatting |
|
|
47
|
+
| `${builderNode}` | rendered into the template's dialect |
|
|
48
|
+
| `${anotherDocument}` | inlined as-is if dialects match, throws `RichError` if they don't |
|
|
49
|
+
| `${array}` | each item rendered and concatenated |
|
|
50
|
+
| `${null \| undefined \| false}` | empty string — so `cond && bold("x")` composes cleanly |
|
|
51
|
+
|
|
52
|
+
multi-line templates are **dedented** (common leading indentation stripped) so you can write at your code's natural indent level. `html`/`md` also accept a plain string (passed through as-is, no escaping/dedent — for already-formatted content) or an array of blocks (each rendered and, for markdown, blank-line-joined — the form to reach for when composing from data instead of prose):
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
html([heading(1, title), list(items.map((i) => paragraph(i.text)))]);
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`document(blocks, { dialect, rtl, skipEntityDetection })` is the options-object equivalent of `html(blocks)`/`md(blocks)`, for when the dialect is a runtime variable rather than a call-site choice.
|
|
59
|
+
|
|
60
|
+
### `RichDocument` — the sendable result
|
|
61
|
+
|
|
62
|
+
`html`/`md`/`document()` all return a `RichDocument`: a rendered string plus the `InputRichMessage` flags, settable fluently.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const doc = html`${paragraph("right-to-left, no auto-linking")}`
|
|
66
|
+
.rtl()
|
|
67
|
+
.noEntityDetection();
|
|
68
|
+
|
|
69
|
+
await sendRichMessage(ctx.api, ctx.chat.id, doc);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`sendRichMessage`/`sendRichMessageDraft`/`RichMessageDraft` all accept a `RichDocument`, a raw `InputRichMessage`, or a plain html string interchangeably — `toJSON()` also delegates to `toInputRichMessage()`, so a `RichDocument` serializes correctly even nested inside a hand-built payload.
|
|
73
|
+
|
|
74
|
+
### install the plugin for `ctx.send`-flavored ergonomics
|
|
27
75
|
|
|
28
76
|
```ts
|
|
29
77
|
import { Bot } from "@yaebal/core";
|
|
30
|
-
import { rich,
|
|
78
|
+
import { rich, html, paragraph } from "@yaebal/rich";
|
|
31
79
|
|
|
32
80
|
const bot = new Bot(token)
|
|
33
81
|
.install(rich())
|
|
34
|
-
.command("hi", (ctx) => ctx.sendRichMessage(
|
|
82
|
+
.command("hi", (ctx) => ctx.sendRichMessage(html`${paragraph("hello!")}`));
|
|
35
83
|
```
|
|
36
84
|
|
|
37
85
|
## streaming a draft
|
|
38
86
|
|
|
39
87
|
`sendRichMessageDraft` streams a partial answer to a private chat — but the draft is **ephemeral**: telegram drops it 30 seconds after the last push, and it never becomes a real message on its own. `RichMessageDraft` owns that lifecycle: it re-pushes the latest draft on a timer so a slow generator doesn't lose it, and it refuses to push after you close it.
|
|
40
88
|
|
|
89
|
+
two ways to grow a draft: `rewrite()` replaces the whole thing — right for a token stream, where every chunk is a longer version of the *same* paragraph. `write()` appends to it (plain string concatenation) — right for tacking on a block after content that's already there, without re-supplying it.
|
|
90
|
+
|
|
41
91
|
```ts
|
|
42
|
-
import { thinking,
|
|
92
|
+
import { thinking, html, paragraph, divider, footer } from "@yaebal/rich";
|
|
43
93
|
|
|
44
94
|
bot.command("ask", async (ctx) => {
|
|
45
95
|
const draft = ctx.richMessageDraft(1); // draft_id, non-zero, per-message
|
|
46
96
|
|
|
47
|
-
await draft.
|
|
97
|
+
await draft.rewrite(html`${thinking("thinking…")}`); // draft-only block, see below
|
|
48
98
|
|
|
49
99
|
let text = "";
|
|
50
100
|
for await (const chunk of streamAnswer(ctx.text)) {
|
|
51
101
|
text += chunk;
|
|
52
|
-
await draft.
|
|
102
|
+
await draft.rewrite(html`${paragraph(text)}`);
|
|
53
103
|
}
|
|
54
104
|
|
|
55
|
-
|
|
56
|
-
|
|
105
|
+
await draft.write(html`${divider()}${footer("streamed")}`); // append, no need to re-supply `text`
|
|
106
|
+
|
|
107
|
+
// required: a draft never persists on its own. send() with no argument
|
|
108
|
+
// auto-assembles from the rewrite()/write() calls above; pass an explicit
|
|
109
|
+
// override (as here) when the persisted message should differ from the last
|
|
110
|
+
// draft snapshot.
|
|
111
|
+
await draft.send(html`${paragraph(text.trim())}${divider()}${footer("streamed")}`);
|
|
57
112
|
});
|
|
58
113
|
```
|
|
59
114
|
|
|
60
|
-
call `draft.cancel()` instead of `
|
|
115
|
+
call `draft.cancel()` instead of `send()` to abandon a draft without persisting anything (it expires within 30s regardless).
|
|
61
116
|
|
|
62
117
|
## reading
|
|
63
118
|
|
|
@@ -76,31 +131,50 @@ bot.on("message:rich_message", (ctx) => {
|
|
|
76
131
|
|
|
77
132
|
every one of telegram's ~50 `Rich*` types is covered on both sides:
|
|
78
133
|
|
|
79
|
-
- **write** — a builder function (or documented auto-detection) for every block and inline mark.
|
|
134
|
+
- **write** — a builder function (or documented auto-detection) for every block and inline mark, in both dialects at once.
|
|
80
135
|
- **read** — an `isX` type guard and a plain-text flattening branch for every block and inline mark.
|
|
81
136
|
|
|
82
|
-
most tags are **confirmed** directly from telegram's schema (`<p>`, `<h1>`–`<h6>`, `<pre><code>`, `<hr/>`, `<footer>`, `<blockquote>`, `<aside>` for pull-quotes, `<details>`/`<summary>`, `<table>`, `<tg-collage>`, `<tg-slideshow>`, `<tg-map>`, `<tg-math-block>`, `<tg-thinking>`, `<img>`/`<video>`/`<audio>`, `<a name>`/`<a href="#…">`, `<cite>`, and the classic `<b>`/`<i>`/`<u>`/`<s>`/`<code>`/`<tg-spoiler>`/`<tg-emoji>`/`tg://user?id=…` set). `url`/`email_address`/`phone_number`/`bank_card_number`/`@mention`/`#hashtag`/`$cashtag`/`/bot_command` need **no explicit tag at all** — telegram auto-detects them from plain text unless you pass
|
|
137
|
+
most tags are **confirmed** directly from telegram's schema (`<p>`, `<h1>`–`<h6>`, `<pre><code>`, `<hr/>`, `<footer>`, `<blockquote>`, `<aside>` for pull-quotes, `<details>`/`<summary>`, `<table>`, `<tg-collage>`, `<tg-slideshow>`, `<tg-map>`, `<tg-math-block>`, `<tg-thinking>`, `<img>`/`<video>`/`<audio>`, `<a name>`/`<a href="#…">`, `<cite>`, and the classic `<b>`/`<i>`/`<u>`/`<s>`/`<code>`/`<tg-spoiler>`/`<tg-emoji>`/`tg://user?id=…` set). `url`/`email_address`/`phone_number`/`bank_card_number`/`@mention`/`#hashtag`/`$cashtag`/`/bot_command` need **no explicit tag at all** — telegram auto-detects them from plain text unless you pass `.noEntityDetection()`.
|
|
83
138
|
|
|
84
|
-
a handful of inline/block features have **no documented tag** in the schema at all (`marked`, `subscript`, `superscript`, `date_time`, inline `mathematical_expression`, `reference`/`reference_link`, table `is_bordered`/`is_striped`). those are implemented as a best-effort guess (standard html5 tags where one exists, a `tg-*`-style name otherwise) and flagged in their doc comments in `inline.ts`/`blocks.ts` — verify against the live "rich message formatting options" docs before relying on the exact spelling in production.
|
|
139
|
+
a handful of inline/block features have **no documented tag** in the schema at all (`marked`, `subscript`, `superscript`, `date_time`, inline `mathematical_expression`, `reference`/`reference_link`, table `is_bordered`/`is_striped`). those are implemented as a best-effort guess (standard html5 tags where one exists, a `tg-*`-style name otherwise) and flagged in their doc comments in `inline.ts`/`blocks.ts` — verify against the live "rich message formatting options" docs before relying on the exact spelling in production. where rich-markdown has no native token for a block at all (`footer`, pull-quote, collage/slideshow, map, `details`, `underline`, `subscript`, `superscript`), the raw html tag is embedded as-is in the markdown output too — telegram's markdown parser accepts embedded html blocks as long as they're blank-line-separated, which the block builders already handle.
|
|
85
140
|
|
|
86
141
|
`sendRichMessage` has no `attach://`/multipart upload path (unlike `sendPhoto`) — media blocks (`image`/`video`/`audio`) take a hosted url, not a local file.
|
|
87
142
|
|
|
143
|
+
### tables and lists carry their full field set
|
|
144
|
+
|
|
145
|
+
`cell()` and `item()` aren't afterthoughts bolted onto a plain-array api — they're first-class `RichNode`s that also carry the options `table()`/`list()` need to do the right thing per dialect:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
table(
|
|
149
|
+
[
|
|
150
|
+
[cell("day", { header: true }), cell("count", { header: true, align: "right" })],
|
|
151
|
+
[cell("mon"), cell(128, { align: "right", colspan: 2 })],
|
|
152
|
+
],
|
|
153
|
+
{ bordered: true, caption: "week" },
|
|
154
|
+
);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
in html this is a full `<table>` with `colspan`/`rowspan`/`valign`/per-cell `<th>`/`<td>`; in markdown it degrades gracefully to a gfm table (structurally header-first, alignment preserved, the rest dropped — gfm has no cell spans). `list()` accepts bare values directly (auto-wrapped in a plain item) or explicit `item()`s for checkboxes and ordered-list numbering overrides (`value`, `type`) — no separate wrapper step required either way.
|
|
158
|
+
|
|
88
159
|
## api
|
|
89
160
|
|
|
90
161
|
| export | what |
|
|
91
162
|
|:-------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------|
|
|
92
|
-
| `html`
|
|
93
|
-
| `
|
|
163
|
+
| `html` / `md` | tagged templates — same builders, either dialect, auto-escaped interpolation |
|
|
164
|
+
| `document` | options-object form: assemble blocks into a `RichDocument` with an explicit dialect |
|
|
165
|
+
| `RichDocument` | the sendable result — `.rtl()`/`.noEntityDetection()`, `toInputRichMessage()`/`toJSON()` |
|
|
166
|
+
| `bold`/`italic`/`underline`/`strikethrough`/`spoiler`/`code`/`marked`/`subscript`/`superscript`/`br` | inline marks |
|
|
94
167
|
| `link`/`textMention`/`anchor`/`anchorLink`/`customEmoji`/`dateTime`/`math`/`reference`/`referenceLink` | inline nodes with data |
|
|
95
|
-
| `paragraph`/`heading`/`preformatted`/`footer`/`divider`/`mathBlock`/`anchorBlock`
|
|
96
|
-
| `blockquote`/`pullquote`/`details`/`list`/`item`/`table`/`cell`
|
|
97
|
-
| `collage`/`slideshow`/`map`/`image`/`video`/`audio`/`thinking` | media & draft-only blocks
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
168
|
+
| `paragraph`/`heading`/`h1`–`h6`/`preformatted`/`footer`/`divider`/`mathBlock`/`anchorBlock` | simple blocks |
|
|
169
|
+
| `blockquote`/`pullquote`/`details`/`list`/`item`/`table`/`cell`/`join` | structural blocks & composition |
|
|
170
|
+
| `collage`/`slideshow`/`map`/`image`/`video`/`audio`/`thinking` | media & draft-only blocks |
|
|
171
|
+
| `RichNode`/`isRichNode`/`makeNode`/`Dialect`/`Level`/`RichError` | the node contract, for writing your own dual-dialect builder |
|
|
172
|
+
| `escapeMarkdown`/`escapeMarkdownUrl` | the raw markdown escapers the builders use internally |
|
|
173
|
+
| `sendRichMessage`/`sendRichMessageDraft` | standalone send functions, no plugin required |
|
|
174
|
+
| `rich()` | plugin: adds `ctx.sendRichMessage`/`ctx.richMessageDraft` |
|
|
175
|
+
| `RichMessageDraft` | the draft/streaming session class — `rewrite()`/`write()`/`send()`/`cancel()` |
|
|
176
|
+
| `isParagraph`, `isTable`, `isCustomEmoji`, … | one type guard per `RichBlock`/`RichText` variant |
|
|
177
|
+
| `richTextToPlainText`/`richBlockToPlainText`/`richMessageToPlainText` | flatten to plain text |
|
|
104
178
|
|
|
105
179
|
plus the full generated type surface (`RichMessage`, `RichBlock`, `RichText`, and every `RichBlock*`/`RichText*` interface) re-exported from `@yaebal/types` for convenience.
|
|
106
180
|
|
package/lib/blocks.d.ts
CHANGED
|
@@ -1,75 +1,128 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RichNode } from "./node.js";
|
|
2
|
+
import { type Insertable } from "./render.js";
|
|
2
3
|
/** a caption + optional credit for a media/collage/slideshow/map block (`RichBlockCaption`). */
|
|
3
4
|
export interface Caption {
|
|
4
5
|
caption?: Insertable;
|
|
5
6
|
/** `RichBlockCaption.credit`, confirmed `<cite>`. */
|
|
6
7
|
credit?: Insertable;
|
|
7
8
|
}
|
|
8
|
-
/** `RichBlockParagraph
|
|
9
|
-
export declare function paragraph(...
|
|
10
|
-
/** `RichBlockSectionHeading
|
|
11
|
-
export declare function heading(level: 1 | 2 | 3 | 4 | 5 | 6, ...
|
|
12
|
-
/** `
|
|
9
|
+
/** `RichBlockParagraph` — `<p>` in html, bare text in markdown (blocks are blank-line-joined). */
|
|
10
|
+
export declare function paragraph(...items: Insertable[]): RichNode;
|
|
11
|
+
/** `RichBlockSectionHeading` — `<h1>`–`<h6>` / `#`–`######`. `level` is telegram's `size` (1 largest). */
|
|
12
|
+
export declare function heading(level: 1 | 2 | 3 | 4 | 5 | 6, ...items: Insertable[]): RichNode;
|
|
13
|
+
/** `heading(1, …)`. */
|
|
14
|
+
export declare const h1: (...items: Insertable[]) => RichNode;
|
|
15
|
+
/** `heading(2, …)`. */
|
|
16
|
+
export declare const h2: (...items: Insertable[]) => RichNode;
|
|
17
|
+
/** `heading(3, …)`. */
|
|
18
|
+
export declare const h3: (...items: Insertable[]) => RichNode;
|
|
19
|
+
/** `heading(4, …)`. */
|
|
20
|
+
export declare const h4: (...items: Insertable[]) => RichNode;
|
|
21
|
+
/** `heading(5, …)`. */
|
|
22
|
+
export declare const h5: (...items: Insertable[]) => RichNode;
|
|
23
|
+
/** `heading(6, …)`. */
|
|
24
|
+
export declare const h6: (...items: Insertable[]) => RichNode;
|
|
25
|
+
/**
|
|
26
|
+
* `RichBlockPreformatted` — nested `<pre><code>` (matching classic parse_mode
|
|
27
|
+
* html) / a fenced code block. `text` is raw code: html-escaped in the html
|
|
28
|
+
* dialect, emitted verbatim inside the markdown fence.
|
|
29
|
+
*/
|
|
13
30
|
export declare function preformatted(text: string, language?: string): RichNode;
|
|
14
|
-
/** `RichBlockFooter
|
|
15
|
-
export declare function footer(...
|
|
16
|
-
/** `RichBlockDivider
|
|
31
|
+
/** `RichBlockFooter` — `<footer>`; no markdown token, raw tag embedded there too. */
|
|
32
|
+
export declare function footer(...items: Insertable[]): RichNode;
|
|
33
|
+
/** `RichBlockDivider` — `<hr/>` / `---`. */
|
|
17
34
|
export declare function divider(): RichNode;
|
|
18
|
-
/** `RichBlockMathematicalExpression
|
|
35
|
+
/** `RichBlockMathematicalExpression` — confirmed `<tg-math-block>` / `$$…$$` (raw LaTeX, unescaped in markdown). */
|
|
19
36
|
export declare function mathBlock(expression: string): RichNode;
|
|
20
|
-
/** `RichBlockAnchor
|
|
37
|
+
/** `RichBlockAnchor` — `<a name="…">` at block level, in both dialects. */
|
|
21
38
|
export declare function anchorBlock(name: string): RichNode;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
39
|
+
/**
|
|
40
|
+
* `RichBlockBlockQuotation` — `<blockquote>` with an optional `<cite>` credit;
|
|
41
|
+
* `>`-prefixed lines in markdown (each array item becomes its own line, the
|
|
42
|
+
* credit a trailing `> — credit` line).
|
|
43
|
+
*/
|
|
44
|
+
export declare function blockquote(items: Insertable[], credit?: Insertable): RichNode;
|
|
45
|
+
/** `RichBlockPullQuotation` — loosely `<aside>` per the schema, with an optional `<cite>` credit. */
|
|
25
46
|
export declare function pullquote(text: Insertable, credit?: Insertable): RichNode;
|
|
26
|
-
/** `RichBlockCollage
|
|
47
|
+
/** `RichBlockCollage` — confirmed custom tag `<tg-collage>` (raw in markdown too). */
|
|
27
48
|
export declare function collage(blocks: Insertable[], caption?: Caption): RichNode;
|
|
28
|
-
/** `RichBlockSlideshow
|
|
49
|
+
/** `RichBlockSlideshow` — confirmed custom tag `<tg-slideshow>` (raw in markdown too). */
|
|
29
50
|
export declare function slideshow(blocks: Insertable[], caption?: Caption): RichNode;
|
|
51
|
+
declare const TABLE_CELL: unique symbol;
|
|
30
52
|
export interface TableCellOptions {
|
|
53
|
+
/** `<th>` instead of `<td>`. html-only — gfm's header is structural (see `table`). */
|
|
31
54
|
header?: boolean;
|
|
55
|
+
/** html-only — gfm has no cell spans. */
|
|
32
56
|
colspan?: number;
|
|
57
|
+
/** html-only — gfm has no cell spans. */
|
|
33
58
|
rowspan?: number;
|
|
34
|
-
/** default `"left"`, matching `RichBlockTableCell.align`. */
|
|
59
|
+
/** default `"left"`, matching `RichBlockTableCell.align`. feeds gfm's column alignment row. */
|
|
35
60
|
align?: "left" | "center" | "right";
|
|
36
|
-
/** default `"top"`, matching `RichBlockTableCell.valign`. */
|
|
61
|
+
/** default `"top"`, matching `RichBlockTableCell.valign`. html-only. */
|
|
37
62
|
valign?: "top" | "middle" | "bottom";
|
|
38
63
|
}
|
|
64
|
+
/** one table cell — a `RichNode` carrying its options so `table()` can read the gfm alignment. */
|
|
65
|
+
export interface TableCell extends RichNode {
|
|
66
|
+
readonly [TABLE_CELL]: true;
|
|
67
|
+
readonly align?: "left" | "center" | "right";
|
|
68
|
+
}
|
|
39
69
|
/** one `<td>`/`<th>` cell; `content` omitted ⇒ an invisible cell (per `RichBlockTableCell`). */
|
|
40
|
-
export declare function cell(content?: Insertable, options?: TableCellOptions):
|
|
70
|
+
export declare function cell(content?: Insertable, options?: TableCellOptions): TableCell;
|
|
41
71
|
export interface TableOptions {
|
|
42
|
-
/** best-effort: rendered as the `border` attribute. */
|
|
72
|
+
/** best-effort: rendered as the `border` attribute. html-only. */
|
|
43
73
|
bordered?: boolean;
|
|
44
|
-
/** best-effort: no standard html equivalent, rendered as `data-striped`. */
|
|
74
|
+
/** best-effort: no standard html equivalent, rendered as `data-striped`. html-only. */
|
|
45
75
|
striped?: boolean;
|
|
76
|
+
/** `<caption>` in html; a leading caption line in markdown. */
|
|
46
77
|
caption?: Insertable;
|
|
47
78
|
}
|
|
48
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* `RichBlockTable`, confirmed `<table>` / a gfm table. build cells with `cell()`
|
|
81
|
+
* (a bare value is wrapped in a plain `cell()` automatically). gfm structurally
|
|
82
|
+
* requires a header row, so in markdown `rows[0]` always renders as the header
|
|
83
|
+
* line and `colspan`/`rowspan`/`valign`/`header`/`bordered`/`striped` are
|
|
84
|
+
* dropped; in html the header is per-cell opt-in (`cell(x, { header: true })`).
|
|
85
|
+
*/
|
|
49
86
|
export declare function table(rows: Insertable[][], options?: TableOptions): RichNode;
|
|
50
87
|
export interface DetailsOptions {
|
|
51
88
|
/** `RichBlockDetails.is_open` — content visible by default. defaults to `false`. */
|
|
52
89
|
open?: boolean;
|
|
53
90
|
}
|
|
54
|
-
/**
|
|
91
|
+
/**
|
|
92
|
+
* `RichBlockDetails`, confirmed `<details>`/`<summary>` (an html-only tag, legal
|
|
93
|
+
* inside markdown too — there the body must be blank-line-separated or telegram
|
|
94
|
+
* renders it as literal text).
|
|
95
|
+
*/
|
|
55
96
|
export declare function details(summary: Insertable, blocks: Insertable[], options?: DetailsOptions): RichNode;
|
|
97
|
+
declare const LIST_ITEM: unique symbol;
|
|
56
98
|
export interface ListItemOptions {
|
|
57
99
|
/** an unchecked/checked checkbox prefix (`RichBlockListItem.has_checkbox`/`is_checked`). */
|
|
58
100
|
checkbox?: boolean;
|
|
59
101
|
checked?: boolean;
|
|
60
|
-
/** ordered-list numeric override (`RichBlockListItem.value`) — standard `<li value
|
|
102
|
+
/** ordered-list numeric override (`RichBlockListItem.value`) — standard `<li value>`; restarts gfm numbering. */
|
|
61
103
|
value?: number;
|
|
62
|
-
/** ordered-list label style override (`RichBlockListItem.type`) — standard `<li type>`. */
|
|
104
|
+
/** ordered-list label style override (`RichBlockListItem.type`) — standard `<li type>`. html-only. */
|
|
63
105
|
type?: "a" | "A" | "i" | "I";
|
|
64
106
|
}
|
|
65
|
-
/** one
|
|
66
|
-
export
|
|
107
|
+
/** one list item — a `RichNode` carrying its options so `list()` can number/prefix it. */
|
|
108
|
+
export interface ListItem extends RichNode {
|
|
109
|
+
readonly [LIST_ITEM]: true;
|
|
110
|
+
readonly value?: number;
|
|
111
|
+
}
|
|
112
|
+
/** one `<li>` for `list()` — only needed when a plain value isn't enough (checkbox, value, type). */
|
|
113
|
+
export declare function item(blocks: Insertable[], options?: ListItemOptions): ListItem;
|
|
67
114
|
export interface ListOptions {
|
|
68
115
|
/** `<ol>` instead of `<ul>`. defaults to `false`. */
|
|
69
116
|
ordered?: boolean;
|
|
117
|
+
/** first number of an ordered list — standard `<ol start>` / the first gfm marker. */
|
|
118
|
+
start?: number;
|
|
70
119
|
}
|
|
71
|
-
/**
|
|
72
|
-
|
|
120
|
+
/**
|
|
121
|
+
* `RichBlockList` — `<ul>`/`<ol>` / `- `/`1. ` lines. entries may be plain
|
|
122
|
+
* values (wrapped in a default `item()` automatically) or explicit `item()`s
|
|
123
|
+
* for checkboxes and numbering overrides.
|
|
124
|
+
*/
|
|
125
|
+
export declare function list(entries: Insertable[], options?: ListOptions): RichNode;
|
|
73
126
|
export interface MapOptions {
|
|
74
127
|
/** 13–20, per `RichBlockMap.zoom`. */
|
|
75
128
|
zoom: number;
|
|
@@ -77,8 +130,9 @@ export interface MapOptions {
|
|
|
77
130
|
height: number;
|
|
78
131
|
}
|
|
79
132
|
/**
|
|
80
|
-
* `RichBlockMap`, confirmed custom tag `<tg-map>`
|
|
81
|
-
* best-effort guess (lat/long/zoom/width/height
|
|
133
|
+
* `RichBlockMap`, confirmed custom tag `<tg-map>` (raw in markdown too) —
|
|
134
|
+
* attribute names/encoding are a best-effort guess (lat/long/zoom/width/height
|
|
135
|
+
* are telegram's own field names).
|
|
82
136
|
*/
|
|
83
137
|
export declare function map(location: {
|
|
84
138
|
latitude: number;
|
|
@@ -111,5 +165,12 @@ export declare function audio(src: string, options?: MediaOptions): RichNode;
|
|
|
111
165
|
* schema states it can be used in `sendRichMessageDraft` payloads but is never
|
|
112
166
|
* received back on a real message. see `RichMessageDraft` in draft.ts.
|
|
113
167
|
*/
|
|
114
|
-
export declare function thinking(...
|
|
168
|
+
export declare function thinking(...items: Insertable[]): RichNode;
|
|
169
|
+
/**
|
|
170
|
+
* join content with a separator. if any entry is a block, the result is a block
|
|
171
|
+
* and entries are blank-line-joined (markdown) / concatenated (html) — the
|
|
172
|
+
* separator only applies to all-inline joins.
|
|
173
|
+
*/
|
|
174
|
+
export declare function join(entries: Insertable[], separator?: Insertable): RichNode;
|
|
175
|
+
export {};
|
|
115
176
|
//# sourceMappingURL=blocks.d.ts.map
|
package/lib/blocks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../src/blocks.ts"],"names":[],"mappings":"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"}
|