Skip to content

Commit

Permalink
feat(convert): add unsupportedTagsStrategy option that allows to es…
Browse files Browse the repository at this point in the history
…cape unsupported tags

Closes #5
  • Loading branch information
skoropadas committed Mar 15, 2023
1 parent f10c703 commit 4e78930
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 59 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,39 @@ And simple text with \+ some \- symbols\.
*/
```

## Possible options

You can also add unsupported tags strategy as a second argument, which can be one of the following:

- `escape` - escape unsupported symbols for unsupported tags
- `remove` - remove unsupported tags
- `keep` - ignore unsupported tags (default)

```js
const telegramifyMarkdown = require('telegramify-markdown');
const markdown = `
# Header
> Blockquote
<div>Text in div</div>
`;

telegramifyMarkdown(markdown, 'escape');
/*
*Header*
\> Blockquote
<div\>Text in div</div\>
*/

telegramifyMarkdown(markdown, 'remove');
/*
*Header*
*/
```

sec

[MIT Licence](LICENSE)
6 changes: 3 additions & 3 deletions lib/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ const unified = require('unified');
const { collectDefinitions, removeDefinitions } = require('./definitions');
const createTelegramifyOptions = require('./telegramify');

module.exports = (markdown, options) => {
module.exports = (markdown, unsupportedTagsStrategy) => {
const definitions = {};

const telegramifyOptions = createTelegramifyOptions(definitions);
const telegramifyOptions = createTelegramifyOptions(definitions, unsupportedTagsStrategy);

return unified()
.use(parse, options)
.use(parse)
.use(gfm)
.use(removeComments)
.use(collectDefinitions, definitions)
Expand Down
17 changes: 11 additions & 6 deletions lib/telegramify.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const defaultHandlers = require('mdast-util-to-markdown/lib/handle');
const phrasing = require('mdast-util-to-markdown/lib/util/container-phrasing');

const {wrap, isURL, escapeSymbols} = require('./utils');
const {wrap, isURL, escapeSymbols, processUnsupportedTags} = require('./utils');

/**
* Creates custom `mdast-util-to-markdown` handlers that tailor the output for
Expand All @@ -12,7 +12,7 @@ const {wrap, isURL, escapeSymbols} = require('./utils');
*
* @returns {import('mdast-util-to-markdown').Handlers}
*/
const createHandlers = definitions => ({
const createHandlers = (definitions, unsupportedTagsStrategy) => ({
heading: (node, _parent, context) => {
// make headers to be just *strong*
const marker = '*';
Expand Down Expand Up @@ -54,8 +54,7 @@ const createHandlers = definitions => ({
return wrap(value, marker);
},

list: (...args) => defaultHandlers.list(...args).replace(/^(\d+)./gm, '$1\\.')
,
list: (...args) => defaultHandlers.list(...args).replace(/^(\d+)./gm, '$1\\.'),

listItem: (...args) => defaultHandlers.listItem(...args).replace(/^\*/, '•'),

Expand Down Expand Up @@ -127,6 +126,11 @@ const createHandlers = definitions => ({

return escapeSymbols(text);
},

blockquote: (node, _parent, context) =>
processUnsupportedTags(defaultHandlers.blockquote(node, _parent, context), unsupportedTagsStrategy),
html: (node, _parent, context) =>
processUnsupportedTags(defaultHandlers.html(node, _parent, context), unsupportedTagsStrategy),
});

/**
Expand All @@ -138,9 +142,10 @@ const createHandlers = definitions => ({
*
* @returns {import('remark-stringify').RemarkStringifyOptions}
*/
const createOptions = definitions => ({
const createOptions = (definitions, unsupportedTagsStrategy) => ({
bullet: '*',
handlers: createHandlers(definitions),
tightDefinitions: true,
handlers: createHandlers(definitions, unsupportedTagsStrategy),
});

module.exports = createOptions;
117 changes: 67 additions & 50 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,74 @@
const { URL } = require('url');

module.exports = {
wrap(string, ...wrappers) {
return [
...wrappers,
string,
...wrappers.reverse(),
].join('');
},
function wrap(string, ...wrappers) {
return [
...wrappers,
string,
...wrappers.reverse(),
].join('');
}

isURL(string) {
try {
return Boolean(new URL(string));
} catch (error) {
return false;
}
},
function isURL(string) {
try {
return Boolean(new URL(string));
} catch (error) {
return false;
}
}

escapeSymbols(text, textType = 'text') {
if (!text) {
return text;
}
switch (textType) {
case 'code':
return text
.replace(/`/g, '\\`')
.replace(/\\/g, '\\\\')
case 'link':
return text
.replace(/\(/g, '\\(')
.replace(/\)/g, '\\)')
.replace(/\\/g, '\\\\')
default:
return text
.replace(/_/g, '\\_')
.replace(/\*/g, '\\*')
.replace(/\[/g, '\\[')
.replace(/]/g, '\\]')
.replace(/\(/g, '\\(')
.replace(/\)/g, '\\)')
.replace(/~/g, '\\~')
.replace(/`/g, '\\`')
.replace(/>/g, '\\>')
.replace(/#/g, '\\#')
.replace(/\+/g, '\\+')
.replace(/-/g, '\\-')
.replace(/=/g, '\\=')
.replace(/\|/g, '\\|')
.replace(/{/g, '\\{')
.replace(/}/g, '\\}')
.replace(/\./g, '\\.')
.replace(/!/g, '\\!');
function escapeSymbols(text, textType = 'text') {
if (!text) {
return text;
}
switch (textType) {
case 'code':
return text
.replace(/`/g, '\\`')
.replace(/\\/g, '\\\\')
case 'link':
return text
.replace(/\(/g, '\\(')
.replace(/\)/g, '\\)')
.replace(/\\/g, '\\\\')
default:
return text
.replace(/_/g, '\\_')
.replace(/\*/g, '\\*')
.replace(/\[/g, '\\[')
.replace(/]/g, '\\]')
.replace(/\(/g, '\\(')
.replace(/\)/g, '\\)')
.replace(/~/g, '\\~')
.replace(/`/g, '\\`')
.replace(/>/g, '\\>')
.replace(/#/g, '\\#')
.replace(/\+/g, '\\+')
.replace(/-/g, '\\-')
.replace(/=/g, '\\=')
.replace(/\|/g, '\\|')
.replace(/{/g, '\\{')
.replace(/}/g, '\\}')
.replace(/\./g, '\\.')
.replace(/!/g, '\\!');

}
}
}

function processUnsupportedTags(content, strategy) {
switch (strategy) {
case 'escape':
return escapeSymbols(content);
case 'remove':
return '';
case 'keep':
default:
return content;
}
}

module.exports = {
wrap,
isURL,
escapeSymbols,
processUnsupportedTags,
};
32 changes: 32 additions & 0 deletions tests/convert.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,36 @@ describe('Test convert method', () => {

expect(convert(markdown)).toBe(tgMarkdown);
})

describe('escape unsupported tags', () => {
it('should escape blockquote', () => {
const markdown = '> test';
const tgMarkdown = '\\> test\n';

expect(convert(markdown, 'escape')).toBe(tgMarkdown);
});

it('should escape html', () => {
const markdown = '<div></div>';
const tgMarkdown = '<div\\></div\\>\n';

expect(convert(markdown, 'escape')).toBe(tgMarkdown);
});
})

describe('remove unsupported tags', () => {
it('should remove blockquote', () => {
const markdown = '> test';
const tgMarkdown = '';

expect(convert(markdown, 'remove')).toBe(tgMarkdown);
});

it('should remove html', () => {
const markdown = '<div></div>';
const tgMarkdown = '';

expect(convert(markdown, 'remove')).toBe(tgMarkdown);
});
})
});

0 comments on commit 4e78930

Please sign in to comment.