UNPKG

@je-es/format

Version:

A function to format text with ANSI styles, padding, and borders

1 lines 19.2 kB
{"version":3,"sources":["../src/code/modules/types.ts","../src/code/modules/format.ts","../src/code/modules/pattern.ts"],"sourcesContent":["/**\r\n * @name format.d.ts\r\n * @description Definitions for the `format` module\r\n*/\r\n\r\n\r\n/* ---------------------------------------- PACK ---------------------------------------- */\r\n\r\n import { t_style } from '@je-es/ansi';\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */\r\n\r\n\r\n/* ---------------------------------------- INIT ---------------------------------------- */\r\n\r\n export type t_padding =\r\n {\r\n top ?: number,\r\n bottom ?: number,\r\n left ?: number,\r\n right ?: number,\r\n };\r\n\r\n export type t_prefix =\r\n {\r\n value : string,\r\n style : t_style,\r\n }\r\n\r\n export type t_border =\r\n {\r\n width ?: number,\r\n color ?: string,\r\n };\r\n\r\n export type formatOptions =\r\n {\r\n ansi ?: t_style,\r\n padding ?: t_padding,\r\n border ?: t_border,\r\n prefix ?: t_prefix,\r\n suffix ?: t_prefix,\r\n width ?: number,\r\n align ?: 'left' | 'center' | 'right',\r\n }\r\n\r\n export type borderDimensions =\r\n {\r\n topBeg : string,\r\n topEnd : string,\r\n\r\n botBeg : string,\r\n botEnd : string,\r\n\r\n char : string,\r\n side : string,\r\n };\r\n\r\n export type t_pattern =\r\n [{\r\n value ?: string,\r\n gvalue ?: string,\r\n options : formatOptions,\r\n }[]];\r\n\r\n export { t_style };\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */","/**\r\n * @name format.ts\r\n * @description This module provides functions to format text with ANSI styles, padding, and borders.\r\n*/\r\n\r\n\r\n/* ---------------------------------------- PACK ---------------------------------------- */\r\n\r\n import * as ansi from '@je-es/ansi';\r\n import * as types from './types';\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */\r\n\r\n\r\n/* ---------------------------------------- CORE ---------------------------------------- */\r\n\r\n /**\r\n * Applies styles, padding, and borders to a given string.\r\n *\r\n * @param {string} input - The string to apply styles to.\r\n * @param {types.formatOptions} options - The formatting options.\r\n * @param {types.t_style} options.ansi - The ANSI styles to apply.\r\n * @param {types.t_prefix} options.prefix - The prefix options.\r\n * @param {types.t_prefix} options.suffix - The suffix options.\r\n * @param {number} options.width - The width of the formatted string.\r\n * @param {'left'|'center'|'right'} options.align - The alignment of the formatted string.\r\n * @param {types.t_padding} options.padding - The padding options.\r\n * @param {types.t_border} options.border - The border options.\r\n * @return {string} The formatted string.\r\n */\r\n export const style\r\n = (input: string, options: types.formatOptions = {})\r\n : string =>\r\n {\r\n if (Object.keys(options).length === 0) return input;\r\n\r\n let res = '';\r\n let originalLength = input.length + (options.prefix?.value?.length || 0) + (options.suffix?.value?.length || 0);\r\n\r\n // Apply Prefix\r\n if(options.prefix)\r\n {\r\n\r\n if(options.ansi?.bg && !(options.prefix?.style?.bg))\r\n options.prefix.style.bg = options.ansi?.bg;\r\n\r\n if(options.ansi?.fg && !(options.prefix?.style?.fg))\r\n options.prefix.style.fg = options.ansi?.fg;\r\n\r\n if(options.ansi?.attr && !(options.prefix?.style?.attr))\r\n options.prefix.style.attr = options.ansi?.attr;\r\n\r\n res += Helpers.ApplyPrefix(options.prefix);\r\n }\r\n\r\n // Apply ANSI styles\r\n if (options.ansi) res += Helpers.ApplyStyle(input, options);\r\n\r\n // Apply Suffix\r\n if(options.suffix)\r\n {\r\n\r\n if(options.ansi?.bg && !(options.suffix?.style?.bg))\r\n options.suffix.style.bg = options.ansi?.bg;\r\n\r\n if(options.ansi?.fg && !(options.suffix?.style?.fg))\r\n options.suffix.style.fg = options.ansi?.fg;\r\n\r\n if(options.ansi?.attr && !(options.suffix?.style?.attr))\r\n options.suffix.style.attr = options.ansi?.attr;\r\n\r\n res += Helpers.ApplySuffix(options.suffix);\r\n }\r\n\r\n // Apply Width\r\n if (options.width && options.width > originalLength)\r\n {\r\n // Apply Alignment\r\n {\r\n if(options.align === 'center')\r\n {\r\n const left = Math.floor((options.width - originalLength) / 2);\r\n const right = options.width - originalLength - left;\r\n res = ' '.repeat(left) + res + ' '.repeat(right);\r\n }\r\n else if(options.align === 'right')\r\n {\r\n const left = options.width - originalLength;\r\n res = ' '.repeat(left) + res;\r\n }\r\n else\r\n {\r\n const right = options.width - originalLength;\r\n res += ' '.repeat(right);\r\n }\r\n }\r\n\r\n // Save original length\r\n originalLength = options.width;\r\n }\r\n\r\n // Apply padding\r\n if (options.padding) res = Helpers.ApplyPadding(res, options);\r\n\r\n // Apply border\r\n if (options.border) res = Helpers.ApplyBorder(res, options, originalLength);\r\n\r\n return res;\r\n };\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */\r\n\r\n\r\n/* ---------------------------------------- HELP ---------------------------------------- */\r\n\r\n const Helpers =\r\n {\r\n ApplyPrefix\r\n : (options: types.t_prefix)\r\n : string =>\r\n {\r\n const { value, style } = options;\r\n return ansi.style(value, style);\r\n },\r\n\r\n ApplySuffix\r\n : (options: types.t_prefix)\r\n : string =>\r\n {\r\n const { value, style } = options;\r\n return ansi.style(value, style);\r\n },\r\n\r\n ApplyStyle\r\n : (input: string, options: types.formatOptions)\r\n : string =>\r\n {\r\n const { fg, bg, attr } = options.ansi || {};\r\n return ansi.style(input, { fg, bg, attr });\r\n },\r\n\r\n ApplyPadding\r\n : (input: string, options: types.formatOptions)\r\n : string =>\r\n {\r\n if (options.padding?.left)\r\n {\r\n input = ' '.repeat(options.padding.left) + input;\r\n }\r\n\r\n if (options.padding?.right)\r\n {\r\n input = input + ' '.repeat(options.padding.right);\r\n }\r\n\r\n if (options.padding?.top)\r\n {\r\n input = '\\n'.repeat(options.padding.top) + input;\r\n }\r\n\r\n if (options.padding?.bottom)\r\n {\r\n input = input + '\\n'.repeat(options.padding.bottom);\r\n }\r\n\r\n return input;\r\n },\r\n\r\n ApplyBorder\r\n : (input: string, options: types.formatOptions, originalLength: number)\r\n : string =>\r\n {\r\n // options.border = { char, color, width }\r\n\r\n const Bwidth : number = options.border?.width || 1;\r\n const color : string = options.border?.color || 'white';\r\n const _paddingWidth : number = Helpers.More.__GetPaddingWidth(options);\r\n const width : number = Math.max(originalLength + _paddingWidth + 2, 0);\r\n let chars : types.borderDimensions = { topBeg: '', topEnd: '', botBeg: '', botEnd: '', char: '', side: '' };\r\n\r\n switch (Bwidth)\r\n {\r\n case 1:\r\n chars = { topBeg: '┌', topEnd: '┐', botBeg: '└', botEnd: '┘', char: '─', side: '│' };\r\n break;\r\n case 2:\r\n chars = { topBeg: '╔', topEnd: '╗', botBeg: '╚', botEnd: '╝', char: '═', side: '║' };\r\n break;\r\n case 3:\r\n chars = { topBeg: '┏', topEnd: '┓', botBeg: '┗', botEnd: '┛', char: '━', side: '┃' };\r\n break;\r\n case 4:\r\n chars = { topBeg: '╭', topEnd: '╮', botBeg: '╰', botEnd: '╯', char: '─', side: '│' };\r\n break;\r\n case 5:\r\n chars = { topBeg: '╭', topEnd: '╮', botBeg: '╰', botEnd: '╯', char: '═', side: '║' };\r\n break;\r\n default:\r\n chars = { topBeg: '┌', topEnd: '┐', botBeg: '└', botEnd: '┘', char: '─', side: '│' };\r\n break;\r\n }\r\n\r\n // Calculate total width for each line including padding and border\r\n const totalWidth = originalLength + _paddingWidth + 2;\r\n\r\n // Ensure the width is not negative\r\n const paddedWidth = Math.max(totalWidth, 0);\r\n\r\n // Sides (add char to start/end of each line)\r\n input = input.split('\\n').map(line =>\r\n {\r\n const lineWidth = line.length;\r\n\r\n if (lineWidth)\r\n {\r\n // Ensure each line is padded correctly\r\n const n = ((paddedWidth - lineWidth - 2) + 1)\r\n const x = n && n > 0 ? n : 1;\r\n return ansi.style(chars.side, { fg: color}) + ' ' + line + ' '.repeat(x) + ansi.style(chars.side, { fg: color});\r\n }\r\n\r\n else\r\n {\r\n return ansi.style(chars.side, { fg: color}) + ' '.repeat(paddedWidth) + ansi.style(chars.side, { fg: color});\r\n }\r\n }).join('\\n');\r\n\r\n // First line\r\n const firstLine = ansi.style(chars.topBeg + chars.char.repeat(paddedWidth) + chars.topEnd, { fg: color});\r\n input = firstLine + '\\n' + input;\r\n\r\n // Last line\r\n const lastLine = ansi.style(chars.botBeg + chars.char.repeat(paddedWidth) + chars.botEnd, { fg: color});\r\n input = input + '\\n' + lastLine;\r\n\r\n return input;\r\n },\r\n\r\n More :\r\n {\r\n __GetPaddingWidth\r\n : (options: types.formatOptions)\r\n : number =>\r\n {\r\n return (options.padding?.left || 0) + (options.padding?.right || 0);\r\n },\r\n }\r\n };\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */","/**\r\n * @name tools.ts\r\n * @description More tools !\r\n*/\r\n\r\n\r\n/* ---------------------------------------- PACK ---------------------------------------- */\r\n\r\n import * as types from './types';\r\n import { style } from './format';\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */\r\n\r\n\r\n/* ---------------------------------------- CORE ---------------------------------------- */\r\n\r\n /**\r\n * Applies styles to a given message based on a pattern and optional values.\r\n *\r\n * @param {any} msg - The message to apply styles to.\r\n * @param {types.t_pattern} pattern - The pattern to apply styles from.\r\n * @param {object} [values] - Optional values to use for dynamic styles.\r\n * @return {string} The formatted message with applied styles.\r\n */\r\n export const apply\r\n = (msg: any, pattern: types.t_pattern, values?: {})\r\n : string =>\r\n {\r\n let result = '';\r\n\r\n for (let x = 0; x < pattern.length; x++)\r\n {\r\n const pat = pattern[x];\r\n\r\n for (let i = 0; i < pat.length; i++)\r\n {\r\n if(values && pat[i].gvalue)\r\n {\r\n result += style((values as any)[pat[i].gvalue ? pat[i].gvalue : msg], pat[i].options);\r\n }\r\n else result += style(pat[i].value || msg, pat[i].options);\r\n }\r\n\r\n // add\r\n if(x < pattern.length - 1) result += '\\n';\r\n }\r\n\r\n return result;\r\n };\r\n\r\n /**\r\n * Combines multiple messages with patterns and optional values into a single string.\r\n *\r\n * @param {Array<{ msg?: any, pattern?: any, values?: any }>} opt - An array of objects containing the message, pattern, and optional values.\r\n * @return {string} - The combined string with applied styles.\r\n */\r\n export const combine\r\n = (opt : { msg ?: any, pattern ?:any, values ?: any }[] )\r\n : string =>\r\n {\r\n let res = '';\r\n\r\n for (let i = 0; i < opt.length; i++)\r\n {\r\n res += apply(opt[i].msg, opt[i].pattern, opt[i].values);\r\n\r\n if(i < opt[i].pattern.length - 1) res += '\\n';\r\n }\r\n\r\n return res;\r\n }\r\n\r\n/* ---------------------------------------- ---- ---------------------------------------- */"],"mappings":"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","names":["style","style"]}