Module Ansi_text

Library for parsing text that contains ANSI escape codes.

Implements types for parsing the whole spec, but with a focus on representing Select Graphic Rendition (SGR) codes through the Style module, Control Sequence Introducer (CSI) codes through the Control module, and terminal hyperlinks (OSC-8) through the Hyperlink module.

More details on SGR: https://en.wikipedia.org/wiki/ANSI_escape_code#Select_Graphic_Rendition_parameters

More details on CSI: https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands

The primary type Ansi_text.t is defined in text_with_ansi.ml, and represents text as a list of `Text and Ansi.t elements. The functions defined in parser.ml and input_output.ml handle parsing to/from strings. These serve three primary purposes: 1) stripping out ANSI codes or rendering them in a more human-readable form for use in expect-tests. 2) performing text-wrapping and similar operations that depend on string-length in a way that ignores ANSI codes and respects Unicode character widths. 3) simplifying ANSI codes in text that contains lots of them.

The Text_with_style_ranges module is intended for applying styles to specific ranges within a text or for parsing text with such styles. This is used by the version of patdiff4 in the Fe web-ui to extract the ranges of the styles that patdiff applied.

module Color : sig ... end
module Attr : sig ... end
module Style : sig ... end
module Control : sig ... end
module Text : sig ... end
module Style_ranges : sig ... end
module Text_with_style_ranges : sig ... end
type element = [
  1. | Ansi_text__.Ansi.t
  2. | `Text of Text.t
]
val compare_element : element -> element -> int
val compare_element__local : element @ local -> (element @ local -> int) @ local
val equal_element : element -> element -> bool
val equal_element__local : element @ local -> (element @ local -> bool) @ local
val sexp_of_element : element -> Sexplib0.Sexp.t
val element_of_sexp : Sexplib0.Sexp.t -> element
val __element_of_sexp__ : Sexplib0.Sexp.t -> element
type t = element list

The primary representation of text with ANSI codes. We should be able to parse any string into this type.

include Ppx_compare_lib.Comparable.S with type t := t
val compare : t -> t -> int
include Ppx_compare_lib.Comparable.S__local with type t := t
include Ppx_compare_lib.Equal.S with type t := t
val equal : t -> t -> bool
include Ppx_compare_lib.Equal.S__local with type t := t
include Ppx_quickcheck_runtime.Quickcheckable.S with type t := t
val quickcheck_generator : t Base_quickcheck.Generator.t
val quickcheck_observer : t Base_quickcheck.Observer.t
val quickcheck_shrinker : t Base_quickcheck.Shrinker.t
include Sexplib0.Sexpable.S with type t := t
include Sexplib0.Sexpable.Of_sexp with type t := t
val t_of_sexp : Sexplib0.Sexp.t -> t
include Sexplib0.Sexpable.Sexp_of with type t := t
val sexp_of_t : t -> Sexplib0.Sexp.t
val width : t -> int

The total length of all Text elements in an Ansi_text.t.

val is_empty : t -> bool

Whether the Ansi_text.t has width 0.

val to_string : t -> string

A string that includes all text and all ANSI codes.

val to_string_hum : t -> string

A string where ANSI codes have been replaced by more-human-readable names.

val to_unstyled : t -> string

A string where all ANSI codes have been removed.

val map : f:(element -> element option) -> t -> t

Map over the elements; if f outputs None the element is unchanged. This makes it easy to write an f that applies only to `Style elements, for example.

val simplify_styles : t -> t

Best-effort to reduce the ansi-codes needed to express the same styles.

val style_at_end : t -> Style.t

Determines what styles are active at the end of the string. Assumes there are no styles active at the start of the text.

val split : pos:int -> t -> t * t

Split at an index in the printable text, terminating and restoring active styles.

val parse : string -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list

Parse a string (possibly) containing ANSI escape sequences into structured form. Malformed sequences are captured as Unknown or Other in the result. The resulting Text_with_ansi.t can always be converted back to a semantically equivalent string via Text_with_ansi.to_string.

val pad : ?char:char -> ?style:Style.t -> width:int -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list

Pad the text to the given length with spaces or another character.

val center : ?char:char -> ?style:Style.t -> width:int -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list

Center the text within the given length, using the given character (default=' '). The left side can end up with one fewer padding character than the right.

val truncate : width:int -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list

Truncate the text at the given length.

val wrap : width:int -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list -> [ Ansi_text__.Ansi.t | `Text of Text.t ] list list

Wrap the text at the given length.

val apply : Style.t -> string -> string

A string where the given styles are turned on at the start and off at the end. Note that this does not parse or minimize the string.

val visualize : string -> string

Print a string with ANSI style codes converted into a more human-readable format.

val minimize : string -> string

Remove redundant ANSI style codes from a string. Note that this is best-effort, and the resulting string is not guaranteed to be globally minimal.

val strip : string -> string

Remove all ANSI style codes from a string.

val to_double_column : width:int -> left:string -> right:string -> (string * string) list

Prepares a pair of strings for printing as two columns in a single buffer. Wraps both strings to the given width, then pads the shorter list to the same length with empty strings, then pads each left-side line to the width with spaces.

module Unknown_esc : sig ... end

Escape sequences we recognize structurally but don't interpret as Ansi_text.