@kr_ilya

Как отформатировать строку?

При выполнении некоторых запросов к telegram bot api он возвращает массив с элементами форматирования текста сообщения, например для сообщения

<b>qwerty</b>
<a href="https://vk.com/">Ссылка</a>


массив будет таким
{ offset: 0, length: 7, type: 'bold' },
{ offset: 7, length: 6, type: 'text_link', url: 'https://vk.com/' }


Это значит, что с 0 по 7 позицию текст жирный, а с 7 по 13 - содержит гиперссылку (мне не совсем понятно, учитывается ли символ переноса строки, но сейчас это не так важно)

Проблема в том, что api телеграм не принимает в качестве параметров запроса этот массив. Поэтому, чтобы например отредактировать исходное сообщение ботом, необходимо самому на сервере его отформатировать перед отправкой, что я и пытаюсь сделать...

Я думаю, что это можно сделать с помощью функции, которая вставляет подстроку substr в указанную позицию pos строки str. По умолчанию подстрока вставляется в начало строки. (источник)
function insert(str, substr, pos) {
  var array = str.split('');
  array.splice(pos, 0, substr);
  return array.join('');
}


На основе этой функции можно вставлять характерные html теги форматирования текста в указанную позицию, например для жирного текста в позицию 0 вставим <b>, и через 7 символов закрывающий тег </b>.

Все бы хорошо, но при таком подходе будут трудности с определением позиции последующих тегов.
Например после вставки тега <b> в начале, закрывающий тег нужно будет вставить не в 7 позиции, как это изначально дано, а в 10, учитывая, что открывающий тег <b> содержит 3 символа.

Так вот как можно упростить этот процесс? Может есть готовые библиотеки для nodejs? Что посоветуйте?
  • Вопрос задан
  • 229 просмотров
Решения вопроса 2
@Karpion
Не надо вставлять в исходную строку. Надо создать новую строку и переписывать в неё кусочки исходной строки, перемежаемые тегами.

Также можно вставлять теги, начиная с конца строки. Тогда позиции не сместятся.

Ну или держать переменную "смещение", куда суммировать длину всех добавленных тегов; это "смещение" надо будет добавлять к значениям, которые Вы берёте из "массива с элементами форматирования текста сообщения"
Ответ написан
Комментировать
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Я бы так сделал:
// export или module.export =
function formatText(text, formatters) {
  return formatters.reduceRight(applyFormatter, text);
}

function applyFormatter(text, formatter) {
  const {offset, length, type} = formatter;
  const endOffset = offset + length;
  const wrapper = getWrapper(type);
  return `${text.slice(0, offset)}${wrapper(
    text.slice(offset, endOffset),
    formatter
  )}${text.slice(endOffset)}`;
}

function getWrapper(type) {
  switch(type) {
  case 'bold':
    return boldWrapper;
  case 'text_link':
    return linkWrapper;
  default:
    return identityWraper;
  }
}

function boldWrapper(text) {
  return `<b>${text}</b>`;
}
function linkWrapper(text, {url}) {
  return `<a href="${url}">${text}</a>`
}
function identityWraper(text) {
  return text;
}

Использование:
console.log(formatText('qwerty Ссылка', [
  { offset: 0, length: 7, type: 'bold' },
  { offset: 7, length: 6, type: 'text_link', url: 'https://vk.com/' }
])); // <b>qwerty </b><a href="https://vk.com/">Ссылка</a>
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы