UNPKG

@gramio/format

Version:

Library for formatting text for Telegram Bot API

94 lines (91 loc) 2.94 kB
import { lexer } from 'marked'; import { join, blockquote, bold, italic, link, strikethrough, code, pre, formatSaveIndents, format } from '../index.js'; function processToken(token) { if (token.type === "blockquote") { const tokenBlockquote = token; return blockquote(join(tokenBlockquote.tokens, processToken, "")); } if (token.type === "strong" || token.type === "heading") { const tokenStrong = token; return bold(join(tokenStrong.tokens, processToken, "")); } if (token.type === "em") { const tokenEm = token; return italic(join(tokenEm.tokens, processToken, "")); } if (token.type === "link" || token.type === "image") { const tokenLink = token; return link(join(tokenLink.tokens, processToken, ""), tokenLink.href); } if (token.type === "del") { const tokenDel = token; return strikethrough(join(tokenDel.tokens, processToken, "")); } if (token.type === "list") { const tokenList = token; return processListToken(tokenList); } if (token.type === "codespan") { const tokenCodespan = token; return code(tokenCodespan.text); } if (token.type === "code") { const tokenCode = token; return pre(tokenCode.text, tokenCode.lang); } if (token.type === "text") { const tokenText = token; return tokenText.tokens ? join(tokenText.tokens, processToken, "") : formatSaveIndents`${tokenText.text}`; } if (token.type === "paragraph") { const tokenParagraph = token; return join(tokenParagraph.tokens, processToken, ""); } return formatSaveIndents`${"text" in token ? token.text : token.raw}`; } function processListToken(tokenList) { const isOrdered = tokenList.ordered; const startNumber = isOrdered && typeof tokenList.start === "number" ? tokenList.start : 1; return join( tokenList.items, (item, itemIndex) => { const bulletOrNumber = isOrdered ? startNumber + itemIndex : "-"; return join( item.tokens, (subToken, subTokenIndex) => { if (subTokenIndex === 0) { return format`${bulletOrNumber}${isOrdered ? "." : ""} ${processToken(subToken)}`; } if (subToken.type === "list") { return format`\n${processToken(subToken)}`; } return processToken(subToken); }, "" ); }, "\n" ); } function workaroundForHeading(tokens) { const result = []; for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; result.push(token); if (token.type === "heading") { const nextLines = token.raw.match(/\n/g); if (nextLines?.length) { result.push({ type: "space", raw: "\n".repeat(nextLines.length) }); } } } return result; } function markdownToFormattable(markdown) { const tokens = workaroundForHeading(lexer(markdown)); return join(tokens, processToken, ""); } export { markdownToFormattable };