@nuintun/ansi
v0.1.1
Published
A pure JavaScript ANSI style parser library.
Downloads
129
Maintainers
Readme
ansi
A pure JavaScript ANSI style parser library.
interface
export type AnsiColor = [
// Red
R: number,
// Green
G: number,
// Blue
B: number
];
export interface AnsiStyle {
dim: boolean;
bold: boolean;
blink: boolean;
hidden: boolean;
italic: boolean;
inverse: boolean;
overline: boolean;
underline: boolean;
strikethrough: boolean;
color: AnsiColor | null;
background: AnsiColor | null;
}
export interface AnsiBlock {
url?: string;
value: string;
style: AnsiStyle;
}
export interface Theme {
red?: AnsiColor;
blue?: AnsiColor;
cyan?: AnsiColor;
black?: AnsiColor;
green?: AnsiColor;
white?: AnsiColor;
yellow?: AnsiColor;
magenta?: AnsiColor;
brightRed?: AnsiColor;
brightBlue?: AnsiColor;
brightCyan?: AnsiColor;
brightBlack?: AnsiColor;
brightGreen?: AnsiColor;
brightWhite?: AnsiColor;
brightYellow?: AnsiColor;
brightMagenta?: AnsiColor;
}
export class Ansi {
/**
* @public
* @constructor
* @description Constructor for the Ansi class.
* @param theme The theme object containing color values.
*/
public constructor(theme?: Theme);
/**
* @public
* @description Writes the given text to the buffer and processes it.
* @param text The text to be written.
* @param callback The callback function to be called for each processed AnsiBlock.
*/
public write(text: string, callback: (block: AnsiBlock) => void): void;
/**
* @public
* @description Flushes the buffer and invokes the callback with the flushed block.
* @param callback - The callback function to invoke with the flushed block.
*/
public flush(callback: (block: AnsiBlock) => void): void;
}
Usage
import Ansi, { AnsiBlock, Theme } from '@nuintun/ansi';
function escapeHTML(text: string): string {
return text.replace(/[&<>"']/gm, match => {
switch (match) {
case '&':
return '&';
case '<':
return '<';
case '>':
return '>';
case '"':
return '"';
case "'":
return ''';
default:
return match;
}
});
}
function blockToHTML({ style, value, url }: AnsiBlock): string {
const styles: string[] = [];
const textDecorations: string[] = [];
if (style.dim) {
styles.push(`opacity: 0.5`);
}
if (style.bold) {
styles.push(`font-weight: bold`);
}
if (style.italic) {
styles.push(`font-style: italic`);
}
if (style.inverse) {
styles.push(`filter: invert(1)`);
}
if (style.hidden) {
styles.push(`visibility: hidden`);
}
if (style.blink) {
textDecorations.push('blink');
}
if (style.overline) {
textDecorations.push('overline');
}
if (style.underline) {
textDecorations.push('underline');
}
if (style.strikethrough) {
textDecorations.push('line-through');
}
const { color, background } = style;
if (color) {
styles.push(`color: rgb(${color})`);
}
if (background) {
styles.push(`background-color: rgb(${background})`);
}
if (textDecorations.length > 0) {
styles.push(`text-decoration: ${textDecorations.join(' ')}`);
}
const escapedValue = escapeHTML(value);
const href = url ? JSON.stringify(new URL(url).toString()) : null;
if (styles.length <= 0) {
if (!href) {
return escapedValue;
}
return `<a href=${href} target="_blank">${escapedValue}</a>`;
}
const inlineStyle = JSON.stringify(`${styles.join('; ')};`);
if (!href) {
return `<span style=${inlineStyle}>${escapedValue}</span>`;
}
return `<a style=${inlineStyle} href=${href} target="_blank">${escapedValue}</a>`;
}
export function ansiToHTML(text: string, theme?: Theme): string {
let html = '';
const ansi = new Ansi(theme);
ansi.write(text, block => {
html += blockToHTML(block);
});
ansi.flush(block => {
html += blockToHTML(block);
});
return html;
}
References
Optimized and modified by drudru/ansi_up