ansibump

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2025 License: MIT Imports: 10 Imported by: 1

README

ANSIbump

Go Reference Go Report Card

ANSIbump takes texts encoded with ANSI escape codes and transforms it into a HTML fragment for use in a template or webpage.

See the reference documentation for usage, and examples, including changing the character sets and the color palette.

ANSIbump was created for and is in use on the website archive Defacto2, home to thousands of ANSI texts and artworks that are now rendered in HTML.

Some ANSI highlights that are rendered by ANSIbump:

Quick usage
package main

import (
	"log"
	"os"

	"github.com/bengarrett/ansibump"
)

func main() {
	file, _ := os.Open("file.ans")
	defer file.Close()
	const columns = 80
	_, _ = ansibump.WriteTo(file, os.Stdout, columns)
}
HTML

ANSIbump will output a <div> "content division" element containing colors, styles, newlines, and text.

<html>
  <head>
    <title>Quick usage</title>
  </head>
  <style>
    @font-face {
      font-family: cascadia-mono;
      src: url(CascadiaMono.woff2) format("woff2");
    }
    pre {
      font-family: cascadia-mono, monospace, serif;
    }
  </style>
  <body>
    <pre><!--- ansibump output ---><div style="color:#aaa;background-color:#000;">   <span style="color:#a50;background-color:#0a0;">HI‼︎</span>   </div>
    </pre>
  </body>
</html>
Not supported or known issues
Sauce metadata

ANSIbump doesn't parse any SAUCE metadata, however this can be done with a separate bengarrett/sauce package.

Important

ANSIbump was initially vibe coded, you can see the original prompt, output, and read of the many needed manual changes.

Similar projects
  • Deark is a utility that can output ANSI to HTML or an image.
  • ansipants a Python module and utility for converting ANSI art to HTML.
  • RetroTxt a web browser extension that renders ANSI as HTML in a tab.
  • Ansilove is a collection of tools to convert ANSI to images.
  • Ultimate Oldschool PC Font Pack offers various retro DOS and PC fonts.

Documentation

Overview

Package ansibump converts ANSI escape sequences such as colors, cursor movements, and character deletions, into a HTML representation.

Index

Examples

Constants

View Source
const (
	NUL = 0x00 // NUL is an ASCII null character
	EOF = 0x1a // EOF is the MS-DOS end-of-file character value
	ESC = 0x1b // ESC is the escape control character code

	Reset        = 0
	Bold         = 1
	NotBold      = 21
	NotBoldFaint = 22
	Underline    = 4
	NotUnderline = 24
	Invert       = 7
	NotInvert    = 27
	DefaultFG    = 39
	DefaultBG    = 49
	FG1st        = 30
	FGEnd        = 37
	BG1st        = 40
	BGEnd        = 47
	BrightFG1st  = 90
	BrightFGEnd  = 97
	BrightBG1st  = 100
	BrightBGEnd  = 107
	SetFG        = 38
	SetBG        = 48
)

Variables

View Source
var (
	ErrReader     = errors.New("reader is nil")
	ErrUnexpected = errors.New("unexpected parameters")
	ErrRecognized = errors.New("unrecognised parameters")
	ErrParam      = errors.New("encountered ';' without parameter")
	ErrExpect0or1 = errors.New("expected 0 or 1 parameters")
	ErrExpect0or2 = errors.New("expected 0 or 2 parameters")
	ErrExpect1    = errors.New("expected 1 parameter")
	ErrUnknownCSI = errors.New("unrecognized CSI final byte")
	ErrUnknownCtr = errors.New("unrecognized control byte")
	ErrUnknownEsc = errors.New("unrecognized ESC sequence after ESC")
)

Functions

func BasicHex

func BasicHex(code int, bright bool, pal Palette) string

BasicHex takes a standard color code and returns a corresponding hexadecimal string. When bright is toggled, a lighter color variant is used. Codes are values between 0 and 7, and any invalid codes returns a blank string.

func Bytes

func Bytes(r io.Reader, width int) ([]byte, error)

Bytes returns the HTML elements of the ANSI encoded text found in the Reader. It assumes the Reader is using IBM Code Page 437 encoding. If width is <= 0, an 80 columns value is used.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/bengarrett/ansibump"
)

func main() {
	const ansi = "\x1b[0m\x1b[5;30;42mHI\x1b[0m"
	r := strings.NewReader(ansi)
	p, _ := ansibump.Bytes(r, 80)
	fmt.Printf("%q", p)
}
Output:

"<div style=\"color:#aaa;background-color:#000;\"><span style=\"color:#000;background-color:#0a0;\">HI</span></div>"

func RGBHex added in v1.0.1

func RGBHex(params []int, i int) string

RGBHex converts the params into a "true color", red, green, blue hex string.

func String

func String(r io.Reader, width int) (string, error)

String returns the HTML elements of the ANSI encoded text found in the Reader. It assumes the Reader is using IBM Code Page 437 encoding. If width is <= 0, an 80 columns value is used.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/bengarrett/ansibump"
)

func main() {
	const ansi = "\x1b[0m\n\x1b[1;34m\x02\x1b[0m \x1b[1;34mA\x1b[36mN\x1b[33mS\x1b[37mI\x1b[35mbump\x1b[0;33m\x1b[37m"
	r := strings.NewReader(ansi)
	s, _ := ansibump.String(r, 80)
	fmt.Printf("%q", s)
}
Output:

"<div style=\"color:#aaa;background-color:#000;\">\n<span style=\"color:#55f;\">\x02</span><span style=\"color:#aaa;\"> </span><span style=\"color:#55f;\">A</span><span style=\"color:#5ff;\">N</span><span style=\"color:#ff5;\">S</span><span style=\"color:#fff;\">I</span><span style=\"color:#f5f;\">bump</span></div>"
Example (Rgb)
package main

import (
	"fmt"
	"strings"

	"github.com/bengarrett/ansibump"
)

func main() {
	const ansi = "\x1b[0m\x1b[38;2;135;0;255;48;2;135;95;0mPurple on Orange4\x1b[0m"
	r := strings.NewReader(ansi)
	s, _ := ansibump.String(r, 80)
	fmt.Printf("%q", s)
}
Output:

"<div style=\"color:#aaa;background-color:#000;\"><span style=\"color:#8700ff;background-color:#875f00;\">Purple on Orange4</span></div>"
Example (Xterm256)
package main

import (
	"fmt"
	"strings"

	"github.com/bengarrett/ansibump"
)

func main() {
	const ansi = "\x1b[0m\x1b[38;5;93mPurple\x1b[0m \x1b[38;5;94mOrange4\x1b[0m"
	r := strings.NewReader(ansi)
	s, _ := ansibump.String(r, 80)
	fmt.Printf("%q", s)
}
Output:

"<div style=\"color:#aaa;background-color:#000;\"><span style=\"color:#8700ff;\">Purple</span><span style=\"color:#aaa;\"> </span><span style=\"color:#875f00;\">Orange4</span></div>"

func WriteTo

func WriteTo(r io.Reader, w io.Writer, width int) (int64, error)

WriteTo writes to w the HTML elements of the ANSI encoded text found in the Reader. It assumes the Reader is using IBM Code Page 437 encoding. If width is <= 0, an 80 columns value is used.

The return int64 is the number of bytes written.

Example
package main

import (
	"bufio"
	"bytes"
	"fmt"
	"strings"

	"github.com/bengarrett/ansibump"
)

func main() {
	const ansi = "\x1b[0m\x1b[5;30;42mHI\x1b[0m"
	input := strings.NewReader(ansi)
	var b bytes.Buffer
	output := bufio.NewWriter(&b)
	cnt, _ := ansibump.WriteTo(input, output, 80)
	output.Flush()
	fmt.Printf("%d bytes written\n%q", cnt, b.String())
}
Output:

110 bytes written
"<div style=\"color:#aaa;background-color:#000;\"><span style=\"color:#000;background-color:#0a0;\">HI</span></div>"

func XtermColor

func XtermColor(code int) (int, int, int)

XtermColor returns the RGB values for non-system Xterm colors.

func XtermColors

func XtermColors(code int) (int, int, int)

XtermColors takes a Xterm non-system color code and returns the corresponding RGB values. The code values begin at 16 and finish at 255. If a code is out of range, then the returned RGB values will be -1, which are invalid.

Some helpful links, 256 colors cheat sheet, Xterm Colors, and 8-bit colors wiki.

func XtermGray

func XtermGray(code int) (int, int, int)

XtermGray returns the RGB values for the Xterm greyscale colors.

func XtermHex

func XtermHex(code int, pal Palette) string

XtermHex takes a Xterm color code and returns the corresponding RBG values as a hexadecimal string. Codes are values between 0 and 255, and any invalid codes return a blank string. The Palette is only used for basic colors codes between 0 and 7.

Types

type Attribute

type Attribute struct {
	FG        string // FG is a foreground hex color like "rrggbb" or (no leading #) or empty for default
	BG        string // BG is a background hex color like "rrggbb"
	Bold      bool   // Bold toggles a lighter color variation
	Underline bool   // Underline toggles a underline text decoration
	Inverse   bool   // Inverse swaps the background and foreground colors
}

Attribute describes styling for a single character cell.

func ApplySGR

func ApplySGR(params []int, cur Attribute, pal Palette) (Attribute, error)

ApplySGR applies SGR parameters to an incoming attribute and returns a new Attribute.

type Color

type Color string

Color code represented as hexadecimal numeric value. These are often 6 digit values RRGGBB (red, green, blue), however, certain values can be shortened to 3 digit values.

For example, the code of CGA red "aa0000" (red: aa, green: 00, blue: 00) can shortened to "a00".

const (
	CBlack     Color = "000"    // cga black
	CRed       Color = "a00"    // red
	CGreen     Color = "0a0"    // green
	CBrown     Color = "a50"    // yellow
	CBlue      Color = "00a"    // blue
	CMagenta   Color = "a0a"    // magenta
	CCyan      Color = "0aa"    // cyan
	CGray      Color = "aaa"    // white
	CDarkGray  Color = "555"    // bright black
	CLRed      Color = "f55"    // bright red
	CLGreen    Color = "5f5"    // bright green
	CYellow    Color = "ff5"    // bright yellow
	CLBlue     Color = "55f"    // bright blue
	CLMagenta  Color = "f5f"    // bright magenta
	CLCyan     Color = "5ff"    // bright cyan
	CWhite     Color = "fff"    // bright white
	XBlack     Color = "000"    // xterm black
	XMarron    Color = "800000" // red
	XGreen     Color = "008000" // green
	XOlive     Color = "808000" // yellow
	XNavy      Color = "000080" // blue
	XPurple    Color = "800080" // magenta
	XTeal      Color = "008080" // cyan
	XSilver    Color = "c0c0c0" // white
	XGray      Color = "808080" // bright black
	XRed       Color = "f00"    // bright red
	XLime      Color = "0f0"    // bright green
	XYellow    Color = "ff0"    // bright yellow
	XBlue      Color = "00f"    // bright blue
	XFuchsia   Color = "f5f"    // bright magenta
	XAqua      Color = "0ff"    // bright cyan
	XWhite     Color = "fff"    // bright white
	DPBlack    Color = "000"    // deluxe paint ii black
	DPRed      Color = "a80000" // red
	DPGreen    Color = "008800" // green
	DPBrown    Color = "a85420" // brown
	DPBlue     Color = "0000fc" // blue
	DPMagenta  Color = "cc0088" // magenta
	DPCyan     Color = "00a8fc" // cyan
	DPGray     Color = "747474" // white
	DPDarkGray Color = "646464" // bright black
	DPLRed     Color = "ec0000" // bright red
	DPLGreen   Color = "88fc00" // bright green
	DPYellow   Color = "fcec00" // bright yellow
	DPLBlue    Color = "0074cc" // bright blue
	DPLMagenta Color = "cc00ec" // bright magenta
	DPLCyan    Color = "00dcdc" // bright cyan
	DPWhite    Color = "fcfcfc" // bright white
)

func Bright

func Bright(c Color, pal Palette) Color

Bright takes a palette color and swaps it for a lighter variant. For example, Color.CBlack (CGA black) returns Color.CDarkGray (CGA bright black).

func (Color) BG

func (c Color) BG() string

BG returns the CSS background-color property and color value.

func (Color) FG

func (c Color) FG() string

FG returns the CSS color property and color value.

type Colors added in v1.0.1

type Colors [16]Color

func CGA

func CGA() Colors

func DPaint2 added in v1.0.2

func DPaint2() Colors

func Xterm

func Xterm() Colors

func (Colors) DefaultBG added in v1.0.1

func (c Colors) DefaultBG() Color

DefaultBG will return the "black" variant of the color palette, which can be used as the default background color.

func (Colors) DefaultFG added in v1.0.1

func (c Colors) DefaultFG() Color

DefaultFG will return the "white" variant of the color palette, which can be used as the default foreground color.

type Customizer added in v1.1.0

type Customizer struct {
	// Width is the number of columns of the ANSI encoded text.
	// If a value provided is <= 0, then a common an 80 columns value is used.
	Width int
	// The AmigaParser should be set to false except with edge cases where unusual
	// Commodore Amiga specific encodings are to be parsed. When set to true:
	//   - character 0x0C "♀︎" is a form feed controller and will be replaced with a '<br>' element.
	//   - 0x1B,0x5B,0x1B,0x5B "←[←[" is treated as a single ANSI escape control.
	AmigaParser bool
	// Strict is a debug mode that will throw errors when the ANSI includes malformed and invalid data or values.
	Strict bool
	// Color Palette can either be CGA16, Xterm16, or DP2.
	//   - CGA16 is the default, it is the Color Graphics Adapter colorset defined by IBM for the PC in 1981.
	//   - Xterm16 is the Xterm terminal emulator program for the X Window System colorset from the mid-1980s.
	//   - DP2 is a Commodore Amiga era Deluxe Paint II colorset that mimics the colors of CGA16.
	Color Palette
	// CharSet is the simple character encoding used by the text.
	//
	// Generally the charset of ANSI art should be [charmap.CodePage437],
	// however artworks for the Commodore Amiga are often [charmap.ISO8859_1].
	// Modern artworks or terminal text will usually be in UTF-8 encoding
	// which can be set with CharSet = nil or CharSet = [charmap.XUserDefined].
	CharSet *charmap.Charmap
}

Customizer is optional, and is used to configure the parsing of the ANSI encoded text.

Usually, the defaults work for most texts. Instead, use: ansibump.Bytes, ansibump.String, or ansibump.WriteTo.

func (*Customizer) Buffer added in v1.1.0

func (c *Customizer) Buffer(r io.Reader) (*bytes.Buffer, error)

Buffer creates a new Buffer containing the HTML elements of the ANSI encoded text found in the Reader.

The parser configurations and arguments are configured using the Customizer.

func (*Customizer) NewDecoder added in v1.1.0

func (c *Customizer) NewDecoder() *Decoder

NewDecoder creates a Decoder with the given Customizer.

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder maintains the screen buffer and cursor state while parsing ANSI.

func (*Decoder) ApplyCSI

func (d *Decoder) ApplyCSI(final byte, params []int) error

ApplyCSI handles cursor movement and erase sequences that alter the buffer or cursor. It follows standard ANSI/VT100 CSI final bytes used in the original request: A B C D E F G H f J K s u

func (*Decoder) CursorBack

func (d *Decoder) CursorBack(params []int) error

CursorBack moves cursor back. Attr: CUB.

func (*Decoder) CursorDown

func (d *Decoder) CursorDown(params []int) error

CursorDown moves cursor down. Attr: CUD.

func (*Decoder) CursorForward

func (d *Decoder) CursorForward(params []int) error

CursorForward moves cursor forward. Attr: CUF.

func (*Decoder) CursorHorizontalAbsolute

func (d *Decoder) CursorHorizontalAbsolute(params []int) error

CursorHorizontalAbsolute moves the cursor to column. Attr: CHA.

func (*Decoder) CursorNextLine

func (d *Decoder) CursorNextLine(params []int) error

CursorNextLine moves cursor down to the beginning of the line. Attr: CNL.

func (*Decoder) CursorPosition

func (d *Decoder) CursorPosition(params []int) error

CursorPosition moves the cursor to row and column. Attr: CUP.

func (*Decoder) CursorPreviousLine

func (d *Decoder) CursorPreviousLine(params []int) error

CursorPreviousLine moves cursor up to the beginning of the line. Attr: CPL.

func (*Decoder) CursorUp

func (d *Decoder) CursorUp(params []int) error

CursorUp moves cursor up. Attr: CUU.

func (*Decoder) EraseInDisplay

func (d *Decoder) EraseInDisplay(params []int) error

EraseInDisplay clears part of the screen. Attr: ED.

func (*Decoder) EraseInLine

func (d *Decoder) EraseInLine(params []int) error

EraseInLine part of the line. Attr: EL.

func (*Decoder) Lines

func (d *Decoder) Lines(pal Palette) []string

Lines renders each buffer line into a single HTML string. Each contiguous run of identical attributes is wrapped in a <span style="...">.

func (*Decoder) Read

func (d *Decoder) Read(r io.Reader) error

Read reads bytes from r and interprets ANSI sequences, updating the buffer.

func (*Decoder) RestoreCursorPosition

func (d *Decoder) RestoreCursorPosition(params []int) error

RestoreCursorPosition restores the saved cursor state. Abbr: SCP, SCOSC.

func (*Decoder) SaveCursorPosition

func (d *Decoder) SaveCursorPosition(params []int) error

SaveCursorPosition saves the cursor state for later use. Abbr: RCP, SCORC.

func (*Decoder) Write

func (d *Decoder) Write(w io.Writer) error

Write writes to w the full HTML fragment with outer div using default colors and inner lines joined with newlines.

type Palette

type Palette uint

Palette sets the ANSI 4-bit color codes to a colorset of RGB values. The ANSI standard never formalized color values and it was left to the system to determine. Wikipedia has a useful table of the common palettes.

const (
	CGA16   Palette = iota // Color Graphics Adapter colorset defined by IBM for the PC in 1981
	Xterm16                // Xterm terminal emulator program for the X Window System colorset from the mid-1980s
	DP2                    // DP2 is a Commodore Amiga era Deluxe Paint II colorset that mimics the colors of CGA16
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL