tasq/node_modules/marked-terminal/index.cjs

1368 lines
33 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var process$1 = require('node:process');
var os = require('node:os');
var tty = require('node:tty');
var Table = require('cli-table3');
var cardinal = require('cardinal');
var emoji = require('node-emoji');
var supportsHyperlinks = require('supports-hyperlinks');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var emoji__namespace = /*#__PURE__*/_interopNamespaceDefault(emoji);
const ANSI_BACKGROUND_OFFSET = 10;
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
const styles$1 = {
modifier: {
reset: [0, 0],
// 21 isn't widely supported and 22 does the same thing
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
overline: [53, 55],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29],
},
color: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
// Bright color
blackBright: [90, 39],
gray: [90, 39], // Alias of `blackBright`
grey: [90, 39], // Alias of `blackBright`
redBright: [91, 39],
greenBright: [92, 39],
yellowBright: [93, 39],
blueBright: [94, 39],
magentaBright: [95, 39],
cyanBright: [96, 39],
whiteBright: [97, 39],
},
bgColor: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// Bright color
bgBlackBright: [100, 49],
bgGray: [100, 49], // Alias of `bgBlackBright`
bgGrey: [100, 49], // Alias of `bgBlackBright`
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49],
},
};
Object.keys(styles$1.modifier);
const foregroundColorNames = Object.keys(styles$1.color);
const backgroundColorNames = Object.keys(styles$1.bgColor);
[...foregroundColorNames, ...backgroundColorNames];
function assembleStyles() {
const codes = new Map();
for (const [groupName, group] of Object.entries(styles$1)) {
for (const [styleName, style] of Object.entries(group)) {
styles$1[styleName] = {
open: `\u001B[${style[0]}m`,
close: `\u001B[${style[1]}m`,
};
group[styleName] = styles$1[styleName];
codes.set(style[0], style[1]);
}
Object.defineProperty(styles$1, groupName, {
value: group,
enumerable: false,
});
}
Object.defineProperty(styles$1, 'codes', {
value: codes,
enumerable: false,
});
styles$1.color.close = '\u001B[39m';
styles$1.bgColor.close = '\u001B[49m';
styles$1.color.ansi = wrapAnsi16();
styles$1.color.ansi256 = wrapAnsi256();
styles$1.color.ansi16m = wrapAnsi16m();
styles$1.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
styles$1.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
styles$1.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
Object.defineProperties(styles$1, {
rgbToAnsi256: {
value(red, green, blue) {
// We use the extended greyscale palette here, with the exception of
// black and white. normal palette only has 4 greyscale shades.
if (red === green && green === blue) {
if (red < 8) {
return 16;
}
if (red > 248) {
return 231;
}
return Math.round(((red - 8) / 247) * 24) + 232;
}
return 16
+ (36 * Math.round(red / 255 * 5))
+ (6 * Math.round(green / 255 * 5))
+ Math.round(blue / 255 * 5);
},
enumerable: false,
},
hexToRgb: {
value(hex) {
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
if (!matches) {
return [0, 0, 0];
}
let [colorString] = matches;
if (colorString.length === 3) {
colorString = [...colorString].map(character => character + character).join('');
}
const integer = Number.parseInt(colorString, 16);
return [
/* eslint-disable no-bitwise */
(integer >> 16) & 0xFF,
(integer >> 8) & 0xFF,
integer & 0xFF,
/* eslint-enable no-bitwise */
];
},
enumerable: false,
},
hexToAnsi256: {
value: hex => styles$1.rgbToAnsi256(...styles$1.hexToRgb(hex)),
enumerable: false,
},
ansi256ToAnsi: {
value(code) {
if (code < 8) {
return 30 + code;
}
if (code < 16) {
return 90 + (code - 8);
}
let red;
let green;
let blue;
if (code >= 232) {
red = (((code - 232) * 10) + 8) / 255;
green = red;
blue = red;
} else {
code -= 16;
const remainder = code % 36;
red = Math.floor(code / 36) / 5;
green = Math.floor(remainder / 6) / 5;
blue = (remainder % 6) / 5;
}
const value = Math.max(red, green, blue) * 2;
if (value === 0) {
return 30;
}
// eslint-disable-next-line no-bitwise
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
if (value === 2) {
result += 60;
}
return result;
},
enumerable: false,
},
rgbToAnsi: {
value: (red, green, blue) => styles$1.ansi256ToAnsi(styles$1.rgbToAnsi256(red, green, blue)),
enumerable: false,
},
hexToAnsi: {
value: hex => styles$1.ansi256ToAnsi(styles$1.hexToAnsi256(hex)),
enumerable: false,
},
});
return styles$1;
}
const ansiStyles = assembleStyles();
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
const position = argv.indexOf(prefix + flag);
const terminatorPosition = argv.indexOf('--');
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
const {env} = process$1;
let flagForceColor;
if (
hasFlag('no-color')
|| hasFlag('no-colors')
|| hasFlag('color=false')
|| hasFlag('color=never')
) {
flagForceColor = 0;
} else if (
hasFlag('color')
|| hasFlag('colors')
|| hasFlag('color=true')
|| hasFlag('color=always')
) {
flagForceColor = 1;
}
function envForceColor() {
if ('FORCE_COLOR' in env) {
if (env.FORCE_COLOR === 'true') {
return 1;
}
if (env.FORCE_COLOR === 'false') {
return 0;
}
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
}
}
function translateLevel(level) {
if (level === 0) {
return false;
}
return {
level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3,
};
}
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
const noFlagForceColor = envForceColor();
if (noFlagForceColor !== undefined) {
flagForceColor = noFlagForceColor;
}
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
if (forceColor === 0) {
return 0;
}
if (sniffFlags) {
if (hasFlag('color=16m')
|| hasFlag('color=full')
|| hasFlag('color=truecolor')) {
return 3;
}
if (hasFlag('color=256')) {
return 2;
}
}
// Check for Azure DevOps pipelines.
// Has to be above the `!streamIsTTY` check.
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
return 1;
}
if (haveStream && !streamIsTTY && forceColor === undefined) {
return 0;
}
const min = forceColor || 0;
if (env.TERM === 'dumb') {
return min;
}
if (process$1.platform === 'win32') {
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
const osRelease = os.release().split('.');
if (
Number(osRelease[0]) >= 10
&& Number(osRelease[2]) >= 10_586
) {
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
}
return 1;
}
if ('CI' in env) {
if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
return 3;
}
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
return 1;
}
return min;
}
if ('TEAMCITY_VERSION' in env) {
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
}
if (env.COLORTERM === 'truecolor') {
return 3;
}
if (env.TERM === 'xterm-kitty') {
return 3;
}
if ('TERM_PROGRAM' in env) {
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
switch (env.TERM_PROGRAM) {
case 'iTerm.app': {
return version >= 3 ? 3 : 2;
}
case 'Apple_Terminal': {
return 2;
}
// No default
}
}
if (/-256(color)?$/i.test(env.TERM)) {
return 2;
}
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
return 1;
}
if ('COLORTERM' in env) {
return 1;
}
return min;
}
function createSupportsColor(stream, options = {}) {
const level = _supportsColor(stream, {
streamIsTTY: stream && stream.isTTY,
...options,
});
return translateLevel(level);
}
const supportsColor = {
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
};
// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.
function stringReplaceAll(string, substring, replacer) {
let index = string.indexOf(substring);
if (index === -1) {
return string;
}
const substringLength = substring.length;
let endIndex = 0;
let returnValue = '';
do {
returnValue += string.slice(endIndex, index) + substring + replacer;
endIndex = index + substringLength;
index = string.indexOf(substring, endIndex);
} while (index !== -1);
returnValue += string.slice(endIndex);
return returnValue;
}
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
let endIndex = 0;
let returnValue = '';
do {
const gotCR = string[index - 1] === '\r';
returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix;
endIndex = index + 1;
index = string.indexOf('\n', endIndex);
} while (index !== -1);
returnValue += string.slice(endIndex);
return returnValue;
}
const {stdout: stdoutColor, stderr: stderrColor} = supportsColor;
const GENERATOR = Symbol('GENERATOR');
const STYLER = Symbol('STYLER');
const IS_EMPTY = Symbol('IS_EMPTY');
// `supportsColor.level` → `ansiStyles.color[name]` mapping
const levelMapping = [
'ansi',
'ansi',
'ansi256',
'ansi16m',
];
const styles = Object.create(null);
const applyOptions = (object, options = {}) => {
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
throw new Error('The `level` option should be an integer from 0 to 3');
}
// Detect level if not set manually
const colorLevel = stdoutColor ? stdoutColor.level : 0;
object.level = options.level === undefined ? colorLevel : options.level;
};
const chalkFactory = options => {
const chalk = (...strings) => strings.join(' ');
applyOptions(chalk, options);
Object.setPrototypeOf(chalk, createChalk.prototype);
return chalk;
};
function createChalk(options) {
return chalkFactory(options);
}
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
for (const [styleName, style] of Object.entries(ansiStyles)) {
styles[styleName] = {
get() {
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
Object.defineProperty(this, styleName, {value: builder});
return builder;
},
};
}
styles.visible = {
get() {
const builder = createBuilder(this, this[STYLER], true);
Object.defineProperty(this, 'visible', {value: builder});
return builder;
},
};
const getModelAnsi = (model, level, type, ...arguments_) => {
if (model === 'rgb') {
if (level === 'ansi16m') {
return ansiStyles[type].ansi16m(...arguments_);
}
if (level === 'ansi256') {
return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));
}
return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));
}
if (model === 'hex') {
return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));
}
return ansiStyles[type][model](...arguments_);
};
const usedModels = ['rgb', 'hex', 'ansi256'];
for (const model of usedModels) {
styles[model] = {
get() {
const {level} = this;
return function (...arguments_) {
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);
return createBuilder(this, styler, this[IS_EMPTY]);
};
},
};
const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
styles[bgModel] = {
get() {
const {level} = this;
return function (...arguments_) {
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);
return createBuilder(this, styler, this[IS_EMPTY]);
};
},
};
}
const proto = Object.defineProperties(() => {}, {
...styles,
level: {
enumerable: true,
get() {
return this[GENERATOR].level;
},
set(level) {
this[GENERATOR].level = level;
},
},
});
const createStyler = (open, close, parent) => {
let openAll;
let closeAll;
if (parent === undefined) {
openAll = open;
closeAll = close;
} else {
openAll = parent.openAll + open;
closeAll = close + parent.closeAll;
}
return {
open,
close,
openAll,
closeAll,
parent,
};
};
const createBuilder = (self, _styler, _isEmpty) => {
// Single argument is hot path, implicit coercion is faster than anything
// eslint-disable-next-line no-implicit-coercion
const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
// We alter the prototype because we must return a function, but there is
// no way to create a function with a different prototype
Object.setPrototypeOf(builder, proto);
builder[GENERATOR] = self;
builder[STYLER] = _styler;
builder[IS_EMPTY] = _isEmpty;
return builder;
};
const applyStyle = (self, string) => {
if (self.level <= 0 || !string) {
return self[IS_EMPTY] ? '' : string;
}
let styler = self[STYLER];
if (styler === undefined) {
return string;
}
const {openAll, closeAll} = styler;
if (string.includes('\u001B')) {
while (styler !== undefined) {
// Replace any instances already present with a re-opening code
// otherwise only the part of the string until said closing code
// will be colored, and the rest will simply be 'plain'.
string = stringReplaceAll(string, styler.close, styler.open);
styler = styler.parent;
}
}
// We can move both next actions out of loop, because remaining actions in loop won't have
// any/visible effect on parts we add here. Close the styling before a linebreak and reopen
// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92
const lfIndex = string.indexOf('\n');
if (lfIndex !== -1) {
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
}
return openAll + string + closeAll;
};
Object.defineProperties(createChalk.prototype, styles);
const chalk = createChalk();
createChalk({level: stderrColor ? stderrColor.level : 0});
var chalk$1 = chalk;
const ESC = '\u001B[';
const OSC = '\u001B]';
const BEL = '\u0007';
const SEP = ';';
/* global window */
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
const isTerminalApp = !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
const isWindows = !isBrowser && process$1.platform === 'win32';
const cwdFunction = isBrowser ? () => {
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
} : process$1.cwd;
const ansiEscapes = {};
ansiEscapes.cursorTo = (x, y) => {
if (typeof x !== 'number') {
throw new TypeError('The `x` argument is required');
}
if (typeof y !== 'number') {
return ESC + (x + 1) + 'G';
}
return ESC + (y + 1) + SEP + (x + 1) + 'H';
};
ansiEscapes.cursorMove = (x, y) => {
if (typeof x !== 'number') {
throw new TypeError('The `x` argument is required');
}
let returnValue = '';
if (x < 0) {
returnValue += ESC + (-x) + 'D';
} else if (x > 0) {
returnValue += ESC + x + 'C';
}
if (y < 0) {
returnValue += ESC + (-y) + 'A';
} else if (y > 0) {
returnValue += ESC + y + 'B';
}
return returnValue;
};
ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A';
ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B';
ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C';
ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
ansiEscapes.cursorLeft = ESC + 'G';
ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
ansiEscapes.cursorGetPosition = ESC + '6n';
ansiEscapes.cursorNextLine = ESC + 'E';
ansiEscapes.cursorPrevLine = ESC + 'F';
ansiEscapes.cursorHide = ESC + '?25l';
ansiEscapes.cursorShow = ESC + '?25h';
ansiEscapes.eraseLines = count => {
let clear = '';
for (let i = 0; i < count; i++) {
clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : '');
}
if (count) {
clear += ansiEscapes.cursorLeft;
}
return clear;
};
ansiEscapes.eraseEndLine = ESC + 'K';
ansiEscapes.eraseStartLine = ESC + '1K';
ansiEscapes.eraseLine = ESC + '2K';
ansiEscapes.eraseDown = ESC + 'J';
ansiEscapes.eraseUp = ESC + '1J';
ansiEscapes.eraseScreen = ESC + '2J';
ansiEscapes.scrollUp = ESC + 'S';
ansiEscapes.scrollDown = ESC + 'T';
ansiEscapes.clearScreen = '\u001Bc';
ansiEscapes.clearTerminal = isWindows
? `${ansiEscapes.eraseScreen}${ESC}0f`
// 1. Erases the screen (Only done in case `2` is not supported)
// 2. Erases the whole screen including scrollback buffer
// 3. Moves cursor to the top-left position
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
: `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
ansiEscapes.enterAlternativeScreen = ESC + '?1049h';
ansiEscapes.exitAlternativeScreen = ESC + '?1049l';
ansiEscapes.beep = BEL;
ansiEscapes.link = (text, url) => [
OSC,
'8',
SEP,
SEP,
url,
BEL,
text,
OSC,
'8',
SEP,
SEP,
BEL,
].join('');
ansiEscapes.image = (buffer, options = {}) => {
let returnValue = `${OSC}1337;File=inline=1`;
if (options.width) {
returnValue += `;width=${options.width}`;
}
if (options.height) {
returnValue += `;height=${options.height}`;
}
if (options.preserveAspectRatio === false) {
returnValue += ';preserveAspectRatio=0';
}
return returnValue + ':' + buffer.toString('base64') + BEL;
};
ansiEscapes.iTerm = {
setCwd: (cwd = cwdFunction()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
annotation(message, options = {}) {
let returnValue = `${OSC}1337;`;
const hasX = typeof options.x !== 'undefined';
const hasY = typeof options.y !== 'undefined';
if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
}
message = message.replace(/\|/g, '');
returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
if (options.length > 0) {
returnValue += (
hasX
? [message, options.length, options.x, options.y]
: [options.length, message]
).join('|');
} else {
returnValue += message;
}
return returnValue + BEL;
},
};
var TABLE_CELL_SPLIT = '^*||*^';
var TABLE_ROW_WRAP = '*|*|*|*';
var TABLE_ROW_WRAP_REGEXP = new RegExp(escapeRegExp(TABLE_ROW_WRAP), 'g');
var COLON_REPLACER = '*#COLON|*';
var COLON_REPLACER_REGEXP = new RegExp(escapeRegExp(COLON_REPLACER), 'g');
var TAB_ALLOWED_CHARACTERS = ['\t'];
// HARD_RETURN holds a character sequence used to indicate text has a
// hard (no-reflowing) line break. Previously \r and \r\n were turned
// into \n in marked's lexer- preprocessing step. So \r is safe to use
// to indicate a hard (non-reflowed) return.
var HARD_RETURN = '\r',
HARD_RETURN_RE = new RegExp(HARD_RETURN),
HARD_RETURN_GFM_RE = new RegExp(HARD_RETURN + '|<br />');
var defaultOptions = {
code: chalk$1.yellow,
blockquote: chalk$1.gray.italic,
html: chalk$1.gray,
heading: chalk$1.green.bold,
firstHeading: chalk$1.magenta.underline.bold,
hr: chalk$1.reset,
listitem: chalk$1.reset,
list: list,
table: chalk$1.reset,
paragraph: chalk$1.reset,
strong: chalk$1.bold,
em: chalk$1.italic,
codespan: chalk$1.yellow,
del: chalk$1.dim.gray.strikethrough,
link: chalk$1.blue,
href: chalk$1.blue.underline,
text: identity,
unescape: true,
emoji: true,
width: 80,
showSectionPrefix: true,
reflowText: false,
tab: 4,
tableOptions: {}
};
function Renderer(options, highlightOptions) {
this.o = Object.assign({}, defaultOptions, options);
this.tab = sanitizeTab(this.o.tab, defaultOptions.tab);
this.tableSettings = this.o.tableOptions;
this.emoji = this.o.emoji ? insertEmojis : identity;
this.unescape = this.o.unescape ? unescapeEntities : identity;
this.highlightOptions = highlightOptions || {};
this.transform = compose(undoColon, this.unescape, this.emoji);
}
// Compute length of str not including ANSI escape codes.
// See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
function textLength(str) {
return str.replace(/\u001b\[(?:\d{1,3})(?:;\d{1,3})*m/g, '').length;
}
Renderer.prototype.textLength = textLength;
function fixHardReturn(text, reflow) {
return reflow ? text.replace(HARD_RETURN, /\n/g) : text;
}
Renderer.prototype.text = function (text) {
return this.o.text(text);
};
Renderer.prototype.code = function (code, lang, escaped) {
return section(
indentify(this.tab, highlight(code, lang, this.o, this.highlightOptions))
);
};
Renderer.prototype.blockquote = function (quote) {
return section(this.o.blockquote(indentify(this.tab, quote.trim())));
};
Renderer.prototype.html = function (html) {
return this.o.html(html);
};
Renderer.prototype.heading = function (text, level, raw) {
text = this.transform(text);
var prefix = this.o.showSectionPrefix
? new Array(level + 1).join('#') + ' '
: '';
text = prefix + text;
if (this.o.reflowText) {
text = reflowText(text, this.o.width, this.options.gfm);
}
return section(
level === 1 ? this.o.firstHeading(text) : this.o.heading(text)
);
};
Renderer.prototype.hr = function () {
return section(this.o.hr(hr('-', this.o.reflowText && this.o.width)));
};
Renderer.prototype.list = function (body, ordered) {
body = this.o.list(body, ordered, this.tab);
return section(fixNestedLists(indentLines(this.tab, body), this.tab));
};
Renderer.prototype.listitem = function (text) {
var transform = compose(this.o.listitem, this.transform);
var isNested = text.indexOf('\n') !== -1;
if (isNested) text = text.trim();
// Use BULLET_POINT as a marker for ordered or unordered list item
return '\n' + BULLET_POINT + transform(text);
};
Renderer.prototype.checkbox = function (checked) {
return '[' + (checked ? 'X' : ' ') + '] ';
};
Renderer.prototype.paragraph = function (text) {
var transform = compose(this.o.paragraph, this.transform);
text = transform(text);
if (this.o.reflowText) {
text = reflowText(text, this.o.width, this.options.gfm);
}
return section(text);
};
Renderer.prototype.table = function (header, body) {
var table = new Table(
Object.assign(
{},
{
head: generateTableRow(header)[0]
},
this.tableSettings
)
);
generateTableRow(body, this.transform).forEach(function (row) {
table.push(row);
});
return section(this.o.table(table.toString()));
};
Renderer.prototype.tablerow = function (content) {
return TABLE_ROW_WRAP + content + TABLE_ROW_WRAP + '\n';
};
Renderer.prototype.tablecell = function (content, flags) {
return content + TABLE_CELL_SPLIT;
};
// span level renderer
Renderer.prototype.strong = function (text) {
return this.o.strong(text);
};
Renderer.prototype.em = function (text) {
text = fixHardReturn(text, this.o.reflowText);
return this.o.em(text);
};
Renderer.prototype.codespan = function (text) {
text = fixHardReturn(text, this.o.reflowText);
return this.o.codespan(text.replace(/:/g, COLON_REPLACER));
};
Renderer.prototype.br = function () {
return this.o.reflowText ? HARD_RETURN : '\n';
};
Renderer.prototype.del = function (text) {
return this.o.del(text);
};
Renderer.prototype.link = function (href, title, text) {
if (this.options.sanitize) {
try {
var prot = decodeURIComponent(unescape(href))
.replace(/[^\w:]/g, '')
.toLowerCase();
} catch (e) {
return '';
}
if (prot.indexOf('javascript:') === 0) {
return '';
}
}
var hasText = text && text !== href;
var out = '';
if (supportsHyperlinks.stdout) {
let link = '';
if (text) {
link = this.o.href(this.emoji(text));
} else {
link = this.o.href(href);
}
out = ansiEscapes.link(link, href);
} else {
if (hasText) out += this.emoji(text) + ' (';
out += this.o.href(href);
if (hasText) out += ')';
}
return this.o.link(out);
};
Renderer.prototype.image = function (href, title, text) {
if (typeof this.o.image === 'function') {
return this.o.image(href, title, text);
}
var out = '![' + text;
if (title) out += ' ' + title;
return out + '](' + href + ')\n';
};
function markedTerminal(options, highlightOptions) {
const r = new Renderer(options, highlightOptions);
const funcs = [
'text',
'code',
'blockquote',
'html',
'heading',
'hr',
'list',
'listitem',
'checkbox',
'paragraph',
'table',
'tablerow',
'tablecell',
'strong',
'em',
'codespan',
'br',
'del',
'link',
'image'
];
return funcs.reduce(
(extension, func) => {
extension.renderer[func] = function (...args) {
r.options = this.options;
return r[func](...args);
};
return extension;
},
{ renderer: {} }
);
}
// Munge \n's and spaces in "text" so that the number of
// characters between \n's is less than or equal to "width".
function reflowText(text, width, gfm) {
// Hard break was inserted by Renderer.prototype.br or is
// <br /> when gfm is true
var splitRe = gfm ? HARD_RETURN_GFM_RE : HARD_RETURN_RE,
sections = text.split(splitRe),
reflowed = [];
sections.forEach(function (section) {
// Split the section by escape codes so that we can
// deal with them separately.
var fragments = section.split(/(\u001b\[(?:\d{1,3})(?:;\d{1,3})*m)/g);
var column = 0;
var currentLine = '';
var lastWasEscapeChar = false;
while (fragments.length) {
var fragment = fragments[0];
if (fragment === '') {
fragments.splice(0, 1);
lastWasEscapeChar = false;
continue;
}
// This is an escape code - leave it whole and
// move to the next fragment.
if (!textLength(fragment)) {
currentLine += fragment;
fragments.splice(0, 1);
lastWasEscapeChar = true;
continue;
}
var words = fragment.split(/[ \t\n]+/);
for (var i = 0; i < words.length; i++) {
var word = words[i];
var addSpace = column != 0;
if (lastWasEscapeChar) addSpace = false;
// If adding the new word overflows the required width
if (column + word.length + addSpace > width) {
if (word.length <= width) {
// If the new word is smaller than the required width
// just add it at the beginning of a new line
reflowed.push(currentLine);
currentLine = word;
column = word.length;
} else {
// If the new word is longer than the required width
// split this word into smaller parts.
var w = word.substr(0, width - column - addSpace);
if (addSpace) currentLine += ' ';
currentLine += w;
reflowed.push(currentLine);
currentLine = '';
column = 0;
word = word.substr(w.length);
while (word.length) {
var w = word.substr(0, width);
if (!w.length) break;
if (w.length < width) {
currentLine = w;
column = w.length;
break;
} else {
reflowed.push(w);
word = word.substr(width);
}
}
}
} else {
if (addSpace) {
currentLine += ' ';
column++;
}
currentLine += word;
column += word.length;
}
lastWasEscapeChar = false;
}
fragments.splice(0, 1);
}
if (textLength(currentLine)) reflowed.push(currentLine);
});
return reflowed.join('\n');
}
function indentLines(indent, text) {
return text.replace(/(^|\n)(.+)/g, '$1' + indent + '$2');
}
function indentify(indent, text) {
if (!text) return text;
return indent + text.split('\n').join('\n' + indent);
}
var BULLET_POINT_REGEX = '\\*';
var NUMBERED_POINT_REGEX = '\\d+\\.';
var POINT_REGEX =
'(?:' + [BULLET_POINT_REGEX, NUMBERED_POINT_REGEX].join('|') + ')';
// Prevents nested lists from joining their parent list's last line
function fixNestedLists(body, indent) {
var regex = new RegExp(
'' +
'(\\S(?: | )?)' + // Last char of current point, plus one or two spaces
// to allow trailing spaces
'((?:' +
indent +
')+)' + // Indentation of sub point
'(' +
POINT_REGEX +
'(?:.*)+)$',
'gm'
); // Body of subpoint
return body.replace(regex, '$1\n' + indent + '$2$3');
}
var isPointedLine = function (line, indent) {
return line.match('^(?:' + indent + ')*' + POINT_REGEX);
};
function toSpaces(str) {
return ' '.repeat(str.length);
}
var BULLET_POINT = '* ';
function bulletPointLine(indent, line) {
return isPointedLine(line, indent) ? line : toSpaces(BULLET_POINT) + line;
}
function bulletPointLines(lines, indent) {
var transform = bulletPointLine.bind(null, indent);
return lines.split('\n').filter(identity).map(transform).join('\n');
}
var numberedPoint = function (n) {
return n + '. ';
};
function numberedLine(indent, line, num) {
return isPointedLine(line, indent)
? {
num: num + 1,
line: line.replace(BULLET_POINT, numberedPoint(num + 1))
}
: {
num: num,
line: toSpaces(numberedPoint(num)) + line
};
}
function numberedLines(lines, indent) {
var transform = numberedLine.bind(null, indent);
let num = 0;
return lines
.split('\n')
.filter(identity)
.map((line) => {
const numbered = transform(line, num);
num = numbered.num;
return numbered.line;
})
.join('\n');
}
function list(body, ordered, indent) {
body = body.trim();
body = ordered ? numberedLines(body, indent) : bulletPointLines(body, indent);
return body;
}
function section(text) {
return text + '\n\n';
}
function highlight(code, lang, opts, hightlightOpts) {
if (chalk$1.level === 0) return code;
var style = opts.code;
code = fixHardReturn(code, opts.reflowText);
if (lang !== 'javascript' && lang !== 'js') {
return style(code);
}
try {
return cardinal.highlight(code, hightlightOpts);
} catch (e) {
return style(code);
}
}
function insertEmojis(text) {
return text.replace(/:([A-Za-z0-9_\-\+]+?):/g, function (emojiString) {
var emojiSign = emoji__namespace.get(emojiString);
if (!emojiSign) return emojiString;
return emojiSign + ' ';
});
}
function hr(inputHrStr, length) {
length = length || process.stdout.columns;
return new Array(length).join(inputHrStr);
}
function undoColon(str) {
return str.replace(COLON_REPLACER_REGEXP, ':');
}
function generateTableRow(text, escape) {
if (!text) return [];
escape = escape || identity;
var lines = escape(text).split('\n');
var data = [];
lines.forEach(function (line) {
if (!line) return;
var parsed = line
.replace(TABLE_ROW_WRAP_REGEXP, '')
.split(TABLE_CELL_SPLIT);
data.push(parsed.splice(0, parsed.length - 1));
});
return data;
}
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
}
function unescapeEntities(html) {
return html
.replace(/&amp;/g, '&')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'");
}
function identity(str) {
return str;
}
function compose() {
var funcs = arguments;
return function () {
var args = arguments;
for (var i = funcs.length; i-- > 0; ) {
args = [funcs[i].apply(this, args)];
}
return args[0];
};
}
function isAllowedTabString(string) {
return TAB_ALLOWED_CHARACTERS.some(function (char) {
return string.match('^(' + char + ')+$');
});
}
function sanitizeTab(tab, fallbackTab) {
if (typeof tab === 'number') {
return new Array(tab + 1).join(' ');
} else if (typeof tab === 'string' && isAllowedTabString(tab)) {
return tab;
} else {
return new Array(fallbackTab + 1).join(' ');
}
}
exports.default = Renderer;
exports.markedTerminal = markedTerminal;