{"version":3,"file":"html-to-text-f2a73f7a.js","sources":["../../node_modules/html-to-text/lib/html-to-text.mjs"],"sourcesContent":["import { hp2Builder } from '@selderee/plugin-htmlparser2';\nimport { parseDocument } from 'htmlparser2';\nimport { DecisionTree } from 'selderee';\nimport merge from 'deepmerge';\nimport { render } from 'dom-serializer';\n\n/**\n * Make a recursive function that will only run to a given depth\n * and switches to an alternative function at that depth. \\\n * No limitation if `n` is `undefined` (Just wraps `f` in that case).\n *\n * @param { number | undefined } n Allowed depth of recursion. `undefined` for no limitation.\n * @param { Function } f Function that accepts recursive callback as the first argument.\n * @param { Function } [g] Function to run instead, when maximum depth was reached. Do nothing by default.\n * @returns { Function }\n */\nfunction limitedDepthRecursive (n, f, g = () => undefined) {\n if (n === undefined) {\n const f1 = function (...args) { return f(f1, ...args); };\n return f1;\n }\n if (n >= 0) {\n return function (...args) { return f(limitedDepthRecursive(n - 1, f, g), ...args); };\n }\n return g;\n}\n\n/**\n * Return the same string or a substring with\n * the given character occurrences removed from each side.\n *\n * @param { string } str A string to trim.\n * @param { string } char A character to be trimmed.\n * @returns { string }\n */\nfunction trimCharacter (str, char) {\n let start = 0;\n let end = str.length;\n while (start < end && str[start] === char) { ++start; }\n while (end > start && str[end - 1] === char) { --end; }\n return (start > 0 || end < str.length)\n ? str.substring(start, end)\n : str;\n}\n\n/**\n * Return the same string or a substring with\n * the given character occurrences removed from the end only.\n *\n * @param { string } str A string to trim.\n * @param { string } char A character to be trimmed.\n * @returns { string }\n */\nfunction trimCharacterEnd (str, char) {\n let end = str.length;\n while (end > 0 && str[end - 1] === char) { --end; }\n return (end < str.length)\n ? str.substring(0, end)\n : str;\n}\n\n/**\n * Return a new string will all characters replaced with unicode escape sequences.\n * This extreme kind of escaping can used to be safely compose regular expressions.\n *\n * @param { string } str A string to escape.\n * @returns { string } A string of unicode escape sequences.\n */\nfunction unicodeEscape (str) {\n return str.replace(/[\\s\\S]/g, c => '\\\\u' + c.charCodeAt().toString(16).padStart(4, '0'));\n}\n\n/**\n * Deduplicate an array by a given key callback.\n * Item properties are merged recursively and with the preference for last defined values.\n * Of items with the same key, merged item takes the place of the last item,\n * others are omitted.\n *\n * @param { any[] } items An array to deduplicate.\n * @param { (x: any) => string } getKey Callback to get a value that distinguishes unique items.\n * @returns { any[] }\n */\nfunction mergeDuplicatesPreferLast (items, getKey) {\n const map = new Map();\n for (let i = items.length; i-- > 0;) {\n const item = items[i];\n const key = getKey(item);\n map.set(\n key,\n (map.has(key))\n ? merge(item, map.get(key), { arrayMerge: overwriteMerge$1 })\n : item\n );\n }\n return [...map.values()].reverse();\n}\n\nconst overwriteMerge$1 = (acc, src, options) => [...src];\n\n/**\n * Get a nested property from an object.\n *\n * @param { object } obj The object to query for the value.\n * @param { string[] } path The path to the property.\n * @returns { any }\n */\nfunction get (obj, path) {\n for (const key of path) {\n if (!obj) { return undefined; }\n obj = obj[key];\n }\n return obj;\n}\n\n/**\n * Convert a number into alphabetic sequence representation (Sequence without zeroes).\n *\n * For example: `a, ..., z, aa, ..., zz, aaa, ...`.\n *\n * @param { number } num Number to convert. Must be >= 1.\n * @param { string } [baseChar = 'a'] Character for 1 in the sequence.\n * @param { number } [base = 26] Number of characters in the sequence.\n * @returns { string }\n */\nfunction numberToLetterSequence (num, baseChar = 'a', base = 26) {\n const digits = [];\n do {\n num -= 1;\n digits.push(num % base);\n num = (num / base) >> 0; // quick `floor`\n } while (num > 0);\n const baseCode = baseChar.charCodeAt(0);\n return digits\n .reverse()\n .map(n => String.fromCharCode(baseCode + n))\n .join('');\n}\n\nconst I = ['I', 'X', 'C', 'M'];\nconst V = ['V', 'L', 'D'];\n\n/**\n * Convert a number to it's Roman representation. No large numbers extension.\n *\n * @param { number } num Number to convert. `0 < num <= 3999`.\n * @returns { string }\n */\nfunction numberToRoman (num) {\n return [...(num) + '']\n .map(n => +n)\n .reverse()\n .map((v, i) => ((v % 5 < 4)\n ? (v < 5 ? '' : V[i]) + I[i].repeat(v % 5)\n : I[i] + (v < 5 ? V[i] : I[i + 1])))\n .reverse()\n .join('');\n}\n\n/**\n * Helps to build text from words.\n */\nclass InlineTextBuilder {\n /**\n * Creates an instance of InlineTextBuilder.\n *\n * If `maxLineLength` is not provided then it is either `options.wordwrap` or unlimited.\n *\n * @param { Options } options HtmlToText options.\n * @param { number } [ maxLineLength ] This builder will try to wrap text to fit this line length.\n */\n constructor (options, maxLineLength = undefined) {\n /** @type { string[][] } */\n this.lines = [];\n /** @type { string[] } */\n this.nextLineWords = [];\n this.maxLineLength = maxLineLength || options.wordwrap || Number.MAX_VALUE;\n this.nextLineAvailableChars = this.maxLineLength;\n this.wrapCharacters = get(options, ['longWordSplit', 'wrapCharacters']) || [];\n this.forceWrapOnLimit = get(options, ['longWordSplit', 'forceWrapOnLimit']) || false;\n\n this.stashedSpace = false;\n this.wordBreakOpportunity = false;\n }\n\n /**\n * Add a new word.\n *\n * @param { string } word A word to add.\n * @param { boolean } [noWrap] Don't wrap text even if the line is too long.\n */\n pushWord (word, noWrap = false) {\n if (this.nextLineAvailableChars <= 0 && !noWrap) {\n this.startNewLine();\n }\n const isLineStart = this.nextLineWords.length === 0;\n const cost = word.length + (isLineStart ? 0 : 1);\n if ((cost <= this.nextLineAvailableChars) || noWrap) { // Fits into available budget\n\n this.nextLineWords.push(word);\n this.nextLineAvailableChars -= cost;\n\n } else { // Does not fit - try to split the word\n\n // The word is moved to a new line - prefer to wrap between words.\n const [first, ...rest] = this.splitLongWord(word);\n if (!isLineStart) { this.startNewLine(); }\n this.nextLineWords.push(first);\n this.nextLineAvailableChars -= first.length;\n for (const part of rest) {\n this.startNewLine();\n this.nextLineWords.push(part);\n this.nextLineAvailableChars -= part.length;\n }\n\n }\n }\n\n /**\n * Pop a word from the currently built line.\n * This doesn't affect completed lines.\n *\n * @returns { string }\n */\n popWord () {\n const lastWord = this.nextLineWords.pop();\n if (lastWord !== undefined) {\n const isLineStart = this.nextLineWords.length === 0;\n const cost = lastWord.length + (isLineStart ? 0 : 1);\n this.nextLineAvailableChars += cost;\n }\n return lastWord;\n }\n\n /**\n * Concat a word to the last word already in the builder.\n * Adds a new word in case there are no words yet in the last line.\n *\n * @param { string } word A word to be concatenated.\n * @param { boolean } [noWrap] Don't wrap text even if the line is too long.\n */\n concatWord (word, noWrap = false) {\n if (this.wordBreakOpportunity && word.length > this.nextLineAvailableChars) {\n this.pushWord(word, noWrap);\n this.wordBreakOpportunity = false;\n } else {\n const lastWord = this.popWord();\n this.pushWord((lastWord) ? lastWord.concat(word) : word, noWrap);\n }\n }\n\n /**\n * Add current line (and more empty lines if provided argument > 1) to the list of complete lines and start a new one.\n *\n * @param { number } n Number of line breaks that will be added to the resulting string.\n */\n startNewLine (n = 1) {\n this.lines.push(this.nextLineWords);\n if (n > 1) {\n this.lines.push(...Array.from({ length: n - 1 }, () => []));\n }\n this.nextLineWords = [];\n this.nextLineAvailableChars = this.maxLineLength;\n }\n\n /**\n * No words in this builder.\n *\n * @returns { boolean }\n */\n isEmpty () {\n return this.lines.length === 0\n && this.nextLineWords.length === 0;\n }\n\n clear () {\n this.lines.length = 0;\n this.nextLineWords.length = 0;\n this.nextLineAvailableChars = this.maxLineLength;\n }\n\n /**\n * Join all lines of words inside the InlineTextBuilder into a complete string.\n *\n * @returns { string }\n */\n toString () {\n return [...this.lines, this.nextLineWords]\n .map(words => words.join(' '))\n .join('\\n');\n }\n\n /**\n * Split a long word up to fit within the word wrap limit.\n * Use either a character to split looking back from the word wrap limit,\n * or truncate to the word wrap limit.\n *\n * @param { string } word Input word.\n * @returns { string[] } Parts of the word.\n */\n splitLongWord (word) {\n const parts = [];\n let idx = 0;\n while (word.length > this.maxLineLength) {\n\n const firstLine = word.substring(0, this.maxLineLength);\n const remainingChars = word.substring(this.maxLineLength);\n\n const splitIndex = firstLine.lastIndexOf(this.wrapCharacters[idx]);\n\n if (splitIndex > -1) { // Found a character to split on\n\n word = firstLine.substring(splitIndex + 1) + remainingChars;\n parts.push(firstLine.substring(0, splitIndex + 1));\n\n } else { // Not found a character to split on\n\n idx++;\n if (idx < this.wrapCharacters.length) { // There is next character to try\n\n word = firstLine + remainingChars;\n\n } else { // No more characters to try\n\n if (this.forceWrapOnLimit) {\n parts.push(firstLine);\n word = remainingChars;\n if (word.length > this.maxLineLength) {\n continue;\n }\n } else {\n word = firstLine + remainingChars;\n }\n break;\n\n }\n\n }\n\n }\n parts.push(word); // Add remaining part to array\n return parts;\n }\n}\n\n/* eslint-disable max-classes-per-file */\n\n\nclass StackItem {\n constructor (next = null) { this.next = next; }\n\n getRoot () { return (this.next) ? this.next : this; }\n}\n\nclass BlockStackItem extends StackItem {\n constructor (options, next = null, leadingLineBreaks = 1, maxLineLength = undefined) {\n super(next);\n this.leadingLineBreaks = leadingLineBreaks;\n this.inlineTextBuilder = new InlineTextBuilder(options, maxLineLength);\n this.rawText = '';\n this.stashedLineBreaks = 0;\n this.isPre = next && next.isPre;\n this.isNoWrap = next && next.isNoWrap;\n }\n}\n\nclass ListStackItem extends BlockStackItem {\n constructor (\n options,\n next = null,\n {\n interRowLineBreaks = 1,\n leadingLineBreaks = 2,\n maxLineLength = undefined,\n maxPrefixLength = 0,\n prefixAlign = 'left',\n } = {}\n ) {\n super(options, next, leadingLineBreaks, maxLineLength);\n this.maxPrefixLength = maxPrefixLength;\n this.prefixAlign = prefixAlign;\n this.interRowLineBreaks = interRowLineBreaks;\n }\n}\n\nclass ListItemStackItem extends BlockStackItem {\n constructor (\n options,\n next = null,\n {\n leadingLineBreaks = 1,\n maxLineLength = undefined,\n prefix = '',\n } = {}\n ) {\n super(options, next, leadingLineBreaks, maxLineLength);\n this.prefix = prefix;\n }\n}\n\nclass TableStackItem extends StackItem {\n constructor (next = null) {\n super(next);\n this.rows = [];\n this.isPre = next && next.isPre;\n this.isNoWrap = next && next.isNoWrap;\n }\n}\n\nclass TableRowStackItem extends StackItem {\n constructor (next = null) {\n super(next);\n this.cells = [];\n this.isPre = next && next.isPre;\n this.isNoWrap = next && next.isNoWrap;\n }\n}\n\nclass TableCellStackItem extends StackItem {\n constructor (options, next = null, maxColumnWidth = undefined) {\n super(next);\n this.inlineTextBuilder = new InlineTextBuilder(options, maxColumnWidth);\n this.rawText = '';\n this.stashedLineBreaks = 0;\n this.isPre = next && next.isPre;\n this.isNoWrap = next && next.isNoWrap;\n }\n}\n\nclass TransformerStackItem extends StackItem {\n constructor (next = null, transform) {\n super(next);\n this.transform = transform;\n }\n}\n\nfunction charactersToCodes (str) {\n return [...str]\n .map(c => '\\\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))\n .join('');\n}\n\n/**\n * Helps to handle HTML whitespaces.\n *\n * @class WhitespaceProcessor\n */\nclass WhitespaceProcessor {\n\n /**\n * Creates an instance of WhitespaceProcessor.\n *\n * @param { Options } options HtmlToText options.\n * @memberof WhitespaceProcessor\n */\n constructor (options) {\n this.whitespaceChars = (options.preserveNewlines)\n ? options.whitespaceCharacters.replace(/\\n/g, '')\n : options.whitespaceCharacters;\n const whitespaceCodes = charactersToCodes(this.whitespaceChars);\n this.leadingWhitespaceRe = new RegExp(`^[${whitespaceCodes}]`);\n this.trailingWhitespaceRe = new RegExp(`[${whitespaceCodes}]$`);\n this.allWhitespaceOrEmptyRe = new RegExp(`^[${whitespaceCodes}]*$`);\n this.newlineOrNonWhitespaceRe = new RegExp(`(\\\\n|[^\\\\n${whitespaceCodes}])`, 'g');\n this.newlineOrNonNewlineStringRe = new RegExp(`(\\\\n|[^\\\\n]+)`, 'g');\n\n if (options.preserveNewlines) {\n\n const wordOrNewlineRe = new RegExp(`\\\\n|[^\\\\n${whitespaceCodes}]+`, 'gm');\n\n /**\n * Shrink whitespaces and wrap text, add to the builder.\n *\n * @param { string } text Input text.\n * @param { InlineTextBuilder } inlineTextBuilder A builder to receive processed text.\n * @param { (str: string) => string } [ transform ] A transform to be applied to words.\n * @param { boolean } [noWrap] Don't wrap text even if the line is too long.\n */\n this.shrinkWrapAdd = function (text, inlineTextBuilder, transform = (str => str), noWrap = false) {\n if (!text) { return; }\n const previouslyStashedSpace = inlineTextBuilder.stashedSpace;\n let anyMatch = false;\n let m = wordOrNewlineRe.exec(text);\n if (m) {\n anyMatch = true;\n if (m[0] === '\\n') {\n inlineTextBuilder.startNewLine();\n } else if (previouslyStashedSpace || this.testLeadingWhitespace(text)) {\n inlineTextBuilder.pushWord(transform(m[0]), noWrap);\n } else {\n inlineTextBuilder.concatWord(transform(m[0]), noWrap);\n }\n while ((m = wordOrNewlineRe.exec(text)) !== null) {\n if (m[0] === '\\n') {\n inlineTextBuilder.startNewLine();\n } else {\n inlineTextBuilder.pushWord(transform(m[0]), noWrap);\n }\n }\n }\n inlineTextBuilder.stashedSpace = (previouslyStashedSpace && !anyMatch) || (this.testTrailingWhitespace(text));\n // No need to stash a space in case last added item was a new line,\n // but that won't affect anything later anyway.\n };\n\n } else {\n\n const wordRe = new RegExp(`[^${whitespaceCodes}]+`, 'g');\n\n this.shrinkWrapAdd = function (text, inlineTextBuilder, transform = (str => str), noWrap = false) {\n if (!text) { return; }\n const previouslyStashedSpace = inlineTextBuilder.stashedSpace;\n let anyMatch = false;\n let m = wordRe.exec(text);\n if (m) {\n anyMatch = true;\n if (previouslyStashedSpace || this.testLeadingWhitespace(text)) {\n inlineTextBuilder.pushWord(transform(m[0]), noWrap);\n } else {\n inlineTextBuilder.concatWord(transform(m[0]), noWrap);\n }\n while ((m = wordRe.exec(text)) !== null) {\n inlineTextBuilder.pushWord(transform(m[0]), noWrap);\n }\n }\n inlineTextBuilder.stashedSpace = (previouslyStashedSpace && !anyMatch) || this.testTrailingWhitespace(text);\n };\n\n }\n }\n\n /**\n * Add text with only minimal processing.\n * Everything between newlines considered a single word.\n * No whitespace is trimmed.\n * Not affected by preserveNewlines option - `\\n` always starts a new line.\n *\n * `noWrap` argument is `true` by default - this won't start a new line\n * even if there is not enough space left in the current line.\n *\n * @param { string } text Input text.\n * @param { InlineTextBuilder } inlineTextBuilder A builder to receive processed text.\n * @param { boolean } [noWrap] Don't wrap text even if the line is too long.\n */\n addLiteral (text, inlineTextBuilder, noWrap = true) {\n if (!text) { return; }\n const previouslyStashedSpace = inlineTextBuilder.stashedSpace;\n let anyMatch = false;\n let m = this.newlineOrNonNewlineStringRe.exec(text);\n if (m) {\n anyMatch = true;\n if (m[0] === '\\n') {\n inlineTextBuilder.startNewLine();\n } else if (previouslyStashedSpace) {\n inlineTextBuilder.pushWord(m[0], noWrap);\n } else {\n inlineTextBuilder.concatWord(m[0], noWrap);\n }\n while ((m = this.newlineOrNonNewlineStringRe.exec(text)) !== null) {\n if (m[0] === '\\n') {\n inlineTextBuilder.startNewLine();\n } else {\n inlineTextBuilder.pushWord(m[0], noWrap);\n }\n }\n }\n inlineTextBuilder.stashedSpace = (previouslyStashedSpace && !anyMatch);\n }\n\n /**\n * Test whether the given text starts with HTML whitespace character.\n *\n * @param { string } text The string to test.\n * @returns { boolean }\n */\n testLeadingWhitespace (text) {\n return this.leadingWhitespaceRe.test(text);\n }\n\n /**\n * Test whether the given text ends with HTML whitespace character.\n *\n * @param { string } text The string to test.\n * @returns { boolean }\n */\n testTrailingWhitespace (text) {\n return this.trailingWhitespaceRe.test(text);\n }\n\n /**\n * Test whether the given text contains any non-whitespace characters.\n *\n * @param { string } text The string to test.\n * @returns { boolean }\n */\n testContainsWords (text) {\n return !this.allWhitespaceOrEmptyRe.test(text);\n }\n\n /**\n * Return the number of newlines if there are no words.\n *\n * If any word is found then return zero regardless of the actual number of newlines.\n *\n * @param { string } text Input string.\n * @returns { number }\n */\n countNewlinesNoWords (text) {\n this.newlineOrNonWhitespaceRe.lastIndex = 0;\n let counter = 0;\n let match;\n while ((match = this.newlineOrNonWhitespaceRe.exec(text)) !== null) {\n if (match[0] === '\\n') {\n counter++;\n } else {\n return 0;\n }\n }\n return counter;\n }\n\n}\n\n/**\n * Helps to build text from inline and block elements.\n *\n * @class BlockTextBuilder\n */\nclass BlockTextBuilder {\n\n /**\n * Creates an instance of BlockTextBuilder.\n *\n * @param { Options } options HtmlToText options.\n * @param { import('selderee').Picker } picker Selectors decision tree picker.\n * @param { any} [metadata] Optional metadata for HTML document, for use in formatters.\n */\n constructor (options, picker, metadata = undefined) {\n this.options = options;\n this.picker = picker;\n this.metadata = metadata;\n this.whitespaceProcessor = new WhitespaceProcessor(options);\n /** @type { StackItem } */\n this._stackItem = new BlockStackItem(options);\n /** @type { TransformerStackItem } */\n this._wordTransformer = undefined;\n }\n\n /**\n * Put a word-by-word transform function onto the transformations stack.\n *\n * Mainly used for uppercasing. Can be bypassed to add unformatted text such as URLs.\n *\n * Word transformations applied before wrapping.\n *\n * @param { (str: string) => string } wordTransform Word transformation function.\n */\n pushWordTransform (wordTransform) {\n this._wordTransformer = new TransformerStackItem(this._wordTransformer, wordTransform);\n }\n\n /**\n * Remove a function from the word transformations stack.\n *\n * @returns { (str: string) => string } A function that was removed.\n */\n popWordTransform () {\n if (!this._wordTransformer) { return undefined; }\n const transform = this._wordTransformer.transform;\n this._wordTransformer = this._wordTransformer.next;\n return transform;\n }\n\n /**\n * Ignore wordwrap option in followup inline additions and disable automatic wrapping.\n */\n startNoWrap () {\n this._stackItem.isNoWrap = true;\n }\n\n /**\n * Return automatic wrapping to behavior defined by options.\n */\n stopNoWrap () {\n this._stackItem.isNoWrap = false;\n }\n\n /** @returns { (str: string) => string } */\n _getCombinedWordTransformer () {\n const wt = (this._wordTransformer)\n ? ((str) => applyTransformer(str, this._wordTransformer))\n : undefined;\n const ce = this.options.encodeCharacters;\n return (wt)\n ? ((ce) ? (str) => ce(wt(str)) : wt)\n : ce;\n }\n\n _popStackItem () {\n const item = this._stackItem;\n this._stackItem = item.next;\n return item;\n }\n\n /**\n * Add a line break into currently built block.\n */\n addLineBreak () {\n if (!(\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof ListItemStackItem\n || this._stackItem instanceof TableCellStackItem\n )) { return; }\n if (this._stackItem.isPre) {\n this._stackItem.rawText += '\\n';\n } else {\n this._stackItem.inlineTextBuilder.startNewLine();\n }\n }\n\n /**\n * Allow to break line in case directly following text will not fit.\n */\n addWordBreakOpportunity () {\n if (\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof ListItemStackItem\n || this._stackItem instanceof TableCellStackItem\n ) {\n this._stackItem.inlineTextBuilder.wordBreakOpportunity = true;\n }\n }\n\n /**\n * Add a node inline into the currently built block.\n *\n * @param { string } str\n * Text content of a node to add.\n *\n * @param { object } [param1]\n * Object holding the parameters of the operation.\n *\n * @param { boolean } [param1.noWordTransform]\n * Ignore word transformers if there are any.\n * Don't encode characters as well.\n * (Use this for things like URL addresses).\n */\n addInline (str, { noWordTransform = false } = {}) {\n if (!(\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof ListItemStackItem\n || this._stackItem instanceof TableCellStackItem\n )) { return; }\n\n if (this._stackItem.isPre) {\n this._stackItem.rawText += str;\n return;\n }\n\n if (\n str.length === 0 || // empty string\n (\n this._stackItem.stashedLineBreaks && // stashed linebreaks make whitespace irrelevant\n !this.whitespaceProcessor.testContainsWords(str) // no words to add\n )\n ) { return; }\n\n if (this.options.preserveNewlines) {\n const newlinesNumber = this.whitespaceProcessor.countNewlinesNoWords(str);\n if (newlinesNumber > 0) {\n this._stackItem.inlineTextBuilder.startNewLine(newlinesNumber);\n // keep stashedLineBreaks unchanged\n return;\n }\n }\n\n if (this._stackItem.stashedLineBreaks) {\n this._stackItem.inlineTextBuilder.startNewLine(this._stackItem.stashedLineBreaks);\n }\n this.whitespaceProcessor.shrinkWrapAdd(\n str,\n this._stackItem.inlineTextBuilder,\n (noWordTransform) ? undefined : this._getCombinedWordTransformer(),\n this._stackItem.isNoWrap\n );\n this._stackItem.stashedLineBreaks = 0; // inline text doesn't introduce line breaks\n }\n\n /**\n * Add a string inline into the currently built block.\n *\n * Use this for markup elements that don't have to adhere\n * to text layout rules.\n *\n * @param { string } str Text to add.\n */\n addLiteral (str) {\n if (!(\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof ListItemStackItem\n || this._stackItem instanceof TableCellStackItem\n )) { return; }\n\n if (str.length === 0) { return; }\n\n if (this._stackItem.isPre) {\n this._stackItem.rawText += str;\n return;\n }\n\n if (this._stackItem.stashedLineBreaks) {\n this._stackItem.inlineTextBuilder.startNewLine(this._stackItem.stashedLineBreaks);\n }\n this.whitespaceProcessor.addLiteral(\n str,\n this._stackItem.inlineTextBuilder,\n this._stackItem.isNoWrap\n );\n this._stackItem.stashedLineBreaks = 0;\n }\n\n /**\n * Start building a new block.\n *\n * @param { object } [param0]\n * Object holding the parameters of the block.\n *\n * @param { number } [param0.leadingLineBreaks]\n * This block should have at least this number of line breaks to separate it from any preceding block.\n *\n * @param { number } [param0.reservedLineLength]\n * Reserve this number of characters on each line for block markup.\n *\n * @param { boolean } [param0.isPre]\n * Should HTML whitespace be preserved inside this block.\n */\n openBlock ({ leadingLineBreaks = 1, reservedLineLength = 0, isPre = false } = {}) {\n const maxLineLength = Math.max(20, this._stackItem.inlineTextBuilder.maxLineLength - reservedLineLength);\n this._stackItem = new BlockStackItem(\n this.options,\n this._stackItem,\n leadingLineBreaks,\n maxLineLength\n );\n if (isPre) { this._stackItem.isPre = true; }\n }\n\n /**\n * Finalize currently built block, add it's content to the parent block.\n *\n * @param { object } [param0]\n * Object holding the parameters of the block.\n *\n * @param { number } [param0.trailingLineBreaks]\n * This block should have at least this number of line breaks to separate it from any following block.\n *\n * @param { (str: string) => string } [param0.blockTransform]\n * A function to transform the block text before adding to the parent block.\n * This happens after word wrap and should be used in combination with reserved line length\n * in order to keep line lengths correct.\n * Used for whole block markup.\n */\n closeBlock ({ trailingLineBreaks = 1, blockTransform = undefined } = {}) {\n const block = this._popStackItem();\n const blockText = (blockTransform) ? blockTransform(getText(block)) : getText(block);\n addText(this._stackItem, blockText, block.leadingLineBreaks, Math.max(block.stashedLineBreaks, trailingLineBreaks));\n }\n\n /**\n * Start building a new list.\n *\n * @param { object } [param0]\n * Object holding the parameters of the list.\n *\n * @param { number } [param0.maxPrefixLength]\n * Length of the longest list item prefix.\n * If not supplied or too small then list items won't be aligned properly.\n *\n * @param { 'left' | 'right' } [param0.prefixAlign]\n * Specify how prefixes of different lengths have to be aligned\n * within a column.\n *\n * @param { number } [param0.interRowLineBreaks]\n * Minimum number of line breaks between list items.\n *\n * @param { number } [param0.leadingLineBreaks]\n * This list should have at least this number of line breaks to separate it from any preceding block.\n */\n openList ({ maxPrefixLength = 0, prefixAlign = 'left', interRowLineBreaks = 1, leadingLineBreaks = 2 } = {}) {\n this._stackItem = new ListStackItem(this.options, this._stackItem, {\n interRowLineBreaks: interRowLineBreaks,\n leadingLineBreaks: leadingLineBreaks,\n maxLineLength: this._stackItem.inlineTextBuilder.maxLineLength,\n maxPrefixLength: maxPrefixLength,\n prefixAlign: prefixAlign\n });\n }\n\n /**\n * Start building a new list item.\n *\n * @param {object} param0\n * Object holding the parameters of the list item.\n *\n * @param { string } [param0.prefix]\n * Prefix for this list item (item number, bullet point, etc).\n */\n openListItem ({ prefix = '' } = {}) {\n if (!(this._stackItem instanceof ListStackItem)) {\n throw new Error('Can\\'t add a list item to something that is not a list! Check the formatter.');\n }\n const list = this._stackItem;\n const prefixLength = Math.max(prefix.length, list.maxPrefixLength);\n const maxLineLength = Math.max(20, list.inlineTextBuilder.maxLineLength - prefixLength);\n this._stackItem = new ListItemStackItem(this.options, list, {\n prefix: prefix,\n maxLineLength: maxLineLength,\n leadingLineBreaks: list.interRowLineBreaks\n });\n }\n\n /**\n * Finalize currently built list item, add it's content to the parent list.\n */\n closeListItem () {\n const listItem = this._popStackItem();\n const list = listItem.next;\n\n const prefixLength = Math.max(listItem.prefix.length, list.maxPrefixLength);\n const spacing = '\\n' + ' '.repeat(prefixLength);\n const prefix = (list.prefixAlign === 'right')\n ? listItem.prefix.padStart(prefixLength)\n : listItem.prefix.padEnd(prefixLength);\n const text = prefix + getText(listItem).replace(/\\n/g, spacing);\n\n addText(\n list,\n text,\n listItem.leadingLineBreaks,\n Math.max(listItem.stashedLineBreaks, list.interRowLineBreaks)\n );\n }\n\n /**\n * Finalize currently built list, add it's content to the parent block.\n *\n * @param { object } param0\n * Object holding the parameters of the list.\n *\n * @param { number } [param0.trailingLineBreaks]\n * This list should have at least this number of line breaks to separate it from any following block.\n */\n closeList ({ trailingLineBreaks = 2 } = {}) {\n const list = this._popStackItem();\n const text = getText(list);\n if (text) {\n addText(this._stackItem, text, list.leadingLineBreaks, trailingLineBreaks);\n }\n }\n\n /**\n * Start building a table.\n */\n openTable () {\n this._stackItem = new TableStackItem(this._stackItem);\n }\n\n /**\n * Start building a table row.\n */\n openTableRow () {\n if (!(this._stackItem instanceof TableStackItem)) {\n throw new Error('Can\\'t add a table row to something that is not a table! Check the formatter.');\n }\n this._stackItem = new TableRowStackItem(this._stackItem);\n }\n\n /**\n * Start building a table cell.\n *\n * @param { object } [param0]\n * Object holding the parameters of the cell.\n *\n * @param { number } [param0.maxColumnWidth]\n * Wrap cell content to this width. Fall back to global wordwrap value if undefined.\n */\n openTableCell ({ maxColumnWidth = undefined } = {}) {\n if (!(this._stackItem instanceof TableRowStackItem)) {\n throw new Error('Can\\'t add a table cell to something that is not a table row! Check the formatter.');\n }\n this._stackItem = new TableCellStackItem(this.options, this._stackItem, maxColumnWidth);\n }\n\n /**\n * Finalize currently built table cell and add it to parent table row's cells.\n *\n * @param { object } [param0]\n * Object holding the parameters of the cell.\n *\n * @param { number } [param0.colspan] How many columns this cell should occupy.\n * @param { number } [param0.rowspan] How many rows this cell should occupy.\n */\n closeTableCell ({ colspan = 1, rowspan = 1 } = {}) {\n const cell = this._popStackItem();\n const text = trimCharacter(getText(cell), '\\n');\n cell.next.cells.push({ colspan: colspan, rowspan: rowspan, text: text });\n }\n\n /**\n * Finalize currently built table row and add it to parent table's rows.\n */\n closeTableRow () {\n const row = this._popStackItem();\n row.next.rows.push(row.cells);\n }\n\n /**\n * Finalize currently built table and add the rendered text to the parent block.\n *\n * @param { object } param0\n * Object holding the parameters of the table.\n *\n * @param { TablePrinter } param0.tableToString\n * A function to convert a table of stringified cells into a complete table.\n *\n * @param { number } [param0.leadingLineBreaks]\n * This table should have at least this number of line breaks to separate if from any preceding block.\n *\n * @param { number } [param0.trailingLineBreaks]\n * This table should have at least this number of line breaks to separate it from any following block.\n */\n closeTable ({ tableToString, leadingLineBreaks = 2, trailingLineBreaks = 2 }) {\n const table = this._popStackItem();\n const output = tableToString(table.rows);\n if (output) {\n addText(this._stackItem, output, leadingLineBreaks, trailingLineBreaks);\n }\n }\n\n /**\n * Return the rendered text content of this builder.\n *\n * @returns { string }\n */\n toString () {\n return getText(this._stackItem.getRoot());\n // There should only be the root item if everything is closed properly.\n }\n\n}\n\nfunction getText (stackItem) {\n if (!(\n stackItem instanceof BlockStackItem\n || stackItem instanceof ListItemStackItem\n || stackItem instanceof TableCellStackItem\n )) {\n throw new Error('Only blocks, list items and table cells can be requested for text contents.');\n }\n return (stackItem.inlineTextBuilder.isEmpty())\n ? stackItem.rawText\n : stackItem.rawText + stackItem.inlineTextBuilder.toString();\n}\n\nfunction addText (stackItem, text, leadingLineBreaks, trailingLineBreaks) {\n if (!(\n stackItem instanceof BlockStackItem\n || stackItem instanceof ListItemStackItem\n || stackItem instanceof TableCellStackItem\n )) {\n throw new Error('Only blocks, list items and table cells can contain text.');\n }\n const parentText = getText(stackItem);\n const lineBreaks = Math.max(stackItem.stashedLineBreaks, leadingLineBreaks);\n stackItem.inlineTextBuilder.clear();\n if (parentText) {\n stackItem.rawText = parentText + '\\n'.repeat(lineBreaks) + text;\n } else {\n stackItem.rawText = text;\n stackItem.leadingLineBreaks = lineBreaks;\n }\n stackItem.stashedLineBreaks = trailingLineBreaks;\n}\n\n/**\n * @param { string } str A string to transform.\n * @param { TransformerStackItem } transformer A transformer item (with possible continuation).\n * @returns { string }\n */\nfunction applyTransformer (str, transformer) {\n return ((transformer) ? applyTransformer(transformer.transform(str), transformer.next) : str);\n}\n\n/**\n * Compile selectors into a decision tree,\n * return a function intended for batch processing.\n *\n * @param { Options } [options = {}] HtmlToText options (defaults, formatters, user options merged, deduplicated).\n * @returns { (html: string, metadata?: any) => string } Pre-configured converter function.\n * @static\n */\nfunction compile$1 (options = {}) {\n const selectorsWithoutFormat = options.selectors.filter(s => !s.format);\n if (selectorsWithoutFormat.length) {\n throw new Error(\n 'Following selectors have no specified format: ' +\n selectorsWithoutFormat.map(s => `\\`${s.selector}\\``).join(', ')\n );\n }\n const picker = new DecisionTree(\n options.selectors.map(s => [s.selector, s])\n ).build(hp2Builder);\n\n if (typeof options.encodeCharacters !== 'function') {\n options.encodeCharacters = makeReplacerFromDict(options.encodeCharacters);\n }\n\n const baseSelectorsPicker = new DecisionTree(\n options.baseElements.selectors.map((s, i) => [s, i + 1])\n ).build(hp2Builder);\n function findBaseElements (dom) {\n return findBases(dom, options, baseSelectorsPicker);\n }\n\n const limitedWalk = limitedDepthRecursive(\n options.limits.maxDepth,\n recursiveWalk,\n function (dom, builder) {\n builder.addInline(options.limits.ellipsis || '');\n }\n );\n\n return function (html, metadata = undefined) {\n return process(html, metadata, options, picker, findBaseElements, limitedWalk);\n };\n}\n\n\n/**\n * Convert given HTML according to preprocessed options.\n *\n * @param { string } html HTML content to convert.\n * @param { any } metadata Optional metadata for HTML document, for use in formatters.\n * @param { Options } options HtmlToText options (preprocessed).\n * @param { import('selderee').Picker } picker\n * Tag definition picker for DOM nodes processing.\n * @param { (dom: DomNode[]) => DomNode[] } findBaseElements\n * Function to extract elements from HTML DOM\n * that will only be present in the output text.\n * @param { RecursiveCallback } walk Recursive callback.\n * @returns { string }\n */\nfunction process (html, metadata, options, picker, findBaseElements, walk) {\n const maxInputLength = options.limits.maxInputLength;\n if (maxInputLength && html && html.length > maxInputLength) {\n console.warn(\n `Input length ${html.length} is above allowed limit of ${maxInputLength}. Truncating without ellipsis.`\n );\n html = html.substring(0, maxInputLength);\n }\n\n const document = parseDocument(html, { decodeEntities: options.decodeEntities });\n const bases = findBaseElements(document.children);\n const builder = new BlockTextBuilder(options, picker, metadata);\n walk(bases, builder);\n return builder.toString();\n}\n\n\nfunction findBases (dom, options, baseSelectorsPicker) {\n const results = [];\n\n function recursiveWalk (walk, /** @type { DomNode[] } */ dom) {\n dom = dom.slice(0, options.limits.maxChildNodes);\n for (const elem of dom) {\n if (elem.type !== 'tag') {\n continue;\n }\n const pickedSelectorIndex = baseSelectorsPicker.pick1(elem);\n if (pickedSelectorIndex > 0) {\n results.push({ selectorIndex: pickedSelectorIndex, element: elem });\n } else if (elem.children) {\n walk(elem.children);\n }\n if (results.length >= options.limits.maxBaseElements) {\n return;\n }\n }\n }\n\n const limitedWalk = limitedDepthRecursive(\n options.limits.maxDepth,\n recursiveWalk\n );\n limitedWalk(dom);\n\n if (options.baseElements.orderBy !== 'occurrence') { // 'selectors'\n results.sort((a, b) => a.selectorIndex - b.selectorIndex);\n }\n return (options.baseElements.returnDomByDefault && results.length === 0)\n ? dom\n : results.map(x => x.element);\n}\n\n/**\n * Function to walk through DOM nodes and accumulate their string representations.\n *\n * @param { RecursiveCallback } walk Recursive callback.\n * @param { DomNode[] } [dom] Nodes array to process.\n * @param { BlockTextBuilder } builder Passed around to accumulate output text.\n * @private\n */\nfunction recursiveWalk (walk, dom, builder) {\n if (!dom) { return; }\n\n const options = builder.options;\n\n const tooManyChildNodes = dom.length > options.limits.maxChildNodes;\n if (tooManyChildNodes) {\n dom = dom.slice(0, options.limits.maxChildNodes);\n dom.push({\n data: options.limits.ellipsis,\n type: 'text'\n });\n }\n\n for (const elem of dom) {\n switch (elem.type) {\n case 'text': {\n builder.addInline(elem.data);\n break;\n }\n case 'tag': {\n const tagDefinition = builder.picker.pick1(elem);\n const format = options.formatters[tagDefinition.format];\n format(elem, walk, builder, tagDefinition.options || {});\n break;\n }\n }\n }\n\n return;\n}\n\n/**\n * @param { Object } dict\n * A dictionary where keys are characters to replace\n * and values are replacement strings.\n *\n * First code point from dict keys is used.\n * Compound emojis with ZWJ are not supported (not until Node 16).\n *\n * @returns { ((str: string) => string) | undefined }\n */\nfunction makeReplacerFromDict (dict) {\n if (!dict || Object.keys(dict).length === 0) {\n return undefined;\n }\n /** @type { [string, string][] } */\n const entries = Object.entries(dict).filter(([, v]) => v !== false);\n const regex = new RegExp(\n entries\n .map(([c]) => `(${unicodeEscape([...c][0])})`)\n .join('|'),\n 'g'\n );\n const values = entries.map(([, v]) => v);\n const replacer = (m, ...cgs) => values[cgs.findIndex(cg => cg)];\n return (str) => str.replace(regex, replacer);\n}\n\n/**\n * Dummy formatter that discards the input and does nothing.\n *\n * @type { FormatCallback }\n */\nfunction formatSkip (elem, walk, builder, formatOptions) {\n /* do nothing */\n}\n\n/**\n * Insert the given string literal inline instead of a tag.\n *\n * @type { FormatCallback }\n */\nfunction formatInlineString (elem, walk, builder, formatOptions) {\n builder.addLiteral(formatOptions.string || '');\n}\n\n/**\n * Insert a block with the given string literal instead of a tag.\n *\n * @type { FormatCallback }\n */\nfunction formatBlockString (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n builder.addLiteral(formatOptions.string || '');\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process an inline-level element.\n *\n * @type { FormatCallback }\n */\nfunction formatInline (elem, walk, builder, formatOptions) {\n walk(elem.children, builder);\n}\n\n/**\n * Process a block-level container.\n *\n * @type { FormatCallback }\n */\nfunction formatBlock$1 (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\nfunction renderOpenTag (elem) {\n const attrs = (elem.attribs && elem.attribs.length)\n ? ' ' + Object.entries(elem.attribs)\n .map(([k, v]) => ((v === '') ? k : `${k}=${v.replace(/\"/g, '"')}`))\n .join(' ')\n : '';\n return `<${elem.name}${attrs}>`;\n}\n\nfunction renderCloseTag (elem) {\n return `${elem.name}>`;\n}\n\n/**\n * Render an element as inline HTML tag, walk through it's children.\n *\n * @type { FormatCallback }\n */\nfunction formatInlineTag (elem, walk, builder, formatOptions) {\n builder.startNoWrap();\n builder.addLiteral(renderOpenTag(elem));\n builder.stopNoWrap();\n walk(elem.children, builder);\n builder.startNoWrap();\n builder.addLiteral(renderCloseTag(elem));\n builder.stopNoWrap();\n}\n\n/**\n * Render an element as HTML block bag, walk through it's children.\n *\n * @type { FormatCallback }\n */\nfunction formatBlockTag (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n builder.startNoWrap();\n builder.addLiteral(renderOpenTag(elem));\n builder.stopNoWrap();\n walk(elem.children, builder);\n builder.startNoWrap();\n builder.addLiteral(renderCloseTag(elem));\n builder.stopNoWrap();\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Render an element with all it's children as inline HTML.\n *\n * @type { FormatCallback }\n */\nfunction formatInlineHtml (elem, walk, builder, formatOptions) {\n builder.startNoWrap();\n builder.addLiteral(\n render(elem, { decodeEntities: builder.options.decodeEntities })\n );\n builder.stopNoWrap();\n}\n\n/**\n * Render an element with all it's children as HTML block.\n *\n * @type { FormatCallback }\n */\nfunction formatBlockHtml (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n builder.startNoWrap();\n builder.addLiteral(\n render(elem, { decodeEntities: builder.options.decodeEntities })\n );\n builder.stopNoWrap();\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Render inline element wrapped with given strings.\n *\n * @type { FormatCallback }\n */\nfunction formatInlineSurround (elem, walk, builder, formatOptions) {\n builder.addLiteral(formatOptions.prefix || '');\n walk(elem.children, builder);\n builder.addLiteral(formatOptions.suffix || '');\n}\n\nvar genericFormatters = /*#__PURE__*/Object.freeze({\n __proto__: null,\n block: formatBlock$1,\n blockHtml: formatBlockHtml,\n blockString: formatBlockString,\n blockTag: formatBlockTag,\n inline: formatInline,\n inlineHtml: formatInlineHtml,\n inlineString: formatInlineString,\n inlineSurround: formatInlineSurround,\n inlineTag: formatInlineTag,\n skip: formatSkip\n});\n\nfunction getRow (matrix, j) {\n if (!matrix[j]) { matrix[j] = []; }\n return matrix[j];\n}\n\nfunction findFirstVacantIndex (row, x = 0) {\n while (row[x]) { x++; }\n return x;\n}\n\nfunction transposeInPlace (matrix, maxSize) {\n for (let i = 0; i < maxSize; i++) {\n const rowI = getRow(matrix, i);\n for (let j = 0; j < i; j++) {\n const rowJ = getRow(matrix, j);\n if (rowI[j] || rowJ[i]) {\n const temp = rowI[j];\n rowI[j] = rowJ[i];\n rowJ[i] = temp;\n }\n }\n }\n}\n\nfunction putCellIntoLayout (cell, layout, baseRow, baseCol) {\n for (let r = 0; r < cell.rowspan; r++) {\n const layoutRow = getRow(layout, baseRow + r);\n for (let c = 0; c < cell.colspan; c++) {\n layoutRow[baseCol + c] = cell;\n }\n }\n}\n\nfunction getOrInitOffset (offsets, index) {\n if (offsets[index] === undefined) {\n offsets[index] = (index === 0) ? 0 : 1 + getOrInitOffset(offsets, index - 1);\n }\n return offsets[index];\n}\n\nfunction updateOffset (offsets, base, span, value) {\n offsets[base + span] = Math.max(\n getOrInitOffset(offsets, base + span),\n getOrInitOffset(offsets, base) + value\n );\n}\n\n/**\n * Render a table into a string.\n * Cells can contain multiline text and span across multiple rows and columns.\n *\n * Modifies cells to add lines array.\n *\n * @param { TablePrinterCell[][] } tableRows Table to render.\n * @param { number } rowSpacing Number of spaces between columns.\n * @param { number } colSpacing Number of empty lines between rows.\n * @returns { string }\n */\nfunction tableToString (tableRows, rowSpacing, colSpacing) {\n const layout = [];\n let colNumber = 0;\n const rowNumber = tableRows.length;\n const rowOffsets = [0];\n // Fill the layout table and row offsets row-by-row.\n for (let j = 0; j < rowNumber; j++) {\n const layoutRow = getRow(layout, j);\n const cells = tableRows[j];\n let x = 0;\n for (let i = 0; i < cells.length; i++) {\n const cell = cells[i];\n x = findFirstVacantIndex(layoutRow, x);\n putCellIntoLayout(cell, layout, j, x);\n x += cell.colspan;\n cell.lines = cell.text.split('\\n');\n const cellHeight = cell.lines.length;\n updateOffset(rowOffsets, j, cell.rowspan, cellHeight + rowSpacing);\n }\n colNumber = (layoutRow.length > colNumber) ? layoutRow.length : colNumber;\n }\n\n transposeInPlace(layout, (rowNumber > colNumber) ? rowNumber : colNumber);\n\n const outputLines = [];\n const colOffsets = [0];\n // Fill column offsets and output lines column-by-column.\n for (let x = 0; x < colNumber; x++) {\n let y = 0;\n let cell;\n const rowsInThisColumn = Math.min(rowNumber, layout[x].length);\n while (y < rowsInThisColumn) {\n cell = layout[x][y];\n if (cell) {\n if (!cell.rendered) {\n let cellWidth = 0;\n for (let j = 0; j < cell.lines.length; j++) {\n const line = cell.lines[j];\n const lineOffset = rowOffsets[y] + j;\n outputLines[lineOffset] = (outputLines[lineOffset] || '').padEnd(colOffsets[x]) + line;\n cellWidth = (line.length > cellWidth) ? line.length : cellWidth;\n }\n updateOffset(colOffsets, x, cell.colspan, cellWidth + colSpacing);\n cell.rendered = true;\n }\n y += cell.rowspan;\n } else {\n const lineOffset = rowOffsets[y];\n outputLines[lineOffset] = (outputLines[lineOffset] || '');\n y++;\n }\n }\n }\n\n return outputLines.join('\\n');\n}\n\n/**\n * Process a line-break.\n *\n * @type { FormatCallback }\n */\nfunction formatLineBreak (elem, walk, builder, formatOptions) {\n builder.addLineBreak();\n}\n\n/**\n * Process a `wbr` tag (word break opportunity).\n *\n * @type { FormatCallback }\n */\nfunction formatWbr (elem, walk, builder, formatOptions) {\n builder.addWordBreakOpportunity();\n}\n\n/**\n * Process a horizontal line.\n *\n * @type { FormatCallback }\n */\nfunction formatHorizontalLine (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n builder.addInline('-'.repeat(formatOptions.length || builder.options.wordwrap || 40));\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a paragraph.\n *\n * @type { FormatCallback }\n */\nfunction formatParagraph (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a preformatted content.\n *\n * @type { FormatCallback }\n */\nfunction formatPre (elem, walk, builder, formatOptions) {\n builder.openBlock({\n isPre: true,\n leadingLineBreaks: formatOptions.leadingLineBreaks || 2\n });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a heading.\n *\n * @type { FormatCallback }\n */\nfunction formatHeading (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n if (formatOptions.uppercase !== false) {\n builder.pushWordTransform(str => str.toUpperCase());\n walk(elem.children, builder);\n builder.popWordTransform();\n } else {\n walk(elem.children, builder);\n }\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a blockquote.\n *\n * @type { FormatCallback }\n */\nfunction formatBlockquote (elem, walk, builder, formatOptions) {\n builder.openBlock({\n leadingLineBreaks: formatOptions.leadingLineBreaks || 2,\n reservedLineLength: 2\n });\n walk(elem.children, builder);\n builder.closeBlock({\n trailingLineBreaks: formatOptions.trailingLineBreaks || 2,\n blockTransform: str => ((formatOptions.trimEmptyLines !== false) ? trimCharacter(str, '\\n') : str)\n .split('\\n')\n .map(line => '> ' + line)\n .join('\\n')\n });\n}\n\nfunction withBrackets (str, brackets) {\n if (!brackets) { return str; }\n\n const lbr = (typeof brackets[0] === 'string')\n ? brackets[0]\n : '[';\n const rbr = (typeof brackets[1] === 'string')\n ? brackets[1]\n : ']';\n return lbr + str + rbr;\n}\n\nfunction pathRewrite (path, rewriter, baseUrl, metadata, elem) {\n const modifiedPath = (typeof rewriter === 'function')\n ? rewriter(path, metadata, elem)\n : path;\n return (modifiedPath[0] === '/' && baseUrl)\n ? trimCharacterEnd(baseUrl, '/') + modifiedPath\n : modifiedPath;\n}\n\n/**\n * Process an image.\n *\n * @type { FormatCallback }\n */\nfunction formatImage (elem, walk, builder, formatOptions) {\n const attribs = elem.attribs || {};\n const alt = (attribs.alt)\n ? attribs.alt\n : '';\n const src = (!attribs.src)\n ? ''\n : pathRewrite(attribs.src, formatOptions.pathRewrite, formatOptions.baseUrl, builder.metadata, elem);\n const text = (!src)\n ? alt\n : (!alt)\n ? withBrackets(src, formatOptions.linkBrackets)\n : alt + ' ' + withBrackets(src, formatOptions.linkBrackets);\n\n builder.addInline(text, { noWordTransform: true });\n}\n\n// a img baseUrl\n// a img pathRewrite\n// a img linkBrackets\n\n// a ignoreHref: false\n// ignoreText ?\n// a noAnchorUrl: true\n// can be replaced with selector\n// a hideLinkHrefIfSameAsText: false\n// how to compare, what to show (text, href, normalized) ?\n// a mailto protocol removed without options\n\n// a protocols: mailto, tel, ...\n// can be matched with selector?\n\n// anchors, protocols - only if no pathRewrite fn is provided\n\n// normalize-url ?\n\n// a\n// a[href^=\"#\"] - format:skip by default\n// a[href^=\"mailto:\"] - ?\n\n/**\n * Process an anchor.\n *\n * @type { FormatCallback }\n */\nfunction formatAnchor (elem, walk, builder, formatOptions) {\n function getHref () {\n if (formatOptions.ignoreHref) { return ''; }\n if (!elem.attribs || !elem.attribs.href) { return ''; }\n let href = elem.attribs.href.replace(/^mailto:/, '');\n if (formatOptions.noAnchorUrl && href[0] === '#') { return ''; }\n href = pathRewrite(href, formatOptions.pathRewrite, formatOptions.baseUrl, builder.metadata, elem);\n return href;\n }\n const href = getHref();\n if (!href) {\n walk(elem.children, builder);\n } else {\n let text = '';\n builder.pushWordTransform(\n str => {\n if (str) { text += str; }\n return str;\n }\n );\n walk(elem.children, builder);\n builder.popWordTransform();\n\n const hideSameLink = formatOptions.hideLinkHrefIfSameAsText && href === text;\n if (!hideSameLink) {\n builder.addInline(\n (!text)\n ? href\n : ' ' + withBrackets(href, formatOptions.linkBrackets),\n { noWordTransform: true }\n );\n }\n }\n}\n\n/**\n * @param { DomNode } elem List items with their prefixes.\n * @param { RecursiveCallback } walk Recursive callback to process child nodes.\n * @param { BlockTextBuilder } builder Passed around to accumulate output text.\n * @param { FormatOptions } formatOptions Options specific to a formatter.\n * @param { () => string } nextPrefixCallback Function that returns increasing index each time it is called.\n */\nfunction formatList (elem, walk, builder, formatOptions, nextPrefixCallback) {\n const isNestedList = get(elem, ['parent', 'name']) === 'li';\n\n // With Roman numbers, index length is not as straightforward as with Arabic numbers or letters,\n // so the dumb length comparison is the most robust way to get the correct value.\n let maxPrefixLength = 0;\n const listItems = (elem.children || [])\n // it might be more accurate to check only for html spaces here, but no significant benefit\n .filter(child => child.type !== 'text' || !/^\\s*$/.test(child.data))\n .map(function (child) {\n if (child.name !== 'li') {\n return { node: child, prefix: '' };\n }\n const prefix = (isNestedList)\n ? nextPrefixCallback().trimStart()\n : nextPrefixCallback();\n if (prefix.length > maxPrefixLength) { maxPrefixLength = prefix.length; }\n return { node: child, prefix: prefix };\n });\n if (!listItems.length) { return; }\n\n builder.openList({\n interRowLineBreaks: 1,\n leadingLineBreaks: isNestedList ? 1 : (formatOptions.leadingLineBreaks || 2),\n maxPrefixLength: maxPrefixLength,\n prefixAlign: 'left'\n });\n\n for (const { node, prefix } of listItems) {\n builder.openListItem({ prefix: prefix });\n walk([node], builder);\n builder.closeListItem();\n }\n\n builder.closeList({ trailingLineBreaks: isNestedList ? 1 : (formatOptions.trailingLineBreaks || 2) });\n}\n\n/**\n * Process an unordered list.\n *\n * @type { FormatCallback }\n */\nfunction formatUnorderedList (elem, walk, builder, formatOptions) {\n const prefix = formatOptions.itemPrefix || ' * ';\n return formatList(elem, walk, builder, formatOptions, () => prefix);\n}\n\n/**\n * Process an ordered list.\n *\n * @type { FormatCallback }\n */\nfunction formatOrderedList (elem, walk, builder, formatOptions) {\n let nextIndex = Number(elem.attribs.start || '1');\n const indexFunction = getOrderedListIndexFunction(elem.attribs.type);\n const nextPrefixCallback = () => ' ' + indexFunction(nextIndex++) + '. ';\n return formatList(elem, walk, builder, formatOptions, nextPrefixCallback);\n}\n\n/**\n * Return a function that can be used to generate index markers of a specified format.\n *\n * @param { string } [olType='1'] Marker type.\n * @returns { (i: number) => string }\n */\nfunction getOrderedListIndexFunction (olType = '1') {\n switch (olType) {\n case 'a': return (i) => numberToLetterSequence(i, 'a');\n case 'A': return (i) => numberToLetterSequence(i, 'A');\n case 'i': return (i) => numberToRoman(i).toLowerCase();\n case 'I': return (i) => numberToRoman(i);\n case '1':\n default: return (i) => (i).toString();\n }\n}\n\n/**\n * Given a list of class and ID selectors (prefixed with '.' and '#'),\n * return them as separate lists of names without prefixes.\n *\n * @param { string[] } selectors Class and ID selectors (`[\".class\", \"#id\"]` etc).\n * @returns { { classes: string[], ids: string[] } }\n */\nfunction splitClassesAndIds (selectors) {\n const classes = [];\n const ids = [];\n for (const selector of selectors) {\n if (selector.startsWith('.')) {\n classes.push(selector.substring(1));\n } else if (selector.startsWith('#')) {\n ids.push(selector.substring(1));\n }\n }\n return { classes: classes, ids: ids };\n}\n\nfunction isDataTable (attr, tables) {\n if (tables === true) { return true; }\n if (!attr) { return false; }\n\n const { classes, ids } = splitClassesAndIds(tables);\n const attrClasses = (attr['class'] || '').split(' ');\n const attrIds = (attr['id'] || '').split(' ');\n\n return attrClasses.some(x => classes.includes(x)) || attrIds.some(x => ids.includes(x));\n}\n\n/**\n * Process a table (either as a container or as a data table, depending on options).\n *\n * @type { FormatCallback }\n */\nfunction formatTable (elem, walk, builder, formatOptions) {\n return isDataTable(elem.attribs, builder.options.tables)\n ? formatDataTable(elem, walk, builder, formatOptions)\n : formatBlock(elem, walk, builder, formatOptions);\n}\n\nfunction formatBlock (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks });\n}\n\n/**\n * Process a data table.\n *\n * @type { FormatCallback }\n */\nfunction formatDataTable (elem, walk, builder, formatOptions) {\n builder.openTable();\n elem.children.forEach(walkTable);\n builder.closeTable({\n tableToString: (rows) => tableToString(rows, formatOptions.rowSpacing ?? 0, formatOptions.colSpacing ?? 3),\n leadingLineBreaks: formatOptions.leadingLineBreaks,\n trailingLineBreaks: formatOptions.trailingLineBreaks\n });\n\n function formatCell (cellNode) {\n const colspan = +get(cellNode, ['attribs', 'colspan']) || 1;\n const rowspan = +get(cellNode, ['attribs', 'rowspan']) || 1;\n builder.openTableCell({ maxColumnWidth: formatOptions.maxColumnWidth });\n walk(cellNode.children, builder);\n builder.closeTableCell({ colspan: colspan, rowspan: rowspan });\n }\n\n function walkTable (elem) {\n if (elem.type !== 'tag') { return; }\n\n const formatHeaderCell = (formatOptions.uppercaseHeaderCells !== false)\n ? (cellNode) => {\n builder.pushWordTransform(str => str.toUpperCase());\n formatCell(cellNode);\n builder.popWordTransform();\n }\n : formatCell;\n\n switch (elem.name) {\n case 'thead':\n case 'tbody':\n case 'tfoot':\n case 'center':\n elem.children.forEach(walkTable);\n return;\n\n case 'tr': {\n builder.openTableRow();\n for (const childOfTr of elem.children) {\n if (childOfTr.type !== 'tag') { continue; }\n switch (childOfTr.name) {\n case 'th': {\n formatHeaderCell(childOfTr);\n break;\n }\n case 'td': {\n formatCell(childOfTr);\n break;\n }\n // do nothing\n }\n }\n builder.closeTableRow();\n break;\n }\n // do nothing\n }\n }\n}\n\nvar textFormatters = /*#__PURE__*/Object.freeze({\n __proto__: null,\n anchor: formatAnchor,\n blockquote: formatBlockquote,\n dataTable: formatDataTable,\n heading: formatHeading,\n horizontalLine: formatHorizontalLine,\n image: formatImage,\n lineBreak: formatLineBreak,\n orderedList: formatOrderedList,\n paragraph: formatParagraph,\n pre: formatPre,\n table: formatTable,\n unorderedList: formatUnorderedList,\n wbr: formatWbr\n});\n\n/**\n * Default options.\n *\n * @constant\n * @type { Options }\n * @default\n * @private\n */\nconst DEFAULT_OPTIONS = {\n baseElements: {\n selectors: [ 'body' ],\n orderBy: 'selectors', // 'selectors' | 'occurrence'\n returnDomByDefault: true\n },\n decodeEntities: true,\n encodeCharacters: {},\n formatters: {},\n limits: {\n ellipsis: '...',\n maxBaseElements: undefined,\n maxChildNodes: undefined,\n maxDepth: undefined,\n maxInputLength: (1 << 24) // 16_777_216\n },\n longWordSplit: {\n forceWrapOnLimit: false,\n wrapCharacters: []\n },\n preserveNewlines: false,\n selectors: [\n { selector: '*', format: 'inline' },\n {\n selector: 'a',\n format: 'anchor',\n options: {\n baseUrl: null,\n hideLinkHrefIfSameAsText: false,\n ignoreHref: false,\n linkBrackets: ['[', ']'],\n noAnchorUrl: true\n }\n },\n { selector: 'article', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n { selector: 'aside', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n {\n selector: 'blockquote',\n format: 'blockquote',\n options: { leadingLineBreaks: 2, trailingLineBreaks: 2, trimEmptyLines: true }\n },\n { selector: 'br', format: 'lineBreak' },\n { selector: 'div', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n { selector: 'footer', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n { selector: 'form', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n { selector: 'h1', format: 'heading', options: { leadingLineBreaks: 3, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h2', format: 'heading', options: { leadingLineBreaks: 3, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h3', format: 'heading', options: { leadingLineBreaks: 3, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h4', format: 'heading', options: { leadingLineBreaks: 2, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h5', format: 'heading', options: { leadingLineBreaks: 2, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h6', format: 'heading', options: { leadingLineBreaks: 2, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'header', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n {\n selector: 'hr',\n format: 'horizontalLine',\n options: { leadingLineBreaks: 2, length: undefined, trailingLineBreaks: 2 }\n },\n {\n selector: 'img',\n format: 'image',\n options: { baseUrl: null, linkBrackets: ['[', ']'] }\n },\n { selector: 'main', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n { selector: 'nav', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n {\n selector: 'ol',\n format: 'orderedList',\n options: { leadingLineBreaks: 2, trailingLineBreaks: 2 }\n },\n { selector: 'p', format: 'paragraph', options: { leadingLineBreaks: 2, trailingLineBreaks: 2 } },\n { selector: 'pre', format: 'pre', options: { leadingLineBreaks: 2, trailingLineBreaks: 2 } },\n { selector: 'section', format: 'block', options: { leadingLineBreaks: 1, trailingLineBreaks: 1 } },\n {\n selector: 'table',\n format: 'table',\n options: {\n colSpacing: 3,\n leadingLineBreaks: 2,\n maxColumnWidth: 60,\n rowSpacing: 0,\n trailingLineBreaks: 2,\n uppercaseHeaderCells: true\n }\n },\n {\n selector: 'ul',\n format: 'unorderedList',\n options: { itemPrefix: ' * ', leadingLineBreaks: 2, trailingLineBreaks: 2 }\n },\n { selector: 'wbr', format: 'wbr' },\n ],\n tables: [], // deprecated\n whitespaceCharacters: ' \\t\\r\\n\\f\\u200b',\n wordwrap: 80\n};\n\nconst concatMerge = (acc, src, options) => [...acc, ...src];\nconst overwriteMerge = (acc, src, options) => [...src];\nconst selectorsMerge = (acc, src, options) => (\n (acc.some(s => typeof s === 'object'))\n ? concatMerge(acc, src) // selectors\n : overwriteMerge(acc, src) // baseElements.selectors\n);\n\n/**\n * Preprocess options, compile selectors into a decision tree,\n * return a function intended for batch processing.\n *\n * @param { Options } [options = {}] HtmlToText options.\n * @returns { (html: string, metadata?: any) => string } Pre-configured converter function.\n * @static\n */\nfunction compile (options = {}) {\n options = merge(\n DEFAULT_OPTIONS,\n options,\n {\n arrayMerge: overwriteMerge,\n customMerge: (key) => ((key === 'selectors') ? selectorsMerge : undefined)\n }\n );\n options.formatters = Object.assign({}, genericFormatters, textFormatters, options.formatters);\n options.selectors = mergeDuplicatesPreferLast(options.selectors, (s => s.selector));\n\n handleDeprecatedOptions(options);\n\n return compile$1(options);\n}\n\n/**\n * Convert given HTML content to plain text string.\n *\n * @param { string } html HTML content to convert.\n * @param { Options } [options = {}] HtmlToText options.\n * @param { any } [metadata] Optional metadata for HTML document, for use in formatters.\n * @returns { string } Plain text string.\n * @static\n *\n * @example\n * const { convert } = require('html-to-text');\n * const text = convert('Hello World
', {\n * wordwrap: 130\n * });\n * console.log(text); // HELLO WORLD\n */\nfunction convert (html, options = {}, metadata = undefined) {\n return compile(options)(html, metadata);\n}\n\n/**\n * Map previously existing and now deprecated options to the new options layout.\n * This is a subject for cleanup in major releases.\n *\n * @param { Options } options HtmlToText options.\n */\nfunction handleDeprecatedOptions (options) {\n if (options.tags) {\n const tagDefinitions = Object.entries(options.tags).map(\n ([selector, definition]) => ({ ...definition, selector: selector || '*' })\n );\n options.selectors.push(...tagDefinitions);\n options.selectors = mergeDuplicatesPreferLast(options.selectors, (s => s.selector));\n }\n\n function set (obj, path, value) {\n const valueKey = path.pop();\n for (const key of path) {\n let nested = obj[key];\n if (!nested) {\n nested = {};\n obj[key] = nested;\n }\n obj = nested;\n }\n obj[valueKey] = value;\n }\n\n if (options['baseElement']) {\n const baseElement = options['baseElement'];\n set(\n options,\n ['baseElements', 'selectors'],\n (Array.isArray(baseElement) ? baseElement : [baseElement])\n );\n }\n if (options['returnDomByDefault'] !== undefined) {\n set(options, ['baseElements', 'returnDomByDefault'], options['returnDomByDefault']);\n }\n\n for (const definition of options.selectors) {\n if (definition.format === 'anchor' && get(definition, ['options', 'noLinkBrackets'])) {\n set(definition, ['options', 'linkBrackets'], false);\n }\n }\n}\n\nexport { compile, convert, convert as htmlToText };\n"],"names":["limitedDepthRecursive","f","g","f1","args","trimCharacter","str","char","start","end","trimCharacterEnd","unicodeEscape","c","mergeDuplicatesPreferLast","items","getKey","map","i","item","key","merge","overwriteMerge$1","acc","src","options","get","obj","path","numberToLetterSequence","num","baseChar","base","digits","baseCode","n","I","V","numberToRoman","v","InlineTextBuilder","maxLineLength","word","noWrap","isLineStart","cost","first","rest","part","lastWord","words","parts","idx","firstLine","remainingChars","splitIndex","StackItem","next","BlockStackItem","leadingLineBreaks","ListStackItem","interRowLineBreaks","maxPrefixLength","prefixAlign","ListItemStackItem","prefix","TableStackItem","TableRowStackItem","TableCellStackItem","maxColumnWidth","TransformerStackItem","transform","charactersToCodes","WhitespaceProcessor","whitespaceCodes","wordOrNewlineRe","text","inlineTextBuilder","previouslyStashedSpace","anyMatch","m","wordRe","counter","match","BlockTextBuilder","picker","metadata","wordTransform","wt","applyTransformer","ce","noWordTransform","newlinesNumber","reservedLineLength","isPre","trailingLineBreaks","blockTransform","block","blockText","getText","addText","list","prefixLength","listItem","spacing","colspan","rowspan","cell","row","tableToString","table","output","stackItem","parentText","lineBreaks","transformer","compile$1","selectorsWithoutFormat","s","DecisionTree","hp2Builder","makeReplacerFromDict","baseSelectorsPicker","findBaseElements","dom","findBases","limitedWalk","recursiveWalk","builder","html","process","walk","maxInputLength","document","parseDocument","bases","results","elem","pickedSelectorIndex","a","b","x","tagDefinition","format","dict","entries","regex","values","replacer","cgs","cg","formatSkip","formatOptions","formatInlineString","formatBlockString","formatInline","formatBlock$1","renderOpenTag","attrs","k","renderCloseTag","formatInlineTag","formatBlockTag","formatInlineHtml","render","formatBlockHtml","formatInlineSurround","genericFormatters","getRow","matrix","j","findFirstVacantIndex","transposeInPlace","maxSize","rowI","rowJ","temp","putCellIntoLayout","layout","baseRow","baseCol","r","layoutRow","getOrInitOffset","offsets","index","updateOffset","span","value","tableRows","rowSpacing","colSpacing","colNumber","rowNumber","rowOffsets","cells","cellHeight","outputLines","colOffsets","y","rowsInThisColumn","cellWidth","line","lineOffset","formatLineBreak","formatWbr","formatHorizontalLine","formatParagraph","formatPre","formatHeading","formatBlockquote","withBrackets","brackets","lbr","rbr","pathRewrite","rewriter","baseUrl","modifiedPath","formatImage","attribs","alt","formatAnchor","getHref","href","formatList","nextPrefixCallback","isNestedList","listItems","child","node","formatUnorderedList","formatOrderedList","nextIndex","indexFunction","getOrderedListIndexFunction","olType","splitClassesAndIds","selectors","classes","ids","selector","isDataTable","attr","tables","attrClasses","attrIds","formatTable","formatDataTable","formatBlock","walkTable","rows","formatCell","cellNode","formatHeaderCell","childOfTr","textFormatters","DEFAULT_OPTIONS","concatMerge","overwriteMerge","selectorsMerge","compile","handleDeprecatedOptions","convert","tagDefinitions","definition","set","valueKey","nested","baseElement"],"mappings":"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","x_google_ignoreList":[0]}