tellegram 1.1.6 → 1.1.8
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 +44 -0
- package/lib/convert.mjs +6 -2
- package/lib/table-to-list.mjs +66 -0
- package/lib/tellegram.mjs +16 -5
- package/package.json +1 -1
- package/types/index.d.ts +13 -2
package/README.md
CHANGED
|
@@ -86,6 +86,11 @@ You can also add unsupported tags strategy as a second argument, which can be on
|
|
|
86
86
|
- `remove` - remove unsupported tags
|
|
87
87
|
- `keep` - ignore unsupported tags
|
|
88
88
|
|
|
89
|
+
`convert` also accepts a third argument for feature options:
|
|
90
|
+
|
|
91
|
+
- `table: 'list'` - convert GFM tables into MarkdownV2-safe hierarchical lists (default)
|
|
92
|
+
- `table: 'unsupported'` - treat tables as unsupported and apply the second-argument strategy
|
|
93
|
+
|
|
89
94
|
```js
|
|
90
95
|
import { convert } from 'tellegram';
|
|
91
96
|
const markdown = `
|
|
@@ -111,4 +116,43 @@ convert(markdown, 'remove');
|
|
|
111
116
|
*/
|
|
112
117
|
```
|
|
113
118
|
|
|
119
|
+
### Convert tables to list
|
|
120
|
+
|
|
121
|
+
Telegram does not support Markdown tables. By default, teLLegraM converts a
|
|
122
|
+
table into a vertical hierarchical list. In this mode, list markers and
|
|
123
|
+
placeholder `-` are escaped to stay safe for Telegram MarkdownV2.
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
import { convert } from 'tellegram';
|
|
127
|
+
|
|
128
|
+
const markdown = `
|
|
129
|
+
| Name | Role | Score |
|
|
130
|
+
| ----- | ----- | ----- |
|
|
131
|
+
| Alice | Admin | 95 |
|
|
132
|
+
| Bob | User | 88 |
|
|
133
|
+
`;
|
|
134
|
+
|
|
135
|
+
convert(markdown, 'escape');
|
|
136
|
+
/*
|
|
137
|
+
\- Name: Alice
|
|
138
|
+
\- Role: Admin
|
|
139
|
+
\- Score: 95
|
|
140
|
+
|
|
141
|
+
\- Name: Bob
|
|
142
|
+
\- Role: User
|
|
143
|
+
\- Score: 88
|
|
144
|
+
*/
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
If you want the previous behavior (table treated as unsupported), use
|
|
148
|
+
`table: 'unsupported'` with the strategy you need:
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
convert(markdown, 'escape', { table: 'unsupported' });
|
|
152
|
+
// => table is kept as escaped Markdown table text
|
|
153
|
+
|
|
154
|
+
convert(markdown, 'remove', { table: 'unsupported' });
|
|
155
|
+
// => ''
|
|
156
|
+
```
|
|
157
|
+
|
|
114
158
|
[MIT Licence](LICENSE)
|
package/lib/convert.mjs
CHANGED
|
@@ -7,10 +7,14 @@ import unified from 'unified';
|
|
|
7
7
|
import { collectDefinitions, removeDefinitions } from './definitions.mjs';
|
|
8
8
|
import createTellegramOptions from './tellegram.mjs';
|
|
9
9
|
|
|
10
|
-
export default (markdown, unsupportedTagsStrategy = 'escape') => {
|
|
10
|
+
export default (markdown, unsupportedTagsStrategy = 'escape', options = {}) => {
|
|
11
11
|
const definitions = {};
|
|
12
12
|
|
|
13
|
-
const tellegramOptions = createTellegramOptions(
|
|
13
|
+
const tellegramOptions = createTellegramOptions(
|
|
14
|
+
definitions,
|
|
15
|
+
unsupportedTagsStrategy,
|
|
16
|
+
options,
|
|
17
|
+
);
|
|
14
18
|
|
|
15
19
|
return unified()
|
|
16
20
|
.use(parse)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import phrasing from 'mdast-util-to-markdown/lib/util/container-phrasing.js';
|
|
2
|
+
|
|
3
|
+
import { escapeSymbols } from './utils.mjs';
|
|
4
|
+
|
|
5
|
+
const EMPTY_VALUE = escapeSymbols('-');
|
|
6
|
+
const FALLBACK_HEADER = escapeSymbols('-');
|
|
7
|
+
|
|
8
|
+
const normalizeCell = (node, context) => {
|
|
9
|
+
if (!node) {
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const value = phrasing(node, context, { before: '', after: '' });
|
|
14
|
+
return value.replace(/\n/g, ' ').trim();
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const normalizeHeader = (cell, index, context) => {
|
|
18
|
+
const value = normalizeCell(cell, context);
|
|
19
|
+
return value || `${FALLBACK_HEADER}`;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const normalizeValue = (cell, context) => {
|
|
23
|
+
const value = normalizeCell(cell, context);
|
|
24
|
+
return value || EMPTY_VALUE;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const pairToLine = (pair, isNested) => {
|
|
28
|
+
const prefix = isNested ? ' \\- ' : '\\- ';
|
|
29
|
+
return `${prefix}${pair.header}: ${pair.value}`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default (node, context) => {
|
|
33
|
+
if (!node.children.length) {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const [headerRow, ...rows] = node.children;
|
|
38
|
+
if (!headerRow || !rows.length) {
|
|
39
|
+
return '';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const headers = headerRow.children.map((cell, index) =>
|
|
43
|
+
normalizeHeader(cell, index, context));
|
|
44
|
+
|
|
45
|
+
const listRows = rows
|
|
46
|
+
.map((row, rowIndex) => {
|
|
47
|
+
const columnCount = Math.max(headers.length, row.children.length);
|
|
48
|
+
const pairs = Array.from({ length: columnCount }, (_, index) => {
|
|
49
|
+
const header = headers[index] || FALLBACK_HEADER;
|
|
50
|
+
const value = normalizeValue(row.children[index], context);
|
|
51
|
+
return { header, value };
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (!pairs.length) {
|
|
55
|
+
return `\\- Item ${rowIndex + 1}: ${EMPTY_VALUE}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const [first, ...rest] = pairs;
|
|
59
|
+
return [
|
|
60
|
+
pairToLine(first, false),
|
|
61
|
+
...rest.map(pair => pairToLine(pair, true)),
|
|
62
|
+
].join('\n');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return listRows.join('\n\n');
|
|
66
|
+
};
|
package/lib/tellegram.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import phrasing from 'mdast-util-to-markdown/lib/util/container-phrasing.js';
|
|
|
3
3
|
import { toMarkdown as gfmTableToMarkdown } from 'mdast-util-gfm-table';
|
|
4
4
|
|
|
5
5
|
import { wrap, isURL, escapeSymbols, processUnsupportedTags } from './utils.mjs';
|
|
6
|
+
import tableToList from './table-to-list.mjs';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Creates custom `mdast-util-to-markdown` handlers that tailor the output for
|
|
@@ -13,7 +14,7 @@ import { wrap, isURL, escapeSymbols, processUnsupportedTags } from './utils.mjs'
|
|
|
13
14
|
*
|
|
14
15
|
* @returns {import('mdast-util-to-markdown').Handlers}
|
|
15
16
|
*/
|
|
16
|
-
const createHandlers = (definitions, unsupportedTagsStrategy) => ({
|
|
17
|
+
const createHandlers = (definitions, unsupportedTagsStrategy, options) => ({
|
|
17
18
|
heading: (node, _parent, context) => {
|
|
18
19
|
// make headers to be just *strong*
|
|
19
20
|
const marker = '*';
|
|
@@ -134,8 +135,18 @@ const createHandlers = (definitions, unsupportedTagsStrategy) => ({
|
|
|
134
135
|
processUnsupportedTags(defaultHandlers.blockquote(node, _parent, context), unsupportedTagsStrategy),
|
|
135
136
|
html: (node, _parent, context) =>
|
|
136
137
|
processUnsupportedTags(defaultHandlers.html(node, _parent, context), unsupportedTagsStrategy),
|
|
137
|
-
table: (node, _parent, context) =>
|
|
138
|
-
|
|
138
|
+
table: (node, _parent, context) => {
|
|
139
|
+
const tableMode = options.table || 'list';
|
|
140
|
+
|
|
141
|
+
if (tableMode === 'list') {
|
|
142
|
+
return tableToList(node, context);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return processUnsupportedTags(
|
|
146
|
+
gfmTableToMarkdown().handlers.table(node, _parent, context),
|
|
147
|
+
unsupportedTagsStrategy,
|
|
148
|
+
);
|
|
149
|
+
},
|
|
139
150
|
thematicBreak: () =>
|
|
140
151
|
processUnsupportedTags('---', unsupportedTagsStrategy),
|
|
141
152
|
});
|
|
@@ -149,10 +160,10 @@ const createHandlers = (definitions, unsupportedTagsStrategy) => ({
|
|
|
149
160
|
*
|
|
150
161
|
* @returns {import('remark-stringify').RemarkStringifyOptions}
|
|
151
162
|
*/
|
|
152
|
-
const createOptions = (definitions, unsupportedTagsStrategy) => ({
|
|
163
|
+
const createOptions = (definitions, unsupportedTagsStrategy, options = {}) => ({
|
|
153
164
|
bullet: '*',
|
|
154
165
|
tightDefinitions: true,
|
|
155
|
-
handlers: createHandlers(definitions, unsupportedTagsStrategy),
|
|
166
|
+
handlers: createHandlers(definitions, unsupportedTagsStrategy, options),
|
|
156
167
|
});
|
|
157
168
|
|
|
158
169
|
export default createOptions;
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
type UnsupportedTagsStrategy = 'escape' | 'remove' | 'keep'
|
|
2
|
+
type TableStrategy = 'list' | 'unsupported'
|
|
3
|
+
|
|
4
|
+
interface ConvertOptions {
|
|
5
|
+
/** Table conversion mode. Default: 'list' */
|
|
6
|
+
table?: TableStrategy
|
|
7
|
+
}
|
|
2
8
|
|
|
3
9
|
declare module 'tellegram' {
|
|
4
10
|
/**
|
|
5
11
|
* Converts markdown to Telegram's format.
|
|
6
12
|
* @param markdown The markdown to convert.
|
|
7
13
|
* @param unsupportedTagsStrategy The strategy to use for unsupported tags.
|
|
14
|
+
* @param options Additional conversion options.
|
|
8
15
|
*/
|
|
9
|
-
export function convert(
|
|
16
|
+
export function convert(
|
|
17
|
+
markdown: string,
|
|
18
|
+
unsupportedTagsStrategy?: UnsupportedTagsStrategy,
|
|
19
|
+
options?: ConvertOptions
|
|
20
|
+
): string;
|
|
10
21
|
|
|
11
22
|
/**
|
|
12
23
|
* Paginates text (placeholder).
|
|
@@ -16,4 +27,4 @@ declare module 'tellegram' {
|
|
|
16
27
|
|
|
17
28
|
const defaultExport: typeof convert;
|
|
18
29
|
export default defaultExport;
|
|
19
|
-
}
|
|
30
|
+
}
|