@adriangalilea/utils 2.2.0 → 2.3.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.
@@ -0,0 +1,73 @@
1
+ /**
2
+ * tg-md — the opinionated Telegram-Markdown formatter (xtldr's house style,
3
+ * grown from theSummaryBot's tg-html lineage). ONE input dialect, the
4
+ * markdown LLMs actually emit, rendered to every shape a bot sends:
5
+ *
6
+ * markdownToRichHtml(md, coverUrl?) rich-message HTML (Bot API 10.1): real
7
+ * headings/lists, optional cover <img>
8
+ * spliced after the title
9
+ * markdownToTelegramHtml(md) strict parse_mode=HTML subset: # title
10
+ * -> bold underlined line, ## headings ->
11
+ * bold lines with breathing room, ######
12
+ * footer -> quiet plain line, bullets -> •
13
+ * toPlainText(md) last-ditch fallback (quotes keep their
14
+ * > marker so they still read as quotes)
15
+ * tidyRichMarkdown(md) strip the stray ```fence``` models add
16
+ *
17
+ * The dialect contract, load-bearing and deliberate:
18
+ * - `_` is NEVER emphasis — snake_case in model output survives verbatim.
19
+ * Only `*italic*` / `**bold**` are honored.
20
+ * - Every tag is balanced by construction: a render can never produce a
21
+ * message Telegram rejects; unmatched markers stay literal.
22
+ * - Pure functions of the whole string — safe for full-frame draft repaints
23
+ * (bot/draft): malformed mid-stream markdown degrades to literal text
24
+ * this frame and renders correctly the next.
25
+ *
26
+ * Typography (heading air, bullet glyph, the title underline) IS the opinion;
27
+ * it becomes configurable when a second consumer needs a different look, not
28
+ * before. Zero deps, worker-safe.
29
+ */
30
+ /** Unwrap a leading/trailing ```…``` code fence (some models add one) and trim. */
31
+ export declare function tidyRichMarkdown(raw: string): string;
32
+ /**
33
+ * Render the model's rich Markdown into Telegram's strict `parse_mode=HTML` subset,
34
+ * which has no headings or lists:
35
+ * `#` title -> a bold UNDERLINED line + blank line (the wordmark look)
36
+ * `##`..`#####` headings -> a bold line + blank line after (air between head and body)
37
+ * `######` footer heading -> a bold line, no forced air (it's the last line)
38
+ * bullets (`- `/`* `/`+ `) -> a `• ` prefix
39
+ * blockquote (`> `) -> `<blockquote>` (consecutive lines merged)
40
+ * `**bold**`/`*italic*` -> `<b>`/`<i>`; `` `code` `` -> `<code>`; links -> `<a>`
41
+ * Only `*`-based emphasis is honored (never `_`), so `snake_case` survives. Every tag
42
+ * is balanced, so Telegram can't reject the message; unmatched markers stay literal.
43
+ * The spacing is the legacy tghtml contract (now @adriangalilea/utils/tg-html): every
44
+ * heading is followed by a blank line so sections breathe — a heading hugging its
45
+ * bullets reads as a wall.
46
+ */
47
+ export declare function markdownToTelegramHtml(markdown: string): string;
48
+ /**
49
+ * Render the model's rich Markdown into rich-message HTML (the `rich_message.html`
50
+ * field, Bot API 10.1), which supports tags `parse_mode=HTML` lacks, so headings and
51
+ * lists survive as real structure instead of flattening:
52
+ * headings (`#`..`######`) -> `<h1>`..`<h6>` (level = count of `#`)
53
+ * bullets (`- `/`* `/`+ `) -> `<ul><li>…</li></ul>` (consecutive items merged)
54
+ * blockquote (`> `) -> `<blockquote>` (consecutive lines merged)
55
+ * Inline emphasis/code/links reuse {@link inlineMd}. Every tag is balanced, so Telegram
56
+ * can't reject the message; unmatched markers stay literal.
57
+ *
58
+ * `coverUrl` (rich path only) embeds a cover image as a standalone `<img>` block right after
59
+ * the title heading (title, cover, then body), matching the rich-message photo block, which
60
+ * accepts HTTP(S) URLs only. Ignored unless it's a well-formed http(s) URL. The strict-HTML and
61
+ * plain fallbacks have no image support, so they never carry a cover.
62
+ */
63
+ export declare function markdownToRichHtml(markdown: string, coverUrl?: string): string;
64
+ /** Escape text/code content for Telegram HTML. */
65
+ export declare function escapeHtml(s: string): string;
66
+ /**
67
+ * Strip Markdown to plain text: the fallback when Telegram rejects the rich message.
68
+ * Removes heading/bullet markers and emphasis, unwraps links to their text, but KEEPS
69
+ * the `>` blockquote marker on every quote line so quotes still read as quotes with no
70
+ * formatting to lean on. Best-effort, not a full parser.
71
+ */
72
+ export declare function toPlainText(markdown: string): string;
73
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tg-md/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAkD/D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GACf,MAAM,CA+DR;AA+DD,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAWD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAYpD"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * tg-md — the opinionated Telegram-Markdown formatter (xtldr's house style,
3
+ * grown from theSummaryBot's tg-html lineage). ONE input dialect, the
4
+ * markdown LLMs actually emit, rendered to every shape a bot sends:
5
+ *
6
+ * markdownToRichHtml(md, coverUrl?) rich-message HTML (Bot API 10.1): real
7
+ * headings/lists, optional cover <img>
8
+ * spliced after the title
9
+ * markdownToTelegramHtml(md) strict parse_mode=HTML subset: # title
10
+ * -> bold underlined line, ## headings ->
11
+ * bold lines with breathing room, ######
12
+ * footer -> quiet plain line, bullets -> •
13
+ * toPlainText(md) last-ditch fallback (quotes keep their
14
+ * > marker so they still read as quotes)
15
+ * tidyRichMarkdown(md) strip the stray ```fence``` models add
16
+ *
17
+ * The dialect contract, load-bearing and deliberate:
18
+ * - `_` is NEVER emphasis — snake_case in model output survives verbatim.
19
+ * Only `*italic*` / `**bold**` are honored.
20
+ * - Every tag is balanced by construction: a render can never produce a
21
+ * message Telegram rejects; unmatched markers stay literal.
22
+ * - Pure functions of the whole string — safe for full-frame draft repaints
23
+ * (bot/draft): malformed mid-stream markdown degrades to literal text
24
+ * this frame and renders correctly the next.
25
+ *
26
+ * Typography (heading air, bullet glyph, the title underline) IS the opinion;
27
+ * it becomes configurable when a second consumer needs a different look, not
28
+ * before. Zero deps, worker-safe.
29
+ */
30
+ /** Unwrap a leading/trailing ```…``` code fence (some models add one) and trim. */
31
+ export function tidyRichMarkdown(raw) {
32
+ const trimmed = raw.trim();
33
+ const fenced = /^```[a-zA-Z]*\n([\s\S]*?)\n?```$/.exec(trimmed);
34
+ return (fenced ? fenced[1] : trimmed).trim();
35
+ }
36
+ /**
37
+ * Render the model's rich Markdown into Telegram's strict `parse_mode=HTML` subset,
38
+ * which has no headings or lists:
39
+ * `#` title -> a bold UNDERLINED line + blank line (the wordmark look)
40
+ * `##`..`#####` headings -> a bold line + blank line after (air between head and body)
41
+ * `######` footer heading -> a bold line, no forced air (it's the last line)
42
+ * bullets (`- `/`* `/`+ `) -> a `• ` prefix
43
+ * blockquote (`> `) -> `<blockquote>` (consecutive lines merged)
44
+ * `**bold**`/`*italic*` -> `<b>`/`<i>`; `` `code` `` -> `<code>`; links -> `<a>`
45
+ * Only `*`-based emphasis is honored (never `_`), so `snake_case` survives. Every tag
46
+ * is balanced, so Telegram can't reject the message; unmatched markers stay literal.
47
+ * The spacing is the legacy tghtml contract (now @adriangalilea/utils/tg-html): every
48
+ * heading is followed by a blank line so sections breathe — a heading hugging its
49
+ * bullets reads as a wall.
50
+ */
51
+ export function markdownToTelegramHtml(markdown) {
52
+ const lines = tidyRichMarkdown(markdown).split(/\r?\n/);
53
+ const out = [];
54
+ let quote = [];
55
+ const flushQuote = () => {
56
+ if (quote.length) {
57
+ out.push(`<blockquote>${quote.join("\n")}</blockquote>`);
58
+ quote = [];
59
+ }
60
+ };
61
+ for (const raw of lines) {
62
+ const line = raw.replace(/\s+$/, "");
63
+ const q = /^\s{0,3}>\s?(.*)$/.exec(line);
64
+ if (q) {
65
+ quote.push(inlineMd(q[1]));
66
+ continue;
67
+ }
68
+ flushQuote();
69
+ if (!line.trim()) {
70
+ out.push("");
71
+ continue;
72
+ }
73
+ const heading = /^\s{0,3}(#{1,6})\s+(.*)$/.exec(line);
74
+ if (heading) {
75
+ const level = heading[1].length;
76
+ const text = inlineMd(heading[2]);
77
+ // ###### is the source footer: metadata, not a heading — it renders as a quiet
78
+ // plain line (the legacy look), never bold.
79
+ if (level === 1)
80
+ out.push(`<b><u>${text}</u></b>`, "");
81
+ else if (level === 6)
82
+ out.push(text);
83
+ else
84
+ out.push(`<b>${text}</b>`, "");
85
+ continue;
86
+ }
87
+ const bullet = /^\s{0,3}[-*+]\s+(.*)$/.exec(line);
88
+ if (bullet) {
89
+ out.push(`• ${inlineMd(bullet[1])}`);
90
+ continue;
91
+ }
92
+ out.push(inlineMd(line));
93
+ }
94
+ flushQuote();
95
+ return tidyHtml(out.join("\n"));
96
+ }
97
+ /**
98
+ * Render the model's rich Markdown into rich-message HTML (the `rich_message.html`
99
+ * field, Bot API 10.1), which supports tags `parse_mode=HTML` lacks, so headings and
100
+ * lists survive as real structure instead of flattening:
101
+ * headings (`#`..`######`) -> `<h1>`..`<h6>` (level = count of `#`)
102
+ * bullets (`- `/`* `/`+ `) -> `<ul><li>…</li></ul>` (consecutive items merged)
103
+ * blockquote (`> `) -> `<blockquote>` (consecutive lines merged)
104
+ * Inline emphasis/code/links reuse {@link inlineMd}. Every tag is balanced, so Telegram
105
+ * can't reject the message; unmatched markers stay literal.
106
+ *
107
+ * `coverUrl` (rich path only) embeds a cover image as a standalone `<img>` block right after
108
+ * the title heading (title, cover, then body), matching the rich-message photo block, which
109
+ * accepts HTTP(S) URLs only. Ignored unless it's a well-formed http(s) URL. The strict-HTML and
110
+ * plain fallbacks have no image support, so they never carry a cover.
111
+ */
112
+ export function markdownToRichHtml(markdown, coverUrl) {
113
+ const lines = tidyRichMarkdown(markdown).split(/\r?\n/);
114
+ const out = [];
115
+ let quote = [];
116
+ let bullets = [];
117
+ const flushQuote = () => {
118
+ if (quote.length) {
119
+ out.push(`<blockquote>${quote.join("\n")}</blockquote>`);
120
+ quote = [];
121
+ }
122
+ };
123
+ const flushBullets = () => {
124
+ if (bullets.length) {
125
+ out.push(`<ul>${bullets.map((b) => `<li>${b}</li>`).join("")}</ul>`);
126
+ bullets = [];
127
+ }
128
+ };
129
+ for (const raw of lines) {
130
+ const line = raw.replace(/\s+$/, "");
131
+ const q = /^\s{0,3}>\s?(.*)$/.exec(line);
132
+ if (q) {
133
+ flushBullets();
134
+ quote.push(inlineMd(q[1]));
135
+ continue;
136
+ }
137
+ const bullet = /^\s{0,3}[-*+]\s+(.*)$/.exec(line);
138
+ if (bullet) {
139
+ flushQuote();
140
+ bullets.push(inlineMd(bullet[1]));
141
+ continue;
142
+ }
143
+ flushQuote();
144
+ flushBullets();
145
+ if (!line.trim()) {
146
+ out.push("");
147
+ continue;
148
+ }
149
+ const heading = /^\s{0,3}(#{1,6})\s+(.*)$/.exec(line);
150
+ if (heading) {
151
+ const level = heading[1].length;
152
+ out.push(`<h${level}>${inlineMd(heading[2])}</h${level}>`);
153
+ continue;
154
+ }
155
+ out.push(inlineMd(line));
156
+ }
157
+ flushQuote();
158
+ flushBullets();
159
+ insertCover(out, coverUrl);
160
+ return out
161
+ .join("\n")
162
+ .replace(/[ \t]+\n/g, "\n")
163
+ .replace(/\n{3,}/g, "\n\n")
164
+ .trim();
165
+ }
166
+ /**
167
+ * Insert a cover `<img>` block into the rendered rich-HTML lines: right after the title heading
168
+ * (so it reads title → cover → body), or at the very top when there's no title. Anchors on `<h1>`
169
+ * only, since the summary's title is `#` (h1) while section headings are `##` (h2) and the source
170
+ * footer is `######` (h6): matching any `<h[1-6]>` would splice the cover below the footer when the
171
+ * model omits the title. A blank line surrounds it so it stays its own block (media blocks can't be
172
+ * inline). No-op unless `url` is a well-formed http(s) URL, since the rich photo block accepts only those.
173
+ */
174
+ function insertCover(out, url) {
175
+ if (!url || !/^https?:\/\/\S+$/i.test(url.trim()))
176
+ return;
177
+ const img = `<img src="${escapeAttr(url.trim())}"/>`;
178
+ const titleAt = out.findIndex((line) => /^<h1>/.test(line));
179
+ const at = titleAt === -1 ? 0 : titleAt + 1;
180
+ out.splice(at, 0, "", img, "");
181
+ }
182
+ /** Normalize rendered HTML: strip trailing whitespace, collapse blank-line runs. Blank lines
183
+ * around lists stay — that air is the layout (the legacy look); only runs of 3+ collapse. */
184
+ function tidyHtml(html) {
185
+ return html
186
+ .replace(/[ \t]+\n/g, "\n")
187
+ .replace(/\n{3,}/g, "\n\n")
188
+ .trim();
189
+ }
190
+ /**
191
+ * Inline Markdown to Telegram HTML for one line. Code spans and links are pulled out
192
+ * first (so their contents aren't escaped twice or treated as emphasis) and stashed;
193
+ * the rest is escaped, `**bold**`/`*italic*` become tags, then the fragments are restored.
194
+ */
195
+ function inlineMd(text) {
196
+ const tokens = [];
197
+ const stash = (html) => {
198
+ tokens.push(html);
199
+ return `${tokens.length - 1}`;
200
+ };
201
+ // Code spans first: their contents are literal (no emphasis, no nested links).
202
+ let s = text.replace(/`([^`]+)`/g, (_, code) => stash(`<code>${escapeHtml(code)}</code>`));
203
+ // Then links: drop the href unless it's a trusted scheme, keeping the label.
204
+ s = s.replace(/\[([^\]]*)\]\(([^)\s]+)\)/g, (_, label, url) => {
205
+ const safe = /^(https?:|tg:|mailto:)/i.test(url) ? url : null;
206
+ return stash(safe
207
+ ? `<a href="${escapeAttr(safe)}">${escapeHtml(label)}</a>`
208
+ : escapeHtml(label));
209
+ });
210
+ s = escapeHtml(s);
211
+ s = s.replace(/\*\*([^*]+)\*\*/g, "<b>$1</b>"); // bold before italic so `**` wins over `*`
212
+ s = s.replace(/(^|[^*])\*(?!\s)([^*]+?)\*/g, "$1<i>$2</i>");
213
+ return s.replace(/(\d+)/g, (_, i) => tokens[Number(i)]);
214
+ }
215
+ /** Escape text/code content for Telegram HTML. */
216
+ export function escapeHtml(s) {
217
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
218
+ }
219
+ /** Escape an href for a Telegram HTML attribute. */
220
+ function escapeAttr(s) {
221
+ return s
222
+ .replace(/&/g, "&amp;")
223
+ .replace(/"/g, "&quot;")
224
+ .replace(/</g, "&lt;")
225
+ .replace(/>/g, "&gt;");
226
+ }
227
+ /**
228
+ * Strip Markdown to plain text: the fallback when Telegram rejects the rich message.
229
+ * Removes heading/bullet markers and emphasis, unwraps links to their text, but KEEPS
230
+ * the `>` blockquote marker on every quote line so quotes still read as quotes with no
231
+ * formatting to lean on. Best-effort, not a full parser.
232
+ */
233
+ export function toPlainText(markdown) {
234
+ return tidyRichMarkdown(markdown)
235
+ .replace(/```[a-zA-Z]*\n?([\s\S]*?)```/g, "$1") // fenced code -> its contents
236
+ .replace(/^\s{0,3}#{1,6}\s+/gm, "") // heading markers
237
+ .replace(/^\s{0,3}>\s?/gm, "> ") // normalize blockquote markers, keep them
238
+ .replace(/^(\s*)[-*+]\s+/gm, "$1• ") // bullet markers -> •
239
+ .replace(/\[([^\]]*)\]\([^)]*\)/g, "$1") // [text](url) -> text
240
+ .replace(/(\*\*|__)(.*?)\1/g, "$2") // bold
241
+ .replace(/(\*|_)(.*?)\1/g, "$2") // italic
242
+ .replace(/`([^`]*)`/g, "$1") // inline code
243
+ .replace(/\n{3,}/g, "\n\n")
244
+ .trim();
245
+ }
246
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tg-md/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adriangalilea/utils",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "TypeScript utilities - logger, currency, formatter, GramIO bot plugins, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -44,6 +44,10 @@
44
44
  "types": "./dist/tg-html/index.d.ts",
45
45
  "default": "./dist/tg-html/index.js"
46
46
  },
47
+ "./tg-md": {
48
+ "types": "./dist/tg-md/index.d.ts",
49
+ "default": "./dist/tg-md/index.js"
50
+ },
47
51
  "./bot": {
48
52
  "types": "./dist/bot/index.d.ts",
49
53
  "default": "./dist/bot/index.js"