ansiart

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: May 16, 2026 License: MIT Imports: 6 Imported by: 0

README

Go CodeQL

go-ansiart

Render DOS ANSI art formats as terminal text from Go.

go-ansiart decodes ANSI (.ans), BIN (.bin), and XBin (.xb) byte streams and returns a string containing Unicode text plus terminal escape sequences. It supports ANSI SGR colors, optional XBin palettes, compressed XBin image data, raw textmode BIN cells, multiple character sets, several terminal color modes, and bitmap rendering with embedded or fallback fonts.

The text renderer maps character bytes through Unicode charset tables. The bitmap renderers rasterize embedded XBin fonts when present, otherwise they use the bundled 8x16 fallback font, and can emit Kitty graphics protocol or Sixel output.

Install

go get github.com/Crushless/go-ansiart

Basic Usage

package main

import (
	"fmt"
	"log"
	"os"

	ansiart "github.com/Crushless/go-ansiart"
	"github.com/Crushless/go-ansiart/char_sets"
	"github.com/Crushless/go-ansiart/color_modes"
)

func main() {
	data, err := os.ReadFile("art.xb")
	if err != nil {
		log.Fatal(err)
	}

	out, err := ansiart.Decode(data, ansiart.Options{
		ColorMode: color_modes.NewTrueColorMode(),
		Charset:   char_sets.CP437,
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(out)
}

Use the decoder that matches the source format:

ansiText, err := ansiart.DecodeANSI(ansBytes)
binText, err := ansiart.DecodeBIN(binBytes, ansiart.Options{Columns: 80})
xbinText, err := ansiart.Decode(xbBytes)

Parsing and rendering are separate. Each input format has its own parser, and all parsers produce the same ansiart.Image structure for the shared renderer:

ansiImage, err := ansiart.ParseANSI(ansBytes)
binImage, err := ansiart.ParseBIN(binBytes, ansiart.Options{Columns: 80})
xbinImage, err := ansiart.Parse(xbBytes)

out := ansiart.Render(xbinImage, ansiart.Options{
	ColorMode: color_modes.NewTrueColorMode(),
	Charset:   char_sets.CP437,
})

Images can also be rasterized instead of rendered as Unicode text. XBin embedded fonts are used when present; otherwise the bundled 8x16 fallback font is used:

xbinImage, err := ansiart.Parse(xbBytes)
if err != nil {
	log.Fatal(err)
}

kitty, err := ansiart.RenderKitty(xbinImage, ansiart.Options{Opaque: true})
if err != nil {
	log.Fatal(err)
}

sixel, err := ansiart.RenderSixel(xbinImage, ansiart.Options{Opaque: true})
if err != nil {
	log.Fatal(err)
}

fmt.Print(kitty)
fmt.Print(sixel)

Reader helpers are also available:

ansiText, err := ansiart.DecodeANSIReader(r)
binText, err := ansiart.DecodeBINReader(r)
xbinText, err := ansiart.DecodeReader(r)

CLI

The repository includes a small renderer command:

go run ./cmd -f ansi art.ans
go run ./cmd -f bin -w 80 art.bin
go run ./cmd -f xbin art.xb

Useful flags include:

-f, --format              input format: ansi, bin, or xbin
-s, --charset             character set: cp437, pet, or amiga
-w, --width               ANSI/BIN column width, ignored for XBin
-c, --color-mode          truecolor, monochrome, or halfbright
-a, --halfbright-algorithm palette or luminance
-o, --opaque              render palette index 0 as an opaque background
    --disable-autowrap    disable terminal autowrap while rendering
    --stable-columns      reposition after each cell for stricter alignment

Options

Options values are optional. Defaults are true color, CP437, transparent background index 0, and 80 columns for ANSI/BIN streams.

ansiart.Options{
	ColorMode:       color_modes.NewTrueColorMode(),
	Charset:         char_sets.CP437,
	Columns:         80,
	Opaque:          false,
	FillSolidBlocks: false,
	DisableAutoWrap: false,
	StableColumns:   false,
}

Color Modes

True color preserves ANSI 24-bit SGR colors, converts ANSI 256-color SGR colors to RGB, and uses the embedded XBin palette when present. XBin files without a palette use the default DOS palette.

ansiart.Options{ColorMode: color_modes.NewTrueColorMode()}

Indexed ANSI preserves ANSI 256-color SGR colors and maps XBin/DOS palette indices to terminal ANSI color indices.

ansiart.Options{ColorMode: color_modes.NewIndexedANSIMode()}

Monochrome emits only text and line breaks.

ansiart.Options{ColorMode: color_modes.NewMonochromeMode()}

Half-bright monochrome emits SGR 2 faint/half-bright for dark colors. Palette-column mode follows the classic low/high DOS color split:

ansiart.Options{
	ColorMode: color_modes.NewHalfBrightMode(color_modes.HalfBrightByPaletteColumn),
}

For visual downgrading to monochrome terminals, luminance mode is often better:

ansiart.Options{
	ColorMode: color_modes.NewHalfBrightMode(color_modes.HalfBrightByLuminance),
}

Character Sets

ansiart.Options{Charset: char_sets.CP437}
ansiart.Options{Charset: char_sets.PETSCII}
ansiart.Options{Charset: char_sets.AmigaTopaz}

CP437 is the default when no charset is specified.

Terminal Rendering

By default, background palette index 0 is treated as transparent and rendered as the terminal default background. Set Opaque to render it as a color:

ansiart.Options{Opaque: true}

Some terminals or fonts draw the Unicode full-block glyph with tiny side bearings, which can show thin gaps between solid color cells. Set FillSolidBlocks to render those cells as filled backgrounds instead:

ansiart.Options{FillSolidBlocks: true}

For terminals that handle autowrap differently at the rightmost column, set DisableAutoWrap while rendering rectangular artwork:

ansiart.Options{DisableAutoWrap: true}

For terminals that apply unexpected widths to block-element glyphs, set StableColumns to keep each rendered cell aligned without replacing the artist's chosen characters:

ansiart.Options{StableColumns: true}

Supported Features

Feature State Notes
ANSI byte streams yes CP437 text plus common cursor/SGR CSI
ANSI 24-bit true color SGR yes foreground and background
ANSI 256-color SGR yes preserved or converted by color mode
BIN raw textmode cells yes configurable width, defaults to 80
XBin image data yes uncompressed and compressed streams
XBin embedded palette yes used when present
XBin embedded fonts yes preferred by bitmap/Kitty/Sixel renderers
Bitmap fallback font yes bundled 8x16 PSFU font
Kitty graphics protocol yes PNG payload generated from bitmap rendering
Sixel graphics protocol yes generated from bitmap rendering, up to 256 colors

Documentation

Index

Constants

View Source
const (
	AnsiSub = shared.AnsiSub
	CellLen = shared.CellLen
)

Variables

View Source
var DefaultPalette = shared.DefaultPalette

Functions

func Decode

func Decode(data []byte, options ...Options) (string, error)

func DecodeANSI

func DecodeANSI(data []byte, options ...Options) (string, error)

func DecodeANSIReader

func DecodeANSIReader(r io.Reader, options ...Options) (string, error)

func DecodeBIN

func DecodeBIN(data []byte, options ...Options) (string, error)

func DecodeBINReader

func DecodeBINReader(r io.Reader, options ...Options) (string, error)

func DecodeReader

func DecodeReader(r io.Reader, options ...Options) (string, error)

func Render

func Render(image *Image, options Options) string

func RenderBitmap

func RenderBitmap(image *Image, options Options) (*image.RGBA, error)

func RenderKitty

func RenderKitty(image *Image, options Options) (string, error)

func RenderSixel

func RenderSixel(image *Image, options Options) (string, error)

Types

type Cell

type Cell = shared.Cell

type Font

type Font = shared.Font

type Image

type Image = shared.Image

func Parse

func Parse(data []byte, options ...Options) (*Image, error)

func ParseANSI

func ParseANSI(data []byte, options ...Options) (*Image, error)

func ParseBIN

func ParseBIN(data []byte, options ...Options) (*Image, error)

type Options

type Options = shared.Options

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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