UNPKG

@telegraf/entity

Version:

Convert Telegram entities to HTML or Markdown

136 lines (135 loc) 4.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.toMarkdownV2 = exports.toHTML = exports.serialiseWith = exports.escapers = exports.serialisers = exports.toTree = exports.parse_markdown = exports.parse_html = void 0; const serialisers = __importStar(require("./serialisers.js")); exports.serialisers = serialisers; const escapers = __importStar(require("./escapers.js")); exports.escapers = escapers; const index_js_1 = require("./parser/index.js"); exports.parse_html = index_js_1.Parser.parse_html; exports.parse_markdown = index_js_1.Parser.parse_markdown; // https://github.com/tdlib/td/blob/721300bcb4d0f2114505712f4dc6350af1ce1a09/td/telegram/MessageEntity.cpp#L39 const TYPE_PRIORITY = { mention: 50, hashtag: 50, bot_command: 50, url: 50, email: 50, bold: 90, italic: 91, code: 20, pre: 11, text_link: 49, text_mention: 49, cashtag: 50, phone_number: 50, underline: 92, strikethrough: 93, blockquote: 0, spoiler: 94, custom_emoji: 99, expandable_blockquote: 0, }; function findChildren(fromEntityIndex, parent, entities) { const ret = []; for (let i = fromEntityIndex + 1; i < entities.length; i++) { const entity = entities[i]; if (entity.offset + entity.length > parent.offset + parent.length) break; ret.push(entity); } return ret; } const ends = (entity) => entity.offset + entity.length; function toTree(msg, offset = 0, upto = Infinity) { if (!msg.entities?.length) return [msg.text.slice(offset, upto)]; const nodes = []; let last = offset; let i = 0; while (i < msg.entities.length) { const entity = msg.entities[i]; // there's some text that isn't in an entity if (last < entity.offset) { nodes.push(msg.text.slice(last, entity.offset)); last = entity.offset; } const children = findChildren(i, entity, msg.entities); const node = { ...entity, text: msg.text.slice(entity.offset, ends(entity)), children: toTree({ text: msg.text, entities: children }, entity.offset, ends(entity)), }; last = ends(node); nodes.push(node); i += children.length + 1; } if (last < upto) { const final = msg.text.slice(last, upto); if (final) nodes.push(final); } return nodes; } exports.toTree = toTree; function serialse(tree, serialiser, escaper) { let ret = ""; for (const node of tree) { if (typeof node === "string") ret += escaper(node); else ret += serialiser(serialse(node.children, serialiser, escaper), node); } return ret; } const serialiseWith = (serialiser, escaper) => (message) => { const msg = "text" in message ? message : { text: message.caption || "", entities: message.caption_entities }; if (!msg.entities || msg.entities.length === 0) return serialiser(msg.text); const entities = msg.entities.sort((a, b) => { if (a.offset < b.offset) return -1; if (a.offset > b.offset) return 1; if (a.length > b.length) return -1; if (a.length < b.length) return 1; const a_priority = TYPE_PRIORITY[a.type]; const b_priority = TYPE_PRIORITY[b.type]; if (a_priority < b_priority) return -1; if (a_priority > b_priority) return 1; return 0; }); return serialse(toTree({ text: msg.text, entities }), serialiser, escaper); }; exports.serialiseWith = serialiseWith; const toHTML = serialiseWith(serialisers.HTML, escapers.HTML); exports.toHTML = toHTML; const toMarkdownV2 = serialiseWith(serialisers.MarkdownV2, escapers.MarkdownV2); exports.toMarkdownV2 = toMarkdownV2;